Archived

This topic is now archived and is closed to further replies.

the_grip

Triangle problem persists - source code posted

Recommended Posts

i'm having an immensely frustating time with D3D in DX8. i'm a professional client/server programmer (2.5 years), but this stuff is a whip. i've got the concepts easily, but the implementation is causing me to want to rips my eyeballs out. Anyways, i can't get one $%@#&*! triangle to render. i scratched everything i had that wasn't working previously, aiming to keep it simple and get one triangle on the screen. Now i get the debug message "Not enough indicies in the index stream" or something like that when i call DrawIndexedPrimitive (DrawPrimitive shows nothing, BTW) - i know what that message means, but it sure seems like i have 3 indicies and 3 verticies ( = 1 triangle). i'm trying to add some abstraction for future use. Here's all the relevant code. Any help is appreciated, and if you solve it, i'll forever be in your debt.
        
//triangle class (derived from a generic object class):

//struct TRIANGLEVERTEX

//{

//	D3DXVECTOR3 p;

//	D3DXVECTOR3 n;

//	FLOAT       tu, tv;

//};

//FVF is (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)

//D3DXVECTOR3 m_vPt0;

//D3DXVECTOR3 m_vPt1;

//D3DXVECTOR3 m_vPt2;

//TRIANGLEVERTEX m_pTriangleVertices[3];

//WORD m_pwObjectIndices[3];


//constructor of CD3DApplication:

MyApp::MyApp
{
     m_bUseDepthBuffer = TRUE;
     //variable initialization...

}

//OneTimeSceneInit - triangle classes initialize function:

//triangle has been initialized with the following:

//m_vPt0 = D3DXVECTOR3(-1.0f, 1.0f, -1.0f)

//m_vPt1 = D3DXVECTOR3(1.0f, 1.0f, -1.0f)

//m_vPt2 = D3DXVECTOR3(-1.0f, 0.0f, -1.0f)

BOOL CTriangleObject::InitializeObject()
{
	if(!m_bInitialized)
	{
		ClearVerticiesAndIndicies();

		//front normal

		D3DXVECTOR3 nFront; C3DGeometryUtility::CrossProduct(&m_vPt2, &m_vPt0, &m_vPt1, &nFront);  //Cross product is my function - returns 0,0,-1 as is

		D3DXVec3Normalize(&nFront, &nFront);
		
		// vertices

		m_pTriangleVertices[0].p = m_vPt0;	m_pTriangleVertices[1].p = m_vPt1;	m_pTriangleVertices[2].p = m_vPt2;		
		m_pTriangleVertices[0].n = nFront;	m_pTriangleVertices[1].n = nFront;	m_pTriangleVertices[2].n = nFront;	
		m_pTriangleVertices[0].tu = 0.0;	m_pTriangleVertices[1].tu = 1.0;	m_pTriangleVertices[2].tu = 1.0;	
		m_pTriangleVertices[0].tv = 0.0;	m_pTriangleVertices[1].tv = 1.0;	m_pTriangleVertices[2].tv = 0.0;	

		//setup the index buffer 

		m_pwObjectIndices[0] = 0;	m_pwObjectIndices[1] = 1;	m_pwObjectIndices[2] = 2;

		m_pVertexBuffer = (VOID*)m_pTriangleVertices;
		m_pIndexBuffer = (VOID*)m_pwObjectIndices;
		m_dwVertexBufferSize = sizeof(m_pTriangleVertices);
		m_dwIndexBufferSize = sizeof(m_pwObjectIndices);

		m_pVertexStructure = &m_pTriangleVertices;

		m_bInitialized = TRUE;
	}

	return TRUE;
}

//CHECKFAIL is just a quick macro i wrote for the if(SUCCEEDED) stuff

HRESULT MyApp::RestoreDeviceObjects()
{
	D3DXVECTOR3			vEyePt( 0.0f, 0.0f, 2.0f );
	D3DXVECTOR3			vLookAtPt( 0.0f, 0.0f, 1.0f );
	D3DXVECTOR3			vUpVec( 0.0f, 1.0f, 0.0f );

	D3DXMATRIX matWorld, matView, matProj;
	D3DXMatrixIdentity( &matWorld );

	FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
	D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 500.0f );

	m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
	m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
	m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

	for(long nIndex = 0; nIndex < m_pObjectList->GetSize(); nIndex++)
	{
		_BaseObject *pObject = m_pObjectList->GetAt(nIndex);
		CHECKFAIL( pObject->RestoreDeviceObjects(m_pd3dDevice), E_FAIL);
	}

	return S_OK;
}

//base class for triangle - called in RestoreDeviceObjects

