Example #1
0
int luaGetH(lua_State *L)
{
	float x=(float)lua_tonumber(L, 1);
	float z=(float)lua_tonumber(L, 2);
	BOOL hit;
	FLOAT dist;
	LPDIRECT3DVERTEXBUFFER8 pVB;
	LPDIRECT3DINDEXBUFFER8  pIB;
	WORD*            pIndices;
	D3DVERTEX*    pVertices;
	if(m_pLandMesh==NULL) {
		lua_pushnumber(L,-100000.0f);
		return 1;
	}
	m_pLandMesh->GetSysMemMesh()->GetVertexBuffer( &pVB );
	m_pLandMesh->GetSysMemMesh()->GetIndexBuffer( &pIB );
	pIB->Lock( 0, 0, (BYTE**)&pIndices, 0 );
	pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 );
	D3DXVECTOR3 v1,v2;
	GVector dir2=GVector(0,-1,0);
	v1.x=x;v1.y=100000.0f;v1.z=z;
	v2.x=0;v2.y=-1;v2.z=0;
	D3DXIntersect(m_pLandMesh->GetSysMemMesh(),&v1,&v2,&hit,NULL,NULL,NULL,&dist,NULL,NULL);
	if(!hit) dist=-100000.0f;
	else dist=100000.0f-dist;
	lua_pushnumber(L,dist);
	return 1;

}
Example #2
0
//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: Creates the scene geometry
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // Create the vertex buffer.
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50*2*sizeof(CUSTOMVERTEX),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB ) ) )
    {
        return E_FAIL;
    }

    // Fill the vertex buffer. We are algorithmically generating a cylinder
    // here, including the normals, which are used for lighting.
    CUSTOMVERTEX* pVertices;
    if( FAILED( g_pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 ) ) )
        return E_FAIL;
    for( DWORD i=0; i<50; i++ )
    {
        FLOAT theta = (2*D3DX_PI*i)/(50-1);
        pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
        pVertices[2*i+0].normal   = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
        pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
        pVertices[2*i+1].normal   = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
    }
    g_pVB->Unlock();

    return S_OK;
}
Example #3
0
//-----------------------------------------------------------------------------
// Name: RenderGradientBackground()
// Desc: Draws a gradient filled background
//-----------------------------------------------------------------------------
HRESULT CXBApplication::RenderGradientBackground( DWORD dwTopColor, 
                                                  DWORD dwBottomColor )
{
    // First time around, allocate a vertex buffer
    static LPDIRECT3DVERTEXBUFFER8 g_pVB  = NULL;
    if( g_pVB == NULL )
    {
        m_pd3dDevice->CreateVertexBuffer( 4*5*sizeof(FLOAT), D3DUSAGE_WRITEONLY, 
                                          0L, D3DPOOL_DEFAULT, &g_pVB );
        struct BACKGROUNDVERTEX { D3DXVECTOR4 p; D3DCOLOR color; };
        BACKGROUNDVERTEX* v;
        g_pVB->Lock( 0, 0, (BYTE**)&v, 0L );
        v[0].p = D3DXVECTOR4(   0 - 0.5f,   0 - 0.5f, 1.0f, 1.0f );  v[0].color = dwTopColor;
        v[1].p = D3DXVECTOR4( 640 - 0.5f,   0 - 0.5f, 1.0f, 1.0f );  v[1].color = dwTopColor;
        v[2].p = D3DXVECTOR4(   0 - 0.5f, 480 - 0.5f, 1.0f, 1.0f );  v[2].color = dwBottomColor;
        v[3].p = D3DXVECTOR4( 640 - 0.5f, 480 - 0.5f, 1.0f, 1.0f );  v[3].color = dwBottomColor;
        g_pVB->Unlock();
    }

    // Set states
    m_pd3dDevice->SetTexture( 0, NULL );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_DISABLE );
    m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE ); 
    m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); 
    m_pd3dDevice->SetVertexShader( D3DFVF_XYZRHW|D3DFVF_DIFFUSE );
    m_pd3dDevice->SetStreamSource( 0, g_pVB, 5*sizeof(FLOAT) );

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

    // Clear the zbuffer
    m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0x00000000, 1.0f, 0L );

    return S_OK;
}
Example #4
0
//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: Creates the scene geometry
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // Initialize three vertices for rendering a triangle
    CUSTOMVERTEX g_Vertices[] =
    {
        { -1.0f,-1.0f, 0.0f, 0xffff0000, },
        {  1.0f,-1.0f, 0.0f, 0xff0000ff, },
        {  0.0f, 1.0f, 0.0f, 0xffffffff, },
    };

    // Create the vertex buffer.
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB ) ) )
    {
        return E_FAIL;
    }

    // Fill the vertex buffer.
    VOID* pVertices;
    if( FAILED( g_pVB->Lock( 0, sizeof(g_Vertices), (BYTE**)&pVertices, 0 ) ) )
        return E_FAIL;
    memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );
    g_pVB->Unlock();

    return S_OK;
}
Example #5
0
//-----------------------------------------------------------------------------
// Name: ApplyEnvironmentMap()
// Desc: Performs a calculation on each of the vertices' normals to determine
//       what the texture coordinates should be for the environment map (in this 
//       case the bump map).
//-----------------------------------------------------------------------------
VOID CMyD3DApplication::ApplyEnvironmentMap()
{
    EMBOSSVERTEX* pv;
    DWORD         dwNumVertices;
    dwNumVertices = m_pObject->GetLocalMesh()->GetNumVertices();

    LPDIRECT3DVERTEXBUFFER8 pVB;
    m_pObject->GetLocalMesh()->GetVertexBuffer( &pVB );
    pVB->Lock( 0, 0, (BYTE**)&pv, 0 );

    // Get the World matrix
    D3DXMATRIX  WV,InvWV;
    m_pd3dDevice->GetTransform( D3DTS_WORLD, &WV );
    D3DXMatrixInverse( &InvWV, NULL, &WV );
    
    // Get the current light position in object space
    D3DXVECTOR4 vTransformed;
    D3DXVec3Transform( &vTransformed, (D3DXVECTOR3*)&m_Light.Position, &InvWV );
    m_vBumpLightPos.x = vTransformed.x;
    m_vBumpLightPos.y = vTransformed.y;
    m_vBumpLightPos.z = vTransformed.z;

    // Dimensions of texture needed for shifting tex coords
    D3DSURFACE_DESC d3dsd;
    m_pEmbossTexture->GetLevelDesc( 0, &d3dsd );
    
    // Loop through the vertices, transforming each one and calculating
    // the correct texture coordinates.
    for( WORD i = 0; i < dwNumVertices; i++ )
    {
        // Find light vector in tangent space
        D3DXVECTOR3 vLightToVertex;
        D3DXVec3Normalize( &vLightToVertex, &(m_vBumpLightPos - pv[i].p) );
        
        // Create rotation matrix (rotate into tangent space)
        FLOAT r = D3DXVec3Dot( &vLightToVertex, &pv[i].n );

        if( r < 0.f ) 
        {
            // Don't shift coordinates when light below surface
            pv[i].tu2 = pv[i].tu;
            pv[i].tv2 = pv[i].tv;
        }
        else
        {
            // Shift coordinates for the emboss effect
            D3DXVECTOR2 vEmbossShift;
            vEmbossShift.x = D3DXVec3Dot( &vLightToVertex, &m_pTangents[i] );
            vEmbossShift.y = D3DXVec3Dot( &vLightToVertex, &m_pBinormals[i] );
            D3DXVec2Normalize( &vEmbossShift, &vEmbossShift );
            pv[i].tu2 = pv[i].tu + vEmbossShift.x/d3dsd.Width;
            pv[i].tv2 = pv[i].tv - vEmbossShift.y/d3dsd.Height;
        }
    }

    pVB->Unlock();
    pVB->Release();
}
Example #6
0
//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
VOID CMyD3DApplication::ComputeTangentsAndBinormals()
{
    EMBOSSVERTEX* pVertices;
    WORD*         pIndices;
    DWORD         dwNumVertices;
    DWORD         dwNumIndices;

    // Gain access to the object's vertex and index buffers
    LPDIRECT3DVERTEXBUFFER8 pVB;
    m_pObject->GetSysMemMesh()->GetVertexBuffer( &pVB );
    pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 );
    dwNumVertices = m_pObject->GetSysMemMesh()->GetNumVertices();

    LPDIRECT3DINDEXBUFFER8 pIB;
    m_pObject->GetSysMemMesh()->GetIndexBuffer( &pIB );
    pIB->Lock( 0, 0, (BYTE**)&pIndices, 0 );
    dwNumIndices  = m_pObject->GetSysMemMesh()->GetNumFaces() * 3;

    // Allocate space for the vertices' tangents and binormals
    m_pTangents  = new D3DXVECTOR3[dwNumVertices];
    m_pBinormals = new D3DXVECTOR3[dwNumVertices];
    ZeroMemory( m_pTangents,  sizeof(D3DXVECTOR3)*dwNumVertices );
    ZeroMemory( m_pBinormals, sizeof(D3DXVECTOR3)*dwNumVertices );

    // Generate the vertices' tangents and binormals
    for( DWORD i=0; i<dwNumIndices; i+=3 )
    {
        WORD a = pIndices[i+0];
        WORD b = pIndices[i+1];
        WORD c = pIndices[i+2];

        // To find a tangent that heads in the direction of +tv(texcoords),
        // find the components of both vectors on the tangent surface ,
        // and add a linear combination of the two projections that head in the +tv direction
        m_pTangents[a] += ComputeTangentVector( pVertices[a], pVertices[b], pVertices[c] );
        m_pTangents[b] += ComputeTangentVector( pVertices[b], pVertices[a], pVertices[c] );
        m_pTangents[c] += ComputeTangentVector( pVertices[c], pVertices[a], pVertices[b] );
    }

    for( i=0; i<dwNumVertices; i++ )
    {
        // Normalize the tangents
        D3DXVec3Normalize( &m_pTangents[i], &m_pTangents[i] );

        // Compute the binormals
        D3DXVec3Cross( &m_pBinormals[i], &pVertices[i].n, &m_pTangents[i] );
    }

    // Unlock and release the vertex and index buffers
    pIB->Unlock();
    pVB->Unlock();
    pIB->Release();
    pVB->Release();
}
Example #7
0
// Draws a rectangle on screen
void	D3D_DrawRect ( float x, float y, float width, float height, D3DCOLOR Color )
{
	d3dvertex_t *rectVert;

	if (!m_pVertexBuffer)
		return;

	m_pVertexBuffer->Lock ( 0, 0, (BYTE**)&rectVert, 0 );
	rectVert[0].x = x;
	rectVert[0].y = y+height;
	rectVert[0].z = 0;
	rectVert[0].rwh = 1;
	rectVert[0].color = Color;
	rectVert[1].x = x+width;
	rectVert[1].y = y+height;
	rectVert[1].z = 0;
	rectVert[1].rwh = 1;
	rectVert[1].color = Color;
	rectVert[2].x = x+width;
	rectVert[2].y = y;
	rectVert[2].z = 0;
	rectVert[2].rwh = 1;
	rectVert[2].color = Color;
	rectVert[3].x = x;
	rectVert[3].y = y;
	rectVert[3].z = 0;
	rectVert[3].rwh = 1;
	rectVert[3].color = Color;
	/*rectVert[4].x = x+width;
	rectVert[4].y = y;
	rectVert[4].z = 0;
	rectVert[4].rwh = 1;
	rectVert[4].color = Color;
	rectVert[5].x = x;
	rectVert[5].y = y+height;
	rectVert[5].z = 0;
	rectVert[5].rwh = 1;
	rectVert[5].color = Color;*/
	m_pVertexBuffer->Unlock ( );

	m_pOrigDDevice->SetTexture ( 0, NULL );
	m_pOrigDDevice->SetStreamSource ( 0, m_pVertexBuffer, sizeof(d3dvertex_t) );
	m_pOrigDDevice->SetVertexShader ( D3D_VERTEX );
	if (m_pOrigDDevice->DrawPrimitive ( D3DPT_TRIANGLEFAN, 0, 2 ) != D3D_OK)
	{
		assert ( 0 );
	}
}
Example #8
0
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Initialize scene objects
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    m_pFont->RestoreDeviceObjects();

    // Set the transform matrices
    D3DXVECTOR3 vEyePt    = D3DXVECTOR3( 0.0f, 0.0f, -2001.0f );
    D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f,     0.0f );
    D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f,     0.0f );
    D3DXMATRIX matWorld, matView, matProj;

    D3DXMatrixIdentity( &matWorld );
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 3000.0f );
    m_pd3dDevice->SetTransform( D3DTS_WORLD,      &matWorld );
    m_pd3dDevice->SetTransform( D3DTS_VIEW,       &matView );
    m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

    // Set any appropiate state
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ADDRESSU,   D3DTADDRESS_CLAMP );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_MIPFILTER, D3DTEXF_NONE );

    // Size the background image
    BACKGROUNDVERTEX* vBackground;
    m_pBackgroundVB->Lock( 0, 0, (BYTE**)&vBackground, 0 );
    for( UINT i=0; i<4; i ++ )
    {
        vBackground[i].p = D3DXVECTOR4( 0.0f, 0.0f, 0.9f, 1.0f );
        vBackground[i].color = 0xffffffff;
    }
    vBackground[0].p.y = (FLOAT)m_d3dsdBackBuffer.Height;
    vBackground[2].p.y = (FLOAT)m_d3dsdBackBuffer.Height;
    vBackground[2].p.x = (FLOAT)m_d3dsdBackBuffer.Width;
    vBackground[3].p.x = (FLOAT)m_d3dsdBackBuffer.Width;
    vBackground[0].tu = 0.0f; vBackground[0].tv = 1.0f;
    vBackground[1].tu = 0.0f; vBackground[1].tv = 0.0f;
    vBackground[2].tu = 1.0f; vBackground[2].tv = 1.0f;
    vBackground[3].tu = 1.0f; vBackground[3].tv = 0.0f;
    m_pBackgroundVB->Unlock();

    return S_OK;
}
Example #9
0
//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    if( g_pVB != NULL )
        g_pVB->Release();

    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();

    if( g_pD3D != NULL )
        g_pD3D->Release();
}
Example #10
0
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
    m_pFont->InitDeviceObjects( m_pd3dDevice );

    // Load the texture for the background image
    if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("Lake.bmp"),
                                       &m_pBackgroundTexture ) ) )
        return E_FAIL;

    // Create the bump map texture
    if( FAILED( CreateBumpMap( 256, 256 ) ) )
       return E_FAIL;

    // Create a square for rendering the background
    if( FAILED( m_pd3dDevice->CreateVertexBuffer( 4*sizeof(BACKGROUNDVERTEX),
                                                  D3DUSAGE_WRITEONLY, D3DFVF_BACKGROUNDVERTEX,
                                                  D3DPOOL_MANAGED, &m_pBackgroundVB ) ) )
        return E_FAIL;

    // Create a square for rendering the lens
    if( FAILED( m_pd3dDevice->CreateVertexBuffer( 4*sizeof(BUMPVERTEX),
                                                  D3DUSAGE_WRITEONLY, D3DFVF_BUMPVERTEX,
                                                  D3DPOOL_MANAGED, &m_pLensVB ) ) )
        return E_FAIL;

    BUMPVERTEX* vLens;
    m_pLensVB->Lock( 0, 0, (BYTE**)&vLens, 0 );
    vLens[0].p = D3DXVECTOR3(-256.0f,-256.0f, 0.0f );
    vLens[1].p = D3DXVECTOR3(-256.0f, 256.0f, 0.0f );
    vLens[2].p = D3DXVECTOR3( 256.0f,-256.0f, 0.0f );
    vLens[3].p = D3DXVECTOR3( 256.0f, 256.0f, 0.0f );
    vLens[0].tu1 = 0.0f; vLens[0].tv1 = 1.0f;
    vLens[1].tu1 = 0.0f; vLens[1].tv1 = 0.0f;
    vLens[2].tu1 = 1.0f; vLens[2].tv1 = 1.0f;
    vLens[3].tu1 = 1.0f; vLens[3].tv1 = 0.0f;
    m_pLensVB->Unlock();

    m_bDeviceValidationFailed = FALSE;

    return S_OK;
}
Example #11
0
//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: Create the textures and vertex buffers
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
    // Use D3DX to create a texture from a file based image
    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "banana.bmp",
                                           &g_pTexture ) ) )
        return E_FAIL;

    // Create the vertex buffer.
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50*2*sizeof(CUSTOMVERTEX),
                                                  0, D3DFVF_CUSTOMVERTEX,
                                                  D3DPOOL_DEFAULT, &g_pVB ) ) )
    {
        return E_FAIL;
    }

    // Fill the vertex buffer. We are setting the tu and tv texture
    // coordinates, which range from 0.0 to 1.0
    CUSTOMVERTEX* pVertices;
    if( FAILED( g_pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 ) ) )
        return E_FAIL;
    for( DWORD i=0; i<50; i++ )
    {
        FLOAT theta = (2*D3DX_PI*i)/(50-1);

        pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
        pVertices[2*i+0].color    = 0xffffffff;
        pVertices[2*i+0].tu       = ((FLOAT)i)/(50-1);
        pVertices[2*i+0].tv       = 1.0f;

        pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
        pVertices[2*i+1].color    = 0xff808080;
        pVertices[2*i+1].tu       = ((FLOAT)i)/(50-1);
        pVertices[2*i+1].tv       = 0.0f;
    }
    g_pVB->Unlock();

    return S_OK;
}
Example #12
0
// Rendering library invalid handle
void	D3D_RendInvalid ( IDirect3DDevice8 *pDevice )
{
	unsigned int n;

	if ( m_pOrigTarget )
		m_pOrigTarget->Release();

	// Release the vertex buffer
	if ( m_pVertexBuffer )
		m_pVertexBuffer->Release();

	// Release all fonts
	for ( n=0; n<m_uiNumFonts; n++ )
	{
		m_pFonts[n]->pFont->Release ( );
		m_pFonts[n]->pFont=NULL;
	}
}
Example #13
0
// Rendering library restore handle
void	D3D_RendRestore ( IDirect3DDevice8 *pDevice )
{
	unsigned int n;

	m_pOrigDDevice->GetRenderTarget ( &m_pOrigTarget );

	// Recreate the vertex buffer
	m_pOrigDDevice->CreateVertexBuffer ( D3D_MAX_VERTICES*sizeof(d3dvertex_t), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, D3D_VERTEX, D3DPOOL_DEFAULT, &m_pVertexBuffer );
	assert ( m_pVertexBuffer != NULL );
	m_pVertexBuffer->SetPriority ( D3DPRIO_LOW );

	// Recreate all fonts
	for (n=0; n<m_uiNumFonts; n++)
	{
		HFONT hFont=CreateFont ( 100, 0, 0, 0, 0, 1, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH || FF_DONTCARE, m_pFonts[n]->face_name );
		D3DXCreateFont ( m_pOrigDDevice, hFont, &m_pFonts[n]->pFont );

		assert ( m_pFonts[n]->pFont != NULL );
		m_pFonts[n]->hFont=hFont;
	}
}
Example #14
0
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: This creates all device-dependent managed objects, such as managed
//       textures and managed vertex buffers.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
    // Initialize the font's internal textures
    m_pFont->InitDeviceObjects( m_pd3dDevice );

    // Create the tree textures
    for( DWORD i=0; i<NUMTREETEXTURES; i++ )
    {
        if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, g_strTreeTextures[i],
                                           &m_pTreeTextures[i] ) ) )
            return D3DAPPERR_MEDIANOTFOUND;
    }

    // Create a quad for rendering each tree
    if( FAILED( m_pd3dDevice->CreateVertexBuffer( NUM_TREES*4*sizeof(TREEVERTEX),
                                                  D3DUSAGE_WRITEONLY, D3DFVF_TREEVERTEX,
                                                  D3DPOOL_MANAGED, &m_pTreeVB ) ) )
    {
        return E_FAIL;
    }

    // Copy tree mesh data into vertexbuffer
    TREEVERTEX* v;
    m_pTreeVB->Lock( 0, 0, (BYTE**)&v, 0 );

    INT iTree;
    DWORD dwOffset = 0;
    for( iTree = 0; iTree < NUM_TREES; iTree++ )
    {
        memcpy( &v[dwOffset], m_Trees[iTree].v, 4*sizeof(TREEVERTEX) );
        m_Trees[iTree].dwOffset = dwOffset;
        dwOffset += 4;
    }

    m_pTreeVB->Unlock();

    // Load the skybox
    if( FAILED( m_pSkyBox->Create( m_pd3dDevice, _T("SkyBox2.x") ) ) )
        return D3DAPPERR_MEDIANOTFOUND;

    // Load the terrain
    if( FAILED( m_pTerrain->Create( m_pd3dDevice, _T("SeaFloor.x") ) ) )
        return D3DAPPERR_MEDIANOTFOUND;

    // Add some "hilliness" to the terrain
    LPDIRECT3DVERTEXBUFFER8 pVB;
    if( SUCCEEDED( m_pTerrain->GetSysMemMesh()->GetVertexBuffer( &pVB ) ) )
    {
        struct VERTEX { FLOAT x,y,z,tu,tv; };
        VERTEX* pVertices;
        DWORD   dwNumVertices = m_pTerrain->GetSysMemMesh()->GetNumVertices();

        pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 );

        for( DWORD i=0; i<dwNumVertices; i++ )
            pVertices[i].y = HeightField( pVertices[i].x, pVertices[i].z );

        pVB->Unlock();
        pVB->Release();
    }

    return S_OK;
}
Example #15
0
void System2::renderFlame()
{
	unsigned int			i, j;
	unsigned int			sub_batch;
	double					t, r, dr;
	static unsigned char	xform_distrib[CHOOSE_XFORM_GRAIN];

	dr = 0.0f;
	for (i = 0; i < NXFORMS; i++) dr += xforms[i].density;
	dr = dr / CHOOSE_XFORM_GRAIN;

	j = 0;
	t = xforms[0].density;
	r = 0.0f;
	for(i = 0; i < CHOOSE_XFORM_GRAIN; i++)
	{
		while (r >= t)
		{
			j++;
			t += xforms[j].density;
		}
		xform_distrib[i] = j;
		r += dr;
	}

	DWORD palette[256];

	ColorMap tmpcmap;
	for(i=0; i < 256; i++)
	{
		float tc[4];
		ColorMap::rgb2hsv(colormap.data[i],tc);
		tc[0] += hue_rotation*6;
		ColorMap::hsv2rgb(tc,tmpcmap.data[i]);

		palette[i]=
			((int)(alpha*105))<<24 | 
			((int)(tmpcmap.data[i][0]*255))<<16 |
			((int)(tmpcmap.data[i][1]*255))<<8 |
			((int)(tmpcmap.data[i][2]*255));
	}

	dr = radius;
	BEGIN_DRAW(center[0],center[1],scale);

/*------------------------*/
    POINTVERTEX* pVertices;
    DWORD        dwNumParticlesToRender = 0;

	// Set up the vertex buffer to be rendered
    g_pd3dDevice->SetStreamSource( 0, ifs_vb, sizeof(POINTVERTEX) );
    g_pd3dDevice->SetVertexShader( POINTVERTEX_FVF );

	m_dwBase += m_dwFlush;
	if(m_dwBase >= m_dwDiscard) m_dwBase = 0;

#define D3DLOCK_DISCARD 0

	WRAP(ifs_vb->Lock( m_dwBase * sizeof(POINTVERTEX), m_dwFlush * sizeof(POINTVERTEX),
		(BYTE**)&pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ));

    POINTVERTEX* p=pVertices;
//				printf("p pVertices[m_dwBase]\n");
//	printf("debug %d %d ... %d/%d\n",m_dwBase, dwNumParticlesToRender, m_dwFlush, m_dwDiscard);
/*------------------------*/


	for(sub_batch = 0; sub_batch < point_quantity; sub_batch += SUB_BATCH_SIZE*5)
	{
		register float p0 = ((rand() - RAND_MAX/2)/(float)(RAND_MAX/2));//random_uniform11();
		register float p1 = ((rand() - RAND_MAX/2)/(float)(RAND_MAX/2));//random_uniform11();
		register float p2 = (rand()/(float)RAND_MAX);//random_uniform01();
		i = FUSE;
		do
		{
			int fn = xform_distrib[rand() % CHOOSE_XFORM_GRAIN];
			float tx, ty, v;

			p2 = (p2+xforms[fn].color)*0.5f;

			tx = coef[0][0] * p0 + coef[1][0] * p1 + coef[2][0];
			ty = coef[0][1] * p0 + coef[1][1] * p1 + coef[2][1];

			p0 = p1 = 0;

			v = vari[0];
			if(v > 0)
			{
				// linear 
				p0 += v * tx;
				p1 += v * ty;
			}
      
			v = vari[1];
			if(v > 0)
			{
				// sinusoidal
				float nx, ny;
				nx = (float)sin(tx);
				ny = (float)sin(ty);
				p0 += v * nx;
				p1 += v * ny;
			}
      
			v = vari[2];
			if(v > 0)
			{
				// complex
				float nx, ny;
				float r2 = 1.0f/(tx * tx + ty * ty + 1e-6f);
				nx = tx * r2;
				ny = ty * r2;
				p0 += v * nx;
				p1 += v * ny;
			}

			v = vari[3];
			if(v > 0)
			{
				// swirl 
				float r2 = tx * tx + ty * ty;  // /k here is fun 
				float c1 = (float)sin(r2);
				float c2 = (float)cos(r2);
				float nx = c1 * tx - c2 * ty;
				float ny = c2 * tx + c1 * ty;
				p0 += v * nx;
				p1 += v * ny;
			}
      
			v = vari[4];
			if(v > 0)
			{
				// horseshoe 
				float a, c1, c2, nx, ny;
				if(tx < -EPS || tx > EPS || ty < -EPS || ty > EPS)
					a = (float)atan2(tx, ty);  // times k here is fun
				else a = 0;
				c1 = (float)sin(a);
				c2 = (float)cos(a);
				nx = c1 * tx - c2 * ty;
				ny = c2 * tx + c1 * ty;
				p0 += v * nx;
				p1 += v * ny;
			}

			v = vari[5];
			if(v > 0)
			{
				// spherical
				float nx, ny;
				if(tx < -EPS || tx > EPS || ty < -EPS || ty > EPS)
					nx = (float)atan2(tx, ty) / M_PI;
				else nx = 0;
				ny = (float)sqrt(tx * tx + ty * ty) - 1;
				p0 += v * nx;
				p1 += v * ny;
			}

			v = vari[6];
			if(v > 0)
			{
				// bent 
				float nx, ny;
				nx = tx;
				ny = ty;
				if(nx < 0) nx *= 2.0f;
				if(ny < 0) ny *= 0.5f;
				p0 += v * nx;
				p1 += v * ny;
			}
		} while(--i);

		i = SUB_BATCH_SIZE;
		do
		{
			int fn = xform_distrib[rand() % CHOOSE_XFORM_GRAIN];
			float tx, ty, v;

			p2 = (p2+xforms[fn].color)*0.5f;

			tx = coef[0][0] * p0 + coef[1][0] * p1 + coef[2][0];
			ty = coef[0][1] * p0 + coef[1][1] * p1 + coef[2][1];

			p0 = p1 = 0;

			v = vari[0];
			if(v > 0)
			{
				// linear 
				p0 += v * tx;
				p1 += v * ty;
			}

			v = vari[1];
			if(v > 0)
			{
				// sinusoidal
				p0 += v * (float)sin(tx);
				p1 += v * (float)sin(ty);
			}
      
			v = vari[2];
			if(v > 0)
			{
				// complex
				float nx, ny;
				float r2 = 1.0f/(tx * tx + ty * ty + 1e-6f);
				nx = tx * r2;
				ny = ty * r2;
				p0 += v * nx;
				p1 += v * ny;
			}

			v = vari[3];
			if(v > 0)
			{
				// swirl 
				float r2 = tx * tx + ty * ty;  // /k here is fun 
				float c1 = (float)sin(r2);
				float c2 = (float)cos(r2);
				float nx = c1 * tx - c2 * ty;
				float ny = c2 * tx + c1 * ty;
				p0 += v * nx;
				p1 += v * ny;
			}
      
			v = vari[4];
			if(v > 0)
			{
				// horseshoe 
				float a, c1, c2, nx, ny;
				if(tx < -EPS || tx > EPS || ty < -EPS || ty > EPS)
					a = (float)atan2(tx, ty);  // times k here is fun
				else a = 0;
				c1 = (float)sin(a);
				c2 = (float)cos(a);
				nx = c1 * tx - c2 * ty;
				ny = c2 * tx + c1 * ty;
				p0 += v * nx;
				p1 += v * ny;
			}

			v = vari[5];
			if(v > 0)
			{
				// spherical
				float nx, ny;
				if(tx < -EPS || tx > EPS || ty < -EPS || ty > EPS)
					nx = (float)atan2(tx, ty) * (1 / M_PI);
				else nx = 0;
				ny = (float)sqrt(tx * tx + ty * ty) - 1;
				p0 += v * nx;
				p1 += v * ny;
			}

			v = vari[6];
			if(v > 0)
			{
				// bent 
				float nx, ny;
				nx = tx;
				ny = ty;
				if (nx < 0) nx *= 2.0f;
				if (ny < 0) ny *= 0.5f;
				p0 += v * nx;
				p1 += v * ny;
			}

			int k = 255&(int)(p2*256.0f);
/*			if(k < 0) k = 0;
			else if(k > 255) k = 255;
*/
/*			DRAW_DOT(p0,p1,dr,
				tmpcmap.data[k][0], tmpcmap.data[k][1], tmpcmap.data[k][2], alpha);
*/

			/*
			{ \
				float f[4];
				f[0]=p0;
				f[1]=p1;
				f[2]=0;
				*((int*)&f[3])=palette[k];
				g_pd3dDevice->DrawPrimitiveUP( D3DPT_POINTLIST, 1, f, 4*4);
			}
*/
//			printf("\t%d\n", dwNumParticlesToRender);
			p->v.x=p0;
			p->v.y=p1;
//			p->v.z=0;
			p->color=palette[k];
			p++;

			//dwNumParticlesToRender++;
            if( ++dwNumParticlesToRender == m_dwFlush )
            {
                // Done filling this chunk of the vertex buffer.  Lets unlock and
                // draw this portion so we can begin filling the next chunk.

                ifs_vb->Unlock();

//				printf("draw %d %d ... %d/%d\n",m_dwBase, dwNumParticlesToRender, m_dwFlush, m_dwDiscard);
                WRAP(g_pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, m_dwBase, dwNumParticlesToRender));

                // Lock the next chunk of the vertex buffer.  If we are at the 
                // end of the vertex buffer, DISCARD the vertex buffer and start
                // at the beginning.  Otherwise, specify NOOVERWRITE, so we can
                // continue filling the VB while the previous chunk is drawing.
				m_dwBase += m_dwFlush;

				if(m_dwBase >= m_dwDiscard) m_dwBase = 0;

				WRAP(ifs_vb->Lock( m_dwBase * sizeof(POINTVERTEX), m_dwFlush * sizeof(POINTVERTEX),
		            (BYTE**) &pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) );

//				printf("p pVertices[m_dwBase]\n");
				p=pVertices;

                dwNumParticlesToRender = 0;
            }

	 	} while(--i);
//		printf("---\n");
	}
	END_DRAW();
/*------------------------*/
//				printf("enddraw\n");
    // Unlock the vertex buffer
    ifs_vb->Unlock();

    // Render any remaining particles
    if( dwNumParticlesToRender )
    {
        WRAP(g_pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, m_dwBase, dwNumParticlesToRender ));
    }
//    return S_OK;
/*------------------------*/
}
Example #16
0
BRUSH* ConvertXModelToBrushFormat ( char* szFilename, BRUSH* pBrush, int* piCount, LPDIRECT3DDEVICE8 lpDevice )
{
	// takes an x model and converts it into brushes

	// check the pointers are valid
	if ( !szFilename || !piCount )
		return NULL;

	// used to access vertex data
	struct sMeshData
	{
		float x, y, z;
		float nx, ny, nz;
		float tu, tv;
	};

	// variable declarations
	tagModelData*			ptr;				// model data
	LPDIRECT3DVERTEXBUFFER8 pMeshVertexBuffer;	// vertex buffer
	LPDIRECT3DINDEXBUFFER8  pMeshIndexBuffer;	// index buffer
	sMeshData*				pMeshVertices;		// mesh vertices
	WORD*					pMeshIndices;		// mesh indices
	sMesh*					pMesh;				// mesh data
	int						iCount;
	
	// load the model
	Constructor ( lpDevice );
	ptr = Load ( 1, szFilename );

	pMesh = ptr->m_Object.m_Meshes;

	// count the number of brushes so we can allocate enough memory for them
	iCount = 0;

	while ( pMesh )
	{
		pMesh = pMesh->m_Next;
		iCount++;
	}

	// store the number of models in the brush count pointer
	*piCount = iCount;

	// now setup the brushes
	pBrush = new BRUSH [ iCount ];	// allocate memory
	
	// set the mesh pointer back to the original mesh
	pMesh = ptr->m_Object.m_Meshes;

	// run through all meshes and store the brush data
	// first off set iCount to 0 so we know which brush
	// we are dealing with
	iCount = 0;

	while ( pMesh )
	{
		int   iInd          = 0;
		DWORD dwNumVertices = pMesh->m_Mesh->GetNumVertices ( );
		DWORD dwNumFaces	= pMesh->m_Mesh->GetNumFaces ( );

		pBrush [ iCount ].Faces      = new POLYGON [ dwNumFaces ];
		pBrush [ iCount ].FaceCount  = dwNumFaces;
		pBrush [ iCount ].Bounds.Max = D3DXVECTOR3 (  150.0f,  150.0f,  150.0f );
		pBrush [ iCount ].Bounds.Min = D3DXVECTOR3 ( -150.0f, -150.0f, -150.0f );
		pBrush [ iCount ].BSPTree    = NULL;

		pMesh->m_Mesh->GetVertexBuffer ( &pMeshVertexBuffer );
		pMesh->m_Mesh->GetIndexBuffer  ( &pMeshIndexBuffer );

		DWORD dwFVF = pMesh->m_Mesh->GetFVF ( );

		pMeshVertexBuffer->Lock ( 0, pMesh->m_Mesh->GetNumVertices  ( ) * sizeof ( sMeshData ), ( BYTE** ) &pMeshVertices, 0 );
		pMeshIndexBuffer->Lock  ( 0, 3 * pMesh->m_Mesh->GetNumFaces ( ) * sizeof ( WORD ),      ( BYTE** ) &pMeshIndices,  0 );
	
		for ( int iTemp = 0; iTemp < dwNumFaces; iTemp++ )
		{
			char szX [ 256 ];
			char szY [ 256 ];
			char szZ [ 256 ];

			int iA = pMeshIndices [ iInd + 0 ];
			int iB = pMeshIndices [ iInd + 1 ];
			int iC = pMeshIndices [ iInd + 2 ];

			WORD wIndices [ ] = { 0, 1, 2 };
			
			pBrush [ iCount ].Faces [ iTemp ].IndexCount   = 3;
			pBrush [ iCount ].Faces [ iTemp ].TextureIndex = 0;
			pBrush [ iCount ].Faces [ iTemp ].VertexCount  = 3;
			pBrush [ iCount ].Faces [ iTemp ].Indices      = new WORD      [ 3 ];
			pBrush [ iCount ].Faces [ iTemp ].Vertices     = new D3DVERTEX [ 3 ];

			pBrush [ iCount ].Faces [ iTemp ].Vertices [ 0 ] = SetupVertex ( pMeshVertices [ iA ].x, pMeshVertices [ iA ].y, pMeshVertices [ iA ].z, pMeshVertices [ iA ].tu, pMeshVertices [ iA ].tv );
			pBrush [ iCount ].Faces [ iTemp ].Vertices [ 1 ] = SetupVertex ( pMeshVertices [ iB ].x, pMeshVertices [ iB ].y, pMeshVertices [ iB ].z, pMeshVertices [ iB ].tu, pMeshVertices [ iB ].tv );
			pBrush [ iCount ].Faces [ iTemp ].Vertices [ 2 ] = SetupVertex ( pMeshVertices [ iC ].x, pMeshVertices [ iC ].y, pMeshVertices [ iC ].z, pMeshVertices [ iC ].tu, pMeshVertices [ iC ].tv );

			for ( int iChar = 0; iChar < 3; iChar++ )
			{
				sprintf ( szX, "%.1f", pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].x );
				sprintf ( szY, "%.1f", pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].y );
				sprintf ( szZ, "%.1f", pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].z );

				pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].x = atof ( szX );
				pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].y = atof ( szY );
				pBrush [ iCount ].Faces [ iTemp ].Vertices [ iChar ].z = atof ( szZ );
			}
			
			memcpy ( pBrush [ iCount ].Faces [ iTemp ].Indices, wIndices, sizeof ( wIndices ) );
			CalculateNormal ( &pBrush [ iCount ].Faces [ iTemp ] );

			iInd += 3;
		}

		SetBlockPosition ( &pBrush [ iCount ], 0.0f, 0.0f, 0.0f, 1.0f );
	
		pMeshVertexBuffer->Unlock ( );
		pMeshIndexBuffer->Unlock  ( );

		iCount++;

		pMesh = pMesh->m_Next;
	}

	iCount = 0;
	pMesh  = ptr->m_Object.m_Meshes;

	for ( int iTemp = ptr->m_Object.m_NumFrames; iTemp > 0; iTemp-- )
	{
		sFrame* pFrame = ptr->m_Object.m_Frames->FindFrame ( iTemp );

		if ( pFrame )
		{
			pBrush [ iCount ].Matrix._41 = pFrame->m_matOriginal._41;
			pBrush [ iCount ].Matrix._42 = pFrame->m_matOriginal._42;
			pBrush [ iCount ].Matrix._43 = pFrame->m_matOriginal._43;

			iCount++;
		}
	}
	
	return pBrush;
}
Example #17
0
Filename_notice *prepare_filename_notice(LPDIRECT3DDEVICE8 pd3dDevice,
        char const *filename)
{
    HRESULT result;
    Filename_notice *notice = NULL;
    HDC hDC = NULL;
    HFONT hFont = NULL;
    SIZE size;
    int width, height;
    LPDIRECT3DTEXTURE8 pTexture = NULL;
    LPDIRECT3DVERTEXBUFFER8 pVB = NULL;
    DWORD *pBitmapBits = NULL;
    BITMAPINFO bmi;
    HBITMAP hbmBitmap = NULL;
    D3DLOCKED_RECT d3dlr;
    BYTE *pDstRow;
    int x, y;
   
    hDC = CreateCompatibleDC(NULL);

    SetMapMode(hDC, MM_TEXT);

    hFont = CreateFont(
            FONT_HEIGHT,                // height
            0,                          // width (0 = closest)
            0,                          // escapement (0 = none)
            0,                          // orientation (0 = none)
            FW_NORMAL,                  // bold
            FALSE,                      // italic
            FALSE,                      // underline
            FALSE,                      // strikeout
            DEFAULT_CHARSET,
            OUT_DEFAULT_PRECIS,         // TrueType (OUT_TT_PRECIS) doesn't help
            CLIP_DEFAULT_PRECIS,
            ANTIALIASED_QUALITY,
            VARIABLE_PITCH,
            FONT_NAME);
    if (hFont == NULL) {
        goto done;
    }

    // Set text properties
    SelectObject(hDC, hFont);
    SetTextColor(hDC, RGB(255,255,255));
    SetBkColor(hDC, 0x00000000);
    SetTextAlign(hDC, TA_TOP);

    GetTextExtentPoint32(hDC, filename, strlen(filename), &size);
    width = size.cx;
    height = size.cy;

    // Create a new texture for the font
    result = pd3dDevice->CreateTexture(width, height, 1, 0, D3DFMT_A4R4G4B4,
            D3DPOOL_MANAGED, &pTexture);
    if (FAILED(result)) {
        goto done;
    }

    // Prepare to create a bitmap
    ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = width;
    bmi.bmiHeader.biHeight = -height;       // negative means top-down
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biBitCount = 32;

    hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS,
            (VOID**)&pBitmapBits, NULL, 0);
    SelectObject(hDC, hbmBitmap);

    ExtTextOut(hDC, 0, 0, ETO_OPAQUE, NULL, filename, strlen(filename), NULL);

    // Lock the surface and write the alpha values for the set pixels
    pTexture->LockRect(0, &d3dlr, 0, 0);
    pDstRow = (BYTE*)d3dlr.pBits;

    for (y = 0; y < height; y++) {
        WORD *pDst16 = (WORD *)pDstRow;

        for (x = 0; x < width; x++) {
            BYTE bAlpha = (BYTE)((pBitmapBits[width*y + x] & 0xff) >> 4);

            if (bAlpha > 0) {
                *pDst16++ = (WORD)((bAlpha << 12) | 0x0fff);
            } else {
                *pDst16++ = (WORD)(0x0000);
            }
        }

        pDstRow += d3dlr.Pitch;
    }

    // Done updating texture
    pTexture->UnlockRect(0);

    // Create vertices
    result = pd3dDevice->CreateVertexBuffer(4*sizeof(FONT2DVERTEX),
            D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &pVB);
    if (FAILED(result)) {
        goto done;
    }

    notice = new Filename_notice;
    notice->width = width;
    notice->height = height;
    notice->pd3dDevice = pd3dDevice;
    notice->pTexture = pTexture;
    pTexture = NULL;
    notice->pVB = pVB;
    pVB = NULL;

    pd3dDevice->BeginStateBlock();
    apply_render_state(pd3dDevice);
    pd3dDevice->SetTexture(0, notice->pTexture);
    pd3dDevice->EndStateBlock(&notice->dwSavedStateBlock);

    pd3dDevice->BeginStateBlock();
    apply_render_state(pd3dDevice);
    pd3dDevice->SetTexture(0, notice->pTexture);
    pd3dDevice->EndStateBlock(&notice->dwDrawTextStateBlock);

