www.pudn.com > D3D9Cartoon.rar > D3D9Cartoon.cpp
//----------------------------------------------------------------------------- // File: D3D9Cartoon.cpp // // Desc: DirectX window application created by the DirectX AppWizard //----------------------------------------------------------------------------- #define STRICT #include#include #include #include #include #include #include #include #include #include "DXUtil.h" #include "D3DEnumeration.h" #include "D3DSettings.h" #include "D3DApp.h" #include "D3DFont.h" #include "D3DFile.h" #include "D3DUtil.h" #include "resource.h" #include "D3D9Cartoon.h" //----------------------------------------------------------------------------- // Global access to the app (needed for the global WndProc()) //----------------------------------------------------------------------------- CMyD3DApplication* g_pApp = NULL; HINSTANCE g_hInst = NULL; //----------------------------------------------------------------------------- // 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; g_pApp = &d3dApp; g_hInst = hInst; InitCommonControls(); if( FAILED( d3dApp.Create( hInst ) ) ) return 0; return d3dApp.Run(); } //----------------------------------------------------------------------------- // Name: CMyD3DApplication() // Desc: Application constructor. Paired with ~CMyD3DApplication() // Member variables should be initialized to a known state here. // The application window has not yet been created and no Direct3D device // has been created, so any initialization that depends on a window or // Direct3D should be deferred to a later stage. //----------------------------------------------------------------------------- CMyD3DApplication::CMyD3DApplication() { m_dwCreationWidth = 500; m_dwCreationHeight = 375; m_strWindowTitle = TEXT( "D3D9Cartoon" ); m_d3dEnumeration.AppUsesDepthBuffer = TRUE; m_bStartFullscreen = false; m_bShowCursorWhenFullscreen = false; // Create a D3D font using d3dfont.cpp m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD ); m_bLoadingApp = TRUE; m_pD3DXMesh = NULL; ZeroMemory( &m_UserInput, sizeof(m_UserInput) ); m_fWorldRotX = 0.0f; m_fWorldRotY = 0.0f; /////////////////////////////////////////////////////////////// m_pSilhouetteVertexShader=0; m_pSilhouetteVertexDecl=0; m_pSurfaceVertexShader=0; m_pSurfaceVertexDecl=0; m_pFloorVertexShader=0; m_pFloorVertexDecl=0; m_pObject=new CD3DMesh(); m_pFloor=new CD3DMesh(); } //----------------------------------------------------------------------------- // Name: ~CMyD3DApplication() // Desc: Application destructor. Paired with CMyD3DApplication() //----------------------------------------------------------------------------- CMyD3DApplication::~CMyD3DApplication() { } //----------------------------------------------------------------------------- // Name: OneTimeSceneInit() // Desc: Paired with FinalCleanup(). // The window has been created and the IDirect3D9 interface has been // created, but the device has not been created yet. Here you can // perform application-related initialization and cleanup that does // not depend on a device. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::OneTimeSceneInit() { // TODO: perform one time initialization // Drawing loading status message until app finishes loading SendMessage( m_hWnd, WM_PAINT, 0, 0 ); m_bLoadingApp = FALSE; return S_OK; } //----------------------------------------------------------------------------- // Name: ConfirmDevice() // Desc: Called during device initialization, this code checks the display device // for some minimum set of capabilities //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior, D3DFORMAT Format ) { UNREFERENCED_PARAMETER( Format ); UNREFERENCED_PARAMETER( dwBehavior ); UNREFERENCED_PARAMETER( pCaps ); BOOL bCapsAcceptable; // TODO: Perform checks to see if these display caps are acceptable. bCapsAcceptable = TRUE; if( bCapsAcceptable ) return S_OK; else return E_FAIL; } //----------------------------------------------------------------------------- // Name: InitDeviceObjects() // Desc: Paired with DeleteDeviceObjects() // The device has been created. Resources that are not lost on // Reset() can be created here -- resources in D3DPOOL_MANAGED, // D3DPOOL_SCRATCH, or D3DPOOL_SYSTEMMEM. Image surfaces created via // CreateImageSurface are never lost and can be created here. Vertex // shaders and pixel shaders can also be created here as they are not // lost on Reset(). //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::InitDeviceObjects() { // TODO: create device objects HRESULT hr; // Init the font m_pFont->InitDeviceObjects( m_pd3dDevice ); // Create a teapot mesh using D3DX if( FAILED( hr = D3DXCreateTeapot( m_pd3dDevice, &m_pD3DXMesh, NULL ) ) ) return DXTRACE_ERR( "D3DXCreateTeapot", hr ); ///////////////////////////////////////////////////////////////////////// //在 d3dapp.cpp 的 Initialize3DEnvironment 中设置为软件模拟VS2.0(第725行) LPDIRECT3DVERTEXBUFFER9 pVB; LPVOID pVertices; hr=m_pObject->Create(m_pd3dDevice,"tiger.x"); hr=m_pObject->SetFVF(m_pd3dDevice,FVF); hr=m_pObject->m_pSysMemMesh->GetVertexBuffer(&pVB); hr=pVB->Lock(0,0,&pVertices,0); hr=D3DXComputeBoundingSphere((D3DXVECTOR3*)pVertices,m_pObject->m_pSysMemMesh->GetNumVertices(), D3DXGetFVFVertexSize(m_pObject->m_pSysMemMesh->GetFVF()),&m_vCenter,&m_ObjRadius); pVB->Unlock(); SAFE_RELEASE(pVB); hr=m_pFloor->Create(m_pd3dDevice,"seaFloor.x"); hr=m_pFloor->SetFVF(m_pd3dDevice,FVF); hr=BuildShaders(); hr=ModifyTextures(); return S_OK; } HRESULT CMyD3DApplication::BuildShaders() { LPD3DXBUFFER pError=0; LPD3DXBUFFER pCode=0; HRESULT hr; D3DVERTEXELEMENT9 declSilhouette[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END() }; hr=m_pd3dDevice->CreateVertexDeclaration(declSilhouette,&m_pSilhouetteVertexDecl); hr=D3DXAssembleShaderFromFile("zzSilhouette.vsh",0,0,0,&pCode,&pError); hr=m_pd3dDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(),&m_pSilhouetteVertexShader); D3DVERTEXELEMENT9 declSurface[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END() }; hr=m_pd3dDevice->CreateVertexDeclaration(declSurface,&m_pSurfaceVertexDecl); hr=D3DXAssembleShaderFromFile("zzSurface.vsh",0,0,0,&pCode,&pError); hr=m_pd3dDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(),&m_pSurfaceVertexShader); D3DVERTEXELEMENT9 declFloor[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END() }; hr=m_pd3dDevice->CreateVertexDeclaration(declFloor,&m_pFloorVertexDecl); hr=D3DXAssembleShaderFromFile("zzFloor.vsh",0,0,0,&pCode,&pError); hr=m_pd3dDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(),&m_pFloorVertexShader); return(S_OK); } HRESULT CMyD3DApplication::ModifyTextures() { LPDIRECT3DSURFACE9 pSurface; LPBYTE pMemSurface,pMemData; D3DSURFACE_DESC desc; RECT rect; HRESULT hr; DWORD i,j; (*m_pObject->m_pTextures)->Release(); hr=D3DXCreateTexture(m_pd3dDevice,256,8,D3DX_DEFAULT,0,D3DFMT_L8, D3DPOOL_MANAGED,m_pObject->m_pTextures); (*m_pObject->m_pTextures)->GetSurfaceLevel(0,&pSurface); pSurface->GetDesc(&desc); pMemSurface=new BYTE[desc.Width*desc.Height]; pMemData=pMemSurface; for(i=0;i Release(); return(S_OK); } //----------------------------------------------------------------------------- // Name: RestoreDeviceObjects() // Desc: Paired with InvalidateDeviceObjects() // The device exists, but may have just been Reset(). Resources in // D3DPOOL_DEFAULT and any other device state that persists during // rendering should be set here. Render states, matrices, textures, // etc., that don't change during rendering can be set once here to // avoid redundant state setting during Render() or FrameMove(). //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::RestoreDeviceObjects() { // TODO: setup render states // Setup a material D3DMATERIAL9 mtrl; D3DUtil_InitMaterial( mtrl, 1.0f, 0.0f, 0.0f ); m_pd3dDevice->SetMaterial( &mtrl ); // Set up the textures m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); // Set miscellaneous render states m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x000F0F0F ); // Restore the font m_pFont->RestoreDeviceObjects(); /////////////////////////////////////////////////////////////// D3DXVECTOR3 vEye=D3DXVECTOR3(0.0f,0.0f,-2.0f*m_ObjRadius); D3DXVECTOR3 vAt=D3DXVECTOR3(0.0f,0.0f,0.0f); D3DXVECTOR3 vUp=D3DXVECTOR3(0.0f,1.0f,0.0f); FLOAT fAspect; HRESULT hr; D3DXMatrixIdentity(&m_matWorld); D3DXMatrixLookAtLH(&m_matView,&vEye,&vAt,&vUp); fAspect=(FLOAT)m_d3dsdBackBuffer.Width/(FLOAT)m_d3dsdBackBuffer.Height; D3DXMatrixPerspectiveFovLH(&m_matProj,D3DXToRadian(60.0f),fAspect,0.1f,100.0f); m_pd3dDevice->SetTransform(D3DTS_WORLD,&m_matWorld); m_pd3dDevice->SetTransform(D3DTS_VIEW,&m_matView); m_pd3dDevice->SetTransform(D3DTS_PROJECTION,&m_matProj); m_ArcBall.SetWindow(m_d3dsdBackBuffer.Width,m_d3dsdBackBuffer.Height,0.8f); m_ArcBall.SetRadius(m_ObjRadius); hr=m_pObject->RestoreDeviceObjects(m_pd3dDevice); hr=m_pFloor->RestoreDeviceObjects(m_pd3dDevice); return S_OK; } //----------------------------------------------------------------------------- // Name: FrameMove() // Desc: Called once per frame, the call is the entry point for animating // the scene. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::FrameMove() { // TODO: update world /////////////////////////////////////////////////////////////// D3DXMATRIX matT,matX,matY,matZ; D3DXMatrixTranslation(&matT,0.01f,0.01f,0.01f); D3DXMatrixRotationX(&matX,10.0f*D3DX_PI/180.0f); D3DXMatrixRotationY(&matY,110.0f*D3DX_PI/180.0f); D3DXMatrixRotationZ(&matZ,15.0f*D3DX_PI/180.0f); D3DXMatrixMultiply(&m_matWorld,&matX,&matY); D3DXMatrixMultiply(&m_matWorld,&m_matWorld,&matZ); D3DXMatrixMultiply(&m_matWorld,&m_matWorld,&matT); D3DXMatrixMultiply(&m_matWorld,&m_matWorld,m_ArcBall.GetRotationMatrix()); D3DXMatrixMultiply(&m_matWorld,&m_matWorld,m_ArcBall.GetTranslationMatrix()); D3DXMATRIX matWVPTranspose,matWVTranspose,matViewTranspose,matProjTranspose; D3DXMATRIX matWVP,matWV; HRESULT hr; D3DXMatrixMultiply(&matWV,&m_matWorld,&m_matView); D3DXMatrixMultiply(&matWVP,&matWV,&m_matProj); D3DXMatrixTranspose(&matWVPTranspose,&matWVP); D3DXMatrixTranspose(&matWVTranspose,&matWV); D3DXMatrixTranspose(&matViewTranspose,&m_matView); D3DXMatrixTranspose(&matProjTranspose,&m_matProj); FLOAT fLight[4]={-1.0f,-1.0f,1.0f,0.0f}; FLOAT fDiffuse[4]={1.0f,1.0f,0.0f,1.0f}; FLOAT fAmbient[4]={0.25f,0.25f,0.25f,1.0f}; hr=m_pd3dDevice->SetVertexShaderConstantF(1,(FLOAT*)&matWVTranspose,4); hr=m_pd3dDevice->SetVertexShaderConstantF(5,(FLOAT*)&matWVPTranspose,4); hr=m_pd3dDevice->SetVertexShaderConstantF(18,(FLOAT*)&matViewTranspose,4); hr=m_pd3dDevice->SetVertexShaderConstantF(22,(FLOAT*)&matProjTranspose,4); hr=m_pd3dDevice->SetVertexShaderConstantF(9,(FLOAT*)&fDiffuse,1); hr=m_pd3dDevice->SetVertexShaderConstantF(10,(FLOAT*)&fLight,1); hr=m_pd3dDevice->SetVertexShaderConstantF(11,(FLOAT*)&fAmbient,1); return S_OK; } //----------------------------------------------------------------------------- // Name: UpdateInput() // Desc: Update the user input. Called once per frame //----------------------------------------------------------------------------- void CMyD3DApplication::UpdateInput( UserInput* pUserInput ) { pUserInput->bRotateUp = ( m_bActive && (GetAsyncKeyState( VK_UP ) & 0x8000) == 0x8000 ); pUserInput->bRotateDown = ( m_bActive && (GetAsyncKeyState( VK_DOWN ) & 0x8000) == 0x8000 ); pUserInput->bRotateLeft = ( m_bActive && (GetAsyncKeyState( VK_LEFT ) & 0x8000) == 0x8000 ); pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 ); } //----------------------------------------------------------------------------- // 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() { // Clear the viewport m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0L ); // Begin the scene if( SUCCEEDED( m_pd3dDevice->BeginScene() ) ) { // TODO: render world // Render the teapot mesh //m_pD3DXMesh->DrawSubset(0); /////////////////////////////////////////////////////////// HRESULT hr; hr=m_pd3dDevice->SetVertexDeclaration(m_pFloorVertexDecl); hr=m_pd3dDevice->SetVertexShader(m_pFloorVertexShader); hr=m_pFloor->Render(m_pd3dDevice); hr=m_pd3dDevice->SetVertexDeclaration(m_pSurfaceVertexDecl); hr=m_pd3dDevice->SetVertexShader(m_pSurfaceVertexShader); hr=m_pObject->Render(m_pd3dDevice); m_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE,1); m_pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL); m_pd3dDevice->SetRenderState(D3DRS_ALPHAREF,200); hr=m_pd3dDevice->SetVertexDeclaration(m_pSilhouetteVertexDecl); hr=m_pd3dDevice->SetVertexShader(m_pSilhouetteVertexShader); hr=m_pObject->Render(m_pd3dDevice); // Render stats and help text RenderText(); // End the scene. m_pd3dDevice->EndScene(); } return S_OK; } //----------------------------------------------------------------------------- // Name: RenderText() // Desc: Renders stats and help text to the scene. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::RenderText() { D3DCOLOR fontColor = D3DCOLOR_ARGB(255,255,255,0); TCHAR szMsg[MAX_PATH] = TEXT(""); // Output display stats FLOAT fNextLine = 40.0f; lstrcpy( szMsg, m_strDeviceStats ); fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg ); lstrcpy( szMsg, m_strFrameStats ); fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg ); return S_OK; } //----------------------------------------------------------------------------- // Name: MsgProc() // Desc: Overrrides the main WndProc, so the sample can do custom message // handling (e.g. processing mouse, keyboard, or menu commands). //----------------------------------------------------------------------------- LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { /////////////////////////////////////////////////////////////// m_ArcBall.HandleMouseMessages(hWnd,msg,wParam,lParam); return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam ); } //----------------------------------------------------------------------------- // Name: InvalidateDeviceObjects() // Desc: Invalidates device objects. Paired with RestoreDeviceObjects() //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::InvalidateDeviceObjects() { // TODO: Cleanup any objects created in RestoreDeviceObjects() m_pFont->InvalidateDeviceObjects(); /////////////////////////////////////////////////////////////// m_pObject->InvalidateDeviceObjects(); m_pFloor->InvalidateDeviceObjects(); return S_OK; } //----------------------------------------------------------------------------- // Name: DeleteDeviceObjects() // Desc: Paired with InitDeviceObjects() // Called when the app is exiting, or the device is being changed, // this function deletes any device dependent objects. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::DeleteDeviceObjects() { // TODO: Cleanup any objects created in InitDeviceObjects() m_pFont->DeleteDeviceObjects(); SAFE_RELEASE( m_pD3DXMesh ); /////////////////////////////////////////////////////////////// m_pObject->Destroy(); m_pFloor->Destroy(); SAFE_RELEASE(m_pSilhouetteVertexShader); SAFE_RELEASE(m_pSilhouetteVertexDecl); SAFE_RELEASE(m_pSurfaceVertexShader); SAFE_RELEASE(m_pSurfaceVertexDecl); SAFE_RELEASE(m_pFloorVertexShader); SAFE_RELEASE(m_pFloorVertexDecl); return S_OK; } //----------------------------------------------------------------------------- // Name: FinalCleanup() // Desc: Paired with OneTimeSceneInit() // Called before the app exits, this function gives the app the chance // to cleanup after itself. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::FinalCleanup() { // TODO: Perform any final cleanup needed // Cleanup D3D font SAFE_DELETE( m_pFont ); /////////////////////////////////////////////////////////////// SAFE_DELETE(m_pObject); SAFE_DELETE(m_pFloor); return S_OK; }