🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Trying to export binary models from a DX9 game

Started by
3 comments, last by cozzie 4 years, 1 month ago

I am trying to build a tool to export and import binary models from an old DX9 game. The models are packed in a single file and I have managed to extract the relevant parts in hexadecimal.

By analyzing the Vertex buffer, I have concluded that it was using the following format. Basically the stride is 24 bytes.

struct CUSTOMVERTEX
{
    CUSTOMVERTEX(FLOAT fx, FLOAT fy, FLOAT fz, DWORD dwcolor, FLOAT fu, FLOAT fv) :
        X(fx), Y(fy), Z(fz), COLOR(dwcolor), U(fu), V(fv) {}
    FLOAT X, Y, Z;
    DWORD COLOR;
    FLOAT U, V;
};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)

I wrote the following program to get the model to show up in DX9

LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
LPDIRECT3DINDEXBUFFER9 i_buffer = NULL;

struct CUSTOMVERTEX
{
    CUSTOMVERTEX(FLOAT fx, FLOAT fy, FLOAT fz, DWORD dwcolor, FLOAT fu, FLOAT fv) :
        X(fx), Y(fy), Z(fz), COLOR(dwcolor), U(fu), V(fv) {}
    FLOAT X, Y, Z;
    DWORD COLOR;
    FLOAT U, V;
};

#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)

void initD3D(HWND hWnd)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);

    D3DPRESENT_PARAMETERS d3dpp;

    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = hWnd;
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
    d3dpp.BackBufferWidth = SCREEN_WIDTH;
    d3dpp.BackBufferHeight = SCREEN_HEIGHT;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    d3d->CreateDevice(D3DADAPTER_DEFAULT,
        D3DDEVTYPE_HAL,
        hWnd,
        D3DCREATE_SOFTWARE_VERTEXPROCESSING,
        &d3dpp,
        &d3ddev);

    init_graphics();

    d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE);    // turn off the 3D lighting
    d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);    // turn off culling
    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer
}

void render_frame(void)
{
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

    d3ddev->BeginScene();

    d3ddev->SetFVF(CUSTOMFVF);

    // set the view transform
    D3DXMATRIX matView;    // the view transform matrix
    D3DXMatrixLookAtLH(&matView,
        &D3DXVECTOR3(0.0f, 0.0f, 15.0f),    // the camera position
        &D3DXVECTOR3(0.0f, 0.0f, 0.0f),      // the look-at position
        &D3DXVECTOR3(0.0f, 1.0f, 0.0f));    // the up direction
    d3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the view transform to matView 

    // set the projection transform
    D3DXMATRIX matProjection;    // the projection transform matrix
    D3DXMatrixPerspectiveFovLH(&matProjection,
        D3DXToRadian(45),    // the horizontal field of view
        (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
        1.0f,   // the near view-plane
        100.0f);    // the far view-plane
    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection

    // set the world transform
    static float index = 0.0f; index += 0.03f; // an ever-increasing float value
    D3DXMATRIX matRotateY;    // a matrix to store the rotation for each triangle
    D3DXMatrixRotationY(&matRotateY, index);    // the rotation matrix
    d3ddev->SetTransform(D3DTS_WORLD, &(matRotateY));    // set the world transform


     // select the vertex buffer to display
    d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
    d3ddev->SetIndices(i_buffer);

    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 4, 0, 1);
    d3ddev->EndScene();
    d3ddev->Present(NULL, NULL, NULL, NULL);
}

void init_graphics(void)
{

    const int buffer_size = 96;

    char buffer[buffer_size];
    std::ifstream myFile;
    myFile.open("Vertices.dat", std::ios::in | std::ios::binary);
    myFile.read(buffer, buffer_size);

    // create a vertex buffer interface called v_buffer
    d3ddev->CreateVertexBuffer(buffer_size,
        0,
        CUSTOMFVF,
        D3DPOOL_MANAGED,
        &v_buffer,
        NULL);

    VOID* pVoid;

    // lock v_buffer and load the vertices into it
    v_buffer->Lock(0, 0, (void**)&pVoid, 0);
    memcpy(pVoid, buffer, buffer_size);
    v_buffer->Unlock();

    const int indices_size = 12;

    char indices[indices_size];
    std::ifstream myFile1;
    myFile1.open("Indexes.dat", std::ios::in | std::ios::binary);
    myFile1.read(indices, indices_size);

    // create a index buffer interface called i_buffer
    d3ddev->CreateIndexBuffer(indices_size,
        0,
        D3DFMT_INDEX16,
        D3DPOOL_MANAGED,
        &i_buffer,
        NULL);

    // lock i_buffer and load the indices into it
    i_buffer->Lock(0, 0, (void**)&pVoid, 0);
    memcpy(pVoid, indices, indices_size);
    i_buffer->Unlock();
}

However, when running the program, I just get a black screen. I had hooked the D3D9::SetStreamSource function in the game and dumped the vertex buffer. I could confirm that the vertex and the indices buffer was the exact same as it was present in the binary format in the file.

I also noticed that few of the vertex buffer cordinates are NaN. I am not sure where the problem lies. Is there any chance that the vertex buffer co-ordinates could be of a different type other than float?

Advertisement

Try here…

https://forum.xentax.com/

You might even have success with the current MultiEx program…

http://multiex.xentax.com/

🙂🙂🙂🙂🙂<←The tone posse, ready for action.

Thanks ?

Did you try to render a simple triangle or quad (hardcoded), using the rest of the code to validate that the issue is in the mesh data?

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement