www.pudn.com > multitexture.rar > multitexture.cpp
//----------------------------------------------------------------------------- // File: basic.cpp // // Desc: D3D sample showing the basics of DirectX Graphics Programming // // Copyright (c) 1998-2000 Microsoft Corporation. All rights reserved. // Copyright (c) 1998-2001 wolf@direct3d.net //----------------------------------------------------------------------------- #define STRICT #include#include #include #include #include "D3DApp.h" #include "D3DFont.h" #include "D3DUtil.h" #include "DXUtil.h" #include "resource.h" // A structure for our custom vertex type struct CUSTOMVERTEX { FLOAT x, y, z, rhw; // The transformed position for the vertex FLOAT tu, tv; // texture coordinates }; // Our custom FVF, which describes our custom vertex structure #define FVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_TEX1) // cube vertex struct CUBEVERTEX { D3DXVECTOR3 p; D3DXVECTOR3 n; FLOAT tu, tv; }; // cube FVF #define FVF_CUBEVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1) #define FILL_CUBEVERTEX( v, vertex, normal, atu, atv ) \ { v.p.x = vertex.x; v.p.y = vertex.y; v.p.z = vertex.z; \ v.n.x = normal.x; v.n.y = normal.y; v.n.z = normal.z; \ v.tu = atu; v.tv = atv; \ } #define NUM_CUBE_VERTICES (6*4) #define NUM_CUBE_INDICES (6*2*3) //----------------------------------------------------------------------------- // Name: class CMyD3DApplication // Desc: Application class. The base class (CD3DApplication) provides the // generic functionality needed in all Direct3D samples. CMyD3DApplication // adds functionality specific to this sample program. //----------------------------------------------------------------------------- class CMyD3DApplication : public CD3DApplication { CD3DFont* m_pFont; CD3DFont* m_pFontSmall; LPDIRECT3DVERTEXBUFFER8 m_pVB; // Buffer to hold vertices DWORD m_dwSizeofVertices; LPDIRECT3DINDEXBUFFER8 m_pIB; DWORD m_dwSizeofIndices; LPDIRECT3DVERTEXBUFFER8 m_pCubeVB; // Buffer to hold vertices DWORD m_dwSizeofCubeVertices; LPDIRECT3DINDEXBUFFER8 m_pCubeIB; DWORD m_dwSizeofCubeIndices; LPDIRECT3DTEXTURE8 m_pBackgroundTexture; LPDIRECT3DTEXTURE8 m_pWallTexture; LPDIRECT3DTEXTURE8 m_pEnvTexture; LPDIRECT3DTEXTURE8 m_pDetailTexture; // texture switches BOOL m_bTex1, m_bTex2, m_bTex3, m_bTex4, m_bTex5, m_bTex6, m_bTex7, m_bTex8; BOOL m_bAdd1, m_bAdd2, m_bAdd3; BOOL m_bFil1, m_bFil2; BOOL m_bDrawHelp; // for the cube CUBEVERTEX m_pCubeVertices[NUM_CUBE_VERTICES]; WORD m_pCubeIndices[NUM_CUBE_INDICES]; HRESULT ConfirmDevice( D3DCAPS8*, DWORD, D3DFORMAT ); protected: HRESULT OneTimeSceneInit(); HRESULT InitDeviceObjects(); HRESULT RestoreDeviceObjects(); HRESULT InvalidateDeviceObjects(); HRESULT DeleteDeviceObjects(); HRESULT Render(); HRESULT FrameMove(); HRESULT FinalCleanup(); HRESULT CreateCube( CUBEVERTEX* pVertices, WORD* pIndices ); HRESULT SetLights(); public: CMyD3DApplication(); LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); }; //----------------------------------------------------------------------------- // Name: WinMain() // Desc: Entry point to the program. Initializes everything, and goes into a // message-processing loop. Idle time is used to render the scene. //----------------------------------------------------------------------------- INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ) { CMyD3DApplication d3dApp; if( FAILED( d3dApp.Create( hInst ) ) ) return 0; return d3dApp.Run(); } //----------------------------------------------------------------------------- // Name: CMyD3DApplication() // Desc: Application constructor. Sets attributes for the app. //----------------------------------------------------------------------------- CMyD3DApplication::CMyD3DApplication() { m_strWindowTitle = _T("Multitexture"); m_bUseDepthBuffer = TRUE; m_pVB = NULL; m_pIB = NULL; m_pCubeVB = NULL; m_pCubeIB = NULL; m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD ); m_pFontSmall = new CD3DFont( _T("Arial"), 7, D3DFONT_BOLD ); m_bTex1 = TRUE; m_bTex2 = m_bTex3 = m_bTex4 = m_bTex5 = m_bTex6 = m_bTex7 = m_bTex8 = FALSE; m_bFil1 = TRUE; m_bFil2 = FALSE; m_bAdd1 = TRUE; m_bAdd2 = m_bAdd3 = FALSE; m_bDrawHelp = FALSE; } //----------------------------------------------------------------------------- // Name: OneTimeSceneInit() // Desc: Called during initial app startup, this function performs all the // permanent initialization. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::OneTimeSceneInit() { return S_OK; } //----------------------------------------------------------------------------- // Name: FrameMove() // Desc: Called once per frame, the call is the entry point for animating // the scene. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::FrameMove() { FLOAT z=0; // Setup the world matrix to spin and translate the object D3DXMATRIX matSpinY, matSpinX, matWorld; D3DXMatrixRotationY( &matSpinY, m_fTime / 0.5f ); D3DXMatrixRotationX( &matSpinX, m_fTime / 0.3f ); D3DXMatrixTranslation( &matWorld, 0.0f, 0.0f, z ); D3DXMatrixMultiply( &matWorld, &matSpinY, &matWorld ); D3DXMatrixMultiply( &matWorld, &matSpinX, &matWorld ); m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); return S_OK; } //----------------------------------------------------------------------------- // Name: Render() // Desc: Called once per frame, the call is the entry point for 3d // rendering. This function sets up render states, clears the // viewport, and renders the scene. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::Render() { // animate darkmap static int i=0; m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L ); // Begin the scene if( SUCCEEDED( m_pd3dDevice->BeginScene() ) ) { m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_DISABLE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); m_pd3dDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE ); m_pd3dDevice->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); // switch to clamp texture addressing mode if (m_bAdd1 == TRUE) { m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP ); } // mirroronce if (m_bAdd2 == TRUE) { m_pd3dDevice->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_MIRRORONCE); m_pd3dDevice->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_MIRRORONCE); m_pd3dDevice->SetTextureStageState(0, D3DTSS_ADDRESSW, D3DTADDRESS_MIRRORONCE); } // border color if (m_bAdd3 == TRUE) { m_pd3dDevice->SetTextureStageState (0, D3DTSS_ADDRESSU, D3DTADDRESS_BORDER); m_pd3dDevice->SetTextureStageState (0, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_BORDERCOLOR, 0x00000000); } m_pd3dDevice->SetTexture( 0, m_pBackgroundTexture ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(CUSTOMVERTEX) ); m_pd3dDevice->SetVertexShader( FVF_CUSTOMVERTEX ); m_pd3dDevice->SetIndices( m_pIB, 0 ); m_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, // number of vertices 0, 2); // number of primitives /******************************************* Dark mapping *******************************************/ if (m_bTex1 == TRUE) { m_pd3dDevice->SetTexture( 0, m_pWallTexture); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); m_pd3dDevice->SetTexture(1, m_pEnvTexture); m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); } /************************************** Animated Dark mapping ***************************************/ if (m_bTex2 == TRUE) { // Set texture for the cube m_pd3dDevice->SetTexture( 0, m_pWallTexture); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); // Set darkmap m_pd3dDevice->SetTexture(1, m_pEnvTexture); m_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT ); // animate darkmap if (i < 40) { m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); } else if (i < 80) { m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE2X); } else if (i < 120) { m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE4X); } else if (i = 120) { i = 0; } i++; } /**************************************** Blending the texture with material color *****************************************/ if (m_bTex3 == TRUE) { // Set texture for the cube m_pd3dDevice->SetTexture( 0, m_pWallTexture); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_ADD); } /***************************************** Darkmap blended with material color *****************************************/ if (m_bTex4 == TRUE) { m_pd3dDevice->SetTexture( 0, m_pWallTexture); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE); // Set darkmap m_pd3dDevice->SetTexture(1, m_pEnvTexture); m_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); } /***************************************** Glow Mapping ******************************************/ if (m_bTex5 == TRUE) { m_pd3dDevice->SetTexture( 0, m_pWallTexture); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); // Set glow map m_pd3dDevice->SetTexture(1, m_pEnvTexture); m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT ); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD); } /***************************************** Detail Mapping ******************************************/ if (m_bTex6 == TRUE) { m_pd3dDevice->SetTexture( 0, m_pWallTexture); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); // Set detail map m_pd3dDevice->SetTexture(1, m_pDetailTexture); m_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT ); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED); } /***************************************** Night view: Modulate Alpha ******************************************/ if (m_bTex7 == TRUE) { m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); m_pd3dDevice->SetTexture( 0, m_pWallTexture); } /**************************************** Blending with the frame buffer *****************************************/ if (m_bTex8 == TRUE) { m_pd3dDevice->SetRenderState (D3DRS_ALPHABLENDENABLE, TRUE); m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR); m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); m_pd3dDevice->SetTexture( 0, m_pWallTexture); } /*************************************** Bilinear filtering ***************************************/ /* if (m_bFil1 == TRUE) { // bilineaer filtering m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ); } */ /*************************************** Trilinear filtering ***************************************/ if (m_bFil1 == TRUE) { m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR ); } /*************************************** Anisotropic filtering ***************************************/ if (m_bFil2 == TRUE) { m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_ANISOTROPIC); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_ANISOTROPIC); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_ANISOTROPIC); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAXANISOTROPY, 16); } // Display the object m_pd3dDevice->SetStreamSource( 0, m_pCubeVB, sizeof(CUBEVERTEX) ); m_pd3dDevice->SetVertexShader( FVF_CUBEVERTEX ); m_pd3dDevice->SetIndices( m_pCubeIB, 0 ); m_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 24, // number of vertices 0, 36/3); // number of primitives if (m_bTex8 == TRUE) { // switch off alpha blending m_pd3dDevice->SetRenderState (D3DRS_ALPHABLENDENABLE, FALSE); } // Output statistics m_pFont->DrawText( 2, 0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats ); m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats ); // Draw help if( m_bDrawHelp ) { m_pFontSmall->DrawText( 2, 40, 0xffaaffff, _T("Keyboard controls:") ); m_pFontSmall->DrawText( 20, 52, 0xffaaffff, _T("Dark Mapping\n" "Animated Dark Mapping\n" "Blending with Material Diffuse Color\n" "Darkmap with Material Diffuse Color\n" "Glow Mapping\n" "Detail Mapping\n" "Modulate Alpha\n" "Blending with Frame Buffer\n\n" "Trilinear Filtering\n" "Anisotropic Filtering\n\n" "Clamp Addressing Mode\n" "Mirror Once (new in DX8)\n" "Border Color (not supp.: Geforce)\n\n" "Exit\n" "Toggle Menu") ); m_pFontSmall->DrawText( 260, 52, 0xffaaffff, _T("1\n" "2\n" "3\n" "4\n" "5\n" "6\n" "7\n" "8\n\n" "F5\n" "F6\n\n" "F9\n" "F11\n" "F12\n\n" "ESC\n" "F1")); } else m_pFontSmall->DrawText( 2, 40, 0xffffffff, _T("Press F1 for help") ); // End the scene. m_pd3dDevice->EndScene(); } return S_OK; } //----------------------------------------------------------------------------- // Name: InitDeviceObjects() // Desc: Initialize scene objects. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::InitDeviceObjects() { m_pFont->InitDeviceObjects( m_pd3dDevice ); m_pFontSmall->InitDeviceObjects( m_pd3dDevice ); // Load in textures if( FAILED( D3DUtil_CreateTexture(m_pd3dDevice, _T("Lake.bmp"), &m_pBackgroundTexture))) return D3DAPPERR_MEDIANOTFOUND; if( FAILED( D3DUtil_CreateTexture(m_pd3dDevice, _T("wall.bmp"), &m_pWallTexture))) return D3DAPPERR_MEDIANOTFOUND; if( FAILED( D3DUtil_CreateTexture(m_pd3dDevice, _T("env0.bmp"), &m_pEnvTexture))) return D3DAPPERR_MEDIANOTFOUND; if( FAILED( D3DUtil_CreateTexture(m_pd3dDevice, _T("detail.bmp"), &m_pDetailTexture))) return D3DAPPERR_MEDIANOTFOUND; // Generate the cube data CreateCube( m_pCubeVertices, m_pCubeIndices ); return S_OK; } //----------------------------------------------------------------------------- // Name: RestoreDeviceObjects() // Desc: Initialize scene objects. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::RestoreDeviceObjects() { m_pFont->RestoreDeviceObjects(); m_pFontSmall->RestoreDeviceObjects(); // Set the transform matrices D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, 5.0f ); D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 1.0f ); D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); D3DXMATRIX matView, matProj; D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height; D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 500.0f ); m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); // Material D3DMATERIAL8 Material; D3DUtil_InitMaterial( Material, 1.0f, 1.0f, 1.0f, 1.0f ); m_pd3dDevice->SetMaterial( &Material ); // if the viewport has changed ... fill the vertex buffer with the new // data D3DVIEWPORT8 vp; m_pd3dDevice->GetViewport(&vp); // Initialize four vertices to render two triangles CUSTOMVERTEX cvVertices[] = { { 0.0f, 0.0f, 1.0f, 1.0f, -0.5f, -0.5f, }, // x, y, z, rhw, tu, tv { (float)vp.Width, 0.0f, 1.0f, 1.0f, 1.5f, -0.5f, }, { (float)vp.Width, (float)vp.Height, 1.0f, 1.0f, 1.5f, 1.5f, }, { 0.0f, (float)vp.Height, 1.0f, 1.0f, -0.5f, 1.5f}, }; m_dwSizeofVertices = sizeof(cvVertices); // Create the vertex buffer if( FAILED( m_pd3dDevice->CreateVertexBuffer( m_dwSizeofVertices, 0, FVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &m_pVB ) ) ) return E_FAIL; VOID* pVertices; if( FAILED( m_pVB->Lock( 0, m_dwSizeofVertices, (BYTE**)&pVertices, 0 ) ) ) return E_FAIL; memcpy( pVertices, cvVertices, m_dwSizeofVertices); m_pVB->Unlock(); // Initialize the Index buffer WORD dwIndices[] = {0, 1, 2, 0, 2, 3}; m_dwSizeofIndices = sizeof(dwIndices); // Create the index buffer if( FAILED( m_pd3dDevice->CreateIndexBuffer( m_dwSizeofIndices, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pIB ) ) ) return E_FAIL; VOID* pIndices; if( FAILED( m_pIB->Lock( 0, m_dwSizeofIndices, (BYTE**)&pIndices, 0 ) ) ) return E_FAIL; memcpy( pIndices, dwIndices, sizeof(dwIndices) ); m_pIB->Unlock(); // // vertex and index buffer for the cube // m_dwSizeofCubeVertices = sizeof(m_pCubeVertices); // Create the vertex buffer if( FAILED( m_pd3dDevice->CreateVertexBuffer( m_dwSizeofCubeVertices, 0, FVF_CUBEVERTEX, D3DPOOL_MANAGED, &m_pCubeVB ) ) ) return E_FAIL; VOID* tmpVertices; if( FAILED( m_pCubeVB->Lock( 0, m_dwSizeofCubeVertices, (BYTE**)&tmpVertices, 0 ) ) ) return E_FAIL; memcpy( tmpVertices, m_pCubeVertices, m_dwSizeofCubeVertices); m_pCubeVB->Unlock(); m_dwSizeofCubeIndices = sizeof(m_pCubeIndices); // Create the index buffer if( FAILED( m_pd3dDevice->CreateIndexBuffer( m_dwSizeofCubeIndices, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pCubeIB ) ) ) return E_FAIL; VOID* tmpIndices; if( FAILED( m_pCubeIB->Lock( 0, m_dwSizeofCubeIndices, (BYTE**)&tmpIndices, 0 ) ) ) return E_FAIL; memcpy( tmpIndices, m_pCubeIndices, sizeof(m_pCubeIndices) ); m_pCubeIB->Unlock(); return S_OK; } //----------------------------------------------------------------------------- // Name: InvalidateDeviceObjects() // Desc: Called when the app is exiting, or the device is being changed, // this function deletes any device dependent objects. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::InvalidateDeviceObjects() { m_pFont->InvalidateDeviceObjects(); m_pFontSmall->InvalidateDeviceObjects(); SAFE_RELEASE( m_pVB ); SAFE_RELEASE( m_pIB ); SAFE_RELEASE( m_pCubeVB ); SAFE_RELEASE( m_pCubeIB ); return S_OK; } //----------------------------------------------------------------------------- // Name: DeleteDeviceObjects() // Desc: Called when the app is exiting, or the device is being changed, // this function deletes any device dependent objects. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::DeleteDeviceObjects() { m_pFont->DeleteDeviceObjects(); m_pFontSmall->DeleteDeviceObjects(); SAFE_RELEASE( m_pBackgroundTexture ); SAFE_RELEASE( m_pWallTexture ); SAFE_RELEASE( m_pEnvTexture ); SAFE_RELEASE( m_pDetailTexture ); return S_OK; } //----------------------------------------------------------------------------- // Name: FinalCleanup() // Desc: Called before the app exits, this function gives the app the chance // to cleanup after itself. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::FinalCleanup() { SAFE_DELETE( m_pFont ); SAFE_DELETE( m_pFontSmall ); return S_OK; } //----------------------------------------------------------------------------- // Name: ConfirmDevice() // Desc: Called during device intialization, this code checks the device // for some minimum set of capabilities //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format ) { if( (0 == ( pCaps->DestBlendCaps & D3DPBLENDCAPS_INVSRCCOLOR)) && // alpha blending (0 == ( pCaps->SrcBlendCaps & D3DPBLENDCAPS_SRCCOLOR)) && (0 == ( pCaps->TextureOpCaps & D3DTEXOPCAPS_ADDSIGNED )) && // texture blending (0 == ( pCaps->TextureOpCaps & D3DTEXOPCAPS_MODULATE )) && (0 == ( pCaps->TextureOpCaps & D3DTEXOPCAPS_MODULATE2X)) && (0 == ( pCaps->TextureOpCaps & D3DTEXOPCAPS_MODULATE4X)) && (0 == ( pCaps->TextureOpCaps & D3DTEXOPCAPS_ADD )) && (0 == ( pCaps->TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP)) && // texture addressing (0 == ( pCaps->TextureAddressCaps & D3DPTADDRESSCAPS_BORDER )) && (0 == ( pCaps->TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE))) return E_FAIL; if( pCaps->MaxSimultaneousTextures < 2 ) return E_FAIL; return S_OK; } //----------------------------------------------------------------------------- // Name: CreateCube() // Desc: Sets up the vertices for a cube. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::CreateCube( CUBEVERTEX* pVertices, WORD* pIndices ) { D3DXVECTOR3 p1 = D3DXVECTOR3(-1.0f, 1.0f,-1.0f); D3DXVECTOR3 p2 = D3DXVECTOR3( 1.0f, 1.0f,-1.0f); D3DXVECTOR3 p3 = D3DXVECTOR3( 1.0f,-1.0f,-1.0f); D3DXVECTOR3 p4 = D3DXVECTOR3(-1.0f,-1.0f,-1.0f); D3DXVECTOR3 p5 = D3DXVECTOR3(-1.0f, 1.0f, 1.0f); D3DXVECTOR3 p6 = D3DXVECTOR3(-1.0f,-1.0f, 1.0f); D3DXVECTOR3 p7 = D3DXVECTOR3( 1.0f,-1.0f, 1.0f); D3DXVECTOR3 p8 = D3DXVECTOR3( 1.0f, 1.0f, 1.0f); // Define the normals for the cube D3DXVECTOR3 n0( 0.0f, 0.0f,-1.0f ); // Front face D3DXVECTOR3 n1( 0.0f, 0.0f, 1.0f ); // Back face D3DXVECTOR3 n2( 0.0f, 1.0f, 0.0f ); // Bottom face D3DXVECTOR3 n3( 0.0f,-1.0f, 0.0f ); // Top face D3DXVECTOR3 n4( 1.0f, 0.0f, 0.0f ); // Left face D3DXVECTOR3 n5(-1.0f, 0.0f, 0.0f ); // Right face // Set up the vertices for the cube. Note: to prevent tiling problems, // the u/v coords are knocked slightly inwards. // Front face FILL_CUBEVERTEX( pVertices[0], p1, n0, 0.01f, 0.01f ); FILL_CUBEVERTEX( pVertices[1], p2, n0, 0.99f, 0.01f ); FILL_CUBEVERTEX( pVertices[2], p3, n0, 0.99f, 0.99f ); FILL_CUBEVERTEX( pVertices[3], p4, n0, 0.01f, 0.99f ); // Back face FILL_CUBEVERTEX( pVertices[4], p5, n1, 0.99f, 0.01f ); FILL_CUBEVERTEX( pVertices[5], p6, n1, 0.99f, 0.99f ); FILL_CUBEVERTEX( pVertices[6], p7, n1, 0.01f, 0.99f ); FILL_CUBEVERTEX( pVertices[7], p8, n1, 0.01f, 0.01f ); // Top face FILL_CUBEVERTEX( pVertices[8], p5, n2, 0.01f, 0.01f ); FILL_CUBEVERTEX( pVertices[9], p8, n2, 0.99f, 0.01f ); FILL_CUBEVERTEX( pVertices[10], p2, n2, 0.99f, 0.99f ); FILL_CUBEVERTEX( pVertices[11], p1, n2, 0.01f, 0.99f ); // Bottom face FILL_CUBEVERTEX( pVertices[12], p6, n3, 0.01f, 0.99f ); FILL_CUBEVERTEX( pVertices[13], p4, n3, 0.01f, 0.01f ); FILL_CUBEVERTEX( pVertices[14], p3, n3, 0.99f, 0.01f ); FILL_CUBEVERTEX( pVertices[15], p7, n3, 0.99f, 0.99f ); // Left face FILL_CUBEVERTEX( pVertices[16], p2, n4, 0.01f, 0.01f ); FILL_CUBEVERTEX( pVertices[17], p8, n4, 0.99f, 0.01f ); FILL_CUBEVERTEX( pVertices[18], p7, n4, 0.99f, 0.99f ); FILL_CUBEVERTEX( pVertices[19], p3, n4, 0.01f, 0.99f ); // Right face FILL_CUBEVERTEX( pVertices[20], p1, n5, 0.99f, 0.01f ); FILL_CUBEVERTEX( pVertices[21], p4, n5, 0.99f, 0.99f ); FILL_CUBEVERTEX( pVertices[22], p6, n5, 0.01f, 0.99f ); FILL_CUBEVERTEX( pVertices[23], p5, n5, 0.01f, 0.01f ); // Set up the indices for the cube *pIndices++ = 0+0; *pIndices++ = 0+1; *pIndices++ = 0+2; *pIndices++ = 0+2; *pIndices++ = 0+3; *pIndices++ = 0+0; *pIndices++ = 4+0; *pIndices++ = 4+1; *pIndices++ = 4+2; *pIndices++ = 4+2; *pIndices++ = 4+3; *pIndices++ = 4+0; *pIndices++ = 8+0; *pIndices++ = 8+1; *pIndices++ = 8+2; *pIndices++ = 8+2; *pIndices++ = 8+3; *pIndices++ = 8+0; *pIndices++ = 12+0; *pIndices++ = 12+1; *pIndices++ = 12+2; *pIndices++ = 12+2; *pIndices++ = 12+3; *pIndices++ = 12+0; *pIndices++ = 16+0; *pIndices++ = 16+1; *pIndices++ = 16+2; *pIndices++ = 16+2; *pIndices++ = 16+3; *pIndices++ = 16+0; *pIndices++ = 20+0; *pIndices++ = 20+1; *pIndices++ = 20+2; *pIndices++ = 20+2; *pIndices++ = 20+3; *pIndices++ = 20+0; return S_OK; } //---------------------------------------------------------------------------- // Name: MsgProc() // Desc: App custom WndProc function for handling mouse and keyboard input. //---------------------------------------------------------------------------- LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { // Perform commands when keys are rleased if( WM_KEYUP == uMsg ) { HMENU hMenu = GetMenu(m_hWnd); switch( wParam ) { case VK_F5: m_bFil1 = TRUE; m_bFil2 = FALSE; return 1; case VK_F6: m_bFil2 = TRUE; m_bFil1 = FALSE; return 1; case VK_F9: m_bAdd1 = TRUE; m_bAdd2 = m_bAdd3 = FALSE; return 1; case VK_F11: m_bAdd2 = TRUE; m_bAdd1 = m_bAdd3 = FALSE; return 1; case VK_F12: m_bAdd3 = TRUE; m_bAdd1 = m_bAdd2 = FALSE; return 1; case VK_F1: m_bDrawHelp = !m_bDrawHelp; return 1; case '1': m_bTex1 = TRUE; m_bTex2 = m_bTex3 = m_bTex4 = m_bTex5 = m_bTex6 = m_bTex7 = m_bTex8 =FALSE; SetLights(); return 1; case '2': m_bTex2 = TRUE; m_bTex1 = m_bTex3 = m_bTex4 = m_bTex5 = m_bTex6 = m_bTex7 = m_bTex8 =FALSE; SetLights(); return 1; case '3': m_bTex3 = TRUE; m_bTex2 = m_bTex1 = m_bTex4 = m_bTex5 = m_bTex6 = m_bTex7 = m_bTex8 =FALSE; SetLights(); return 1; case '4': m_bTex4 = TRUE; m_bTex2 = m_bTex3 = m_bTex1 = m_bTex5 = m_bTex6 = m_bTex7 = m_bTex8 =FALSE; SetLights(); return 1; case '5': m_bTex5 = TRUE; m_bTex2 = m_bTex3 = m_bTex4 = m_bTex1 = m_bTex6 = m_bTex7 = m_bTex8 =FALSE; SetLights(); return 1; case '6': m_bTex6 = TRUE; m_bTex2 = m_bTex3 = m_bTex4 = m_bTex5 = m_bTex1 = m_bTex7 = m_bTex8 = FALSE; SetLights(); return 1; case '7': m_bTex7 = TRUE; m_bTex2 = m_bTex3 = m_bTex4 = m_bTex5 = m_bTex6 = m_bTex1 = m_bTex8 = FALSE; SetLights(); return 1; case '8': m_bTex8 = TRUE; m_bTex2 = m_bTex3 = m_bTex4 = m_bTex5 = m_bTex6 = m_bTex7 = m_bTex1 = FALSE; SetLights(); return 1; } } // Fall through to the app's main windows proc function return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam ); } HRESULT CMyD3DApplication::SetLights() { if (m_bTex3 == TRUE || m_bTex4 == TRUE) { m_pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0); D3DLIGHT8 light; D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL, 0.0f, -5.0f, -5.0f ); m_pd3dDevice->SetLight( 0, &light ); m_pd3dDevice->LightEnable( 0, TRUE ); } else if (m_bTex7 == TRUE) { m_pd3dDevice->LightEnable( 0, FALSE); // Set the ambient light. m_pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0x00aaffaa); } return S_OK; }