Skip to main content
gamedev.net
🔒 Locked

Triangle problem persists - source code posted

Started by the_grip 4 replies 250+ views
Original Post
the_grip
the_grip
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]
"You call him Dr. Grip, doll!"
Jim Adams
Jim Adams
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.

the_grip
the_grip
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!"
"You call him Dr. Grip, doll!"
Sharky
Sharky
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
the_grip
the_grip
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!"
"You call him Dr. Grip, doll!"
the_grip
the_grip
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!"
"You call him Dr. Grip, doll!"

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.