使用Direct 3D的索引缓冲区

时间:2014-01-22 16:09:19

标签: c++ direct3d

我正在编写一个生成球体的程序,并使用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线框中显示的结果:

http://imgur.com/2D4NN5e

提前谢谢你:)

0 个答案:

没有答案