D3D9 problem

Started by
5 comments, last by Sync Views 15 years, 10 months ago
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?
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.
Quote:
LibAdvObject *Obj = new LibAdvObject(Owner,Tex, Indexes.size()/3, Vertices.size());
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).
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]
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...
...I still havn't solved this, I see no reason why it shouldn't work...

This topic is closed to new replies.

Advertisement