done:
    if (pVB != NULL) {
        pVB->Release();
    }
    if (pTexture != NULL) {
        pTexture->Release();
    }
    if (hbmBitmap != NULL) {
        DeleteObject(hbmBitmap);
    }
    if (hFont != NULL) {
        DeleteObject(hFont);
    }
    if (hDC != NULL) {
        DeleteDC(hDC);
    }

    return notice;
}
Example #18
0
HRESULT CMyD3DApplication::LoadMeshData
    (
    LPD3DXMESH *ppMesh,
    LPD3DXBUFFER *ppAdjacencyBuffer
    )
{
    LPDIRECT3DVERTEXBUFFER8 pMeshVB   = NULL;
    LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
    BYTE*        pVertices;
    TCHAR        strMesh[512];
    HRESULT      hr = S_OK;
    BOOL         bNormalsInFile;
    LPD3DXMESH   pMeshSysMem = NULL;
    LPD3DXMESH   pMeshTemp;
    DWORD        *rgdwAdjacencyTemp = NULL;
    DWORD        i;
    D3DXMATERIAL* d3dxMaterials;
    DWORD        dw32Bit;

    // Get a path to the media file
    DXUtil_FindMediaFile( strMesh, m_strMeshFilename );
    
    // Load the mesh from the specified file
    hr = D3DXLoadMeshFromX( strMesh, D3DXMESH_SYSTEMMEM, m_pd3dDevice, 
                            ppAdjacencyBuffer, &pD3DXMtrlBuffer, 
                            &m_dwNumMaterials, &pMeshSysMem );
    if( FAILED(hr) )
        goto End;

    // remember if the mesh is 32 or 16 bit, to be added in on the clones
    dw32Bit = pMeshSysMem->GetOptions() & D3DXMESH_32BIT;

    // Get the array of materials out of the returned buffer, and allocate a texture array
    d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
    m_pMeshMaterials = new D3DMATERIAL8[m_dwNumMaterials];
    m_pMeshTextures  = new LPDIRECT3DTEXTURE8[m_dwNumMaterials];

    for( i=0; i<m_dwNumMaterials; i++ )
    {
        m_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
        m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse;
        m_pMeshTextures[i]  = NULL;

        // Get a path to the texture
        TCHAR strPath[512];
        if (d3dxMaterials[i].pTextureFilename != NULL)
        {
            DXUtil_FindMediaFile( strPath, d3dxMaterials[i].pTextureFilename );

            // Load the texture
            D3DXCreateTextureFromFile( m_pd3dDevice, strPath, &m_pMeshTextures[i] );
        }
    }

    // Done with the material buffer
    SAFE_RELEASE( pD3DXMtrlBuffer );

    // Lock the vertex buffer, to generate a simple bounding sphere
    hr = pMeshSysMem->GetVertexBuffer( &pMeshVB );
    if( SUCCEEDED(hr) )
    {
        hr = pMeshVB->Lock( 0, 0, &pVertices, D3DLOCK_NOSYSLOCK );
        if( SUCCEEDED(hr) )
        {
            hr = D3DXComputeBoundingSphere( pVertices, pMeshSysMem->GetNumVertices(),
                                            pMeshSysMem->GetFVF(),
                                            &m_vObjectCenter, &m_fObjectRadius );
            pMeshVB->Unlock();
        }
        pMeshVB->Release();
    }
    if( FAILED(hr) )
        goto End;

    // remember if there were normals in the file, before possible clone operation
    bNormalsInFile = pMeshSysMem->GetFVF() & D3DFVF_NORMAL;

    // if using 32byte vertices, check fvf
    if (m_bForce32ByteFVF)
    {
        // force 32 byte vertices
        if (pMeshSysMem->GetFVF() != (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1))
        {
            hr = pMeshSysMem->CloneMeshFVF( pMeshSysMem->GetOptions(), D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1, 
                                              m_pd3dDevice, &pMeshTemp );
            if( FAILED(hr) )
                goto End;

            pMeshSysMem->Release();
            pMeshSysMem = pMeshTemp;
        }
    }
    // otherwise, just make sure that there is a normal mesh
    else if ( !(pMeshSysMem->GetFVF() & D3DFVF_NORMAL) )
    {
        hr = pMeshSysMem->CloneMeshFVF( pMeshSysMem->GetOptions(), pMeshSysMem->GetFVF() | D3DFVF_NORMAL, 
                                            m_pd3dDevice, &pMeshTemp );
        if (FAILED(hr))
            return hr;

        pMeshSysMem->Release();
        pMeshSysMem = pMeshTemp;
    }


    // Compute normals for the mesh, if not present
    if (!bNormalsInFile)
    {
        D3DXComputeNormals( pMeshSysMem, NULL );
    }

    *ppMesh = pMeshSysMem;
    pMeshSysMem = NULL;

End:
    SAFE_RELEASE( pMeshSysMem );
   
    return hr;
}