我正在编写一个生成球体的程序,并使用Direct 3D设备渲染它。我正在使用索引缓冲区,我无法弄清楚为什么我的三角形如此混乱。我测试了发送到顶点缓冲区的顶点的位置,它们看起来都像是在perfekt位置。
使用的基本类型是D3DPT_TRIANGLESTRIP。
如果有人能够指出我对索引缓冲区的理解在哪里,我会非常失败,并且可能会告诉我shizzle是如何工作的,我会很高兴。
这是我的代码:
bool CGameApp::CreateSphere( ULONG nColor, LPDIRECT3DVERTEXBUFFER9 * ppVertexBuffer, LPDIRECT3DINDEXBUFFER9 * ppIndexBuffer, ULONG & nNumVertices, ULONG & nNumFaces )
{
float x, y = 0.0f, z = 0.0f;
float r = 0.0f; // the radius calculated for each circle
ULONG nUsage= D3DUSAGE_WRITEONLY;
LPDIRECT3DVERTEXBUFFER9 pVertexBuffer = NULL;
LPDIRECT3DINDEXBUFFER9 pIndexBuffer = NULL;
HRESULT hRet;
CVertex * pVertex = NULL;
ULONG * pIndex = NULL;
ULONG nSlices, nStacks, jump= 10;
ULONG nStack, nSlice;
if (ppVertexBuffer != NULL) *ppVertexBuffer = NULL;
if (ppIndexBuffer != NULL) *ppIndexBuffer = NULL;
// Validate parameters
if (ppVertexBuffer == NULL | ppIndexBuffer == NULL )
return false;
// The Poles are hardcoded, the rest generated using trigonometry
x = -1.0f;
m_aSphere.push_back(CVertex(x, y, z, 0xFF0000FF));
for (int degreesX = 180; degreesX >= 0; degreesX -= 10) //stack ( 18 stacks )
{
x = (float)cos(D3DXToRadian(degreesX));
for (int degreesY = 0; degreesY < 360; degreesY+= 10) // slices ( 36 slices )
{
r = (float)sin(D3DXToRadian(degreesX));
y = (float)sin(D3DXToRadian(degreesY)) * r; // regulate each unit circle
z = (float)cos(D3DXToRadian(degreesY)) * r; // by multiplying with radius
m_aSphere.push_back(CVertex(x, y, z, nColor));
}
}
nStacks = 180 / jump;
nSlices = 360 / jump;
x = 1.0f; y = 0.0f; z = 0.0f;
m_aSphere.push_back(CVertex(x, y, z, 0xFF0000FF));
//m_aSphere.push_back(CVertex(0, 0, 0, 0xFF0000FF));
/////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////
nNumFaces= nStacks * nSlices * 2;
nNumVertices = m_aSphere.size();
VERTEXPROCESSING_TYPE vp = m_D3DSettings.GetSettings()->VertexProcessingType;
if (vp != HARDWARE_VP && vp != PURE_HARDWARE_VP) nUsage |= D3DUSAGE_SOFTWAREPROCESSING;
hRet = m_pD3DDevice->CreateVertexBuffer(sizeof(CVertex)* m_aSphere.size(), D3DUSAGE_WRITEONLY,
D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &pVertexBuffer, NULL);
if (FAILED(hRet)) return false;
// Lock the vertex buffer ant run in the array generated.
hRet = pVertexBuffer->Lock(0, sizeof(CVertex)* m_aSphere.size(), (void**)&pVertex, 0);
if (FAILED(hRet))
{
pVertexBuffer->Release();
return false;
}
// Load the Vertices into the vertex buffer
for (int i = 0; i <= m_aSphere.size() - 1; i++)
{
*pVertex++ = m_aSphere[i];
}
pVertexBuffer->Unlock(); // Unlock the Vertex Buffer yet again.
// Initialize the Index Buffer
hRet = m_pD3DDevice->CreateIndexBuffer( nNumFaces * 3 * sizeof(ULONG) , nUsage, D3DFMT_INDEX16,
D3DPOOL_MANAGED, &pIndexBuffer, NULL );
if (FAILED(hRet))
{
pIndexBuffer->Release();
pVertexBuffer->Release();
return false;
}
//Try to Lock the index buffer to apply the index stream
hRet = pIndexBuffer->Lock(0, 0, (void**)&pIndex, 0);
if (FAILED(hRet))
{
pIndexBuffer->Release();
pIndex= NULL;
return false;
} // Lock was Successful!
// Here the vertices will be awesomely interpreted by the Index Buffer!!!!!!
// This is where things go wrong apparently
for (nStack = 10; nStack < nStacks; nStack++)
{
for (nSlice = 10; nSlice < nSlices; nSlice++)
{
*pIndex++ = nStack * nSlice;
*pIndex++ = (nStack + 1) * nSlice;
}
*pIndex++ = (nStack + 1) * nSlice; // Make degenerate triangle, then start new stack!
}
pIndexBuffer->Unlock(); // unlock the index buffer;
//return pointers
*ppVertexBuffer = pVertexBuffer;
*ppIndexBuffer = pIndexBuffer;
// Success!
return true;
}
这是fillmode线框中显示的结果:
提前谢谢你:)