2 or more meshes

Started by
3 comments, last by Zammu 21 years, 8 months ago
Hi this is my first post! My problem is when I try to render two meshes which are loaded from .x files the other mesh doesn't have any textures it's just plain black. I think the problem is in my code:
  
//-----------------------------------------------------------------------------

// File: Meshes.cpp

//

// Desc: For advanced geometry, most apps will prefer to load pre-authored

//       meshes from a file. Fortunately, when using meshes, D3DX does most of

//       the work for this, parsing a geometry file and creating vertx buffers

//       (and index buffers) for us. This tutorial shows how to use a D3DXMESH

//       object, including loading it from a file and rendering it. One thing

//       D3DX does not handle for us is the materials and textures for a mesh,

//       so note that we have to handle those manually.

//

//       Note: one advanced (but nice) feature that we don't show here is that

//       when cloning a mesh we can specify the FVF. So, regardless of how the

//       mesh was authored, we can add/remove normals, add more texture

//       coordinate sets (for multi-texturing), etc.

//

// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.

//-----------------------------------------------------------------------------

#include <d3dx8.h>
#include <mmsystem.h>




//-----------------------------------------------------------------------------

// Global variables

//-----------------------------------------------------------------------------

LPDIRECT3D8             g_pD3D           = NULL; // Used to create the D3DDevice

LPDIRECT3DDEVICE8       g_pd3dDevice     = NULL; // Our rendering device


LPD3DXMESH              g_pMesh          = NULL; // Our mesh object in sysmem

D3DMATERIAL8*           g_pMeshMaterials = NULL; // Materials for our mesh

LPDIRECT3DTEXTURE8*     g_pMeshTextures  = NULL; // Textures for our mesh

DWORD                   g_dwNumMaterials = 0L;   // Number of mesh materials


LPD3DXMESH              g_pMesh2          = NULL; // Our mesh object in sysmem

D3DMATERIAL8*           g_pMesh2Materials = NULL; // Materials for our mesh

LPDIRECT3DTEXTURE8*     g_pMesh2Textures  = NULL; // Textures for our mesh

DWORD                   g_dwNumMaterials2 = 0L;   // Number of mesh materials



//-----------------------------------------------------------------------------

// Name: InitD3D()

// Desc: Initializes Direct3D

//-----------------------------------------------------------------------------

