c++directx-9

Directx 9 Rotate Textured Vertex


I used vertexes to draw textures and did not have a problem but now i am trying to rotate some textures and getting black screen.

This is my initial code to draw texture with vertex.

struct CUSTOM_VERTEX { FLOAT X, Y, Z, RHW, U, V; };
#define CUSTOM_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1 )

CUSTOM_VERTEX vertices[4] = 
{   //X, Y, Z, RHW, U, V
    100.0f, 100.0f, 0.0f, 1.0f, 0.0f, 0.0f, 
    1000.0f, 100.0f, 0.0f, 1.0f, 1.0f, 0.0f,
    100.0f,  750.0f, 0.0f, 1.0f, 0.0f, 1.0f,
    1000.0f, 750.0f, 0.0f, 1.0f, 1.0f, 1.0f
};

LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
d3d9device->CreateVertexBuffer(4 * sizeof(CUSTOM_VERTEX),
    0,
    CUSTOM_FVF,
    D3DPOOL_MANAGED,
    &v_buffer,
    NULL);

VOID* pVoid;
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();                         

d3d9device->SetFVF(CUSTOM_FVF);
d3d9device->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOM_VERTEX));

d3d9device->SetTexture(0, d3d9texture);

d3d9device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

I read that RHW describes pre-transformed vertices. Then i changed CUSTOM_VERTEX, CUSTOM_FVF and added SetTransform.

struct CUSTOM_VERTEX { FLOAT X, Y, Z, U, V; };
#define CUSTOM_FVF (D3DFVF_XYZ | D3DFVF_TEX1 )

CUSTOM_VERTEX vertices[4] =
{   //X, Y, Z, U, V
    100.0f, 100.0f, 0.0f, 0.0f, 0.0f,
    1000.0f, 100.0f, 0.0f, 1.0f, 0.0f,
    100.0f, 750.0f, 0.0f, 0.0f, 1.0f,
    1000.0f, 750.0f, 0.0f, 1.0f, 1.0f
};

//CreateVertexBuffer, memcpy, SetFVF and SetStreamsource are the same as above

D3DXMATRIX worldMatrix;
D3DXMatrixRotationZ(&worldMatrix, D3DXToRadian(90));
d3d9device->SetTransform(D3DTS_WORLD, &worldMatrix);

//SetTexture and DrawPrimitive are the same as above

I also tried adding view and projection matrix.

D3DXMATRIX viewMatrix;
D3DXMatrixLookAtLH(&viewMatrix,
                   &D3DXVECTOR3 (0.0f, 0.0f, 10.0f),
                   &D3DXVECTOR3 (0.0f, 0.0f, 0.0f),
                   &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));
d3d9device->SetTransform(D3DTS_VIEW, &viewMatrix);

D3DXMATRIX projectionMatrix;
D3DXMatrixPerspectiveFovLH(&projectionMatrix,
                           D3DXToRadian(45),
                           width / height,
                           1.0f,
                           1000.0f);
d3d9device->SetTransform(D3DTS_PROJECTION, &projectionMatrix);

I changed pEye and pAt inputs of D3DXMatrixLookAtLH method to center of vertex but again black screen.


Solution

  • My problem was using the same points for both pre-transformed (RHW) and non pre-transformed vertices.

    Solved problem like below.

    struct CUSTOM_VERTEX { FLOAT X, Y, Z, U, V; };
    #define CUSTOM_FVF (D3DFVF_XYZ | D3DFVF_TEX1 )
    
    float halfBackBufferWidth = backBufferWidth / 2.0f;
    float halfBackBufferHeight = backBufferHeight / 2.0f;
    
    CUSTOM_VERTEX vertices[4] =
    {   //X, Y, Z, U, V
        { halfBackBufferWidth - 100.0f, halfBackBufferHeight - 100.0f, 0.0f, 0.0f, 0.0f },
        { halfBackBufferWidth - 1000.0f, halfBackBufferHeight - 100.0f, 0.0f, 1.0f, 0.0f },
        { halfBackBufferWidth - 100.0f, halfBackBufferHeight - 750.0f, 0.0f, 0.0f, 1.0f },
        { halfBackBufferWidth - 1000.0f, halfBackBufferHeight - 750.0f, 0.0f, 1.0f, 1.0f }
    };
    
    LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
    d3d9device->CreateVertexBuffer(4 * sizeof(CUSTOM_VERTEX),
        0,
        CUSTOM_FVF,
        D3DPOOL_MANAGED,
        &v_buffer,
        NULL);
    
    VOID* pVoid;
    v_buffer->Lock(0, 0, (void**)&pVoid, 0);
    memcpy(pVoid, vertices, sizeof(vertices));
    v_buffer->Unlock();                         
    
    d3d9device->SetFVF(CUSTOM_FVF);
    d3d9device->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOM_VERTEX));
    
    D3DXMATRIX worldMatrix;
    D3DXMatrixRotationZ(&worldMatrix, D3DXToRadian(45));
    d3d9device->SetTransform(D3DTS_WORLD, &worldMatrix);
    
    D3DXMATRIX viewMatrix;
    D3DXMatrixLookAtLH(&viewMatrix,
                       &D3DXVECTOR3 (0.0f, 0.0f, halfBackBufferHeight),
                       &D3DXVECTOR3 (0.0f, 0.0f, 0.0f),
                       &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));
    d3d9device->SetTransform(D3DTS_VIEW, &viewMatrix);
    
    D3DXMATRIX projectionMatrix;
    D3DXMatrixPerspectiveFovLH(&projectionMatrix,
                               D3DXToRadian(90),
                               backBufferWidth / backBufferHeight,
                               1.0f,
                               halfBackBufferHeight);
    d3d9device->SetTransform(D3DTS_PROJECTION, &projectionMatrix);
    
    d3d9device->SetTexture(0, d3d9texture);
    
    d3d9device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
    

    I dont want to add light so I disable it. If I dont disable it, I get black screen.

    d3d9device->SetRenderState(D3DRS_LIGHTING, FALSE);