[Solved] can't see vertices with colors ( DX9 )

Started by
2 comments, last by stream775 6 years, 2 months ago

EDIT: I've got everything working, even animations. This topic can be locked.  Also, the file format was very horrible, so I was doing a number of things wrong.

Hello!

          I wrote a simple bones system that renders a 3D model with bones using software vertex processing. The model is loaded perfectly, but I can't see any colors on it. For illustration, you can see the 3D lines list, the bones ( 32 bones ) are in correct position ( bind pose ).
 

Spoiler

 

Capture.PNG.c2dc0eab78ad6af20f2b9c7848fd66c2.PNG

Now, here's the problem. When I try to render the mesh with transformations applied then I see this:

Spoiler

Capture.PNG.93cdd5c99144baf21ba76995a98f44ce.PNG

As you can see the 3D lines are disappearing, I'm guessing the model is rendered, but the colors are not visible for whatever reason. I tried moving my camera around the line list, but all I can see is some lines disappearing due to the black color of vertices? I'm not loading any textures, am I suppose to load them?

However, if I render the vertices without applying ANY bone transformations, then I can see it, but it's a mess, obviously. If you're wondering why it's red, I have set color of these vertices ( only half of them ) to red and the rest half is white.

Spoiler

Capture.PNG.624693b44013ee0b570ac5c6a5301184.PNG

First of all, my apologies for the messy code, but here it is:

I'm not sure if vertices are suppose to have weights in them for software vertex processing. I'm storing them in a container, so you don't see them here.


#define CUSTOMFVF ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE )

struct CUSTOMVERTEX 
{ 
    D3DXVECTOR3  Position;
    D3DXVECTOR3  Normal;
    DWORD        Color; 
};

This is how I store the vertices in container and give them red and white color:

Spoiler


bool isWhite = true;

for (RwInt32 i = 0; i < TotalVertices; i++)
{
    RwV3d * Vertex = VerticesToBlend [ i ];
    RwV3d * Normal = NormalsToBlend  [ i ];

    DWORD color;

    isWhite = !isWhite;

    if (isWhite)
        color = D3DCOLOR_XRGB ( 255, 255, 255 );
    else
        color = D3DCOLOR_XRGB ( 255, 0, 0 );

    CUSTOMVERTEX BlendedVertex = { 

        D3DXVECTOR3 ( Vertex->X, Vertex->Y, Vertex->Z ),   
        D3DXVECTOR3 ( Normal->X, Normal->Y, Normal->Z ),
		color 
    };
}

 

This is how I create the device:

Spoiler


void initializeDirect3D ( HWND hWnd )
{
    HRESULT hResult;

    Direct3dInterface = Direct3DCreate9(D3D_SDK_VERSION);       

    if ( !Direct3dInterface )
    {
        //Handle error

    }


    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;
                                                   
    hResult = Direct3dInterface->CreateDevice
    (
        D3DADAPTER_DEFAULT,
        D3DDEVTYPE_HAL,
        hWnd,
        D3DCREATE_SOFTWARE_VERTEXPROCESSING,
        &d3dpp,
        &Direct3dDevice
    );

    if (FAILED(hResult))
    {

    }
     
    Direct3dDevice->SetRenderState ( D3DRS_LIGHTING, FALSE );          
    Direct3dDevice->SetRenderState ( D3DRS_CULLMODE, D3DCULL_NONE );   
    Direct3dDevice->SetRenderState ( D3DRS_ZENABLE, TRUE );           
}

 

For every frame:

Spoiler


void renderFrame ( )
{
    Direct3dDevice->Clear ( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0 );
    Direct3dDevice->BeginScene ( );  

    updatePipeLine ( );

    drawBones2DLines ( );
  
    Direct3dDevice->SetFVF ( CUSTOMFVF );
    Direct3dDevice->SetStreamSource(0, VertexBufferTranformed, 0, sizeof(CUSTOMVERTEX));
    Direct3dDevice->SetIndices ( IndexBuffer );

    BoneMesh * pBoneMesh = PedModel->getBoneMeshPointer ();

    // Update Final Transformation Matrix for all bones
    for ( size_t i = 0; i < pBoneMesh->Bones.size (); i++ )
    {
        D3DXMatrixMultiply 
        (
          &pBoneMesh->Bones [ i ].currentBoneMatrix,           // Final Transformation Matrix
          &pBoneMesh->Bones [ i ].TransformationMatrix,        // Offset Matrix ( local tranform )
          &pBoneMesh->Bones [ i ].CombinedTransformationMatrix // Combined Matrix
        );
    }

    // Update the skinned mesh
    BYTE *src = NULL, *dest = NULL;

    VertexBufferOriginal->Lock ( 0, 0, (void**)&src, D3DLOCK_READONLY );
    VertexBufferTranformed->Lock ( 0, 0, (void**)&dest, 0 );

    PedModel->UpdateSkinnedMesh ( src, dest );

    VertexBufferOriginal->Unlock();
    VertexBufferTranformed->Unlock();



    Geometry * DffGeometry =  PedModel->DFFElement->getClump()->getGeometryPointer ( 0 );

    RwInt32 TotalVertices  = DffGeometry->getTotalVertices ();
    RwInt32 TotalTriangles = DffGeometry->getTotalTriangles ();

    Direct3dDevice->DrawIndexedPrimitive ( D3DPT_TRIANGLELIST, 0, 0, TotalVertices, 0, TotalTriangles );


    Direct3dDevice->EndScene ( );   
    Direct3dDevice->Present ( NULL, NULL, NULL, NULL );  
}

 