HRESULT InitD3D( HWND hWnd )
{
    // Create the D3D object.

    if( NULL == ( g_pD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // Get the current desktop display mode, so we can set up a back

    // buffer of the same format

    D3DDISPLAYMODE d3ddm;
    if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
        return E_FAIL;

    // Set up the structure used to create the D3DDevice. Since we are now

    // using more complex geometry, we will create a device with a zbuffer.

    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = d3ddm.Format;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    // Create the D3DDevice

    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    // Turn on the zbuffer

    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

    // Turn on ambient lighting 

    g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );

    return S_OK;
}




//-----------------------------------------------------------------------------

// Name: InitGeometry()

// Desc: Load the mesh and build the material and texture arrays

//-----------------------------------------------------------------------------

HRESULT InitGeometry()
{
    
	
	// Set up our view matrix. A view matrix can be defined given an eye point,

    // a point to lookat, and a direction for which way is up. Here, we set the

    // eye five units back along the z-axis and up three units, look at the 

    // origin, and define "up" to be in the y-direction.

    D3DXMATRIX matView;
    D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 3.0f,-5.0f ), 
                                  &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), 
                                  &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

    // For the projection matrix, we set up a perspective transform (which

    // transforms geometry from 3D view space to 2D viewport space, with

    // a perspective divide making objects smaller in the distance). To build

    // a perpsective transform, we need the field of view (1/4 pi is common),

    // the aspect ratio, and the near and far clipping planes (which define at

    // what distances geometry should be no longer be rendered).

    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

	
	LPD3DXBUFFER pD3DXMtrlBuffer;

    // Load the mesh from the specified file

    if( FAILED( D3DXLoadMeshFromX( "Tiger.x", D3DXMESH_SYSTEMMEM, 
                                   g_pd3dDevice, NULL, 
                                   &pD3DXMtrlBuffer, &g_dwNumMaterials, 
                                   &g_pMesh ) ) )
    {
        return E_FAIL;
    }

    // We need to extract the material properties and texture names from the 

    // pD3DXMtrlBuffer

    D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
    g_pMeshMaterials = new D3DMATERIAL8[g_dwNumMaterials];
    g_pMeshTextures  = new LPDIRECT3DTEXTURE8[g_dwNumMaterials];

    for( DWORD i=0; i<g_dwNumMaterials; i++ )
    {
        // Copy the material

        g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;

        // Set the ambient color for the material (D3DX does not do this)

        g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;
     
        // Create the texture

        if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, 
                                               d3dxMaterials[i].pTextureFilename, 
                                               &g_pMeshTextures[i] ) ) )
        {
            g_pMeshTextures[i] = NULL;
        }
    }

    // Done with the material buffer

    pD3DXMtrlBuffer->Release();


    LPD3DXBUFFER pD3DXMtrlBuffer2;


	// Load the mesh from the specified file

    if( FAILED( D3DXLoadMeshFromX( "tiger.x", D3DXMESH_SYSTEMMEM, 
                                   g_pd3dDevice, NULL, 
                                   &pD3DXMtrlBuffer2, &g_dwNumMaterials2, 
                                   &g_pMesh2 ) ) )
    {
        return E_FAIL;
    }

    // We need to extract the material properties and texture names from the 

    // pD3DXMtrlBuffer

    g_pMesh2Materials = new D3DMATERIAL8[g_dwNumMaterials2];
    g_pMesh2Textures  = new LPDIRECT3DTEXTURE8[g_dwNumMaterials2];

    for( DWORD j=0; j<g_dwNumMaterials2; j++ )
    {
        // Copy the material

        g_pMesh2Materials[j] = d3dxMaterials[j].MatD3D;

        // Set the ambient color for the material (D3DX does not do this)

        g_pMesh2Materials[j].Ambient = g_pMesh2Materials[j].Diffuse;
     
        // Create the texture

        if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, 
                                               d3dxMaterials[j].pTextureFilename, 
                                               &g_pMesh2Textures[j] ) ) )
        {
            g_pMesh2Textures[j] = NULL;
        }
    }

	// Done with the material buffer

    pD3DXMtrlBuffer2->Release();

    return S_OK;
}




//-----------------------------------------------------------------------------

// Name: Cleanup()

// Desc: Releases all previously initialized objects

//-----------------------------------------------------------------------------

VOID Cleanup()
{

	if( g_pMesh2Materials != NULL ) 
        delete[] g_pMesh2Materials;

    if( g_pMesh2Textures )
    {
        for( DWORD j = 0; j < g_dwNumMaterials2; j++ )
        {
            if( g_pMesh2Textures[j] )
                g_pMesh2Textures[j]->Release();
        }
        delete[] g_pMesh2Textures;
    }
    if( g_pMesh2 != NULL )
        g_pMesh2->Release();



    if( g_pMeshMaterials != NULL ) 
        delete[] g_pMeshMaterials;

    if( g_pMeshTextures )
    {
        for( DWORD i = 0; i < g_dwNumMaterials; i++ )
        {
            if( g_pMeshTextures[i] )
                g_pMeshTextures[i]->Release();
        }
        delete[] g_pMeshTextures;
    }
    if( g_pMesh != NULL )
        g_pMesh->Release();
    
    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();

    if( g_pD3D != NULL )
        g_pD3D->Release();
}



//-----------------------------------------------------------------------------

// Name: SetupMatricesMesh()

// Desc: Sets up the world, view, and projection transform matrices.

//-----------------------------------------------------------------------------

VOID SetupMatricesMesh()
{
    // For our world matrix, we will just leave it as the identity

    D3DXMATRIX matWorld;
    D3DXMatrixRotationY( &matWorld, timeGetTime()/1000.0f );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
}




//-----------------------------------------------------------------------------

// Name: SetupMatricesMesh2()

// Desc: Sets up the world, view, and projection transform matrices.

