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; 
}