Jump to content
  • Advertisement
Sign in to follow this  
Sync Views

D3D9 problem

This topic is 3821 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm working on a class that can draw an entire object (eg a ship + it's turrets) in one go, and eventauly be able to batch several together but I'm getting this error in the render function :( Direct3D9: (ERROR) :Index stream does not have required number of indices. DrawIndexedPrimitive failed.
	LibAdvObject::LibAdvObject(Core* _core, Texture* _tex, unsigned _icount, unsigned _vcount)
	: ib(0), vb(0), TriCount(_icount), VerCount(_vcount)
	{
		Owner = _core;
		Tex = _tex;
	}
	void LibAdvObject::Release()
	{
		SafeRelease(&vb);
		SafeRelease(&ib);
		SafeRelease(&Tex);
		delete this;
	}
	bool LibAdvObject::Render(const std::vector<fw::math::Matrix<4,4>> &Transforms)
	{
		//This will eventualy use a cutom vertex shader to link vertices to additional matrixces.
		//only changes them if there no already set
		((LibCore*)Owner)->SetTex(((LibTexture*)Tex)->Tex);
		((LibCore*)Owner)->SetVb (vb, sizeof(AdvObjectVertex));
		((LibCore*)Owner)->SetIb (ib);

		((LibCore*)Owner)->D3dDevice->SetTransform(D3DTS_WORLD, &D3DXMATRIX((float*)&Transforms[0].m));
		((LibCore*)Owner)->D3dDevice->DrawIndexedPrimitive(
			D3DPT_TRIANGLELIST, 0, 0, VerCount, 0, TriCount);
		//4 vertices, 6 indexes
		//VerCount = 4, TriCount = 3
		return true;
	}
	DLL AdvObject* AdvObjectCreate(Core* Owner, Texture* Tex,
		const std::vector<AdvObjectVertex> &Vertices,
		const std::vector<unsigned short>  &Indexes)
	{
		LibAdvObject *Obj = new LibAdvObject(Owner,Tex, Indexes.size()/3, Vertices.size());
		//VERTEX
		{
			((LibCore*)Obj->Owner)->D3dDevice->CreateVertexBuffer(
				Vertices.size()*sizeof(AdvObjectVertex), D3DUSAGE_WRITEONLY,
				AdvObjectVertex::FVF, D3DPOOL_MANAGED, &Obj->vb, NULL);
			
			AdvObjectVertex* v=NULL;
			Obj->vb->Lock(0, 0, (void**)&v, NULL);
			std::vector<AdvObjectVertex>::const_iterator it = Vertices.begin();
			while(it != Vertices.end())*v++ = *it++;
			Obj->vb->Unlock();
		}

		//INDEX
		{
			((LibCore*)Obj->Owner)->D3dDevice->CreateIndexBuffer(
				Indexes.size(), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,
				D3DPOOL_MANAGED, &Obj->ib, NULL);
			 
			unsigned short* i=NULL;//short == 16 bit == format
			Obj->ib->Lock(0, 0, (void**)&i, NULL);
			std::vector<unsigned short>::const_iterator it = Indexes.begin();
			while(it != Indexes.end())*i++ = *it++;
			Obj->ib->Unlock();
		}
		return Obj;
	}

Also. Since the index buffer values are smaller than the vertex buffers, Is there some way I can attach an additional value through the index buffer. Mainly the component id that will link a vertex to a matrix (So I don't need a set of vertices for every, quite likly identical turret, asnd also because it's lighter to have 20 repeats in the index buffer rather than the vertex buffer for batching multiple objects together. Or is the extra overhead of having additional vertices as well as additional indexes not worth worring about?

Share this post


Link to post
Share on other sites
Advertisement
Where do you come up with the value of "TriCount"? Surely that's where your problem is...the value you pass as the "PrimitiveCount" parameter of DrawIndexedPrimitive has to be less than 1/3 the number of indices in the specified index buffer.

Also as far as your instancing...it sounds like you're trying to implement shader constant instancing. For this you have the have an "extended" vertex buffer to go along with your extended index buffer...you can't store any "extra" info in the index buffer therefore it has to go in the vertex buffer. The alternative is hardware instancing which allows you to specify a separate buffer containing only per-instance data, but this requires SM3.0 hardware.

Share this post


Link to post
Share on other sites
Ahh I see the problem now. You have to specify the size of the index buffer in bytes when you create it, which in your case is Indexes.size() * 2 (since you're using 16-bit indices).

Share this post


Link to post
Share on other sites
Ok. The errors gone but it's not rendering my test shape :(

d3dint

bool LibCore::D3dCreate()
{
if(!Wnd)
{
return false;
}
if(D3d)
{
return false;
}

D3d = Direct3DCreate9(D3D_SDK_VERSION);
if(!D3d)
{
return false;
}

ZeroMemory(&D3dCaps, sizeof(D3dCaps));
if(FAILED(D3d->GetDeviceCaps
(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &D3dCaps)))
{
D3d->Release();
D3d = 0;
return false;
}

//Setup present parameters
D3DPRESENT_PARAMETERS D3dParams;
ZeroMemory(&D3dParams, sizeof(D3dParams));
D3dParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
D3dParams.hDeviceWindow = Wnd;
D3dParams.BackBufferCount = 1;
D3dParams.EnableAutoDepthStencil = true;
D3dParams.AutoDepthStencilFormat = D3DFMT_D16;


D3DDISPLAYMODE d3ddm;
RECT rWindow;
if(!GetClientRect (Wnd, &rWindow))
{
D3d->Release();
D3d = 0;
return false;
}

//Get display mode
D3d->GetAdapterDisplayMode (D3DADAPTER_DEFAULT, &d3ddm);

//Setup backbuffer
D3dParams.Windowed = true;
D3dParams.BackBufferFormat = D3DFMT_A8R8G8B8;
D3dParams.BackBufferWidth = rWindow.right - rWindow.left;
D3dParams.BackBufferHeight = rWindow.bottom - rWindow.top;

//Check if hardware vertex processing is available
if (D3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
{
//Create device with hardware vertex processing
if(FAILED(D3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, Wnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &D3dParams, &D3dDevice)))
{
D3d->Release();
D3d = 0;
return false;
}
}
else
{
//Create device with software vertex processing
if(FAILED(D3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, Wnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &D3dParams, &D3dDevice)))
{
D3d->Release();
D3d = 0;
return false;
}
}
D3DXMATRIX Projection;
//set default projections
D3DXMatrixOrthoLH(&Projection,
(float)D3dParams.BackBufferHeight, (float)D3dParams.BackBufferHeight,
0, 1000000);
D3dDevice->SetTransform(D3DTS_PROJECTION, &Projection);

//Set vertex shader <-- not using any by default
D3dDevice->SetVertexShader(NULL);
D3dDevice->SetFVF(dx::VertexBasic::FVF);

//Create vertex buffer and set as stream source
D3dDevice->CreateVertexBuffer(sizeof(dx::VertexBasic) * 4,
NULL, dx::VertexBasic::FVF, D3DPOOL_MANAGED, &VertexBufferBase, NULL);
dx::VertexBasic* vb = NULL;
VertexBufferBase->Lock(NULL,NULL, (void**)&vb, NULL);

//quad
vb[0] = dx::VertexBasic(-0.5,-0.5,0, 0,0, 0xFFFFFFFF);
vb[1] = dx::VertexBasic( 0.5,-0.5,0, 1,0, 0xFFFFFFFF);
vb[2] = dx::VertexBasic( 0.5, 0.5,0, 1,1, 0xFFFFFFFF);
vb[3] = dx::VertexBasic(-0.5, 0.5,0, 0,1, 0xFFFFFFFF);

VertexBufferBase->Unlock();

D3dDevice->SetStreamSource (0, VertexBufferBase, 0, sizeof(dx::VertexBasic));

//Setup rendering states
D3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
D3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
D3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
D3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
D3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
D3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
D3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

//get pointer to render target
D3dDevice->GetRenderTarget(0, &BackBuffer);

//Successfully initalized Direct3D
return true;
}



before loop

dx::Texture* Tex = dx::TextureCreateFromFile(This, "circle.png");
//0-----1
//| / |
//| / |
//3-----2
std::vector<dx::AdvObjectVertex> v;
v.push_back(dx::AdvObjectVertex(-50,-50,0, 0,0, 0xFF0000FF, 0));
v.push_back(dx::AdvObjectVertex( 50,-50,0, 1,0, 0xFF0000FF, 0));
v.push_back(dx::AdvObjectVertex( 50, 50,0, 1,1, 0xFF0000FF, 0));
v.push_back(dx::AdvObjectVertex(-50, 50,0, 0,1, 0xFF0000FF, 0));

std::vector<unsigned short> i;
i.push_back(0);
i.push_back(1);
i.push_back(3);
i.push_back(1);
i.push_back(2);
i.push_back(3);

Circle = dx::AdvObjectCreate(This, Tex, v,i);



render

D3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,0xFF000000, 0, 0);
D3dDevice->BeginScene();

math::Matrix<4,4> Mat;
math::MatrixCreateTranslation(400,300,0, &Mat);
std::vector<math::Matrix<4,4>> Transforms;
Transforms.push_back(Mat);
Circle->Render(Transforms);

D3dDevice->EndScene();
D3dDevice->Present(NULL,NULL,NULL,NULL);




[Edited by - Sync Views on June 27, 2008 3:45:51 AM]

Share this post


Link to post
Share on other sites
I have checked all my code again, but I still can't see why it isn't drawing, but I'm sure it's in one of those 6 code blocks...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!