This is the UpdateSkinnedMesh method:

Spoiler


void Ped::UpdateSkinnedMesh ( const void * src_vertices, void * dst_vertices )
{
    const std::vector < RwUInt8V4d * >      &  VertexBoneIndices   = pSkinPLG->getVertexBoneIndices ();
    const std::vector < RwMatrixWeights * > &  VertexWeights       = pSkinPLG->getVertexBoneWeights ();

    for ( RwInt32 VertexIndex = 0; VertexIndex < TotalVertices; VertexIndex ++ ) 
    {
        D3DXVECTOR3 * SourcePosition      = (D3DXVECTOR3*)((BYTE*)src_vertices + sizeof(CUSTOMVERTEX) * VertexIndex );
        D3DXVECTOR3 * DestinationPosition = (D3DXVECTOR3*)((BYTE*)dst_vertices + sizeof(CUSTOMVERTEX) * VertexIndex );

        D3DXVECTOR3 * SourceNormal      = (D3DXVECTOR3*)((BYTE*)src_vertices + 
                                          ( sizeof ( CUSTOMVERTEX ) * VertexIndex ) + sizeof ( D3DXVECTOR3 ) );

        D3DXVECTOR3 * DestinationNormal = (D3DXVECTOR3*)((BYTE*)dst_vertices + 
                                          ( sizeof ( CUSTOMVERTEX ) * VertexIndex ) + sizeof ( D3DXVECTOR3 ) );

        /* Reset position */
        memset ( DestinationPosition, 0, sizeof ( D3DXVECTOR3 ) );

        /* Reset normal */
        memset (DestinationNormal, 0, sizeof ( D3DXVECTOR3 ) );

        RwUInt8V4d      * pVertexBoneIndices = VertexBoneIndices [ VertexIndex ];
        RwMatrixWeights * pVertexWeights     = VertexWeights     [ VertexIndex ];


        for (DWORD i = 0; i < 4; i++)
        {
            Bone * pBone = getBonePointerByIndex ( pVertexBoneIndices->Element[i] );


            // Final Transformation Matrix
            const D3DXMATRIX & CurrentBoneMatrix        = getCurrentBoneMatrixReference ( pVertexBoneIndices->Element [i] );

            // Offset Matrix
            const D3DXMATRIX & TransformationBoneMatrix = getTransformationBoneMatrixReference ( pVertexBoneIndices->Element[i] );

            //Inverse Bone Matrix 
            D3DXMATRIX bone_inverse; 

            D3DXMATRIX matrix;

            // I tried taking inverse of both Offset Matrix and Combined Matrix
            D3DXMatrixInverse(&bone_inverse, NULL, &TransformationBoneMatrix);
            //D3DXMatrixInverse(&bone_inverse, NULL, &pBone->CombinedTransformationMatrix);

            D3DXMatrixMultiply(&matrix, &CurrentBoneMatrix, &bone_inverse);
            D3DXMatrixMultiply(&matrix, &matrix, &TransformationBoneMatrix);

            D3DXVECTOR3 position;
            D3DXVec3TransformCoord ( &position, SourcePosition, &matrix );

            DestinationPosition->x += pVertexWeights->weights [ i ] * position.x;
            DestinationPosition->y += pVertexWeights->weights [ i ] * position.y;
            DestinationPosition->z += pVertexWeights->weights [ i ] * position.z;


            D3DXVECTOR3 normal;
            D3DXMATRIX matrix_normal;
            
            D3DXMatrixMultiply(&matrix_normal, &TransformationBoneMatrix, &CurrentBoneMatrix);

            D3DXVec3TransformNormal(&normal, SourceNormal, &bone_inverse);
            D3DXVec3TransformNormal(&normal, &normal, &matrix_normal);

            DestinationNormal->x += pVertexWeights->weights [ i ] * normal.x;
            DestinationNormal->y += pVertexWeights->weights [ i ] * normal.y;
            DestinationNormal->z += pVertexWeights->weights [ i ] * normal.z;
        }
    
       if ((DestinationNormal->x != 0.0f) && (DestinationNormal->y != 0.0f) && (DestinationNormal->z != 0.0f))
       {
          D3DXVec3Normalize ( DestinationNormal, DestinationNormal );
       }

    }
}

 

I have debugged bone weights and bone indices. They are okay. Bone weights add up to 1.0f, so I'm really wondering why I can't see the model with colors on it?

Advertisement

I found the issue. I was not copying the color to destination vertex buffer from source vertex buffer in UpdateSkinnedMesh. Now, I can see the vertices with color on them. Although, it's still a mess, but I am fixing the code in UpdateSkinnedMesh.

I was confusing Offset matrix with local transformation matrix the entire time. Can someone please guide me how to calculate offset matrices from Local Transformation Matrices for bones?

This topic is closed to new replies.

Advertisement