Jump to content
  • Advertisement
stream775

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

Recommended Posts

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?

Edited by stream775
I've solved the issue.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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?

Edited by stream775

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!