VOID Cleanup( ) { if (NULL != g_pFont) { g_pFont->Release(); } if (NULL != g_pMesh) { g_pMesh->Release(); } if ( NULL != g_pD3DDevice ) { g_pD3DDevice->Release(); } if ( NULL != g_pD3D ) { g_pD3D->Release(); } }
//----------------------------------------------------------------------------- // Name: Render() // Desc: Draws the scene //----------------------------------------------------------------------------- int RenderMesh(LPD3DXMESH mesh,D3DMATERIAL9* pMeshMaterials,LPDIRECT3DTEXTURE9* pMeshTextures,DWORD dwNumMaterials,D3DXMATRIXA16* pMatWorld) { g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 ); // 开始渲染 scene if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { SetupMatrices(); for( DWORD i = 0; i < dwNumMaterials; i++ ) { //执行变换矩阵 g_pd3dDevice->SetTransform( D3DTS_WORLD, pMatWorld ); g_pd3dDevice->SetMaterial( &pMeshMaterials[i] ); g_pd3dDevice->SetTexture( 0, pMeshTextures[i] ); mesh->DrawSubset( i ); } // End the scene g_pd3dDevice->EndScene(); } // Present the backbuffer contents to the display g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); return 1; }
VOID Cleanup() { if( g_pMeshMaterials != NULL ) delete[] g_pMeshMaterials; if( g_pMeshTextures ) { for( DWORD i = 0; i < g_dwNumMaterials; i++ ) { if( g_pMeshTextures[i] ) g_pMeshTextures[i]->Release(); } delete[] g_pMeshTextures; } if( g_pMesh != NULL ) g_pMesh->Release(); if( g_pd3dDevice != NULL ) g_pd3dDevice->Release(); if( g_pD3D != NULL ) g_pD3D->Release(); }
void Cleanup() { if (g_pMeshMaterials) delete[] g_pMeshMaterials; if (g_pMeshTextures) { for (DWORD i = 0; i < g_dwNumMaterials; i++) { if (g_pMeshTextures[i]) g_pMeshTextures[i]->Release(); } delete[] g_pMeshTextures; } if (g_pMesh) g_pMesh->Release(); if (g_pd3dDevice) g_pd3dDevice->Release(); if (g_pD3D) g_pD3D->Release(); }
//----------------------------------------------------------------------------- // Name: Cleanup() // Desc: Releases all previously initialized objects //----------------------------------------------------------------------------- VOID Cleanup() { // release all textures used if ( g_pTexture != NULL ) g_pTexture->Release(); if ( g_pTexture2 != NULL ) g_pTexture2->Release(); if ( marbleTexture != NULL ) marbleTexture->Release(); if ( backgroundTexture != NULL ) backgroundTexture->Release(); if( g_pMeshMaterials != NULL ) delete[] g_pMeshMaterials; if( g_pMeshTextures ) { for( DWORD i = 0; i < g_dwNumMaterials; i++ ) { if( g_pMeshTextures[i] ) g_pMeshTextures[i]->Release(); } delete[] g_pMeshTextures; } if( g_pMesh != NULL ) g_pMesh->Release(); if( g_pd3dDevice != NULL ) g_pd3dDevice->Release(); if( g_pD3D != NULL ) g_pD3D->Release(); }
//************************************************************************************************************* void Render(float alpha, float elapsedtime) { D3DXMATRIX vp, inv; D3DXVECTOR3 axis(0, 1, 0); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); device->SetTexture(0, tex); device->SetTexture(1, normalmap); D3DXMatrixMultiply(&vp, &view, &proj); D3DXMatrixInverse(&inv, NULL, &view); effect->SetVector("eyePos", (D3DXVECTOR4*)inv.m[3]); D3DXMatrixRotationAxis(&world, &axis, timeGetTime() / 1000.0f); D3DXMatrixInverse(&inv, NULL, &world); effect->SetMatrix("matWorld", &world); effect->SetMatrix("matWorldInv", &inv); effect->SetMatrix("matViewProj", &vp); if( SUCCEEDED(device->BeginScene()) ) { effect->Begin(NULL, 0); effect->BeginPass(0); { mesh->DrawSubset(0); } effect->EndPass(); effect->End(); device->EndScene(); } device->Present(NULL, NULL, NULL, NULL); }
//************************************************************************************************************* void Render(float alpha, float elapsedtime) { D3DXMATRIX world, view, proj; D3DXMATRIX skyworld, viewproj; D3DXVECTOR3 eye(0, 0, -5); D3DXVECTOR3 look(0, 0, 0); D3DXVECTOR3 up(0, 1, 0); D3DXVECTOR2 orient = cameraangle.smooth(alpha); D3DXMatrixRotationYawPitchRoll(&view, orient.x, orient.y, 0); D3DXVec3TransformCoord(&eye, &eye, &view); D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI / 4, (float)screenwidth / (float)screenheight, 0.1f, 50); D3DXMatrixLookAtLH(&view, &eye, &look, &up); D3DXMatrixMultiply(&viewproj, &view, &proj); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); device->SetTransform(D3DTS_VIEW, &view); device->SetTransform(D3DTS_PROJECTION, &proj); for( int i = 0; i < NUM_DWARFS; ++i ) dwarfs[i].Update(elapsedtime, &dwarfmatrices[i]); effect->SetMatrix("matViewProj", &viewproj); if( SUCCEEDED(device->BeginScene()) ) { // render sky device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); D3DXMatrixScaling(&skyworld, 20, 20, 20); skyeffect->SetMatrix("matWorld", &skyworld); D3DXMatrixIdentity(&skyworld); skyeffect->SetMatrix("matWorldSky", &skyworld); skyeffect->SetMatrix("matViewProj", &viewproj); skyeffect->SetVector("eyePos", (D3DXVECTOR4*)&eye); skyeffect->Begin(0, 0); skyeffect->BeginPass(0); { device->SetTexture(0, skytex); skymesh->DrawSubset(0); } skyeffect->EndPass(); skyeffect->End(); device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); // render ground D3DXMatrixScaling(&world, 5, 0.1f, 5); world._42 = -0.05f; device->SetTransform(D3DTS_WORLD, &world); device->SetTexture(0, texture2); mesh->DrawSubset(0); // dwarfs for( int i = 0; i < NUM_DWARFS; ++i ) dwarfs[i].Draw(); // fire D3DXMatrixTranslation(&world, 0, 0.25f, 0); device->SetTransform(D3DTS_WORLD, &world); system1.Draw(world, view); // render text device->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX1); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); device->SetTexture(0, text); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, textvertices, 6 * sizeof(float)); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->EndScene(); } device->Present(NULL, NULL, NULL, NULL); }
VOID Update() { DWORD currentTime = GetTickCount(); static DWORD preTime; g_ElapsedTime = currentTime - preTime; preTime = currentTime; if ( GetAsyncKeyState( VK_LEFT ) ) { g_Box[0].CenterPos.x -= g_ElapsedTime*0.002f; } if ( GetAsyncKeyState( VK_RIGHT ) ) { g_Box[0].CenterPos.x += g_ElapsedTime*0.002f; } if ( GetAsyncKeyState( VK_UP ) ) { g_Box[0].CenterPos.y += g_ElapsedTime*0.002f; } if ( GetAsyncKeyState( VK_DOWN ) ) { g_Box[0].CenterPos.y -= g_ElapsedTime*0.002f; } if ( GetAsyncKeyState( VK_LBUTTON ) ) { if (g_ElapsedTime > 20) { g_Method = !g_Method; } } if ( GetAsyncKeyState( VK_HOME ) ) { g_Box[1].BoxRotateZ -= 0.2f; } if ( GetAsyncKeyState( VK_END ) ) { g_Box[1].BoxRotateZ += 0.2f; } D3DXVECTOR3 *vertices; g_pMesh->LockVertexBuffer( D3DLOCK_READONLY, (void**) &vertices ); D3DXComputeBoundingBox( vertices, g_pMesh->GetNumVertices(), g_pMesh->GetNumBytesPerVertex(), &g_MinPoint, &g_MaxPoint ); g_pMesh->UnlockVertexBuffer(); D3DXMATRIX matScale, matTrans, matRotateZ, matWorld; D3DXMatrixTranslation( &matTrans, g_Box[0].CenterPos.x, g_Box[0].CenterPos.y, g_Box[0].CenterPos.z ); D3DXMatrixScaling( &matScale, g_Box[0].BoxScaling, g_Box[0].BoxScaling, g_Box[0].BoxScaling ); D3DXMatrixRotationZ( &matRotateZ, g_Box[0].BoxRotateZ ); matWorld = matRotateZ* matScale * matTrans; D3DXVec3TransformCoord( &g_Box[0].MinPoint, &g_MinPoint, &matWorld ); D3DXVec3TransformCoord( &g_Box[0].MaxPoint, &g_MaxPoint, &matWorld ); if (!g_Method) { g_CheckFlag = CheckAABBIntersection( &g_Box[0].MinPoint, &g_Box[0].MaxPoint, &g_Box[1].MinPoint, &g_Box[1].MaxPoint ); } else { g_CheckFlag = CheckOBBIntersection( &g_Box[0], &g_Box[1] ); } }
HRESULT InitGeometry( ) { if (FAILED(D3DXCreateBox(g_pD3DDevice, 1.f, 1.f, 1.f, &g_pMesh, NULL))) { return E_FAIL; } D3DXVECTOR3 *vertices; g_pMesh->LockVertexBuffer( D3DLOCK_READONLY, (void**) &vertices ); D3DXComputeBoundingBox( vertices, g_pMesh->GetNumVertices(), g_pMesh->GetNumBytesPerVertex(), &g_MinPoint, &g_MaxPoint ); g_pMesh->UnlockVertexBuffer(); D3DXMATRIX matScale, matTrans, matRotateZ, matWorld; g_Box[0].BoxScaling = 1.5f; g_Box[0].CenterPos = D3DXVECTOR3( 0.f, 0.f, 0.f ); g_Box[0].BoxRotateZ = 0.f; g_Box[0].AxisDir[0] = D3DXVECTOR3( 1, 0, 0 ); g_Box[0].AxisDir[1] = D3DXVECTOR3( 0, 1, 0 ); g_Box[0].AxisDir[2] = D3DXVECTOR3( 0, 0, 1 ); for ( int i = 0; i < 3; ++i ) { g_Box[0].AxisLen[i] = 0.5f; D3DXVec3TransformNormal( &(g_Box[0].AxisDir[i]), &(g_Box[0].AxisDir[i]), &matRotateZ ); D3DXVec3Normalize( &( g_Box[0].AxisDir[i] ), &( g_Box[0].AxisDir[i] ) ); g_Box[0].AxisLen[i] = g_Box[0].AxisLen[i] * g_Box[0].BoxScaling; } D3DXMatrixTranslation( &matTrans, g_Box[0].CenterPos.x, g_Box[0].CenterPos.y, g_Box[0].CenterPos.z ); D3DXMatrixScaling( &matScale, g_Box[0].BoxScaling, g_Box[0].BoxScaling, g_Box[0].BoxScaling ); D3DXMatrixRotationZ( &matRotateZ, g_Box[0].BoxRotateZ ); matWorld = matRotateZ* matScale * matTrans; D3DXVec3TransformCoord( &g_Box[0].MinPoint, &g_MinPoint, &matWorld ); D3DXVec3TransformCoord( &g_Box[0].MaxPoint, &g_MaxPoint, &matWorld ); g_Box[1].BoxScaling = 2.f; g_Box[1].CenterPos = D3DXVECTOR3( 3.f, 3.f, 0.f ); g_Box[1].BoxRotateZ = 0.f; g_Box[1].AxisDir[0] = D3DXVECTOR3( 1, 0, 0 ); g_Box[1].AxisDir[1] = D3DXVECTOR3( 0, 1, 0 ); g_Box[1].AxisDir[2] = D3DXVECTOR3( 0, 0, 1 ); for ( int i = 0; i < 3; ++i ) { g_Box[1].AxisLen[i] = 0.5f; D3DXVec3TransformNormal( &( g_Box[0].AxisDir[i] ), &( g_Box[1].AxisDir[i] ), &matRotateZ ); D3DXVec3Normalize( &( g_Box[1].AxisDir[i] ), &( g_Box[1].AxisDir[i] ) ); g_Box[1].AxisLen[i] = g_Box[1].AxisLen[i] * g_Box[1].BoxScaling; } D3DXMatrixTranslation( &matTrans, g_Box[1].CenterPos.x, g_Box[1].CenterPos.y, g_Box[1].CenterPos.z ); D3DXMatrixScaling( &matScale, g_Box[1].BoxScaling, g_Box[1].BoxScaling, g_Box[1].BoxScaling ); D3DXMatrixRotationZ( &matRotateZ, g_Box[1].BoxRotateZ ); matWorld = matRotateZ* matScale * matTrans; D3DXVec3TransformCoord( &g_Box[1].MinPoint, &g_MinPoint, &matWorld ); D3DXVec3TransformCoord( &g_Box[1].MaxPoint, &g_MaxPoint, &matWorld ); return S_OK; }
//************************************************************************************************************* void Render(float alpha, float elapsedtime) { static float time = 0; D3DXMATRIX inv; D3DXVECTOR3 axis(0, 1, 0); D3DXVECTOR4 texelsize(1.0f / (float)screenwidth, 1.0f / (float)screenheight, 0, 1); LPDIRECT3DSURFACE9 oldtarget = NULL; time += elapsedtime; D3DXMatrixRotationAxis(&inv, &axis, time); D3DXMatrixScaling(&world, 0.3f, 0.3f, 0.3f); //D3DXMatrixScaling(&world, 0.6f, 0.6f, 0.6f); D3DXMatrixMultiply(&world, &world, &inv); D3DXMatrixInverse(&inv, NULL, &world); device->SetTexture(0, texture); device->SetTexture(1, intensity); effect->SetMatrix("matWorld", &world); effect->SetMatrix("matWorldInv", &inv); effect->SetMatrix("matView", &view); effect->SetMatrix("matProj", &proj); if( useedgedetect ) { device->GetRenderTarget(0, &oldtarget); device->SetRenderTarget(0, colorsurface); device->SetRenderTarget(1, normalsurface); } device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0xff6694ed, 1.0f, 0); if( SUCCEEDED(device->BeginScene()) ) { // draw scene + normals/depth effect->SetTechnique("celshading"); effect->Begin(NULL, 0); effect->BeginPass(0); { mesh->DrawSubset(0); } effect->EndPass(); effect->End(); if( useedgedetect ) { // edge detection device->SetVertexDeclaration(vertexdecl); device->SetRenderTarget(0, edgesurface); device->SetRenderTarget(1, NULL); device->SetTexture(0, normaltarget); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); effect->SetTechnique("edgedetect"); effect->SetVector("texelSize", &texelsize); effect->Begin(NULL, 0); effect->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } effect->EndPass(); effect->End(); // put together device->SetRenderTarget(0, oldtarget); device->SetTexture(0, colortarget); device->SetTexture(2, edgetarget); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); oldtarget->Release(); effect->SetTechnique("final"); effect->Begin(NULL, 0); effect->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } effect->EndPass(); effect->End(); } else { D3DXMATRIX offproj; // use the stencil buffer device->SetRenderState(D3DRS_COLORWRITEENABLE, 0); device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); device->SetRenderState(D3DRS_STENCILENABLE, TRUE); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); device->SetRenderState(D3DRS_STENCILREF, 1); device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); device->SetTransform(D3DTS_WORLD, &world); device->SetTransform(D3DTS_VIEW, &view); float thickness = 3.5f; // render object 4 times with offseted frustum for( float i = -thickness; i < thickness + 1; i += 2 * thickness ) { for( float j = -thickness; j < thickness + 1; j += 2 * thickness ) { D3DXMatrixTranslation(&offproj, i / (float)screenwidth, j / (float)screenheight, 0); D3DXMatrixMultiply(&offproj, &proj, &offproj); device->SetTransform(D3DTS_PROJECTION, &offproj); mesh->DrawSubset(0); } } // erase area in the center device->SetRenderState(D3DRS_STENCILREF, 0); device->SetTransform(D3DTS_PROJECTION, &proj); mesh->DrawSubset(0); // now render outlines device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_ALPHA); device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL); device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); device->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX1); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CONSTANT); device->SetTextureStageState(0, D3DTSS_CONSTANT, 0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); device->SetRenderState(D3DRS_STENCILENABLE, FALSE); } device->SetTexture(2, NULL); // render text device->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX1); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); device->SetTexture(0, text); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, textvertices, 6 * sizeof(float)); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->SetTexture(0, NULL); device->EndScene(); } device->Present(NULL, NULL, NULL, NULL); }
//----------------------------------------------------------------------------- // Name: 描画処理。 //----------------------------------------------------------------------------- VOID Render() { // 画面をクリア。 g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0); static int renderCount = 0; if (SUCCEEDED(g_pd3dDevice->BeginScene())) { renderCount++; D3DXMATRIXA16 matWorld; D3DXMatrixRotationY( &g_worldMatrix, renderCount / 500.0f ); g_rotationMatrix = g_worldMatrix; //ライトを更新 UpdateLight(); // Turn on the zbuffer g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE); //シェーダー適用開始。 g_pEffect->SetTechnique("SkinModel"); g_pEffect->Begin(NULL, D3DXFX_DONOTSAVESHADERSTATE); g_pEffect->BeginPass(0); //定数レジスタに設定するカラー。 D3DXVECTOR4 color( 1.0f, 0.0f, 0.0f, 1.0f); //ワールド行列の転送。 g_pEffect->SetMatrix("g_worldMatrix", &g_worldMatrix); //ビュー行列の転送。 g_pEffect->SetMatrix("g_viewMatrix", &camera.GetViewMatrix()); //@カメラクラスを作るためのヒント。 カメラクラスのゲッターを使用するようにする。 //プロジェクション行列の転送。 g_pEffect->SetMatrix("g_projectionMatrix", &camera.GetProjectionMatrix()); //@カメラクラスを作るためのヒント。 カメラクラスのゲッターを使用するようにする。 //回転行列を転送。 g_pEffect->SetMatrix( "g_rotationMatrix", &g_rotationMatrix ); //ライトの向きを転送。 g_pEffect->SetVectorArray("g_diffuseLightDirection", g_diffuseLightDirection, LIGHT_NUM ); //ライトのカラーを転送。 g_pEffect->SetVectorArray("g_diffuseLightColor", g_diffuseLightColor, LIGHT_NUM ); //環境光を設定。 g_pEffect->SetVector("g_ambientLight", &g_ambientLight); g_pEffect->CommitChanges(); //この関数を呼び出すことで、データの転送が確定する。描画を行う前に一回だけ呼び出す。 // Meshes are divided into subsets, one for each material. Render them in // a loop for( DWORD i = 0; i < g_dwNumMaterials; i++ ) { g_pEffect->SetTexture("g_diffuseTexture", g_pMeshTextures[i]); // Draw the mesh subset g_pMesh->DrawSubset( i ); } g_pEffect->EndPass(); g_pEffect->End(); // End the scene g_pd3dDevice->EndScene(); } // Present the backbuffer contents to the display g_pd3dDevice->Present(NULL, NULL, NULL, NULL); }
HRESULT KModelWater::LoadMesh(LPSTR pFileName) { HRESULT hr = S_OK; m_dwNumPoly_X = 63; //长方形网格的长,网格数 m_dwNumPoly_Z = 63; //长方形网格的宽,网格数 LPD3DXMESH pMesh = m_pWaterUp; LPD3DXMESH pDMesh = m_pWaterDn; DWORD m_dNumPloy = m_dwNumPoly_X * m_dwNumPoly_Z; DWORD m_dNumFaces = m_dNumPloy * 2; DWORD m_dNumVertices = (m_dwNumPoly_X+1)*(m_dwNumPoly_Z+1); SAFE_RELEASE(pMesh); SAFE_RELEASE(pDMesh); WORD *pwIndices; //建立水面网格 if(FAILED(hr = g_pd3dDevice->CreateIndexBuffer(m_dNumFaces * 3 * sizeof(WORD), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pibIndices, NULL))) { return hr; } if (FAILED(hr = D3DXCreateMeshFVF(m_dNumFaces,m_dNumVertices,D3DXMESH_MANAGED|D3DXMESH_32BIT, D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_NORMAL|D3DFVF_TEX1,g_pd3dDevice,&pMesh))) { return hr; } if (FAILED(hr = D3DXCreateMeshFVF(m_dNumFaces,m_dNumVertices,D3DXMESH_MANAGED|D3DXMESH_32BIT, D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_NORMAL|D3DFVF_TEX1,g_pd3dDevice,&pDMesh))) { return hr; } VFormat::FACES_NORMAL_TEXTURE1 * pVers = NULL; DWORD* pIndex = NULL; DWORD * pAttrib = NULL; VFormat::FACES_NORMAL_TEXTURE1 * pDVers = NULL; DWORD* pDIndex = NULL; DWORD * pDAttrib = NULL; if(FAILED(hr = m_pibIndices->Lock(0, m_dNumFaces *3 * sizeof(WORD), (void**) &pwIndices, D3DLOCK_DISCARD))) return E_FAIL; if (FAILED(pMesh->LockVertexBuffer(0,(void**)&pVers))) return E_FAIL; if (FAILED(pMesh->LockIndexBuffer (0,(void**)&pIndex))) return E_FAIL; if (FAILED(pMesh->LockAttributeBuffer(0,(DWORD**)&pAttrib))) return E_FAIL; if (FAILED(pDMesh->LockVertexBuffer(0,(void**)&pDVers))) return E_FAIL; if (FAILED(pDMesh->LockIndexBuffer (0,(void**)&pDIndex))) return E_FAIL; if (FAILED(pDMesh->LockAttributeBuffer(0,(DWORD**)&pDAttrib))) return E_FAIL; DWORD i = 0; float _X = 1.0f/m_dwNumPoly_X; float _Z = 1.0f/m_dwNumPoly_Z; float m_fPolyWidth = 200; float m_fPolyHeight = 200; for(DWORD X =0;X<=m_dwNumPoly_X;X++) { for(DWORD Y =0;Y<=m_dwNumPoly_Z;Y++) { float PX = X * m_fPolyWidth; float PZ = Y * m_fPolyHeight; D3DXVECTOR2 Pos(PX,PZ); pVers[i].p = D3DXVECTOR3(PX,200,PZ); pVers[i].Normal = D3DXVECTOR3(0,1,0); pVers[i].tu1 = (X * _X); pVers[i].tv1 = (1 - Y *_Z); pDVers[i].p = D3DXVECTOR3(PX,0,PZ); pDVers[i].Normal = D3DXVECTOR3(0,1,0); pDVers[i].tu1 = (X * _X); pDVers[i].tv1 = (1 - Y *_Z); i++; } } DWORD Weight = m_dwNumPoly_X + 1; for(X =0;X<m_dwNumPoly_X;X++) { for(DWORD Y =0;Y<m_dwNumPoly_Z;Y++) { DWORD PloyIndex = Y*m_dwNumPoly_X +X; DWORD PolyMaterialID = 0; DWORD Vertex_A = X *Weight+ Y; DWORD Vertex_B = (X+1)*Weight+ Y; DWORD Vertex_C = (X+1)*Weight+(Y+1); DWORD Vertex_D = X *Weight+(Y+1); DWORD Faces_A1 = (PloyIndex*2)*3; DWORD Faces_B1 = Faces_A1 + 1; DWORD Faces_C1 = Faces_B1 + 1; pIndex[Faces_A1] = Vertex_A; pIndex[Faces_B1] = Vertex_B; pIndex[Faces_C1] = Vertex_D; pAttrib[PloyIndex*2] = PolyMaterialID; pDIndex[Faces_A1] = Vertex_A; pDIndex[Faces_B1] = Vertex_B; pDIndex[Faces_C1] = Vertex_D; pDAttrib[PloyIndex*2] = PolyMaterialID; pwIndices[Faces_A1] = WORD(Vertex_A); pwIndices[Faces_B1] = WORD(Vertex_B); pwIndices[Faces_C1] = WORD(Vertex_D); DWORD Faces_A2 = (PloyIndex*2+1)*3; DWORD Faces_B2 = Faces_A2 + 1; DWORD Faces_C2 = Faces_B2 + 1; pIndex[Faces_A2] = Vertex_D; pIndex[Faces_B2] = Vertex_B; pIndex[Faces_C2] = Vertex_C; pAttrib[PloyIndex*2+1] = PolyMaterialID; pDIndex[Faces_A2] = Vertex_D; pDIndex[Faces_B2] = Vertex_B; pDIndex[Faces_C2] = Vertex_C; pDAttrib[PloyIndex*2+1] = PolyMaterialID; pwIndices[Faces_A2] = WORD(Vertex_D); pwIndices[Faces_B2] = WORD(Vertex_B); pwIndices[Faces_C2] = WORD(Vertex_C); } } D3DXComputeBoundingBox((D3DXVECTOR3*)pVers,m_dNumVertices,sizeof(VFormat::FACES_NORMAL_TEXTURE1), &m_BBox_A,&m_BBox_B); D3DXComputeBoundingBox((D3DXVECTOR3*)pDVers,m_dNumVertices,sizeof(VFormat::FACES_NORMAL_TEXTURE1), &m_BBox_A,&m_BBox_B); if (FAILED(pMesh->UnlockVertexBuffer())) return E_FAIL; if (FAILED(pMesh->UnlockIndexBuffer())) return E_FAIL; if (FAILED(pMesh->UnlockAttributeBuffer())) return E_FAIL; if (FAILED(pDMesh->UnlockVertexBuffer())) return E_FAIL; if (FAILED(pDMesh->UnlockIndexBuffer())) return E_FAIL; if (FAILED(pDMesh->UnlockAttributeBuffer())) return E_FAIL; if (FAILED(m_pibIndices->Unlock())) return E_FAIL; m_pWaterUp = pMesh; m_pWaterDn = pDMesh; //水面网格的材质 m_dNumMaterial = 1; m_lpMaterial = new MATERIAL[m_dNumMaterial]; ZeroMemory(m_lpMaterial,sizeof(MATERIAL)*m_dNumMaterial); DWORD Def_Option = MATERIAL_OPTION_ZBUFFER_TRUE| MATERIAL_OPTION_FILL_SOLID| MATERIAL_OPTION_SHADE_GOURAUD| MATERIAL_OPTION_CULL_NONE| MATERIAL_OPTION_SPECULARENABLE; for(DWORD i=0;i<m_dNumMaterial;i++) { m_lpMaterial[i].m_sMaterial9.Diffuse.r = 0.7f ; m_lpMaterial[i].m_sMaterial9.Diffuse.g = 0.7f ; m_lpMaterial[i].m_sMaterial9.Diffuse.b = 0.7f ; m_lpMaterial[i].m_sMaterial9.Diffuse.a = 1.0f ; m_lpMaterial[i].m_sMaterial9.Ambient = m_lpMaterial[i].m_sMaterial9.Diffuse; m_lpMaterial[i].m_sMaterial9.Specular = m_lpMaterial[i].m_sMaterial9.Diffuse; m_lpMaterial[i].m_sMaterial9.Power = 15; m_lpMaterial[i].m_dOption = Def_Option; } TCHAR Name[256]; wsprintf(Name,"%s\\Water.Mtl",g_Def_ModelDirectory); LoadMaterial(Name); //天空盒的纹理 wsprintf(Name,"%s\\%s",g_Def_AppDirectory,"Textures\\LobbyCube.dds"); if( FAILED( hr = D3DXCreateCubeTextureFromFile( g_pd3dDevice,Name, &m_pSkyCubeTex ) ) ) return hr; //水面的纹理 wsprintf(Name,"%s\\%s",g_Def_AppDirectory,"Textures\\Water.bmp"); if( FAILED( hr = D3DXCreateTextureFromFileEx(g_pd3dDevice, Name, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &m_pWaterTex) )) return hr; /* // Effect wsprintf(Name,"%s\\%s",g_Def_AppDirectory,"water.fx"); if(FAILED(hr = D3DXCreateEffectFromFile(g_pd3dDevice, Name, NULL, NULL, 0, NULL, &m_pEffect, NULL))) return hr; m_pEffect->OnResetDevice(); m_pEffect->SetTexture("tFLR", m_pWaterTex); m_pEffect->SetTexture("tENV", m_pSkyCubeTex); */ //创建水面bump纹理 if( FAILED( InitBumpMap() ) ) return E_FAIL; // m_pEffect->SetTexture("tBump", m_pBumpMapTexture); WSea.Initialize(m_dwNumPoly_X,m_dwNumPoly_Z); Water.Initialize(m_pWaterUp,m_dwNumPoly_X,m_dwNumPoly_Z); //初始化水纹 Water.Drop(); //产生水纹 Ripple.Initialize(m_pWaterUp,m_dwNumPoly_X,m_dwNumPoly_Z); //初始化涟漪纹 return S_OK; }
//----------------------------------------------------------------------------- // Desc: 在这里是调用了成员函数 GenerateGameSkinMesh(pMeshContainer); // 是在这里加载了蒙皮信息 //----------------------------------------------------------------------------- HRESULT DexAllocateHierarchy::CreateMeshContainer(LPCSTR Name, CONST D3DXMESHDATA *pMeshData, CONST D3DXMATERIAL *pMaterials, CONST D3DXEFFECTINSTANCE *pEffectInstances, DWORD NumMaterials, CONST DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer) { HRESULT hr; stDexMeshContainerEx *pMeshContainer = NULL; LPDIRECT3DDEVICE9 device = NULL; UINT NumFaces; UINT iMaterial; UINT iBone, cBones; LPD3DXMESH pMesh = NULL; *ppNewMeshContainer = NULL; // this sample does not handle patch meshes, so fail when one is found if (pMeshData->Type != D3DXMESHTYPE_MESH) { hr = E_FAIL; return hr; } // get the pMesh interface pointer out of the mesh data structure pMesh = pMeshData->pMesh; pMesh->GetDevice( &device ); // this sample does not FVF compatible meshes, so fail when one is found if (pMesh->GetFVF() == 0) { hr = E_FAIL; return hr; } // allocate the overloaded structure to return as a D3DXMESHCONTAINER pMeshContainer = new stDexMeshContainerEx; if (pMeshContainer == NULL) { hr = E_OUTOFMEMORY; return hr; } memset(pMeshContainer, 0, sizeof(stDexMeshContainerEx)); // make sure and copy the name. All memory as input belongs to caller, interfaces can be addref'd though hr = AllocateName(Name, &pMeshContainer->Name); if (FAILED(hr)) { if (pMeshContainer != NULL) { DestroyMeshContainer(pMeshContainer); } return hr; } NumFaces = pMesh->GetNumFaces(); // if no normals are in the mesh, add them if (!(pMesh->GetFVF() & D3DFVF_NORMAL)) { pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH; // clone the mesh to make room for the normals hr = pMesh->CloneMeshFVF( pMesh->GetOptions(), pMesh->GetFVF() | D3DFVF_NORMAL, device, &pMeshContainer->MeshData.pMesh ); if (FAILED(hr)) { if (pMeshContainer != NULL) { DestroyMeshContainer(pMeshContainer); } return hr; } // get the new pMesh pointer back out of the mesh container to use // NOTE: we do not release pMesh because we do not have a reference to it yet pMesh = pMeshContainer->MeshData.pMesh; // now generate the normals for the pmesh D3DXComputeNormals( pMesh, NULL ); } else // if no normals, just add a reference to the mesh for the mesh container { pMeshContainer->MeshData.pMesh = pMesh; pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH; pMesh->AddRef(); } // allocate memory to contain the material information. This sample uses // the D3D9 materials and texture names instead of the EffectInstance style materials pMeshContainer->NumMaterials = max(1, NumMaterials); pMeshContainer->pMaterials = new D3DXMATERIAL[pMeshContainer->NumMaterials]; pMeshContainer->ppTextures = new LPDIRECT3DTEXTURE9[pMeshContainer->NumMaterials]; pMeshContainer->pAdjacency = new DWORD[NumFaces*3]; if ((pMeshContainer->pAdjacency == NULL) || (pMeshContainer->pMaterials == NULL)) { hr = E_OUTOFMEMORY; if (pMeshContainer != NULL) { DestroyMeshContainer(pMeshContainer); } return hr; } memcpy(pMeshContainer->pAdjacency, pAdjacency, sizeof(DWORD) * NumFaces*3); memset(pMeshContainer->ppTextures, 0, sizeof(LPDIRECT3DTEXTURE9) * pMeshContainer->NumMaterials); // if materials provided, copy them if (NumMaterials > 0) { memcpy(pMeshContainer->pMaterials, pMaterials, sizeof(D3DXMATERIAL) * NumMaterials); for (iMaterial = 0; iMaterial < NumMaterials; iMaterial++) { if (pMeshContainer->pMaterials[iMaterial].pTextureFilename != NULL) { //TCHAR file[1000]; //FindMediaFile(file,pMeshContainer->pMaterials[iMaterial].pTextureFilename); // 根据纹理的文件名创建纹理资源,如果创建失败,纹理指针必须赋成NULL // MessageNULL(file); //D3DXCreateTextureFromFileEx(device, file, // D3DX_DEFAULT_NONPOW2, // D3DX_DEFAULT_NONPOW2, // D3DX_FROM_FILE, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, // D3DX_FILTER_NONE, D3DX_FILTER_NONE, D3DCOLOR_XRGB(0,0,0), NULL, NULL, // &pMeshContainer->ppTextures[iMaterial]); string texname = "model/"; //轉到model文件夾中去找紋理 texname += pMeshContainer->pMaterials[iMaterial].pTextureFilename; if( FAILED( D3DXCreateTextureFromFile( device, texname.c_str(), &pMeshContainer->ppTextures[iMaterial] ) ) ) { getLog()->BeginLog(); getLog()->Log(log_allert, "load model texture %s failed! \n", texname.c_str()); pMeshContainer->ppTextures[iMaterial] = NULL; getLog()->EndLog(); } // don't remember a pointer into the dynamic memory, just forget the name after loading pMeshContainer->pMaterials[iMaterial].pTextureFilename = NULL; } } } else // if no materials provided, use a default one { pMeshContainer->pMaterials[0].pTextureFilename = NULL; memset(&pMeshContainer->pMaterials[0].MatD3D, 0, sizeof(D3DMATERIAL9)); pMeshContainer->pMaterials[0].MatD3D.Diffuse.r = 0.5f; pMeshContainer->pMaterials[0].MatD3D.Diffuse.g = 0.5f; pMeshContainer->pMaterials[0].MatD3D.Diffuse.b = 0.5f; pMeshContainer->pMaterials[0].MatD3D.Specular = pMeshContainer->pMaterials[0].MatD3D.Diffuse; } // if there is skinning information, save off the required data and then setup for HW skinning if (pSkinInfo != NULL) { // first save off the SkinInfo and original mesh data pMeshContainer->pSkinInfo = pSkinInfo; pSkinInfo->AddRef(); pMeshContainer->pOrigMesh = pMesh; pMesh->AddRef(); // Will need an array of offset matrices to move the vertices from the figure space to the bone's space cBones = pSkinInfo->GetNumBones(); pMeshContainer->pBoneOffsetMatrices = new D3DXMATRIX[cBones]; if (pMeshContainer->pBoneOffsetMatrices == NULL) { hr = E_OUTOFMEMORY; if (pMeshContainer != NULL) { DestroyMeshContainer(pMeshContainer); } return hr; } // get each of the bone offset matrices so that we don't need to get them later for (iBone = 0; iBone < cBones; iBone++) { pMeshContainer->pBoneOffsetMatrices[iBone] = *(pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(iBone)); } // GenerateGameSkinMesh will take the general skinning information and transform it to a HW friendly version hr = GenerateGameSkinMesh(device, pMeshContainer ); if (FAILED(hr)) { if (pMeshContainer != NULL) { DestroyMeshContainer(pMeshContainer); } return hr; } } *ppNewMeshContainer = pMeshContainer; pMeshContainer = NULL; // call Destroy function to properly clean up the memory allocated if (pMeshContainer != NULL) { DestroyMeshContainer(pMeshContainer); } return hr; }
HRESULT InitGeometry() { LPD3DXBUFFER pD3DXMtrlBuffer; if ( FAILED( D3DXLoadMeshFromX( L"./Resource/girl.x", D3DXMESH_SYSTEMMEM, g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh ) ) ) { MessageBox( NULL, L"Could not find girl.x", L"D3D Tutorial", MB_OK ); return E_FAIL; } D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials]; if ( g_pMeshMaterials == NULL ) { return E_OUTOFMEMORY; } g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials]; if ( g_pMeshTextures == NULL ) { return E_OUTOFMEMORY; } if ( !( g_pMesh->GetFVF() & D3DFVF_NORMAL ) ) { //가지고 있지 않다면 메쉬를 복제하고 D3DFVF_NORMAL을 추가한다. ID3DXMesh* pTempMesh = 0; g_pMesh->CloneMeshFVF( D3DXMESH_MANAGED, g_pMesh->GetFVF() | D3DFVF_NORMAL, g_pd3dDevice, &pTempMesh ); // 법선을 계산한다. D3DXComputeNormals( pTempMesh, 0 ); g_pMesh->Release(); // 기존메쉬를 제거한다 g_pMesh = pTempMesh; // 기존메쉬를 법선이 계산된 메쉬로 지정한다. } for ( DWORD i = 0; i < g_dwNumMaterials; ++i ) { g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D; g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse; g_pMeshTextures[i] = NULL; if ( d3dxMaterials[i].pTextureFilename != NULL && lstrlenA( d3dxMaterials[i].pTextureFilename ) > 0 ) { if ( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice, d3dxMaterials[i].pTextureFilename, &g_pMeshTextures[i] ) ) ) { const CHAR* strPrefix = "./Resource/"; CHAR strTexture[MAX_PATH]; strcpy_s( strTexture, MAX_PATH, strPrefix ); strcat_s( strTexture, MAX_PATH, d3dxMaterials[i].pTextureFilename ); if ( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice, strTexture, &g_pMeshTextures[i] ) ) ) { MessageBox( NULL, L"Could not find texture map", L"D3D Tutorial", MB_OK ); } } } } pD3DXMtrlBuffer->Release(); return S_OK; }
HRESULT KG3DMesh::CreateBspFile() { HRESULT hrResult = E_FAIL; HRESULT hrRetCode = E_FAIL; int nRetCode = false; TCHAR szBSPPathName[MAX_PATH]; void *pvVerticesBuffer = NULL; WORD* pIndexBuffer = NULL; D3DXVECTOR3 *pPos = NULL; DWORD *pdwFaceIndex = NULL; DWORD dwStride = 0; DWORD i = 0; DWORD dwNumFaces = 0; DWORD dwNumVertices = 0; DWORD dwStartTime = timeGetTime(); LPD3DXMESH piMesh = m_ppMeshes[SMBT_NORMAL]; KG3DBsp *pBSP = NULL; KGLOG_PROCESS_ERROR(piMesh); dwStride = piMesh->GetNumBytesPerVertex(); dwNumVertices = piMesh->GetNumVertices(); dwNumFaces = piMesh->GetNumFaces(); KG_PROCESS_SUCCESS(dwNumFaces < 256); pPos = new D3DXVECTOR3[dwNumVertices]; KG_ASSERT_EXIT(pPos); pdwFaceIndex = new DWORD[dwNumFaces * 3]; KG_ASSERT_EXIT(pdwFaceIndex); hrRetCode = piMesh->LockVertexBuffer(D3DLOCK_READONLY, (void **)&pvVerticesBuffer); KGLOG_COM_PROCESS_ERROR(hrRetCode); hrRetCode = piMesh->LockIndexBuffer(D3DLOCK_READONLY, (void **)&pIndexBuffer); KGLOG_COM_PROCESS_ERROR(hrRetCode); for (i = 0; i < dwNumVertices; ++i) { pPos[i] = *(D3DXVECTOR3 *)(((BYTE *)pvVerticesBuffer) + dwStride * i); } for (i = 0; i < dwNumFaces * 3; ++i) { pdwFaceIndex[i] = pIndexBuffer[i]; } // -------------------------- create BSP -------------------------- hrRetCode = ChangePathExtName(m_scName.c_str(), "bsp", sizeof(szBSPPathName), szBSPPathName); KGLOG_COM_PROCESS_ERROR(hrRetCode); pBSP = new KG3DBsp; KGLOG_PROCESS_ERROR(pBSP); hrRetCode = pBSP->CreateFromMesh(dwNumVertices, dwNumFaces, pPos, pdwFaceIndex); KGLOG_COM_PROCESS_ERROR(hrRetCode); hrRetCode = pBSP->SaveToFile(szBSPPathName); KGLOG_COM_PROCESS_ERROR(hrRetCode); DWORD dwCost = timeGetTime() - dwStartTime; if(dwCost > 500) { KGLogPrintf( KGLOG_WARNING, "BSP %d %d Face %s", dwCost, dwNumFaces, szBSPPathName ); } KG_DELETE(m_lpBsp); // recreate m_lpBsp = pBSP; pBSP = NULL; Exit1: hrResult = S_OK; Exit0: KG_DELETE(pBSP); if (pIndexBuffer) { piMesh->UnlockIndexBuffer(); pIndexBuffer = NULL; } if (pvVerticesBuffer) { piMesh->UnlockVertexBuffer(); pvVerticesBuffer = NULL; } KG_DELETE_ARRAY(pdwFaceIndex); KG_DELETE_ARRAY(pPos); if(FAILED(hrResult)) { KGLogPrintf(KGLOG_ERR, "%s 创建失败", szBSPPathName); } return hrResult; }
void CreateBox( const float &w, const float &h, const float &d, const bool ¢erWidth, const bool ¢erHeight, const bool ¢erDepth, LPD3DXMESH &mesh ) { float offsetX = 0, offsetY = 0, offsetZ = 0; if( centerWidth ) offsetX = -w / 2.f; if( centerHeight ) offsetY = -h / 2.f; if( centerDepth ) offsetZ = -d / 2.f; std::vector<DWORD> vIB; std::vector<VERTEX3> vVB; std::vector<DWORD> vAB; DWORD offset = 0; // fill in the front face index data vIB.push_back( 0 + offset ); vIB.push_back( 1 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 0 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 3 + offset ); // fill in the front face vertex data vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 0.f, 1.f ) ); vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 0.f, 0.f ) ); vVB.push_back( VERTEX3( w + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 1.f, 0.f ) ); vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 1.f, 1.f ) ); vAB.push_back( 0 ); vAB.push_back( 0 ); offset += 4; // fill in the back face index data vIB.push_back( 0 + offset ); vIB.push_back( 1 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 0 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 3 + offset ); // fill in the back face vertex data vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 1.f, 1.f ) ); vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 0.f, 1.f ) ); vVB.push_back( VERTEX3( w + offsetX, h + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 0.f, 0.f ) ); vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 1.f, 0.f ) ); vAB.push_back( 1 ); vAB.push_back( 1 ); offset += 4; // fill in the top face index data vIB.push_back( 0 + offset ); vIB.push_back( 1 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 0 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 3 + offset ); //fill in the top face vertex data vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 1.f, 0.f, 0.f, 1.f ) ); vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, d + offsetZ, 0.f, 1.f, 0.f, 0.f, 0.f ) ); vVB.push_back( VERTEX3( w + offsetX, h + offsetY, d + offsetZ, 0.f, 1.f, 0.f, 1.f, 0.f ) ); vVB.push_back( VERTEX3( w + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 1.f, 0.f, 1.f, 1.f ) ); vAB.push_back( 2 ); vAB.push_back( 2 ); offset += 4; // fill in the bottom face index data vIB.push_back( 0 + offset ); vIB.push_back( 1 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 0 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 3 + offset ); // fill in the bottom face vertex data vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, -1.f, 0.f, 0.f, 1.f ) ); vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, -1.f, 0.f, 0.f, 0.f ) ); vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, d + offsetZ, 0.f, -1.f, 0.f, 1.f, 0.f ) ); vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, d + offsetZ, 0.f, -1.f, 0.f, 1.f, 1.f ) ); vAB.push_back( 3 ); vAB.push_back( 3 ); offset += 4; // fill in the left face index data vIB.push_back( 0 + offset ); vIB.push_back( 1 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 0 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 3 + offset ); // fill in the left face vertex data vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, d + offsetZ, -1.f, 0.f, 0.f, 0.f, 1.f ) ); vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, d + offsetZ, -1.f, 0.f, 0.f, 0.f, 0.f ) ); vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, 0.f + offsetZ, -1.f, 0.f, 0.f, 1.f, 0.f ) ); vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, 0.f + offsetZ, -1.f, 0.f, 0.f, 1.f, 1.f ) ); vAB.push_back( 4 ); vAB.push_back( 4 ); offset += 4; // fill in the right face index data vIB.push_back( 0 + offset ); vIB.push_back( 1 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 0 + offset ); vIB.push_back( 2 + offset ); vIB.push_back( 3 + offset ); // fill in the right face vertex data vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, 0.f + offsetZ, 1.f, 0.f, 0.f, 0.f, 1.f ) ); vVB.push_back( VERTEX3( w + offsetX, h + offsetY, 0.f + offsetZ, 1.f, 0.f, 0.f, 0.f, 0.f ) ); vVB.push_back( VERTEX3( w + offsetX, h + offsetY, d + offsetZ, 1.f, 0.f, 0.f, 1.f, 0.f ) ); vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, d + offsetZ, 1.f, 0.f, 0.f, 1.f, 1.f ) ); vAB.push_back( 5 ); vAB.push_back( 5 ); offset += 4; D3DXCreateMeshFVF( offset / 2, offset, D3DXMESH_MANAGED | D3DXMESH_32BIT, VERTEX3::FVF, g_pEngine->core->lpd3dd9, &mesh ); VERTEX3 *pVB = nullptr; mesh->LockVertexBuffer( D3DLOCK_DISCARD, reinterpret_cast< void** >( &pVB ) ); copy( vVB.begin(), vVB.end(), pVB ); mesh->UnlockVertexBuffer(); DWORD *pIB = nullptr; mesh->LockIndexBuffer( D3DLOCK_DISCARD, reinterpret_cast< void** >( &pIB ) ); copy( vIB.begin(), vIB.end(), pIB ); mesh->UnlockIndexBuffer(); DWORD *pAB = nullptr; mesh->LockAttributeBuffer( D3DLOCK_DISCARD, &pAB ); copy( vAB.begin(), vAB.end(), pAB ); mesh->UnlockAttributeBuffer(); std::vector<DWORD> adjacencyBuffer( mesh->GetNumFaces() * 3 ); mesh->GenerateAdjacency( 0.f, &adjacencyBuffer[ 0 ] ); mesh->OptimizeInplace( D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, &adjacencyBuffer[ 0 ], nullptr, nullptr, nullptr ); }
//メッシュコンテナ描画 void Dx_Graphics3D::DrawMeshContainer(LPD3DXMESHCONTAINER pMeshContainer, LPD3DXFRAME pFrame) { DxMeshContainer *mesh_container = (DxMeshContainer*)pMeshContainer; DxFrame *frame = (DxFrame*)pFrame; // D3DMATERIAL9 mat; LPDIRECT3DTEXTURE9 pTex=NULL; //D3DXMESHDATA内のメッシュデータを抽出 LPD3DXMESH lpMesh = mesh_container->MeshData.pMesh; //スキニング情報がない場合 if(pMeshContainer->pSkinInfo==NULL) { //デバイスにフレームのワールド行列を設置 this->device->SetTransform( D3DTS_WORLD, &frame->CombinedTransformationMatrix); //メッシュ描画 for (DWORD i=0;i<mesh_container->NumMaterials;i++) { //マテリアル情報の取得 mat = mesh_container->pMaterials[i].MatD3D; //テクスチャ情報の取得 pTex = mesh_container->ppTextures[i]; //メッシュサブセットを描画 this->DrawSubset(lpMesh,i,&mat,pTex); } } //スキニング情報がある場合 else { D3DXMATRIX matId; PBYTE pVerticesSrc; PBYTE pVerticesDest; //ボーン数を取得 DWORD NumBones = pMeshContainer->pSkinInfo->GetNumBones(); for( DWORD i = 0; i < NumBones; i++ ){ D3DXMatrixMultiply( &mesh_container->pBoneMatrices[i], &mesh_container->pBoneOffsetMatrices[i], mesh_container->ppBoneMatrixPtrs[i] ); } //ワールド行列をクリア D3DXMatrixIdentity(&matId); this->device->SetTransform(D3DTS_WORLD, &matId); //頂点バッファをロック mesh_container->lpMesh->LockVertexBuffer( D3DLOCK_READONLY, (LPVOID*)&pVerticesSrc); lpMesh->LockVertexBuffer( 0, (LPVOID*)&pVerticesDest); //スキンメッシュ作成 mesh_container->pSkinInfo->UpdateSkinnedMesh( mesh_container->pBoneMatrices, NULL, pVerticesSrc, pVerticesDest); //頂点バッファのロックを解除 mesh_container->lpMesh->UnlockVertexBuffer(); lpMesh->UnlockVertexBuffer(); //メッシュ描画 for(UINT i = 0;i<mesh_container->NumAttributeGroups;i++) { //メッシュサブセットの属性IDを取得 unsigned AttribId = mesh_container->pAttributeTable[i].AttribId; //マテリアル情報を取得 mat = mesh_container->pMaterials[AttribId].MatD3D; //テクスチャ情報を取得 pTex = mesh_container->ppTextures[AttribId]; //メッシュのサブセットを描画 this->DrawSubset(lpMesh,AttribId,&mat,pTex); } } }
/** * * PRECONDITION: parameter EFacePosition _eSide must be either FACE_TOP, or FACE_BOTTOM. * * @author Rebeccah Cox * @param EFacePosition _eSide - the side the flag is on, either top or bottom. * @param int32 _iX - the position along the X axis. * @param int32 _iY - the position along the Z axis (looks like the y axis when * looking at the flag plate). * @param ETeam _eTeam - team the flagplate belongs to. * @param uint32 _uiTextureID * @param uint32 _uiModelID * @return bool - returns true if the initialisation was successful. */ bool CFlagPlate::Initialise(EFacePosition _eSide, int32 _iX, int32 _iY, ETeam _eTeam, uint32 _uiModelID, uint32 _uiTextureID) { // Set the position and side member variables in CTile. m_eFace = _eSide; m_iX = _iX; m_iY = _iY; m_vec3Position = g_atUpRightDirectionVecs[_eSide].vec3Up * 22.5f; m_vec3Position += g_atUpRightDirectionVecs[_eSide].vec3Right * ((_iX * 3.0f) - 21.0f); m_vec3Position -= g_atUpRightDirectionVecs[_eSide].vec3Direction * ((_iY * 3.0f) - 21.0f); // Set the world matrix using the vectors. m_matWorld._11 = g_atUpRightDirectionVecs[_eSide].vec3Right.x; m_matWorld._21 = g_atUpRightDirectionVecs[_eSide].vec3Up.x; m_matWorld._31 = g_atUpRightDirectionVecs[_eSide].vec3Direction.x; m_matWorld._12 = g_atUpRightDirectionVecs[_eSide].vec3Right.y; m_matWorld._22 = g_atUpRightDirectionVecs[_eSide].vec3Up.y; m_matWorld._32 = g_atUpRightDirectionVecs[_eSide].vec3Direction.y; m_matWorld._13 = g_atUpRightDirectionVecs[_eSide].vec3Right.z; m_matWorld._23 = g_atUpRightDirectionVecs[_eSide].vec3Up.z; m_matWorld._33 = g_atUpRightDirectionVecs[_eSide].vec3Direction.z; m_matWorld._41 = m_vec3Position.x; m_matWorld._42 = m_vec3Position.y; m_matWorld._43 = m_vec3Position.z; m_bTraversable = true; m_iModelID = _uiModelID; m_iTextureID = _uiTextureID; /*// Set the model ID if(BAD_ID == _uiModelID) { m_iModelID = CModelManager::GetInstance().CreateModel("../../models/tile_flagplate.x"); } // Set the texture ID if(BAD_ID == _uiTextureID) { if(TEAM_GREEN == _eTeam) { m_iTextureID = CTextureManager::GetInstance().CreateTexture("../../textures/tile_flagTile_green.png"); } else { m_iTextureID = CTextureManager::GetInstance().CreateTexture("../../textures/tile_flagTile_purple.png"); } }*/ D3DXVECTOR3* pFirstVertex = 0; LPD3DXMESH pMesh = CModelManager::GetInstance().GetModel(m_iModelID)->GetModel(); pMesh->LockVertexBuffer(0, (void**)&pFirstVertex); D3DXComputeBoundingBox(pFirstVertex, pMesh->GetNumVertices(), pMesh->GetNumBytesPerVertex(), &m_tOBB.m_vec3Min, &m_tOBB.m_vec3Max); pMesh->UnlockVertexBuffer(); CEntity::Initialise(); return (true); }
HRESULT D3DXMeshCreateDiamond( LPDIRECT3DDEVICE9 pDevice, DWORD dwFVF, DWORD dwOption, UINT uSlice , FLOAT fRadius, FLOAT fUpperConeHeight, FLOAT fLowerConeHeight, LPD3DXMESH* pRet ) { //创建上下各一棱锥的钻石型 _ASSERTE(fRadius > 0 && fUpperConeHeight >= 0 && fLowerConeHeight >= 0 && uSlice >= 3); HRESULT hr = E_FAIL; LPD3DXMESH pMesh = NULL; KG_PROCESS_ERROR(NULL != pRet); KG_PROCESS_ERROR(fRadius > 0 && fUpperConeHeight >= 0 && fLowerConeHeight >= 0 && uSlice >= 3); { UINT uNumVertices = uSlice + 2; //2是上下两个点 UINT uNumFaces = uSlice * 2; _ASSERTE(IsMeshValidToBeCreated(dwOption, uNumVertices, uNumFaces * 3)); hr = D3DXCreateMeshFVF(uNumFaces, uNumVertices, dwOption, dwFVF, pDevice, &pMesh); KG_COM_CHECK_ERROR(hr); //点的分布是先填圆周的一圈,然后填上下两个点 { D3DXMeshVertexEnumer vertexEnumer; hr = D3DXMeshCreateVertexEnumer(pMesh, vertexEnumer); KG_COM_PROCESS_ERROR(hr); _ASSERTE(vertexEnumer.IsValid() && vertexEnumer.GetVertexCount() == uNumVertices); float fAnglePerVertex = 2 * D3DX_PI /static_cast<FLOAT>(uSlice); float fAngleRotate = D3DX_PI / 4.f; //把所有顶点旋转45度,这样子好些 //注意Angle是不可能超过cos和sin的值域的,不用检查了 for (UINT i = 0; i < vertexEnumer.GetVertexCount() - 2; ++i) { FLOAT fAngle = fAnglePerVertex * i; D3DXVECTOR3 vTemp; vTemp.x = fRadius * cosf(fAngle + fAngleRotate); //单位圆锥,最后再放缩,所以这里用1 vTemp.y = 0; vTemp.z = fRadius * sinf(fAngle + fAngleRotate); vertexEnumer.SetPos(i, vTemp); } _ASSERTE(vertexEnumer.GetVertexCount() > 2); //填上上下两个点 UINT uTopPoint = vertexEnumer.GetVertexCount() - 2; vertexEnumer.SetPos(uTopPoint, D3DXVECTOR3(0, fUpperConeHeight, 0)); UINT uBottomPoint = vertexEnumer.GetVertexCount() - 1; vertexEnumer.SetPos(uBottomPoint, D3DXVECTOR3(0, -fLowerConeHeight, 0)); } { D3DXMeshIndexEnumer indexEnumer; hr = D3DXMeshCreateIndexEnumer(pMesh, indexEnumer); KG_COM_PROCESS_ERROR(hr); _ASSERTE(indexEnumer.IsValid()&& indexEnumer.GetIndexCount() == 2 * uSlice * 3); UINT uVertexCountInCircle = pMesh->GetNumVertices() - 2; { UINT uUpperFaceCount = uVertexCountInCircle; DWORD uTopPointIndex = pMesh->GetNumVertices() - 2; for (UINT uIt = 0, uIndexIndex = 0; uIt < uUpperFaceCount; ++uIt, uIndexIndex += 3) { indexEnumer.SetIndex(uIndexIndex, uIt); indexEnumer.SetIndex(uIndexIndex + 1, uTopPointIndex); indexEnumer.SetIndex(uIndexIndex + 2, (uIt + 1) % uVertexCountInCircle); } } { UINT uBottomFaceCount = uVertexCountInCircle; UINT uUpperFaceCount = uVertexCountInCircle; DWORD uBottomPointIndex = pMesh->GetNumVertices() - 1; for (UINT uIt = 0, uIndexIndex = uUpperFaceCount * 3 ; uIt < uBottomFaceCount; ++uIt, uIndexIndex += 3) { indexEnumer.SetIndex(uIndexIndex, uIt); indexEnumer.SetIndex(uIndexIndex + 1, (uIt + 1) % uVertexCountInCircle); indexEnumer.SetIndex(uIndexIndex + 2, uBottomPointIndex); } } } hr = D3DXMeshZeroMeshAttributes(pMesh); } _ASSERTE(NULL != pRet); *pRet = pMesh; return S_OK; Exit0: SAFE_RELEASE(pMesh); return E_FAIL; }
HRESULT D3DXMeshCreatePlane( LPDIRECT3DDEVICE9 pDevice, DWORD dwFVF, DWORD dwOption, UINT uXSlice, UINT uZSlice , FLOAT fXLength, FLOAT fZLength, LPD3DXMESH* pRet ) { HRESULT hr = E_FAIL; LPD3DXMESH pMesh = NULL; KG_PROCESS_ERROR(D3DFVF_XYZ & dwFVF);//不是XYZ型的Mesh无法自动处理 KG_PROCESS_ERROR(NULL != pRet); KG_PROCESS_ERROR(uXSlice < 2048 && uZSlice < 2048 && _T("不能创建太大的Plane")); { DWORD dwVertexCountInXAxis = (uXSlice + 1); DWORD dwVertexCountInZAxis = (uZSlice + 1); DWORD dwVertexCount = dwVertexCountInXAxis * dwVertexCountInZAxis; DWORD dwNumFaces = uXSlice * uZSlice; _ASSERTE(IsMeshValidToBeCreated(dwOption, dwVertexCount, dwNumFaces * 3)); hr = D3DXCreateMeshFVF(dwNumFaces, dwVertexCount, dwOption, dwFVF, pDevice, &pMesh); KG_COM_PROCESS_ERROR(hr); _ASSERTE(sizeof(BYTE) == 1); ////填点,D3DXMeshVertexEnumer生命域 { D3DXMeshVertexEnumer vertexEnumer; hr = D3DXMeshCreateVertexEnumer(pMesh, vertexEnumer); KG_COM_PROCESS_ERROR(hr); FLOAT XSliceGap = fXLength / static_cast<FLOAT>(uXSlice); FLOAT ZSliceGap = fZLength / static_cast<FLOAT>(uZSlice); _ASSERTE(vertexEnumer.GetVertexCount() == dwVertexCount); for (UINT i = 0; i < dwVertexCountInXAxis; ++i) { for (UINT j = 0; j < dwVertexCountInZAxis; ++j) { FLOAT xPos = i * XSliceGap; FLOAT zPos = i * ZSliceGap; UINT uIndex = i * dwVertexCountInXAxis + j; vertexEnumer.SetPos(uIndex, D3DXVECTOR3(xPos, 0, zPos)); } } //把坐标填上 if (D3DFVF_TEX1 & dwFVF) //这个默认就是UV两个浮点的。如果用了D3DFVF_TEXCOORDn的话,位会变 { D3DXMeshVertexTexCoordEnumer texEnumer; hr = D3DXMeshCreateVertexTexCoordEnumer(vertexEnumer, texEnumer); FLOAT xUGap = 1.f / static_cast<FLOAT>(uXSlice); FLOAT zVGap = 1.f / static_cast<FLOAT>(uZSlice); if (SUCCEEDED(hr)) { _ASSERTE(2 == texEnumer.GetTexCoordSize()); for (UINT i = 0; i < dwVertexCountInXAxis; ++i) { for (UINT j = 0; j < dwVertexCountInZAxis; ++j) { UINT uIndex = i * dwVertexCountInXAxis + j; texEnumer.GetTexCoord2(uIndex) = D3DXVECTOR2(xUGap * i, zVGap * j); } } } } }////填点,D3DXMeshVertexEnumer生命域 //填Index { D3DXMeshIndexEnumer indexEnumer; hr = D3DXMeshCreateIndexEnumer(pMesh, indexEnumer); KG_COM_PROCESS_ERROR(hr); if (! indexEnumer.Is32Bit()) { KG_PROCESS_ERROR((pMesh->GetNumVertices() < SHRT_MAX) && _T("顶点数超过IndexBuffer的最大数")); } for (UINT i = 0; i < uXSlice; ++i) { for (UINT j = 0; j < uZSlice; ++j) { DWORD uLowerLeftVertexIndex = i * (uXSlice + 1) + j; DWORD uLowerRightVertexIndex = uLowerLeftVertexIndex + 1; DWORD uUpperLeftVertexIndex = uLowerLeftVertexIndex + (uXSlice + 1); DWORD uUpperRightVertexIndex = uUpperLeftVertexIndex + 1; UINT uRegionIndexBegin = (i * uXSlice + j) * 6; indexEnumer.SetIndex(uRegionIndexBegin, uLowerLeftVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 1, uUpperLeftVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 2, uLowerRightVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 3, uLowerLeftVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 4, uUpperLeftVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 5, uUpperRightVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 6, uLowerRightVertexIndex); } } } //填Attribute hr = D3DXMeshZeroMeshAttributes(pMesh); _ASSERTE(NULL != pRet); *pRet = pMesh; return S_OK; } Exit0: SAFE_RELEASE(pMesh); return NULL; return E_FAIL; }
void ObjParser::Load(LPCSTR Filename, LPDIRECT3DDEVICE9 pDevice) { FILE* fileHandle = fopen(Filename, "r+"); if( fileHandle == NULL ) return; char line[256]; D3DXVECTOR3 vec; while( !feof(fileHandle) )//Foreach Line { fgets(line, 256, fileHandle); #pragma region Line Read switch(line[0]) { case 'm': { LPCSTR name = new CHAR[256]; sscanf_s(line, "mtllib %s", name, 255); ParseMaterial(name); } break; case 'v'://Vertex Item { switch(line[1]) { case ' '://Vertex { sscanf_s(line, "v %f %f %f", &vec.x, &vec.y, &vec.z ); Vertexs.push_back(vec); mVertexsHT.push_back(NULL);//expand HashTable } break; case 't'://Texture Coordinates { D3DXVECTOR3 tex; sscanf_s(line, "vt %f %f %f", &vec.x, &vec.y, &vec.z); Textures.push_back(vec); } break; case 'n'://Normal { D3DXVECTOR3 nor; sscanf_s(line, "vn %f %f %f", &vec.x, &vec.y, &vec.z ); Normals.push_back(vec); } break; default:// Not supposed to happen assert( false ); } } break; case 'f'://Face Item { DWORD quadP[4];//Position Index quad DWORD quadT[4];//Texture Index quad DWORD quadN[4];//Normal Index quad memset(quadP, -1, sizeof(DWORD)*4); memset(quadT, -1, sizeof(DWORD)*4); memset(quadN, -1, sizeof(DWORD)*4); int size = strlen(line); int barCount = std::count(line, line+size, '/'); int readed = 0; //By default .obj file puts faces with CW winding switch( barCount ) { case 0:// tri/quad pos { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d %d %d %d", &quadP[3], &quadP[2], &quadP[1], &quadP[0] ); else readed = sscanf_s(line, "f %d %d %d %d", &quadP[0], &quadP[1], &quadP[2], &quadP[3] ); assert( readed == 3 || readed == 4 ); } break; case 3:// tri pos/tex { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d %d/%d %d/%d", &quadP[2], &quadT[2], &quadP[1], &quadT[1], &quadP[0], &quadT[0] ); else readed = sscanf_s(line, "f %d/%d %d/%d %d/%d", &quadP[0], quadT[0], &quadP[1], quadT[1], &quadP[2], quadT[2] ); assert( readed == 6 ); readed /= 2; } break; case 4:// quad pos/tex { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d %d/%d %d/%d %d/%d", &quadP[3], &quadT[3], &quadP[2], &quadT[2], &quadP[1], &quadT[1], &quadP[0], &quadT[0] ); else readed = sscanf_s(line, "f %d/%d %d/%d %d/%d %d/%d", &quadP[0], &quadT[0], &quadP[1], &quadT[1], &quadP[2], &quadT[2], &quadP[3], &quadT[3] ); assert( readed == 8 ); readed /= 2; } break; case 6:// tri pos/tex/nor { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[2], &quadT[2], &quadN[2], &quadP[1], &quadT[1], &quadN[1], &quadP[0], &quadT[0], &quadN[0] ); else readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[0], &quadT[0], &quadN[0], &quadP[1], &quadT[1], &quadN[1], &quadP[2], &quadT[2], &quadN[2] ); assert( readed == 9 ); readed /= 3; } break; case 8:// quad pos/tex/nor { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[3], &quadT[3], &quadN[3], &quadP[2], &quadT[2], &quadN[2], &quadP[1], &quadT[1], &quadN[1], &quadP[0], &quadT[0], &quadN[0] ); else readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[0], &quadT[0], &quadN[0], &quadP[1], &quadT[1], &quadN[1], &quadP[2], &quadT[2], &quadN[2], &quadP[3], &quadT[3], &quadN[3] ); assert( readed == 12 ); readed /= 3; } break; default:// Not supposed to happen assert( false ); } //The indexs are in 1 Base, we transform to 0 Base for( int i=0; i < 4 ; ++i ) { quadP[i]--; quadT[i]--; quadN[i]--; } for(int j=0; j < 3 ; ++j) { VertexTextureNormal NewVertex; NewVertex.SetPosition( Vertexs[quadP[j]] ); if( quadT[j] != (DWORD(-1)-1) ) NewVertex.SetTexture ( Textures[quadT[j]].x, Textures[quadT[j]].y ); if( quadN[j] != (DWORD(-1)-1) ) NewVertex.SetNormal ( Normals[quadN[j]] ); DWORD index = AddVertex(quadP[j], NewVertex); mIndexs.push_back(index); } if( readed == 4 )// quad readed { quadP[1] = quadP[2]; quadT[1] = quadT[2]; quadN[1] = quadN[2]; quadP[2] = quadP[3]; quadT[2] = quadT[3]; quadN[1] = quadN[2]; for(int j=0; j < 3 ; ++j) { VertexTextureNormal NewVertex; NewVertex.SetPosition( Vertexs[quadP[j]] ); if( quadT[j] != (DWORD(-1)-1) ) NewVertex.SetTexture ( Textures[quadT[j]].x, Textures[quadT[j]].y ); if( quadN[j] != (DWORD(-1)-1) ) NewVertex.SetNormal ( Normals[quadN[j]] ); DWORD index = AddVertex(quadP[j], NewVertex); mIndexs.push_back(index); } } } break; } #pragma endregion } fclose(fileHandle); DWORD FVF = NULL; D3DVERTEXELEMENT9* pMeshVDeclaration = NULL; int code = 0; IdentifieLoadedFormat(FVF, pMeshVDeclaration, code); if( code == 0 ) return; //Setup Mesh with VertexDeclaration corresponding to the loaded data LPD3DXMESH pMesh = NULL; HRESULT hr = NULL; int FacesCount = mIndexs.size()/3; switch( m_VertexMetaFormat ) { case VertexMetaFormat::VertexDeclaration: { if( FacesCount > 65535 )// if huge mesh, 32 bits face index hr = D3DXCreateMesh(FacesCount, mVertexs.size(), D3DXMESH_32BIT | D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , pMeshVDeclaration, pDevice, &pMesh); else hr = D3DXCreateMesh(FacesCount, mVertexs.size(), D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , pMeshVDeclaration, pDevice, &pMesh); } break; case VertexMetaFormat::FVF: { if( FacesCount > 65535 )// if huge mesh, 32 bits face index hr = D3DXCreateMeshFVF(FacesCount, Vertexs.size(), D3DXMESH_32BIT | D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , FVF, pDevice, &pMesh); else hr = D3DXCreateMeshFVF(FacesCount, Vertexs.size(), D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , FVF, pDevice, &pMesh); } break; default: assert( false ); } assert( !FAILED(hr) ); //Puts vertex data inside loadedData in the smallest format needed //(not nesesarily VertexTextureNormal) void* loadedData = NULL; void* loadedIndex = NULL; size_t size = 0; //Pass to our vertex format PutLoadedDataInVertexDeclarationFormat(loadedData,loadedIndex,size,code, FacesCount); //Free Auxiliary Arrays Vertexs.clear(); Textures.clear(); Normals.clear(); mVertexsHT.clear(); void* data = NULL; //Loads the Vertex Buffer if( FAILED(pMesh->LockVertexBuffer(NULL, &data)) ) return; memcpy(data, loadedData, size*mVertexs.size()); pMesh->UnlockVertexBuffer(); //Loads the Index Buffer if( FAILED(pMesh->LockIndexBuffer(NULL, &data)) ) return; if( FacesCount > 65535 ) memcpy(data, loadedIndex, sizeof(DWORD)*mIndexs.size()); else memcpy(data, loadedIndex, sizeof(WORD)*mIndexs.size()); pMesh->UnlockIndexBuffer(); //Free main Arrays mVertexs.clear(); mIndexs.clear(); //Mesh data ready m_RootMeshContainer = new D3DXMESHCONTAINER; m_RootMeshContainer->MeshData.pMesh = pMesh; return; }
// 3D 물체등을 그린다. void RenderScene() { // 뷰행렬 초기화. D3DXMATRIXA16 matView; // D3DXVECTOR3 vEyePt(0.0f, 0.0f, -200.0f); D3DXVECTOR3 vEyePt(gWorldCameraPosition.x, gWorldCameraPosition.y, gWorldCameraPosition.z); D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f); D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec); // 투영행렬 초기화. D3DXMATRIXA16 matProjection; D3DXMatrixPerspectiveFovLH(&matProjection, FOV, ASPECT_RATIO, NEAR_PLANE, FAR_PLANE); // 회전. gRotationY += ((0.4f * PI) / 180.0f); if (gRotationY > 2 * PI) gRotationY -= 2 * PI; // 월드행렬 초기화. D3DXMATRIXA16 matWorld; // D3DXMatrixIdentity(&matWorld); D3DXMatrixRotationY(&matWorld, gRotationY); // 월드_뷰_투영행렬 D3DXMATRIXA16 matWorldView; D3DXMATRIXA16 matWorldViewProjection; D3DXMatrixMultiply(&matWorldView, &matWorld, &matView); D3DXMatrixMultiply(&matWorldViewProjection, &matWorldView, &matProjection); // 쉐이더에 전달. gpNormalMappingShader->SetMatrix("gWorldMatrix", &matWorld); gpNormalMappingShader->SetMatrix("gWorldViewProjectionMatrix", &matWorldViewProjection); gpNormalMappingShader->SetVector("gWorldLightPosition", &gWorldLightPosition); gpNormalMappingShader->SetVector("gWorldCameraPosition", &gWorldCameraPosition); gpNormalMappingShader->SetVector("gLightColor", &gLightColor); gpNormalMappingShader->SetTexture("DiffuseMap_Tex", gpStoneDM); gpNormalMappingShader->SetTexture("SpecularMap_Tex", gpStoneSM); gpNormalMappingShader->SetTexture("NormalMap_Tex", gpStoneNM); // 쉐이더 적용. UINT numPasses = 0; gpNormalMappingShader->Begin(&numPasses, NULL); for (UINT i = 0; i < numPasses; ++i) { gpNormalMappingShader->BeginPass(i); gpSphere->DrawSubset(0); gpNormalMappingShader->EndPass(); } gpNormalMappingShader->End(); }
void Direct3DRender(HWND hwnd) { RECT formatRect; GetClientRect(hwnd, &formatRect); gPD3DDevice->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0, 30), 1.0f, 0.0f); gPD3DDevice->BeginScene(); MatrixSet(); WCHAR str[50]; int strCount = swprintf_s(str, _T("Mat, Mesh & Light!")); gPFont->DrawTextW(nullptr, str, strCount, &formatRect, DT_TOP| DT_RIGHT, D3DCOLOR_XRGB(25, 134, 111)); D3DXMATRIX Ry; D3DXMatrixRotationY(&Ry, timeGetTime() / 1000.0f); D3DXMATRIX teaPotWorldTrans; D3DXMatrixTranslation(&teaPotWorldTrans, 2.5f, 2.5f, 2.5f); D3DXMATRIX Sa; D3DXMatrixScaling(&Sa, 2.0f, 2.0f, 2.0f); teaPotWorldTrans = teaPotWorldTrans * Ry * Sa; gPD3DDevice->SetTransform(D3DTS_WORLD, &teaPotWorldTrans); D3DMATERIAL9 material; ZeroMemory(&material, sizeof(material)); material.Ambient = D3DXCOLOR(0.5f, 0.5f, 0.7f, 1.0f); material.Diffuse = D3DXCOLOR(0.4f, 0.6f, 0.6f, 1.0f); material.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 0.3f); material.Emissive = D3DXCOLOR(0.3f, 0.0f, 0.1f, 1.0f); gPD3DDevice->SetMaterial(&material); gPTeapot->DrawSubset(0); D3DXMATRIX boxWorldTrans; D3DXMatrixTranslation(&boxWorldTrans, -5.0f, 5.0f, 5.0f); boxWorldTrans *= Ry; gPD3DDevice->SetTransform(D3DTS_WORLD, &boxWorldTrans); ZeroMemory(&material, sizeof(material)); material.Ambient = D3DXCOLOR(0.3f, 0.1f, 0.5f, 1.0f); material.Diffuse = D3DXCOLOR(0.4f, 0.6f, 0.6f, 1.0f); material.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1.3f); material.Emissive = D3DXCOLOR(0.3f, 0.0f, 0.1f, 1.0f); gPD3DDevice->SetMaterial(&material); gPBox->DrawSubset(0); D3DXMATRIX torusWorldTrans; D3DXMatrixTranslation(&torusWorldTrans, 5.0f, -5.0f, 5.0f); torusWorldTrans *= Ry; gPD3DDevice->SetTransform(D3DTS_WORLD, &torusWorldTrans); ZeroMemory(&material, sizeof(material)); material.Ambient = D3DXCOLOR(0.5f, 0.2f, 0.3f, 1.0f); material.Diffuse = D3DXCOLOR(0.6f, 0.2f, 0.4f, 1.0f); material.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 0.3f); material.Emissive = D3DXCOLOR(0.3f, 0.0f, 0.1f, 1.0f); gPD3DDevice->SetMaterial(&material); gPTorus->DrawSubset(0); D3DXMATRIX sphereWorldTrans; D3DXMatrixTranslation(&sphereWorldTrans, -5.0f, -5.0f, 5.0f); sphereWorldTrans *= Ry; gPD3DDevice->SetTransform(D3DTS_WORLD, &sphereWorldTrans); ZeroMemory(&material, sizeof(material)); material.Ambient = D3DXCOLOR(0.9f, 0.1f, 0.9f, 1.0f); material.Diffuse = D3DXCOLOR(0.3f, 0.6f, 0.8f, 1.0f); material.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 0.3f); material.Emissive = D3DXCOLOR(0.9f, 0.4f, 0.7f, 1.0f); gPD3DDevice->SetMaterial(&material); gPSphere->DrawSubset(0); LightSet(gPD3DDevice, 1); gPD3DDevice->EndScene(); gPD3DDevice->Present(nullptr, nullptr, nullptr, nullptr); }
HRESULT EVERYMODULE::DrawMesh(LPD3DXMESH newmesh, UINT EPointSize) { if(!Mesh) return E_FAIL; HRESULT att=S_OK; LPDIRECT3DVERTEXBUFFER9 vertexbuffer; LPDIRECT3DINDEXBUFFER9 indexbuffer; if(newmesh==NULL) { if(CreateAttrib==1) { Mesh->GetVertexBuffer(&vertexbuffer); d3ddevice->SetStreamSource(0, vertexbuffer, 0, EachPointSize); if(VertexShader && Declaration) { d3ddevice->SetVertexDeclaration(Declaration); d3ddevice->SetVertexShader(VertexShader); } else { // d3ddevice->SetVertexDeclaration(NULL); d3ddevice->SetVertexShader(NULL); d3ddevice->SetFVF(m_FVF); } d3ddevice->SetMaterial(&Material); d3ddevice->BeginScene(); if(FAILED(d3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, VertexNum-2))) att=E_FAIL; d3ddevice->EndScene(); } else if(CreateAttrib==2) { Mesh->GetVertexBuffer(&vertexbuffer); Mesh->GetIndexBuffer(&indexbuffer); d3ddevice->SetStreamSource(0, vertexbuffer, 0, EachPointSize); d3ddevice->SetIndices(indexbuffer); if(VertexShader && Declaration) { d3ddevice->SetVertexDeclaration(Declaration); d3ddevice->SetVertexShader(VertexShader); } else { // d3ddevice->SetVertexDeclaration(NULL); d3ddevice->SetVertexShader(NULL); d3ddevice->SetFVF(m_FVF); } d3ddevice->SetMaterial(&Material); d3ddevice->BeginScene(); if(FAILED(d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, VertexNum, 0, IndexVertexNum/3))) att=E_FAIL; d3ddevice->EndScene(); } } else { if(CreateAttrib==1) { newmesh->GetVertexBuffer(&vertexbuffer); d3ddevice->SetStreamSource(0, vertexbuffer, 0, EPointSize); if(VertexShader && Declaration) { d3ddevice->SetVertexDeclaration(Declaration); d3ddevice->SetVertexShader(VertexShader); } else { // d3ddevice->SetVertexDeclaration(NULL); d3ddevice->SetVertexShader(NULL); d3ddevice->SetFVF(m_FVF); } d3ddevice->SetMaterial(&Material); d3ddevice->BeginScene(); if(FAILED(d3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, VertexNum-2))) att=E_FAIL; d3ddevice->EndScene(); } else if(CreateAttrib==2) { newmesh->GetVertexBuffer(&vertexbuffer); newmesh->GetIndexBuffer(&indexbuffer); d3ddevice->SetStreamSource(0, vertexbuffer, 0, EPointSize); d3ddevice->SetIndices(indexbuffer); if(VertexShader && Declaration) { d3ddevice->SetVertexDeclaration(Declaration); d3ddevice->SetVertexShader(VertexShader); } else { // d3ddevice->SetVertexDeclaration(NULL); d3ddevice->SetVertexShader(NULL); d3ddevice->SetFVF(m_FVF); } d3ddevice->SetMaterial(&Material); d3ddevice->BeginScene(); if(FAILED(d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, VertexNum, 0, IndexVertexNum/3))) att=E_FAIL; d3ddevice->EndScene(); } } return att; }
void CALLBACK RenderFunc(void) { /** * Set camera * */ D3DMATRIX* pMatView = nullptr; GD::CMatrix44<float> viewMat(gEnv.m_pCamera->GetViewMatrixDX()); pMatView = (D3DMATRIX*)(&viewMat); gEnv.m_pDXDevice->GetD3DDevice()->SetTransform(D3DTS_VIEW, pMatView); //应用取景变换矩阵 D3DMATRIX* pProjMatrix; pProjMatrix = (D3DMATRIX*)(&gEnv.m_pCamera->GetProjMatrix().GetFliped()); gEnv.m_pDXDevice->GetD3DDevice()->SetTransform(D3DTS_PROJECTION, pProjMatrix); //设置投影变换矩阵 D3DVIEWPORT9* pViewPort; pViewPort = (D3DVIEWPORT9*)(&gEnv.m_pCamera->GetViewPort()); gEnv.m_pDXDevice->GetD3DDevice()->SetViewport(pViewPort); //视口的设置 WCHAR TempName[60] = L"当前显卡型号:"; //定义一个临时字符串,且方便了把"当前显卡型号:"字符串引入我们的目的字符串中 WCHAR adapterName[30]{0}; D3DADAPTER_IDENTIFIER9 Adapter; //定义一个D3DADAPTER_IDENTIFIER9结构体,用于存储显卡信息 LPDIRECT3D9 pD3D = NULL; //Direct3D接口对象的创建 if (NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION))) //初始化Direct3D接口对象,并进行DirectX版本协商 { return; } pD3D->GetAdapterIdentifier(0, 0, &Adapter);//调用GetAdapterIdentifier,获取显卡信息 int len = ::MultiByteToWideChar(CP_ACP, 0, Adapter.Description, -1, NULL, 0);//显卡名称现在已经在Adapter.Description中了,但是其为char类型,我们要将其转为wchar_t类型 ::MultiByteToWideChar(CP_ACP, 0, Adapter.Description, -1, adapterName, len);//这步操作完成后,g_strAdapterName中就为当前我们的显卡类型名的wchar_t型字符串了 wcscat_s(TempName, adapterName);//把当前我们的显卡名加到“当前显卡型号:”字符串后面,结果存在TempName中 pD3D->Release(); gPFont->DrawText(nullptr, TempName, -1, nullptr, DT_TOP | DT_LEFT, D3DCOLOR_XRGB(124, 24, 222)); D3DXMATRIX W; D3DXMatrixIdentity(&W); gEnv.m_pDXDevice->GetD3DDevice()->SetTransform(D3DTS_WORLD, &W); gEnv.m_pDXDevice->GetD3DDevice()->SetFVF(Vertex::FVF); gEnv.m_pDXDevice->GetD3DDevice()->SetStreamSource(0, gPVertexBuffer, 0, sizeof(Vertex)); /** * Draw floor * */ gEnv.m_pDXDevice->GetD3DDevice()->SetMaterial(&gFloorMtrl); gEnv.m_pDXDevice->GetD3DDevice()->SetTexture(0, gPFloorTex); gEnv.m_pDXDevice->GetD3DDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); /** * Draw wall * */ gEnv.m_pDXDevice->GetD3DDevice()->SetMaterial(&gWallMtrl); gEnv.m_pDXDevice->GetD3DDevice()->SetTexture(0, gPWallTex); gEnv.m_pDXDevice->GetD3DDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, 6, 4); /** * Draw mirror * */ gEnv.m_pDXDevice->GetD3DDevice()->SetMaterial(&gMirrorMtrl); gEnv.m_pDXDevice->GetD3DDevice()->SetTexture(0, gPMirrorTex); gEnv.m_pDXDevice->GetD3DDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, 18, 2); // Set teapot position static D3DXMATRIX T; static float x = 0.0f; static float y = 3.0f; static float z = -7.5f; const float delta = 0.01f; // increase/decrease alpha via keyboard input if (gEnv.m_pKeyBoard->IsKeyDown(DIK_UPARROW)) { y += delta; } if (gEnv.m_pKeyBoard->IsKeyDown(DIK_DOWNARROW)) { y -= delta; } if (gEnv.m_pKeyBoard->IsKeyDown(DIK_LEFTARROW)) { x += delta; } if (gEnv.m_pKeyBoard->IsKeyDown(DIK_RIGHTARROW)) { x -= delta; } //Draw teapot D3DXMatrixTranslation(&T, x, y, z); gEnv.m_pDXDevice->GetD3DDevice()->SetTransform(D3DTS_WORLD, &T); gEnv.m_pDXDevice->GetD3DDevice()->SetMaterial(&gTeapotMtrl); gEnv.m_pDXDevice->GetD3DDevice()->SetTexture(0, 0); gPTeapot->DrawSubset(0); /** * Enable stencil, disable write to z-buffer and back-buffer * */ //Enable stencil, so that the mirror fragment which passed z-test's stencil are set to 0x01 gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_STENCILENABLE, true); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_STENCILREF, 0x01); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); //Disable write to z-buffer, use blend to disable write to color-buffer gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_ZWRITEENABLE, false); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, true); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); //Finished setting, draw mirror to stencil-buffer; gEnv.m_pDXDevice->GetD3DDevice()->SetStreamSource(0, gPVertexBuffer, 0, sizeof(Vertex)); gEnv.m_pDXDevice->GetD3DDevice()->SetFVF(Vertex::FVF); gEnv.m_pDXDevice->GetD3DDevice()->SetMaterial(&gMirrorMtrl); gEnv.m_pDXDevice->GetD3DDevice()->SetTexture(0, gPMirrorTex); D3DXMATRIX I; D3DXMatrixIdentity(&I); gEnv.m_pDXDevice->GetD3DDevice()->SetTransform(D3DTS_WORLD, &I); gEnv.m_pDXDevice->GetD3DDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, 18, 2); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_ZWRITEENABLE, true); /** * Then we need to use the modified stencil, disable z-test(why not disable z-test), and use blend to draw mirrored teapot * */ gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); gEnv.m_pDXDevice->GetD3DDevice()->Clear(0, 0, D3DCLEAR_ZBUFFER, 0, 1.0f, 0); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO); D3DXMATRIX R; D3DXPLANE plane(0.0f, 0.0f, 1.0f, 0.0f); D3DXMatrixReflect(&R, &plane); T = T*R; gEnv.m_pDXDevice->GetD3DDevice()->SetTransform(D3DTS_WORLD, &T); gEnv.m_pDXDevice->GetD3DDevice()->SetMaterial(&gTeapotMtrl); gEnv.m_pDXDevice->GetD3DDevice()->SetTexture(0, 0); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); gPTeapot->DrawSubset(0); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, false); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_STENCILENABLE, false); gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); }
void CALLBACK RenderFunc(void) { /** * Set camera * */ D3DMATRIX* pMatView = nullptr; GD::CMatrix44<float> viewMat(gEnv.m_pCamera->GetViewMatrixDX()); pMatView = (D3DMATRIX*)(&viewMat); gEnv.m_pDXDevice->GetD3DDevice()->SetTransform(D3DTS_VIEW, pMatView); //应用取景变换矩阵 D3DMATRIX* pProjMatrix; pProjMatrix = (D3DMATRIX*)(&gEnv.m_pCamera->GetProjMatrix().GetFliped()); gEnv.m_pDXDevice->GetD3DDevice()->SetTransform(D3DTS_PROJECTION, pProjMatrix); //设置投影变换矩阵 D3DVIEWPORT9* pViewPort; pViewPort = (D3DVIEWPORT9*)(&gEnv.m_pCamera->GetViewPort()); gEnv.m_pDXDevice->GetD3DDevice()->SetViewport(pViewPort); //视口的设置 WCHAR TempName[60] = L"当前显卡型号:"; //定义一个临时字符串,且方便了把"当前显卡型号:"字符串引入我们的目的字符串中 WCHAR adapterName[30]{0}; D3DADAPTER_IDENTIFIER9 Adapter; //定义一个D3DADAPTER_IDENTIFIER9结构体,用于存储显卡信息 LPDIRECT3D9 pD3D = NULL; //Direct3D接口对象的创建 if (NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION))) //初始化Direct3D接口对象,并进行DirectX版本协商 { return; } pD3D->GetAdapterIdentifier(0, 0, &Adapter);//调用GetAdapterIdentifier,获取显卡信息 int len = ::MultiByteToWideChar(CP_ACP, 0, Adapter.Description, -1, NULL, 0);//显卡名称现在已经在Adapter.Description中了,但是其为char类型,我们要将其转为wchar_t类型 ::MultiByteToWideChar(CP_ACP, 0, Adapter.Description, -1, adapterName, len);//这步操作完成后,g_strAdapterName中就为当前我们的显卡类型名的wchar_t型字符串了 wcscat_s(TempName, adapterName);//把当前我们的显卡名加到“当前显卡型号:”字符串后面,结果存在TempName中 pD3D->Release(); gPFont->DrawText(nullptr, TempName, -1, nullptr, DT_TOP | DT_LEFT, D3DCOLOR_XRGB(124, 24, 222)); // Set teapot position static D3DXMATRIX T; static float x = 0.0f; static float y = 3.0f; static float z = -7.5f; const float delta = 0.01f; // increase/decrease alpha via keyboard input if (gEnv.m_pKeyBoard->IsKeyDown(DIK_UPARROW)) { y += delta; } if (gEnv.m_pKeyBoard->IsKeyDown(DIK_DOWNARROW)) { y -= delta; } if (gEnv.m_pKeyBoard->IsKeyDown(DIK_LEFTARROW)) { x += delta; } if (gEnv.m_pKeyBoard->IsKeyDown(DIK_RIGHTARROW)) { x -= delta; } //Draw teapot D3DXMatrixTranslation(&T, x, y, z); gEnv.m_pDXDevice->GetD3DDevice()->SetTransform(D3DTS_WORLD, &T); gEnv.m_pDXDevice->GetD3DDevice()->SetMaterial(&gTeapotMtrl); gEnv.m_pDXDevice->GetD3DDevice()->SetTexture(0, 0); gPTeapot->DrawSubset(0); D3DXMatrixIdentity(&T); gEnv.m_pDXDevice->GetD3DDevice()->SetTransform(D3DTS_WORLD, &T); for (int i = 0; i < gAirplaneMtrl.size(); i++) { gEnv.m_pDXDevice->GetD3DDevice()->SetMaterial(&gAirplaneMtrl[i]); gEnv.m_pDXDevice->GetD3DDevice()->SetTexture(0, gPAirplaneTex[i]); gPAirplane->DrawSubset(i); } /** * Change numFaces by pressing key Q E; * */ int numFaces = gPPAirplane->GetNumFaces(); if (gEnv.m_pKeyBoard->IsKeyDown(DIK_Q)) { gPPAirplane->SetNumFaces(numFaces + 1); //Need to add more than one face to invert an edge collapse transformation if (gPPAirplane->GetNumFaces() == numFaces) { gPPAirplane->SetNumFaces(numFaces + 2); } } if (gEnv.m_pKeyBoard->IsKeyDown(DIK_E)) { gPPAirplane->SetNumFaces(numFaces - 1); //Need to add more than one face to invert an edge collapse transformation if (gPPAirplane->GetNumFaces() == numFaces) { gPPAirplane->SetNumFaces(numFaces - 2); } } /** * Use key R to change fill mode: * When pressed, will change between WIREFRAME/SOLID. * */ static bool bFillMode = true; if (bFillMode == true) { if (gEnv.m_pKeyBoard->IsKeyDown(DIK_R)) { bFillMode = false; gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); } else { gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); } } else { if (gEnv.m_pKeyBoard->IsKeyDown(DIK_R)) { bFillMode = true; gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); } else { gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); } } D3DXMatrixTranslation(&T, x, y, z); gEnv.m_pDXDevice->GetD3DDevice()->SetTransform(D3DTS_WORLD, &T); for (int i = 0; i < gAirplaneMtrl.size(); i++) { gEnv.m_pDXDevice->GetD3DDevice()->SetMaterial(&gAirplaneMtrl[i]); gEnv.m_pDXDevice->GetD3DDevice()->SetTexture(0, gPAirplaneTex[i]); gPPAirplane->DrawSubset(i); } gEnv.m_pDXDevice->GetD3DDevice()->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); }
//------------------------------------------------------------------------------------------------ // Name: CreateTerrainMesh // Desc: //------------------------------------------------------------------------------------------------ bool CreateTerrainMesh(LPDIRECT3DDEVICE9 d3dDevice, LPD3DXMESH* terrainMesh) { // Calculate the number of faces and vertices required const unsigned int faces = (TMS_COUNT + 3) * 2; const unsigned int vertices = (TMS_COUNT + 3) * 4; // The internal terrain mesh LPD3DXMESH internalTerrainMesh; // Create the mesh HRESULT hr = D3DXCreateMeshFVF(faces, vertices, D3DXMESH_MANAGED, D3DFVF_GEOMETRYVERTEX, d3dDevice, &internalTerrainMesh); if (APP_ERROR(FAILED(hr))("Unable to create the terrain mesh")) return false; // Lock the mesh buffers GeometryVertex* lockedVertices = 0; WORD* lockedIndices = 0; DWORD* lockedAttributes = 0; if (APP_ERROR(FAILED(internalTerrainMesh->LockAttributeBuffer(0, &lockedAttributes)) || FAILED(internalTerrainMesh->LockVertexBuffer(0, (VOID**)&lockedVertices)) || FAILED(internalTerrainMesh->LockIndexBuffer(0, (VOID**)&lockedIndices)))("Unable to lock terrain mesh")) { // Deallocate the mesh SAFE_RELEASE(internalTerrainMesh); // Exit the method return false; } // Vertices that will be rotated 4x about Y at // 90-degree intervals to produce the wall mesh GeometryVertex wallSide[] = { { -0.5f, 0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -0.5f, 0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { -0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { -0.5f, -1.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }, }; // The flat square with unit size GeometryVertex flat[] = { { -0.5f, 0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { +0.5f, 0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { -0.5f, 0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { +0.5f, 0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }, }; // Geometry template for the high-corner meshes, // with the high corner in the north-west GeometryVertex highCorner[] = { { -0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { +0.5f, 0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { -0.5f, 0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { +0.5f, 0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }, }; // Geometry template for the low-corner meshes, // with the low corner in the north-west GeometryVertex lowCorner[] = { { -0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { +0.5f, 0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { -0.5f, 0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { +0.5f, 0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }, }; // Geometry template for the high-side meshes, // with the high side to the north GeometryVertex highSide[] = { { -0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { +0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { -0.5f, 0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { +0.5f, 0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }, }; // Geometry template for the low-corner meshes, // with the low corner in the north-west GeometryVertex raisedLowCorner[] = { { -0.5f, 0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { +0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { -0.5f, +1.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { +0.5f, +1.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }, }; // Geometry template for the low-side meshes, // with the low side to the north GeometryVertex lowSide[] = { { -0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { +0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { -0.5f, 0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { +0.5f, 0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }, }; // The subset that is currently being written unsigned int currentSubset = TMS_WALL_SIDES; // Copy the wall first--it does not have any texture rotations lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 0.0f * D3DX_PI / 2.0f); lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 1.0f * D3DX_PI / 2.0f); lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 2.0f * D3DX_PI / 2.0f); lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 3.0f * D3DX_PI / 2.0f); // Copy four sets of squares lockedIndices = PrintSquareIndices(lockedIndices, 0, 4); lockedAttributes = PrintAttributes(lockedAttributes, currentSubset, 4); // Move to the next subset currentSubset++; // Write the flat mesh first, since it only has texture rotations for (unsigned int textureDirection = 0; textureDirection < 4; ++textureDirection, ++currentSubset) { SetTerrainTexcoords(flat, textureDirection); lockedVertices = CopyYRotatedGeometry(lockedVertices, flat, 4, 0.0f); lockedIndices = PrintSquareIndices(lockedIndices, 4 + currentSubset - 1, 1); lockedAttributes = PrintAttributes(lockedAttributes, currentSubset, 1); } // Repeat for all combinations of texture direction and rotation for the remaining types for (int type = 0; type < 5; ++type) { GeometryVertex* sourceGeometry; switch(type) { case 0: sourceGeometry = highCorner; break; case 1: sourceGeometry = lowCorner; break; case 2: sourceGeometry = highSide; break; case 3: sourceGeometry = raisedLowCorner; break; case 4: sourceGeometry = lowSide; break; } // Repeat for all rotations for (int rotation = 0; rotation < 4; ++rotation) { // Calculate the rotation angle float rotationAngle = D3DX_PI / 2.0f * rotation; // Repeat for all texture directions for (unsigned int textureDirection = 0; textureDirection < 4; ++textureDirection, ++currentSubset) { // Reverse the rotation of the texture by the rotation of the element so that we get // consistent texture directions (i.e. north is texture-up on all tiles) SetTerrainTexcoords(sourceGeometry, (textureDirection - rotation + 4) % 4); lockedVertices = CopyYRotatedGeometry(lockedVertices, sourceGeometry, 4, rotationAngle); lockedIndices = PrintSquareIndices(lockedIndices, 4 + currentSubset - 1, 1); lockedAttributes = PrintAttributes(lockedAttributes, currentSubset, 1); } } } // Unlock the buffers internalTerrainMesh->UnlockVertexBuffer(); internalTerrainMesh->UnlockIndexBuffer(); internalTerrainMesh->UnlockAttributeBuffer(); // Normalize //CONFIRM(SUCCEEDED(D3DXComputeNormals(internalTerrainMesh, NULL))); // Assign the output mesh *terrainMesh = internalTerrainMesh; // Success return true; }
int main(int argc, char *argv[]) { int ret = 0; try { // initialize directx IDirect3D9 *d3d = Direct3DCreate9(D3D_SDK_VERSION); if (!d3d) throw std::string("This application requires DirectX 9"); // create a window HWND hwnd = CreateWindowEx(0, "static", "GNU Rocket Example", WS_POPUP | WS_VISIBLE, 0, 0, width, height, 0, 0, GetModuleHandle(0), 0); // create the device IDirect3DDevice9 *device = NULL; static D3DPRESENT_PARAMETERS present_parameters = {width, height, D3DFMT_X8R8G8B8, 3, D3DMULTISAMPLE_NONE, 0, D3DSWAPEFFECT_DISCARD, 0, WINDOWED, 1, D3DFMT_D24S8, 0, WINDOWED ? 0 : D3DPRESENT_RATE_DEFAULT, 0 }; if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) throw std::string("Failed to create device"); // init BASS int soundDevice = 1; if (!BASS_Init(soundDevice, 44100, 0, hwnd, 0)) throw std::string("Failed to init bass"); // load tune HSTREAM stream = BASS_StreamCreateFile(false, "tune.ogg", 0, 0, BASS_MP3_SETPOS | (!soundDevice ? BASS_STREAM_DECODE : 0)); if (!stream) throw std::string("Failed to open tune"); // let's just assume 150 BPM (this holds true for the included tune) float bpm = 150.0f; // setup timer and construct sync-device BassTimer timer(stream, bpm, 8); std::auto_ptr<sync::Device> syncDevice = std::auto_ptr<sync::Device>( sync::createDevice("sync", timer)); if (!syncDevice.get()) throw std::string("Failed to connect to host?"); // get tracks sync::Track &clearRTrack = syncDevice->getTrack("clear.r"); sync::Track &clearGTrack = syncDevice->getTrack("clear.g"); sync::Track &clearBTrack = syncDevice->getTrack("clear.b"); sync::Track &camRotTrack = syncDevice->getTrack("cam.rot"); sync::Track &camDistTrack = syncDevice->getTrack("cam.dist"); LPD3DXMESH cubeMesh = NULL; if (FAILED(D3DXCreateBox(device, 1.0f, 1.0f, 1.0f, &cubeMesh, NULL))) return -1; // let's roll! BASS_Start(); timer.play(); bool done = false; while (!done) { float row = float(timer.getRow()); if (!syncDevice->update(row)) done = true; // setup clear color D3DXCOLOR clearColor(clearRTrack.getValue(row), clearGTrack.getValue(row), clearBTrack.getValue(row), 0.0); // paint the window device->BeginScene(); device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, clearColor, 1.0f, 0); /* D3DXMATRIX world; device->SetTransform(D3DTS_WORLD, &world); */ float rot = camRotTrack.getValue(row); float dist = camDistTrack.getValue(row); D3DXVECTOR3 eye(sin(rot) * dist, 0, cos(rot) * dist); D3DXVECTOR3 at(0, 0, 0); D3DXVECTOR3 up(0, 1, 0); D3DXMATRIX view; D3DXMatrixLookAtLH(&view, &(eye + at), &at, &up); device->SetTransform(D3DTS_WORLD, &view); D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH(&proj, D3DXToRadian(60), 4.0f / 3, 0.1f, 1000.f); device->SetTransform(D3DTS_PROJECTION, &proj); cubeMesh->DrawSubset(0); device->EndScene(); device->Present(0, 0, 0, 0); BASS_Update(0); // decrease the chance of missing vsync MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); if (WM_QUIT == msg.message) done = true; if ((WM_KEYDOWN == msg.message) && (VK_ESCAPE == LOWORD(msg.wParam))) done = true; } } BASS_StreamFree(stream); BASS_Free(); device->Release(); d3d->Release(); DestroyWindow(hwnd); } catch (const std::exception &e) { #ifdef _CONSOLE fprintf(stderr, "*** error: %s\n", e.what()); #else MessageBox(NULL, e.what(), NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND); #endif ret = -1; } catch (const std::string &str) { #ifdef _CONSOLE fprintf(stderr, "*** error: %s\n", str.c_str()); #else MessageBox(NULL, e.what(), NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND); #endif ret = -1; } return ret; }
//----------------------------------------------------------------------------- // Convert the mesh to the format specified by the given vertex declarations. //----------------------------------------------------------------------------- HRESULT CDXUTMesh::SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, const D3DVERTEXELEMENT9 *pDecl, bool bAutoComputeNormals, bool bAutoComputeTangents, bool bSplitVertexForOptimalTangents ) { LPD3DXMESH pTempMesh = NULL; if( m_pMesh ) { if( FAILED( m_pMesh->CloneMesh( m_pMesh->GetOptions(), pDecl, pd3dDevice, &pTempMesh ) ) ) { SAFE_RELEASE( pTempMesh ); return E_FAIL; } } // Check if the old declaration contains a normal. bool bHadNormal = false; bool bHadTangent = false; D3DVERTEXELEMENT9 aOldDecl[MAX_FVF_DECL_SIZE]; if( m_pMesh && SUCCEEDED( m_pMesh->GetDeclaration( aOldDecl ) ) ) { for( UINT index = 0; index < D3DXGetDeclLength( aOldDecl ); ++index ) { if( aOldDecl[index].Usage == D3DDECLUSAGE_NORMAL ) { bHadNormal = true; } if( aOldDecl[index].Usage == D3DDECLUSAGE_TANGENT ) { bHadTangent = true; } } } // Check if the new declaration contains a normal. bool bHaveNormalNow = false; bool bHaveTangentNow = false; D3DVERTEXELEMENT9 aNewDecl[MAX_FVF_DECL_SIZE]; if( pTempMesh && SUCCEEDED( pTempMesh->GetDeclaration( aNewDecl ) ) ) { for( UINT index = 0; index < D3DXGetDeclLength( aNewDecl ); ++index ) { if( aNewDecl[index].Usage == D3DDECLUSAGE_NORMAL ) { bHaveNormalNow = true; } if( aNewDecl[index].Usage == D3DDECLUSAGE_TANGENT ) { bHaveTangentNow = true; } } } SAFE_RELEASE( m_pMesh ); if( pTempMesh ) { m_pMesh = pTempMesh; if( !bHadNormal && bHaveNormalNow && bAutoComputeNormals ) { // Compute normals in case the meshes have them D3DXComputeNormals( m_pMesh, NULL ); } if( bHaveNormalNow && !bHadTangent && bHaveTangentNow && bAutoComputeTangents ) { ID3DXMesh* pNewMesh; HRESULT hr; DWORD *rgdwAdjacency = NULL; rgdwAdjacency = new DWORD[m_pMesh->GetNumFaces() * 3]; if( rgdwAdjacency == NULL ) return E_OUTOFMEMORY; V( m_pMesh->GenerateAdjacency(1e-6f,rgdwAdjacency) ); float fPartialEdgeThreshold; float fSingularPointThreshold; float fNormalEdgeThreshold; if( bSplitVertexForOptimalTangents ) { fPartialEdgeThreshold = 0.01f; fSingularPointThreshold = 0.25f; fNormalEdgeThreshold = 0.01f; } else { fPartialEdgeThreshold = -1.01f; fSingularPointThreshold = 0.01f; fNormalEdgeThreshold = -1.01f; } // Compute tangents, which are required for normal mapping hr = D3DXComputeTangentFrameEx( m_pMesh, D3DDECLUSAGE_TEXCOORD, 0, D3DDECLUSAGE_TANGENT, 0, D3DX_DEFAULT, 0, D3DDECLUSAGE_NORMAL, 0, 0, rgdwAdjacency, fPartialEdgeThreshold, fSingularPointThreshold, fNormalEdgeThreshold, &pNewMesh, NULL ); SAFE_DELETE_ARRAY( rgdwAdjacency ); if( FAILED(hr) ) return hr; SAFE_RELEASE( m_pMesh ); m_pMesh = pNewMesh; } } return S_OK; }
//------------------------------------------------------------------------------ //this is a check function //------------------------------------------------------------------------------ void TriPickDemo::checkPick(LPD3DXMESH mesh, D3DXMATRIX matWorld) { HRESULT hr; D3DXMATRIX mWorldViewProjection; mWorldViewProjection = matWorld * g_Camera->viewProj(); HR(m_FX->SetTechnique("RenderScene")); // send matrix to shader HR(m_FX->SetMatrix("g_mWorldViewProjection", &mWorldViewProjection)); HR(m_FX->SetMatrix("g_mWorld", &matWorld)); UINT uPasses; V(m_FX->Begin(&uPasses, 0)); g_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); V(m_FX->BeginPass(0)); //get select ray D3DXVECTOR3 originW(0.0f, 0.0f, 0.0f); D3DXVECTOR3 dirW(0.0f, 0.0f, 0.0f); if (gDInput->mouseButtonDown(0)) { getWorldPickingRay(originW, dirW, matWorld); LPD3DXMESH pMesh; mesh->CloneMeshFVF(D3DXMESH_MANAGED, D3DVERTEX::FVF, g_pDevice, &pMesh); BOOL hit = 0; DWORD faceIndex = -1; float u = 0.0f; float v = 0.0f; float dist = 0.0f; ID3DXBuffer* allhits = 0; DWORD numHits = 0; HR(D3DXIntersect(pMesh, &originW, &dirW, &hit, &faceIndex, &u, &v, &dist, &allhits, &numHits)); SAFE_RELEASE(allhits); //if hit if (hit) { IDirect3DVertexBuffer9* vb = 0; IDirect3DIndexBuffer9* ib = 0; HR(pMesh->GetVertexBuffer(&vb)); HR(pMesh->GetIndexBuffer(&ib)); HR(g_pDevice->SetIndices(ib)); HR(g_pDevice->SetFVF(D3DVERTEX::FVF)); HR(g_pDevice->SetStreamSource(0, vb, 0, sizeof(D3DVERTEX))); //render hit surface HR(g_pDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, pMesh->GetNumVertices(), faceIndex * 3, 1)) g_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); SAFE_RELEASE(vb); SAFE_RELEASE(ib); SAFE_RELEASE(pMesh); } } HR(m_FX->EndPass()); HR(m_FX->End()); }