//-----------------------------------------------------------------------------

VOID SetupMatricesMesh2()
{
    // For our world matrix, we will just leave it as the identity

    D3DXMATRIX matWorld;
	D3DXMATRIX matTrans;
	D3DXMATRIX matRotY;
	D3DXMatrixTranslation( &matTrans, 1, 1, 1 );
    D3DXMatrixRotationY( &matRotY, timeGetTime()/100.0f );
	D3DXMatrixMultiply( &matWorld, &matRotY, &matTrans);
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
}




//-----------------------------------------------------------------------------

// Name: Render()

// Desc: Draws the scene

//-----------------------------------------------------------------------------

VOID Render()
{
    // Clear the backbuffer and the zbuffer

    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 
                         D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
    
    // Begin the scene

    g_pd3dDevice->BeginScene();

	// Setup the world, view, and projection matrices

    SetupMatricesMesh();

    // Meshes are divided into subsets, one for each material. Render them in

    // a loop

    for( DWORD i=0; i<g_dwNumMaterials; i++ )
    {
        // Set the material and texture for this subset

        g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
        g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
        
        // Draw the mesh subset

        g_pMesh->DrawSubset( i );
    }


	SetupMatricesMesh2();


	// Meshes are divided into subsets, one for each material. Render them in

    // a loop

    for( DWORD j=0; j<g_dwNumMaterials2; j++ )
    {
        // Set the material and texture for this subset

        g_pd3dDevice->SetMaterial( &g_pMesh2Materials[j] );
        g_pd3dDevice->SetTexture( 0, g_pMesh2Textures[j] );
        
        // Draw the mesh subset

        g_pMesh2->DrawSubset( j );
    }

    // End the scene

    g_pd3dDevice->EndScene();
    
    // Present the backbuffer contents to the display

    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}




//-----------------------------------------------------------------------------

// Name: MsgProc()

// Desc: The window's message handler

//-----------------------------------------------------------------------------

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            PostQuitMessage( 0 );
            return 0;
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}




//-----------------------------------------------------------------------------

// Name: WinMain()

// Desc: The application's entry point

//-----------------------------------------------------------------------------

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
    // Register the window class

    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, 
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      "D3D Tutorial", NULL };
    RegisterClassEx( &wc );

    // Create the application's window

    HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 06: Meshes", 
                              WS_OVERLAPPEDWINDOW, 0, 0, 500, 500,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

    // Initialize Direct3D

    if( SUCCEEDED( InitD3D( hWnd ) ) )
    { 
        // Create the scene geometry

        if( SUCCEEDED( InitGeometry() ) )
        {
            // Show the window

            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );

            // Enter the message loop

            MSG msg; 
            ZeroMemory( &msg, sizeof(msg) );
            while( msg.message!=WM_QUIT )
            {
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
                {
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                }
                else
                    Render();
            }
        }
    }

    // Clean up everything and exit the app

    Cleanup();
    UnregisterClass( "D3D Tutorial", wc.hInstance );
    return 0;
}
  
**EDIT - added source tags * - Jim [edited by - jim adams on August 11, 2002 9:23:59 PM]
Advertisement
I had the same problem awhile back. I didnt go thru all your code (just skimmed it) and didnt see anything glaring.

Heres what I learnt from my similar problem : find the .x file that is your mesh, and edit it with notepad. Are there texture coordinates or any mention of them near the bottom? (theyd be a long list of decimal numbers, never under 0 or over 1)

What happened to me was the modelling program wasnt including the UV coords with the mesh, and I was getting the same effect you reported. I eventually found a good file conversion program that inserts the UV coords.

Hope this helps,
-Jason

normal_toes@hotmail.com
[ / s o u r c e ] it plz <br><br><font size=1><a href="mailto:rick_rackplayer@hotmail.com">.lick</a></font>
No it can''t be because of that. It is the same .x file that is loaded twice - the tiger.x from the dx 8.1 sdk.
No it can''t be because of that. It is the same .x file that is loaded twice - the tiger.x from the dx 8.1 sdk.

This topic is closed to new replies.

Advertisement