//-------------------------------------------------------------------------------------- // This callback function will be called at the end of every frame to perform all the // rendering calls for the scene, and it will also be called if the window needs to be // repainted. After this function has returned, DXUT will call // IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain //-------------------------------------------------------------------------------------- void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ) { // If the settings dialog is being shown, then // render it instead of rendering the app's scene if( g_SettingsDlg.IsActive() ) { g_SettingsDlg.OnRender( fElapsedTime ); return; } HRESULT hr; D3DXMATRIXA16 mWorld; D3DXMATRIXA16 mView; D3DXMATRIXA16 mProj; D3DXMATRIXA16 mWorldViewProjection; // Clear the render target and the zbuffer V( pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 141, 153, 191 ), 1.0f, 0 ) ); // Render the scene if( SUCCEEDED( pd3dDevice->BeginScene() ) ) { // Get the projection & view matrix from the camera class mWorld = *g_Camera.GetWorldMatrix(); mView = *g_Camera.GetViewMatrix(); mProj = *g_Camera.GetProjMatrix(); mWorldViewProjection = mWorld * mView * mProj; // Update the effect's variables. V( g_pEffect->SetMatrix( g_hWorldViewProjection, &mWorldViewProjection ) ); V( g_pEffect->SetMatrix( g_hWorld, &mWorld ) ); V( g_pEffect->SetFloat( g_hTime, ( float )fTime ) ); V( g_pEffect->SetValue( g_hCameraPosition, g_Camera.GetEyePt(), sizeof( D3DXVECTOR3 ) ) ); UINT iCurSubset = ( UINT )( INT_PTR )g_SampleUI.GetComboBox( IDC_SUBSET )->GetSelectedData(); // A subset of -1 was arbitrarily chosen to represent all subsets if( iCurSubset == -1 ) { // Iterate through subsets, changing material properties for each for( UINT iSubset = 0; iSubset < g_MeshLoader.GetNumMaterials(); iSubset++ ) { RenderSubset( iSubset ); } } else { RenderSubset( iCurSubset ); } RenderText(); V( g_HUD.OnRender( fElapsedTime ) ); V( g_SampleUI.OnRender( fElapsedTime ) ); V( pd3dDevice->EndScene() ); } }
//-------------------------------------------------------------------------------------- // This callback function will be called immediately after the Direct3D device has been // reset, which will happen after a lost device scenario. This is the best location to // create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever // the device is lost. Resources created here should be released in the OnLostDevice // callback. //-------------------------------------------------------------------------------------- HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { HRESULT hr; V_RETURN( g_DialogResourceManager.OnD3D9ResetDevice() ); V_RETURN( g_SettingsDlg.OnD3D9ResetDevice() ); if( g_pFont ) V_RETURN( g_pFont->OnResetDevice() ); if( g_pEffect ) V_RETURN( g_pEffect->OnResetDevice() ); // Store the correct technique handles for each material for( UINT i = 0; i < g_MeshLoader.GetNumMaterials(); i++ ) { Material* pMaterial = g_MeshLoader.GetMaterial( i ); const char* strTechnique = NULL; if( pMaterial->pTexture && pMaterial->bSpecular ) strTechnique = "TexturedSpecular"; else if( pMaterial->pTexture && !pMaterial->bSpecular ) strTechnique = "TexturedNoSpecular"; else if( !pMaterial->pTexture && pMaterial->bSpecular ) strTechnique = "Specular"; else if( !pMaterial->pTexture && !pMaterial->bSpecular ) strTechnique = "NoSpecular"; pMaterial->hTechnique = g_pEffect->GetTechniqueByName( strTechnique ); } // Create a sprite to help batch calls when drawing many lines of text V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) ); // Setup the camera's projection parameters float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height; g_Camera.SetProjParams( D3DX_PI / 4, fAspectRatio, 0.1f, 1000.0f ); g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height ); g_HUD.SetLocation( pBackBufferSurfaceDesc->Width - 170, 0 ); g_HUD.SetSize( 170, 170 ); g_HUD.Refresh(); g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width - 170, pBackBufferSurfaceDesc->Height - 350 ); g_SampleUI.SetSize( 170, 300 ); g_SampleUI.Refresh(); return S_OK; }
//-------------------------------------------------------------------------------------- // Saves the mesh to X-file //-------------------------------------------------------------------------------------- void SaveMeshToXFile() { HRESULT hr; // Fill out D3DXMATERIAL structures UINT numMaterials = g_MeshLoader.GetNumMaterials(); D3DXMATERIAL* pMaterials = new D3DXMATERIAL[numMaterials]; char* pStrTexture = new char[MAX_PATH * numMaterials]; if( ( pMaterials != NULL ) && ( pStrTexture != NULL ) ) { for( UINT i = 0; i < g_MeshLoader.GetNumMaterials(); i++ ) { Material* pMat = g_MeshLoader.GetMaterial( i ); if( pMat != NULL ) { pMaterials[i].MatD3D.Ambient.r = pMat->vAmbient.x; pMaterials[i].MatD3D.Ambient.g = pMat->vAmbient.y; pMaterials[i].MatD3D.Ambient.b = pMat->vAmbient.z; pMaterials[i].MatD3D.Ambient.a = pMat->fAlpha; pMaterials[i].MatD3D.Diffuse.r = pMat->vDiffuse.x; pMaterials[i].MatD3D.Diffuse.g = pMat->vDiffuse.y; pMaterials[i].MatD3D.Diffuse.b = pMat->vDiffuse.z; pMaterials[i].MatD3D.Diffuse.a = pMat->fAlpha; pMaterials[i].MatD3D.Specular.r = pMat->vSpecular.x; pMaterials[i].MatD3D.Specular.g = pMat->vSpecular.y; pMaterials[i].MatD3D.Specular.b = pMat->vSpecular.z; pMaterials[i].MatD3D.Specular.a = pMat->fAlpha; pMaterials[i].MatD3D.Emissive.r = 0; pMaterials[i].MatD3D.Emissive.g = 0; pMaterials[i].MatD3D.Emissive.b = 0; pMaterials[i].MatD3D.Emissive.a = 0; pMaterials[i].MatD3D.Power = ( float )pMat->nShininess; WideCharToMultiByte( CP_ACP, 0, pMat->strTexture, -1, ( pStrTexture + i * MAX_PATH ), MAX_PATH, NULL, NULL ); pMaterials[i].pTextureFilename = ( pStrTexture + i * MAX_PATH ); } } // Write to file in same directory where the .obj file was found WCHAR strBuf[ MAX_PATH ]; swprintf_s( strBuf, MAX_PATH - 1, L"%s\\%s", g_MeshLoader.GetMediaDirectory(), L"MeshFromOBJ.x" ); hr = D3DXSaveMeshToX( strBuf, g_MeshLoader.GetMesh(), NULL, pMaterials, NULL, numMaterials, D3DXF_FILEFORMAT_TEXT ); if( SUCCEEDED( hr ) ) { swprintf_s( g_strFileSaveMessage, MAX_PATH - 1, L"Created %s", strBuf ); } else { DXTRACE_ERR( L"SaveMeshToXFile()::D3DXSaveMeshToX", hr ); swprintf_s( g_strFileSaveMessage, MAX_PATH - 1, L"Error creating %s, check debug output", strBuf ); } } SAFE_DELETE_ARRAY( pMaterials ); SAFE_DELETE_ARRAY( pStrTexture ); }
//-------------------------------------------------------------------------------------- // This callback function will be called immediately after the Direct3D device has been // created, which will happen during application initialization and windowed/full screen // toggles. This is the best location to create D3DPOOL_MANAGED resources since these // resources need to be reloaded whenever the device is destroyed. Resources created // here should be released in the OnDestroyDevice callback. //-------------------------------------------------------------------------------------- HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { HRESULT hr; WCHAR str[MAX_PATH]; V_RETURN( g_DialogResourceManager.OnD3D9CreateDevice( pd3dDevice ) ); V_RETURN( g_SettingsDlg.OnD3D9CreateDevice( pd3dDevice ) ); // Initialize the font V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial", &g_pFont ) ); // Create the mesh and load it with data already gathered from a file V_RETURN( g_MeshLoader.Create( pd3dDevice, L"media\\cup.obj" ) ); // Add the identified material subsets to the UI CDXUTComboBox* pComboBox = g_SampleUI.GetComboBox( IDC_SUBSET ); pComboBox->RemoveAllItems(); pComboBox->AddItem( L"All", ( void* )( INT_PTR )-1 ); for( UINT i = 0; i < g_MeshLoader.GetNumMaterials(); i++ ) { Material* pMaterial = g_MeshLoader.GetMaterial( i ); pComboBox->AddItem( pMaterial->strName, ( void* )( INT_PTR )i ); } // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the // shader debugger. Debugging vertex shaders requires either REF or software vertex // processing, and debugging pixel shaders requires REF. The // D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the // shader debugger. It enables source level debugging, prevents instruction // reordering, prevents dead code elimination, and forces the compiler to compile // against the next higher available software target, which ensures that the // unoptimized shaders do not exceed the shader model limitations. Setting these // flags will cause slower rendering since the shaders will be unoptimized and // forced into software. See the DirectX documentation for more information about // using the shader debugger. DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE; #if defined( DEBUG ) || defined( _DEBUG ) // Set the D3DXSHADER_DEBUG flag to embed debug information in the shaders. // Setting this flag improves the shader debugging experience, but still allows // the shaders to be optimized and to run exactly the way they will run in // the release configuration of this program. dwShaderFlags |= D3DXSHADER_DEBUG; #endif #ifdef DEBUG_VS dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT; #endif #ifdef DEBUG_PS dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT; #endif // Read the D3DX effect file V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"MeshFromOBJ.fx" ) ); // If this fails, there should be debug output as to // they the .fx file failed to compile V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, dwShaderFlags, NULL, &g_pEffect, NULL ) ); // Cache the effect handles g_hAmbient = g_pEffect->GetParameterBySemantic( 0, "Ambient" ); g_hDiffuse = g_pEffect->GetParameterBySemantic( 0, "Diffuse" ); g_hSpecular = g_pEffect->GetParameterBySemantic( 0, "Specular" ); g_hOpacity = g_pEffect->GetParameterBySemantic( 0, "Opacity" ); g_hSpecularPower = g_pEffect->GetParameterBySemantic( 0, "SpecularPower" ); g_hLightColor = g_pEffect->GetParameterBySemantic( 0, "LightColor" ); g_hLightPosition = g_pEffect->GetParameterBySemantic( 0, "LightPosition" ); g_hCameraPosition = g_pEffect->GetParameterBySemantic( 0, "CameraPosition" ); g_hTexture = g_pEffect->GetParameterBySemantic( 0, "Texture" ); g_hTime = g_pEffect->GetParameterBySemantic( 0, "Time" ); g_hWorld = g_pEffect->GetParameterBySemantic( 0, "World" ); g_hWorldViewProjection = g_pEffect->GetParameterBySemantic( 0, "WorldViewProjection" ); // Setup the camera's view parameters D3DXVECTOR3 vecEye( 2.0f, 1.0f, 0.0f ); D3DXVECTOR3 vecAt ( 0.0f, 0.0f, -0.0f ); g_Camera.SetViewParams( &vecEye, &vecAt ); return S_OK; }