Example #1
0
bool StripifyMeshSubset(ID3DXMesh* mesh,
                        DWORD attribId,
                        ostream& meshfile)
{
    // TODO: Fall back to tri lists if the strip size is too small
    // TODO: Detect when a tri fan should be used instead of a tri list

    // Convert to tri strips
    IDirect3DIndexBuffer9* indices = NULL;
    DWORD numIndices = 0;
    ID3DXBuffer* strips = NULL;
    DWORD numStrips = 0;
    HRESULT hr;
    hr = D3DXConvertMeshSubsetToStrips(mesh,
                                       attribId,
                                       0,
                                       &indices,
                                       &numIndices,
                                       &strips,
                                       &numStrips);
    if (FAILED(hr))
    {
        cout << "Stripify failed\n";
        return false;
    }

    cout << "Converted to " << numStrips << " strips\n";
    cout << "Strip buffer size: " << strips->GetBufferSize() << '\n';
    if (numStrips != strips->GetBufferSize() / 4) 
    {
        cout << "Strip count is incorrect!\n";
        return false;
    }

    bool index32 = false;
    {
        D3DINDEXBUFFER_DESC desc;
        indices->GetDesc(&desc);
        if (desc.Format == D3DFMT_INDEX32)
        {
            index32 = true;
        }
        else if (desc.Format == D3DFMT_INDEX16)
        {
            index32 = false;
        }
        else
        {
            cout << "Bad index format.  Strange.\n";
            return false;
        }
    }

    void* indexData = NULL;
    hr = indices->Lock(0, 0, &indexData, D3DLOCK_READONLY);
    if (FAILED(hr))
    {
        cout << "Failed to lock index buffer: " << D3DErrorString(hr) << '\n';
        return false;
    }

    {
        DWORD* stripLengths = reinterpret_cast<DWORD*>(strips->GetBufferPointer());
        int k = 0;
        for (int i = 0; i < numStrips; i++)
        {
            if (stripLengths[i] == 0)
            {
                cout << "Bad triangle strip (length == 0) in mesh!\n";
                return false;
            }

            if (index32)
            {
                DWORD* indices = reinterpret_cast<DWORD*>(indexData) + k;
                int fanStart = checkForFan(stripLengths[i], indices);
                if (fanStart != 1)
                {
                    DumpTriStrip(stripLengths[i], indices, (int) attribId,
                                 meshfile);
                }
                else
                {
                    DumpTriStripAsFan(stripLengths[i], indices, (int) attribId,
                                      fanStart, meshfile);
                }
            }
            else
            {
                WORD* indices = reinterpret_cast<WORD*>(indexData) + k;
                int fanStart = checkForFan(stripLengths[i], indices);
                if (fanStart != 1)
                {
                    DumpTriStrip(stripLengths[i], indices, (int) attribId,
                                 meshfile);
                }
                else
                {
                    DumpTriStripAsFan(stripLengths[i], indices, (int) attribId,
                                      fanStart, meshfile);
                }
            }

            k += stripLengths[i] + 2;
        }

        cout << "k=" << k << ", numIndices=" << numIndices;
        if (index32)
            cout << ", 32-bit indices\n";
        else
            cout << ", 16-bit indices\n";
    }

    return true;
}