Original Post
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.
[edited by - the_grip on November 7, 2002 11:48:52 AM]
//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;
}