HRESULT _BaseObject::RestoreDeviceObjects(LPDIRECT3DDEVICE8 pd3dDevice)
{
	//vertex buffer...

	try
	{
		CHECKFAIL( pd3dDevice->CreateVertexBuffer( m_dwVertexBufferSize, 0, m_dwFVF, D3DPOOL_MANAGED, &m_pVB ), E_FAIL );

		VOID *pVertices;
		CHECKFAIL( m_pVB->Lock( 0, m_dwVertexBufferSize, (BYTE**)&pVertices, 0 ), E_FAIL );

		memcpy( pVertices, m_pVertexBuffer, m_dwVertexBufferSize );

		m_pVB->Unlock();

		//index buffer...

		CHECKFAIL( pd3dDevice->CreateIndexBuffer( m_dwIndexBufferSize, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pIB ), E_FAIL );

		VOID *pIndices = NULL;
		CHECKFAIL( m_pIB->Lock( 0, m_dwIndexBufferSize, (BYTE**)&pIndices, 0), E_FAIL );

		memcpy( pIndices, m_pIndexBuffer, m_dwIndexBufferSize );

		m_pIB->Unlock();
	}
	catch(...)
	{
		return E_FAIL;
	}

	return S_OK;
}

//Rendering:

HRESULT MyApp::Render()
{
    // Clear the render target

    m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0L );

	CHECKFAIL( m_pd3dDevice->BeginScene(), E_FAIL )
	else
	{
		//i know the loop isn't most efficient, but i'm shooting for simplicity

		for(long nIndex = 0; nIndex < m_pObjectList->GetSize(); nIndex++)
		{
			_BaseObject *pObject = m_pObjectList->GetAt(nIndex);
			pObject->Render(m_pd3dDevice); //calls the triangle's render function

		}

		m_pd3dDevice->EndScene();
	}
}

HRESULT _BaseObject::Render(LPDIRECT3DDEVICE8 pd3dDevice)
{
	ASSERT(pd3dDevice);

	pd3dDevice->SetStreamSource( 0, m_pVB, m_dwVertexBufferSize );
	pd3dDevice->SetVertexShader( m_dwFVF );
	pd3dDevice->SetIndices( m_pIB, 0 );

	pd3dDevice->DrawIndexedPrimitive( m_enPrimitiveType, m_nIBMinIndex, m_nNumVertices, m_nIBStartIndex, m_nNumVertices );

	return S_OK;
}
        
[edited by - the_grip on November 7, 2002 11:48:52 AM]

Share this post


Link to post
Share on other sites
While I didn''t look over the entire bit of code, here''s one that sticks out:

m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0f, 0L );

You specify that you want to use a depth buffer, but you are not clearing it. Change D3DCLEAR_TARGET to D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER and change 0.0f to 1.0f.

Also, you''re looking at the backside of the triangle. Change the z values of the triangle to something in the positive axis, like +5. Either that or change your eye point to be on the negative axis, something like -10.

Share this post


Link to post
Share on other sites
Thanks for the reply. i knew there had to be little details that would cause problems on down the line, but i haven''t got there yet (so thanks in advance ). i''m greener than green at this, and i really appreciate the help.

Does anyone know why i would get an error on the index count?

"You call him Dr. Grip, doll!"

Share this post


Link to post
Share on other sites
I haven''t checked through all your code but take a look at the Render method and, more specifically, the m_dwVertexBufferSize member. This value is passed to the SetStreamSource function and I think this is your problem.

m_dwVertexBufferSize is, I asssume, the size of your entire vertex buffer in bytes. However the SetStreamSource function requires the size, in bytes, of a single component in that vertex buffer - i.e. the byte size (stride) of a single vertex. In this case you need to pass the size of:


  
struct TRIANGLEVERTEX
{
D3DXVECTOR3 p;
D3DXVECTOR3 n;
FLOAT tu, tv;
};


Hence the call...
pd3dDevice->SetStreamSource(0,m_pVB,sizeof(TRIANGLEVERTEX));
...should fix the problem.

I hope.

Regards,
Sharky

Share this post


Link to post
Share on other sites
Sharky, you might be on to something here. You are right - the size i pass in is the entire size of the vertex buffer (in this case, TRIANGLEVERTEX[3] ( = 96). If it is the stride, then it should be 32 (TRIANGLEVERTEX). i''ll give it a shot when i get home - that looks like what might be the problem.

Thanks a ton for looking at this!

"You call him Dr. Grip, doll!"

Share this post


Link to post
Share on other sites
Thanks you all... the stuff works perfect now.

i''m having great success learning this stuff since i got that fix, and i really appreciate the help.

"You call him Dr. Grip, doll!"

Share this post


Link to post
Share on other sites