void MeshNode::Draw(IDirect3DDevice9* device) const{ if(!initialized) return; assert(NULL != device); // set the transform device->SetTransform(D3DTS_WORLDMATRIX(0), &transform_); //FIXME Should not be accessed directly ID3DXEffect* effect = GraphicsLayer::GetInstance().m_pEffect; effect->SetMatrix( "g_WorldMatrix", &transform_); effect->SetValue( "g_ColorTint", &m_colorMtrlTint, sizeof( D3DXCOLOR ) ); effect->SetValue( "g_TexOffset", &m_texOffset, sizeof( Vector2 ) ); assert(SUCCEEDED(effect->SetTechnique( "RenderSceneWithTextureDefault" ))); UINT cPasses = 1; assert(SUCCEEDED(effect->Begin( &cPasses, 0 ))); for(UINT iPass = 0; iPass < cPasses; iPass++ ) { effect->BeginPass( iPass ) ; mesh_->Draw(device); assert(SUCCEEDED(effect->EndPass())); } assert(SUCCEEDED(effect->End())); if(NULL != boundsMesh_){ Matrix t = CreateMatrix(worldBounds_.center); device->SetTransform(D3DTS_WORLDMATRIX(0), &t); boundsMesh_->DrawSubset(0); } }
bool noBlendMatrixSetDX9::bind() { LPDIRECT3DDEVICE9 m_pDevice = m_context->GetD3DDevice(); //if (m_context->getCurrentVertexShader()) // Have a shader bound. if (1) { int nb = m_matrices.getSize()<m_maxMatrices? m_matrices.getSize() : m_maxMatrices; hkLocalArray<float> transposedMatrices( (nb * 12) + 4 ); // +4 so we can use it directly to transpose 16 elems as we go, overwiting the last row transposedMatrices.setSizeUnchecked( (nb*12) + 4); // then we need to place these matrices in the shader. for (int m=0; m < nb; ++m) { float* t = &transposedMatrices[m*12]; hkgMat4Transpose( t, (const float*)&m_matrices[m]); } // one big set rather than n small ones const int startReg = 0; // XX assumed in all hkg bone shaders m_pDevice->SetVertexShaderConstantF(startReg, transposedMatrices.begin(), 3*nb ); } else { for (int m=0; m < m_matrices.getSize(); ++m) { m_pDevice->SetTransform( D3DTS_WORLDMATRIX(m), &m_matrices[m] ); } } return true; }
void Screen3D:: DrawAllAlpha() { AlphaRendering = false; SetRenderState(D3DRS_ZWRITEENABLE, FALSE); //SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); //SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); std::list<RenderBlock>::iterator i; while(DrawList.size()) { i = DrawList.begin(); RenderBlock r = (*i); D3DDevice->SetTransform( D3DTS_WORLDMATRIX(0), &r.m); DrawPrimitiveVB((*i).VB, (*i).IB); DrawList.erase(i); } SetRenderState(D3DRS_ZWRITEENABLE, TRUE); }
inline uint32 CD3DSkelMesh::SetMatrixPalette(uint32 MinBone,uint32 MaxBone,D3DMATRIX* pTransforms) { for (uint32 i=MinBone;i<=MaxBone;++i) { if (m_bReIndexedBones) { g_RenderStateMgr.SetTransform(D3DTS_WORLDMATRIX(i),&pTransforms[m_pReIndexedBoneList[i]]); } else { g_RenderStateMgr.SetTransform(D3DTS_WORLDMATRIX(i),&pTransforms[i]); } } switch (m_iMaxBonesPerVert) { case 2 : { PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_1WEIGHTS); break; } case 3 : { PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_2WEIGHTS); break; } case 4 : { PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_3WEIGHTS); break; } default: { PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_DISABLE); } } return (MaxBone-MinBone); }
//----[ renderInstance ]----------------------------------------------------- bool AnimatedMeshRenderer::renderInstance(const D3DXMATRIX* bone_matrices) { assert(initialized_subset_); LPDIRECT3DDEVICE9 d3d_device = d3d_device_; { // Set all of the bone matrices in this subset const unsigned int* matrix_bone_indices = initialized_subset_->matrix_bone_indices; size_t number_of_matrices = initialized_subset_->number_of_matrices; for (size_t i = 0; i < number_of_matrices; ++i) { d3d_device->SetTransform(D3DTS_WORLDMATRIX(i), &bone_matrices[matrix_bone_indices[i]]); } } // Render HRESULT hr = d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, initialized_subset_->number_of_vertices, 0, initialized_subset_->number_of_triangles); return SUCCEEDED(hr) ? true : false; }
void CDexModelXAni::DrawMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase) { stDexMeshContainerEx *pMeshContainer = (stDexMeshContainerEx*)pMeshContainerBase; stDexFrameEx *pFrame = (stDexFrameEx*)pFrameBase; //UINT iMaterial; UINT iAttrib; LPD3DXBONECOMBINATION pBoneComb; UINT iMatrixIndex; UINT iPaletteEntry; D3DXMATRIXA16 matTemp; if(pMeshContainer->pSkinInfo != NULL) { // set the number of vertex blend indices to be blended if( pMeshContainer->NumInfl == 1 ) { DexGameEngine::getEngine()->GetDevice()->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_0WEIGHTS); } else { DexGameEngine::getEngine()->GetDevice()->SetRenderState( D3DRS_VERTEXBLEND, pMeshContainer->NumInfl - 1); } if( pMeshContainer->NumInfl ) DexGameEngine::getEngine()->GetDevice()->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE); // for each attribute group in the mesh, calculate the set of matrices in the palette and then draw the mesh subset pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>( pMeshContainer->pBoneCombinationBuf->GetBufferPointer () ); //DexGameEngine::getEngine()->GetDevice()->SetTransform(D3DTS_WORLD, &((stDexFrameEx*)pFrameBase)->CombinedTransformationMatrix); for( iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++ ) {//遍历网格 // first calculate all the world matrices int tr = pMeshContainer->NumPaletteEntries; for( iPaletteEntry = 0; iPaletteEntry < pMeshContainer->NumPaletteEntries; ++iPaletteEntry ) { iMatrixIndex = pBoneComb[iAttrib].BoneId[iPaletteEntry]; if( iMatrixIndex != UINT_MAX ) { D3DXMATRIX m1 = (pMeshContainer->pBoneOffsetMatrices[iMatrixIndex]); D3DXMATRIX m2 = *(pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex]); D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex],pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex] ); DexGameEngine::getEngine()->GetDevice()->SetTransform( D3DTS_WORLDMATRIX( iPaletteEntry ), &matTemp ); } } // setup the material of the mesh subset - REMEMBER to use the original pre-skinning attribute id to get the correct material id DexGameEngine::getEngine()->GetDevice()->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D ); DexGameEngine::getEngine()->GetDevice()->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] ); // finally draw the subset with the current world matrix palette and material state pMeshContainer->MeshData.pMesh->DrawSubset( iAttrib); } // reset blending state DexGameEngine::getEngine()->GetDevice()->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE); DexGameEngine::getEngine()->GetDevice()->SetRenderState( D3DRS_VERTEXBLEND, 0); } }
// NOTE: The texture list needs to change to be device independent... void CD3DRigidMesh::Render(D3DMATRIX& WorldTransform,CD3DRenderStyle* pRenderStyle,vector<LPDXTexture>& TextureList) { if (pRenderStyle == NULL) return; g_RenderStateMgr.SetTransform(D3DTS_WORLDMATRIX(0), &WorldTransform); PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_DISABLE); PD3DDEVICE->SetRenderState(D3DRS_LIGHTING,TRUE); PD3DDEVICE->SetRenderState(D3DRS_NORMALIZENORMALS,FALSE); //m_VBController.SetStreamSources(); if( (g_EffectMgr.GetEnabled()) && (g_EffectMgr.GetEffect() != NULL) ) { ID3DXEffect *pEffect = g_EffectMgr.GetEffect(); g_EffectMgr.UploadVertexDecl(); m_VBController.SetStreamSources(); // This is a temp HACK //g_RenderStateMgr.SetRenderStyleStates(pRenderStyle,0,TextureList); pEffect->SetTechnique(g_EffectMgr.GetTechnique()); D3DXMATRIX matD3DX( *g_RenderStateMgr.GetTransform(D3DTS_WORLD)); D3DXMATRIX MatWorld; D3DXMatrixTranspose(&MatWorld, &matD3DX); pEffect->SetMatrix("worldMatrix", &MatWorld); //view proj D3DXMATRIX MatView; PD3DDEVICE->GetTransform(D3DTS_VIEW, &MatView); pEffect->SetMatrix("viewMatrix", &MatView); D3DXMATRIX MatProj; PD3DDEVICE->GetTransform(D3DTS_PROJECTION, &MatProj); pEffect->SetMatrix("projMatrix", &MatProj); D3DXMATRIX MatViewProj; D3DXMatrixMultiply(&MatViewProj, &MatView, &MatProj); D3DXMatrixTranspose(&MatViewProj, &MatViewProj); D3DXMATRIX matD3DX2( MatViewProj); pEffect->SetMatrix("viewProjMatrix", &matD3DX2); float fTemp[4]; fTemp[0] = g_EffectMgr.GetPosition()->x; fTemp[1] = g_EffectMgr.GetPosition()->y; fTemp[2] = g_EffectMgr.GetPosition()->z; fTemp[3] = 0.0f; pEffect->SetFloatArray("CameraPosition", fTemp, 4); char szBuf[32]; ZeroMemory(szBuf, 32); for (uint32 iTexStage = 0; iTexStage < 4; ++iTexStage) { if(TextureList[iTexStage]) { PD3DDEVICE->SetTexture(iTexStage, TextureList[iTexStage]->GetTexture()); sprintf(szBuf, "texture%d", iTexStage); D3DXHANDLE hHandle = pEffect->GetParameterByName(NULL, szBuf); HRESULT hrTex = pEffect->SetTexture(hHandle, TextureList[iTexStage]->GetTexture()); if(FAILED(hrTex)) { OutputDebugString("Error sending texture to Effect!"); } } } UINT nPasses; pEffect->Begin(&nPasses, 0); for(int n = 0; n < (int)nPasses; ++n) { pEffect->BeginPass(n); m_VBController.Render(0,0,m_iVertCount,m_iPolyCount); pEffect->EndPass(); } pEffect->End(); PD3DDEVICE->SetTexture(0, NULL); PD3DDEVICE->SetTexture(1, NULL); PD3DDEVICE->SetTexture(2, NULL); PD3DDEVICE->SetTexture(3, NULL); } else { g_EffectMgr.UploadVertexDecl(); m_VBController.SetStreamSources(); for (uint32 iRenderPass = 0; iRenderPass < pRenderStyle->GetRenderPassCount(); ++iRenderPass) { LPDIRECT3DVERTEXSHADER9 VertexShader = pRenderStyle->GetVertexShader(iRenderPass,0); RSD3DRenderPass D3DRenderPass; if (VertexShader) { // Using a custom vertex shader... if (FAILED(g_RenderStateMgr.SetVertexShader(VertexShader))) { assert(0); return; } if (!pRenderStyle->GetRenderPass_D3DOptions(iRenderPass,&D3DRenderPass)) { assert(0); return; } // if (!g_RenderStateMgr.SetVertexShaderConstants(pRenderStyle, &D3DRenderPass,0)) { assert(0); return; } } else { // Using the standand pipe... /* if (!m_VBController.getVertexFormat(0)) return; // This is a non fixed function pipe VB - bail out... if (FAILED(g_RenderStateMgr.SetFVF(m_VBController.getVertexFormat(0)))) { assert(0); return; } */ } g_RenderStateMgr.SetRenderStyleStates(pRenderStyle,iRenderPass,TextureList); // Set your render states with the render state mgr... //g_EffectMgr.UploadVertexDecl(); m_VBController.Render(0,0,m_iVertCount,m_iPolyCount); } } D3DXMATRIX mIdentity; D3DXMatrixIdentity(&mIdentity); // Reset our World Matrix... g_RenderStateMgr.SetTransform(D3DTS_WORLDMATRIX(0),&mIdentity); PD3DDEVICE->SetRenderState(D3DRS_LIGHTING,FALSE); PD3DDEVICE->SetRenderState(D3DRS_ALPHABLENDENABLE, false); PD3DDEVICE->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); PD3DDEVICE->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); PD3DDEVICE->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); PD3DDEVICE->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); }
bool World::drawImage(RenderFrame* pRenderFrame,RenderMesh* pRenderMesh) { //デバイスの状況チェック if(!isDeviceActive()) return false; IDirect3DDevice9* pd3dDevice = Device::getInterface(); if(!pd3dDevice) return false; Mesh* mesh = pRenderMesh->mesh; if(!mesh) return false; RenderFrame* renderFrame = pRenderMesh->renderFrame; Vertex* vertex = mesh->getVertexBuffer(); if(!vertex) return false; IDirect3DVertexBuffer9* pVertexBuffer = vertex->getInterface(); if(!pVertexBuffer) return false; Index* index = mesh->getIndexBuffer(); IDirect3DIndexBuffer9* pIndexBuffer = index?index->getInterface():NULL; RenderUnit* renderUnit = renderFrame->renderUnit; Unit* unit = renderUnit->unit; bool shaderFlag = mesh->isShader(); //ビュークリップ if(unit->isViewClip()) { RECT& viewRect = renderFrame->renderUnit->clipRect; if(viewRect.top >= viewRect.bottom || viewRect.left >= viewRect.right) return true; NVector box1 = {(FLOAT)viewRect.left,(FLOAT)viewRect.top,0,1}; NVector box2 = {(FLOAT)viewRect.right,(FLOAT)viewRect.top,0,1}; NVector box3 = {(FLOAT)viewRect.left,(FLOAT)viewRect.bottom,0,1}; NVector out1 = box1.transformCoord(renderFrame->matrix); NVector out2 = box2.transformCoord(renderFrame->matrix); NVector out3 = box3.transformCoord(renderFrame->matrix); Device::setClipper( out1.x,out1.y,out1.z, out2.x,out2.y,out2.z, out3.x,out3.y,out3.z); } //座標の設定 if(shaderFlag) { VertexShader* vertexShader = mesh->getVertexShader(); Device::getInterface()->SetVertexShader(*vertexShader); //シェーダ NMatrix matrix[100]; NMatrix* matView; NMatrix* matProj; NMatrix matWork; if(m_camera) { if(unit->isView2D()) { matView = &m_camera->getBaseView(); pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); } else { matView = &m_camera->getView(); pd3dDevice->SetRenderState(D3DRS_CULLMODE,m_camera->getCull()); } matProj = &m_camera->getProjection(); } vertexShader->setDefaultParam(); Material* material = mesh->getMaterial(); vertexShader->setParam("MaterialDiffuse",&material->Diffuse); vertexShader->setParam("MaterialAmbient",&material->Ambient); vertexShader->setParam("View",matView); vertexShader->setParam("Proj",matProj); vertexShader->setParam("World",&renderFrame->matrix); if(vertexShader->isParam("LightDir")) { if(unit->isLight()) { NVector v = {0.1f,-0.5f,-0.5f,0.0f}; vertexShader->setParam("LightDir",&v); } else { static NVector v = {0,0,0}; vertexShader->setParam("LightDir",&v); } } if(vertexShader->isParam("WorldView") || vertexShader->isParam("WorldViewProj")) { matWork = renderFrame->matrix * *matView; vertexShader->setParam("WorldView",&matWork); if(vertexShader->isParam("WorldViewProj")) { matWork *= *matProj; vertexShader->setParam("WorldViewProj",&matWork); } } if(vertexShader->isParam("ViewProj")) { matWork = *matView * *matProj; vertexShader->setParam("ViewProj",&matWork); } if(pRenderMesh->boneCount > 0) { INT i; BONEMATRIX* boneMatrixs = &(*mesh->getBoneMatrix())[0]; for(i=0;i<pRenderMesh->boneCount;i++) { matrix[i] = boneMatrixs[i].matrix * pRenderFrame[pRenderMesh->boneData[i]].matrix; } vertexShader->setParam("WorldMatrixArray",matrix,pRenderMesh->boneCount); } } else { //固定機能 if(pRenderMesh->boneCount == 0) { pd3dDevice->SetSoftwareVertexProcessing(false); pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND ,D3DVBF_DISABLE); pd3dDevice->SetTransform(D3DTS_WORLD ,(D3DMATRIX*)&renderFrame->matrix); } else { //ハードウエアの能力が足りるかどうか const D3DCAPS9* desc = Device::getCaps(); if(Device::getCaps()->MaxVertexBlendMatrixIndex < 3 ||(INT)Device::getCaps()->MaxVertexBlendMatrices < pRenderMesh->boneCount) pd3dDevice->SetSoftwareVertexProcessing(true); pd3dDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE,TRUE); pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND ,D3DVBF_3WEIGHTS ); INT i; std::vector<BONEMATRIX>* boneMatrixs = mesh->getBoneMatrix(); for(i=0;i<pRenderMesh->boneCount;i++) { pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(i) ,(D3DMATRIX*)&pRenderFrame[pRenderMesh->boneData[i]].matrix); pd3dDevice->MultiplyTransform(D3DTS_WORLDMATRIX(i) ,(D3DMATRIX*)&(*boneMatrixs)[i].matrix); } } //ビュー設定 if(m_camera) { if(unit->isView2D()) { pd3dDevice->SetTransform( D3DTS_VIEW, (D3DMATRIX*)&m_camera->getBaseView()); pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); } else { pd3dDevice->SetTransform( D3DTS_VIEW, (D3DMATRIX*)&m_camera->getView()); pd3dDevice->SetRenderState(D3DRS_CULLMODE,m_camera->getCull()); } } //---------------------------- //ライティング if(unit->isLight()) pd3dDevice->SetRenderState(D3DRS_LIGHTING,true); else pd3dDevice->SetRenderState(D3DRS_LIGHTING,false); //---------------------------- Material* material = pRenderMesh->mesh->getMaterial(); if(unit->isLight()) { if(material) { pd3dDevice->SetMaterial((D3DMATERIAL9*)material); pd3dDevice->SetRenderState(D3DRS_COLORVERTEX,true); pd3dDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE,D3DMCS_COLOR1); pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1); } } } Texture* pTexture = pRenderMesh->mesh->getTexture(); IDirect3DTexture9* pITexture = NULL; if(pTexture) { if(renderUnit->alpha != 100) { DWORD alpha = (0xff * renderUnit->alpha / 100) << 24; pd3dDevice->SetRenderState(D3DRS_TEXTUREFACTOR,alpha); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); } else { pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); } pITexture = pTexture->getInterface(); } //---------------------------- //Zバッファの設定 if(unit->isZBuffer()) { pd3dDevice->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE); pd3dDevice->SetRenderState(D3DRS_ZFUNC,D3DCMP_LESSEQUAL); } else { pd3dDevice->SetRenderState(D3DRS_ZENABLE,D3DZB_FALSE); // pd3dDevice->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE); // pd3dDevice->SetRenderState(D3DRS_ZFUNC,D3DCMP_ALWAYS); } D3DTEXTUREFILTERTYPE filter = unit->getTextureFilter(); pd3dDevice->SetSamplerState(0,D3DSAMP_MINFILTER,filter); pd3dDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,filter); pd3dDevice->SetSamplerState(0,D3DSAMP_MIPFILTER,filter); if(filter == D3DTEXF_ANISOTROPIC) { pd3dDevice->SetSamplerState(0,D3DSAMP_MAXANISOTROPY,16); } //クリッピングの設定 if(unit->getClipWidth() || unit->getClipHeight() || unit->getClipDepth()) { Device::setClipper(unit->getClipX(),unit->getClipY(),unit->getClipZ(), unit->getClipWidth(),unit->getClipHeight(),unit->getClipDepth()); } if(pRenderMesh->shadow) { pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); } else if(renderUnit->alpha != 100 && !pTexture) { BYTE a = (BYTE)(0xff * renderUnit->alpha / 100); BYTE alpha[4] = {a,a,a,0}; pd3dDevice->SetRenderState(D3DRS_BLENDFACTOR,*(LPDWORD)&alpha); pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BLENDFACTOR); pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVBLENDFACTOR); pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 8); } else { switch(unit->getBlendMode()) { case 0: //ブレンド設定 pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 8); break; case 1: pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE); pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE); break; case 2: pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA); pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCALPHA); pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_LESSEQUAL); pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 247); break; } } if(shaderFlag) { Device::getInterface()->SetVertexDeclaration(mesh->getDeclaration()); } //描画 pd3dDevice->SetTexture(0,pITexture); INT iPrimitiveCount; INT iVertexCount = vertex->getStrideCount(); if(index) { if(mesh->getPrimitiveType() == D3DPT_TRIANGLELIST) iPrimitiveCount = index->getCount() / 3; else iPrimitiveCount = index->getCount() / 2; } else { if(mesh->getPrimitiveType() == D3DPT_TRIANGLELIST) iPrimitiveCount = iVertexCount / 3; else iPrimitiveCount = iVertexCount / 2; } pd3dDevice->SetStreamSource(0,pVertexBuffer,0,vertex->getStrideSize()); if(!shaderFlag) pd3dDevice->SetFVF(vertex->getFVF()); pd3dDevice->SetIndices(pIndexBuffer); if(pRenderMesh->shadow) { if(Device::getCaps()->StencilCaps) { pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, false); //pd3dDevice->SetRenderState(D3DRS_COLORWRITEENABLE, false); pd3dDevice->SetRenderState(D3DRS_SHADEMODE,D3DSHADE_FLAT); pd3dDevice->SetRenderState(D3DRS_STENCILENABLE,true); pd3dDevice->SetRenderState(D3DRS_STENCILFUNC,D3DCMP_ALWAYS); if(false && Device::getCaps()->StencilCaps & D3DSTENCILCAPS_TWOSIDED) { //両面可能 pd3dDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE,true); pd3dDevice->SetRenderState(D3DRS_CCW_STENCILFUNC,D3DCMP_ALWAYS); pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); pd3dDevice->SetRenderState(D3DRS_STENCILPASS,D3DSTENCILOP_KEEP); pd3dDevice->SetRenderState(D3DRS_STENCILZFAIL,D3DSTENCILOP_DECR); pd3dDevice->SetRenderState(D3DRS_CCW_STENCILPASS,D3DSTENCILOP_KEEP); pd3dDevice->SetRenderState(D3DRS_CCW_STENCILZFAIL,D3DSTENCILOP_INCR); pd3dDevice->DrawIndexedPrimitive(mesh->getPrimitiveType() ,0,0 ,iVertexCount,0,iPrimitiveCount); pd3dDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE,false); pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW); } else { pd3dDevice->SetRenderState(D3DRS_STENCILPASS,D3DSTENCILOP_KEEP); pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW); pd3dDevice->SetRenderState(D3DRS_STENCILZFAIL,D3DSTENCILOP_INCR); pd3dDevice->DrawIndexedPrimitive(mesh->getPrimitiveType() ,0,0 ,iVertexCount,0,iPrimitiveCount); pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW); pd3dDevice->SetRenderState(D3DRS_STENCILZFAIL,D3DSTENCILOP_DECR); pd3dDevice->DrawIndexedPrimitive(mesh->getPrimitiveType() ,0,0 ,iVertexCount,0,iPrimitiveCount); } pd3dDevice->SetRenderState(D3DRS_STENCILENABLE,false); pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, true); pd3dDevice->SetRenderState(D3DRS_SHADEMODE,D3DSHADE_GOURAUD); //pd3dDevice->SetRenderState(D3DRS_COLORWRITEENABLE, true); } } else { //pd3dDevice->SetRenderState(D3DRS_STENCILENABLE,true); pd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); pd3dDevice->SetRenderState(D3DRS_STENCILZFAIL,D3DSTENCILOP_KEEP); pd3dDevice->SetRenderState(D3DRS_CCW_STENCILZFAIL,D3DSTENCILOP_KEEP); pd3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); if(pIndexBuffer) pd3dDevice->DrawIndexedPrimitive(mesh->getPrimitiveType() ,0,0 ,iVertexCount,0,iPrimitiveCount); else pd3dDevice->DrawPrimitive(mesh->getPrimitiveType() ,0,iPrimitiveCount); // pd3dDevice->SetRenderState(D3DRS_STENCILENABLE,false); } if(shaderFlag) { Device::getInterface()->SetVertexShader(NULL); Device::getInterface()->SetPixelShader(NULL); Device::getInterface()->SetVertexDeclaration(NULL); } else pd3dDevice->SetFVF(NULL); Device::getInterface()->SetRenderState( D3DRS_SCISSORTESTENABLE, false ); //クリッピングの解除 if(unit->isViewClip() || unit->getClipWidth() || unit->getClipHeight() || unit->getClipDepth()) { Device::setClipper(0,0,0,0,0,0); } return true; }
void MoonSkinmesh::DrawMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase) { D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase; D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED*)pFrameBase; UINT iMaterial; UINT NumBlend; UINT iAttrib; DWORD AttribIdPrev; LPD3DXBONECOMBINATION pBoneComb; UINT iMatrixIndex; UINT iPaletteEntry; D3DXMATRIXA16 matTemp; // first check for skinning if (pMeshContainer->pSkinInfo != NULL) { // if hw doesn't support indexed vertex processing, switch to software vertex processing if (pMeshContainer->UseSoftwareVP) { _pDevice->SetSoftwareVertexProcessing(TRUE); } // set the number of vertex blend indices to be blended if (pMeshContainer->NumInfl == 1) _pDevice->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_0WEIGHTS); else _pDevice->SetRenderState(D3DRS_VERTEXBLEND, pMeshContainer->NumInfl - 1); if (pMeshContainer->NumInfl) _pDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE); // for each attribute group in the mesh, calculate the set of matrices in the palette and then draw the mesh subset pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pMeshContainer->pBoneCombinationBuf->GetBufferPointer()); for (iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++) { // first calculate all the world matrices for (iPaletteEntry = 0; iPaletteEntry < pMeshContainer->NumPaletteEntries; ++iPaletteEntry) { iMatrixIndex = pBoneComb[iAttrib].BoneId[iPaletteEntry]; if (iMatrixIndex != UINT_MAX) { D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex], pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex] ); _pDevice->SetTransform( D3DTS_WORLDMATRIX( iPaletteEntry ), &matTemp ); } } // setup the material of the mesh subset - REMEMBER to use the original pre-skinning attribute id to get the correct material id _pDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D ); _pDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] ); // finally draw the subset with the current world matrix palette and material state pMeshContainer->MeshData.pMesh->DrawSubset( iAttrib ); } // reset blending state _pDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE); _pDevice->SetRenderState(D3DRS_VERTEXBLEND, 0); // remember to reset back to hw vertex processing if software was required if (pMeshContainer->UseSoftwareVP) { _pDevice->SetSoftwareVertexProcessing(FALSE); } } else // standard mesh, just draw it after setting material properties { _pDevice->SetTransform(D3DTS_WORLD, &pFrame->CombinedTransformationMatrix); for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++) { _pDevice->SetMaterial( &pMeshContainer->pMaterials[iMaterial].MatD3D ); _pDevice->SetTexture( 0, pMeshContainer->ppTextures[iMaterial] ); pMeshContainer->MeshData.pMesh->DrawSubset(iMaterial); } } }
void RenderSystem::setWorldMatrix( int idx , Matrix4 const& world ) { getD3DDevice()->SetTransform( D3DTS_WORLDMATRIX(idx ) , reinterpret_cast< D3DXMATRIX const* >( &world ) ); }
void Screen3D::MultTransform ( Matrix& M ) { if(!D3DDevice) return; D3DDevice->MultiplyTransform( D3DTS_WORLDMATRIX(0), &M.Mat); }
void Screen3D::SetTransform ( D3DXMATRIX& M ) { if(!D3DDevice) return; D3DDevice->SetTransform( D3DTS_WORLDMATRIX(0), &M); }
void CD3DVAMesh::Render(ModelInstance *pInstance, D3DMATRIX& WorldTransform, CD3DRenderStyle* pRenderStyle, uint32 iRenderPass) { RSD3DOptions rsD3DOptions; pRenderStyle->GetDirect3D_Options(&rsD3DOptions); // If this pass has a vertex shader, use it. RSD3DRenderPass *pPass = pRenderStyle->GetRenderPass_D3DOptions(iRenderPass); if (NULL != pPass && pPass->bUseVertexShader && pPass->VertexShaderID != LTVertexShader::VERTEXSHADER_INVALID) { if ( m_bSWVSBuffers && !m_bSWVertProcessing ) { m_bSWVertProcessing = true; FreeDeviceObjects(); ReCreateObject(); } // Store the pointer to the actual shader during rendering. m_pVertexShader = LTVertexShaderMgr::GetSingleton().GetVertexShader(pPass->VertexShaderID); if (m_pVertexShader != NULL) { // Install the shader. if (!LTVertexShaderMgr::GetSingleton().InstallVertexShader(m_pVertexShader)) { m_pVertexShader = NULL; return; } } } else if (!rsD3DOptions.bUseEffectShader) { if (!m_VBController.getVertexFormat(0) || m_bNonFixPipeData) { // This is a non fixed function pipe VB - bail out... return; } else if(FAILED(g_RenderStateMgr.SetVertexShader(m_VBController.getVertexFormat(0)))) { return; } } // If this pass has a pixel shader, use it. if (NULL != pPass && pPass->bUsePixelShader && pPass->PixelShaderID != LTPixelShader::PIXELSHADER_INVALID) { // Store the pointer to the actual shader during rendering. m_pPixelShader = LTPixelShaderMgr::GetSingleton().GetPixelShader(pPass->PixelShaderID); if (m_pPixelShader != NULL) { // Install the shader. if (!LTPixelShaderMgr::GetSingleton().InstallPixelShader(m_pPixelShader)) { m_pPixelShader = NULL; return; } } } // We need software processing if(m_bSWVertProcessing) { PD3DDEVICE->SetSoftwareVertexProcessing(TRUE); } g_RenderStateMgr.SetTransform(D3DTS_WORLDMATRIX(0), &WorldTransform); m_VBController.SetStreamSources(); // Set the vertex shader constants. if (m_pVertexShader != NULL) { // Let the client set some constants. if (NULL != i_client_shell) { i_client_shell->OnVertexShaderSetConstants(m_pVertexShader, iRenderPass, pRenderStyle, pInstance, LTShaderDeviceStateImp::GetSingleton()); } // Send the constants to the video card. LTVertexShaderMgr::GetSingleton().SetVertexShaderConstants(m_pVertexShader); } // Set the pixel shader constants. if (m_pPixelShader != NULL) { // Let the client set some constants. if (NULL != i_client_shell) { i_client_shell->OnPixelShaderSetConstants(m_pPixelShader, iRenderPass, pRenderStyle, pInstance, LTShaderDeviceStateImp::GetSingleton()); } // Send the constants to the video card. LTPixelShaderMgr::GetSingleton().SetPixelShaderConstants(m_pPixelShader); } if(rsD3DOptions.bUseEffectShader) { LTEffectImpl* _pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(rsD3DOptions.EffectShaderID); ID3DXEffect* pEffect = _pEffect->GetEffect(); if(pEffect) { i_client_shell->OnEffectShaderSetParams((LTEffectShader*)_pEffect, pRenderStyle, pInstance, LTShaderDeviceStateImp::GetSingleton()); pEffect->CommitChanges(); } } m_VBController.Render(0,0,m_iVertCount,m_iPolyCount); if ( m_bSWVertProcessing ) { // If we are running with hardware then turn back on hardware processing if ( (g_Device.GetDeviceCaps()->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ) { PD3DDEVICE->SetSoftwareVertexProcessing(FALSE); } } PD3DDEVICE->SetStreamSource(0, 0, 0, 0); PD3DDEVICE->SetIndices(0); // Uninstall the vertex shader. if (NULL != m_pVertexShader) { LTVertexShaderMgr::GetSingleton().UninstallVertexShader(); m_pVertexShader = NULL; } // Uninstall the pixel shader. if (NULL != m_pPixelShader) { LTPixelShaderMgr::GetSingleton().UninstallPixelShader(); m_pPixelShader = NULL; } }
HRESULT CAnimationModel::DrawMeshContainerByNonIndexed(LPD3DXMESHCONTAINER pSuperMeshContainer) { HRESULT hr = S_OK; CMeshContainer *pMeshContainer = NULL; LPD3DXBONECOMBINATION pBoneCombinations = NULL; D3DXMATRIX iMatWorld; pMeshContainer = (CMeshContainer*)pSuperMeshContainer; pBoneCombinations = (LPD3DXBONECOMBINATION) pMeshContainer->m_pBoneCombinationBuf->GetBufferPointer(); if( NULL == pBoneCombinations ) return hr; // HW VP for( DWORD i=0; i< pMeshContainer->m_nAttributeSW; ++i ) { DWORD numBlend = 0; for( DWORD h=0; h< pMeshContainer->m_numInfl; ++h ) { if( pBoneCombinations[i].BoneId[h] != UINT_MAX ) { numBlend = h; DWORD iBone = pBoneCombinations[i].BoneId[h]; D3DXMatrixMultiply( &iMatWorld , &pMeshContainer->m_pBoneOffsetMatrices[iBone] , pMeshContainer->m_ppBoneMatrixPtrs[iBone] ); m_pd3dDevice->SetTransform( D3DTS_WORLDMATRIX( h ), &iMatWorld ); } } m_pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, numBlend ); m_pd3dDevice->SetMaterial( &pMeshContainer->m_pMaterials[ pBoneCombinations[i].AttribId ] ); m_pd3dDevice->SetTexture( 0, pMeshContainer->m_ppTextures[ pBoneCombinations[i].AttribId ] ); pMeshContainer->MeshData.pMesh->DrawSubset(i); } // SW VP // 소프트웨어 버텍스프로세싱을 하는 것 말고는 위랑 똑같은 동작을 한다. for( DWORD i=pMeshContainer->m_nAttributeSW; i< pMeshContainer->m_numAttributeGroups; ++i ) { m_pd3dDevice->SetSoftwareVertexProcessing( TRUE ); DWORD numBlend = 0; for( DWORD h=0; h< pMeshContainer->m_numInfl; ++h ) { if( pBoneCombinations[i].BoneId[h] != UINT_MAX ) { ++numBlend; DWORD iBone = pBoneCombinations[i].BoneId[h]; D3DXMatrixMultiply( &iMatWorld , &pMeshContainer->m_pBoneOffsetMatrices[iBone] , pMeshContainer->m_ppBoneMatrixPtrs[iBone] ); m_pd3dDevice->SetTransform( D3DTS_WORLDMATRIX( iBone ), &iMatWorld ); } } m_pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, numBlend ); m_pd3dDevice->SetMaterial( &pMeshContainer->m_pMaterials[i] ); m_pd3dDevice->SetTexture( i, pMeshContainer->m_ppTextures[i] ); pMeshContainer->MeshData.pMesh->DrawSubset(i); } m_pd3dDevice->SetSoftwareVertexProcessing( FALSE ); m_pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, FALSE ); return hr; }
inline int32 CD3DSkelMesh::SetTransformsToBoneSet(BoneSetListItem* pBoneSet,D3DMATRIX* pTransforms, int32 nNumMatrices) { int32 iCurrBone; for (iCurrBone=0; iCurrBone < 4; ++iCurrBone) { if (pBoneSet->BoneSetArray[iCurrBone] == 0xFF) { /* D3DXMATRIX mMat; //D3DXMatrixIdentity(&mMat); ZeroMemory(&mMat, sizeof(D3DXMATRIX)); g_RenderStateMgr.SetTransform(D3DTS_WORLDMATRIX(iCurrBone),&mMat); continue; */ break; } g_RenderStateMgr.SetTransform(D3DTS_WORLDMATRIX(iCurrBone),&pTransforms[pBoneSet->BoneSetArray[iCurrBone]]); } if(nNumMatrices != iCurrBone) { if( g_CV_Use0WeightsForDisable ) { // ATI requires 0 weights instead of disable switch (iCurrBone) { case 1: PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_0WEIGHTS); break; case 2: PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_1WEIGHTS); break; case 3: PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_2WEIGHTS); break; case 4: PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_3WEIGHTS); break; default: PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_DISABLE); ASSERT(0); break; } } else { // but NVIDIA uses disable instead of 0 weights (only on 440MX) switch (iCurrBone) { case 2: PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_1WEIGHTS); break; case 3: PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_2WEIGHTS); break; case 4: PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_3WEIGHTS); break; default: PD3DDEVICE->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_DISABLE); break; } } } return (iCurrBone-1); }
void CLcXSkinSrc::RenderNonIndexed(SMeshContainer* pMeshContainer) { UINT NumBlend; DWORD AttribIdPrev; LPD3DXBONECOMBINATION pBoneComb; UINT iAttrib; UINT iMatrixIndex; D3DXMATRIX matTemp; D3DCAPS9 devCaps; m_pDevice->GetDeviceCaps(&devCaps); //케릭터 뜯어짐 방지 m_pDevice->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP); m_pDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_CLAMP); m_pDevice->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_NONE); AttribIdPrev = UNUSED32; pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pMeshContainer->pBoneCombinationBuf->GetBufferPointer()); // Draw using default vtx processing of the device (typically HW) for (iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++) { NumBlend = 0; for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i) { if (pBoneComb[iAttrib].BoneId[i] != UINT_MAX) { NumBlend = i; } } if (devCaps.MaxVertexBlendMatrices >= NumBlend + 1) { // first calculate the world matrices for the current set of blend weights and get the accurate count of the number of blends for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i) { iMatrixIndex = pBoneComb[iAttrib].BoneId[i]; if (iMatrixIndex != UINT_MAX) { D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex], pMeshContainer->m_pBoneMatrix[iMatrixIndex] ); m_pDevice->SetTransform( D3DTS_WORLDMATRIX( i ), &matTemp ); } } m_pDevice->SetRenderState(D3DRS_VERTEXBLEND, NumBlend); // lookup the material used for this subset of faces if ((AttribIdPrev != pBoneComb[iAttrib].AttribId) || (AttribIdPrev == UNUSED32)) { m_pDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D ); m_pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); // 확대 필터 m_pDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] ); AttribIdPrev = pBoneComb[iAttrib].AttribId; } // draw the subset now that the correct material and matrices are loaded pMeshContainer->MeshData.pMesh->DrawSubset(iAttrib); } } // If necessary, draw parts that HW could not handle using SW if (pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups) { AttribIdPrev = UNUSED32; m_pDevice->SetSoftwareVertexProcessing(TRUE); for (iAttrib = pMeshContainer->iAttributeSW; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++) { NumBlend = 0; for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i) { if (pBoneComb[iAttrib].BoneId[i] != UINT_MAX) { NumBlend = i; } } if (devCaps.MaxVertexBlendMatrices < NumBlend + 1) { // first calculate the world matrices for the current set of blend weights and get the accurate count of the number of blends for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i) { iMatrixIndex = pBoneComb[iAttrib].BoneId[i]; if (iMatrixIndex != UINT_MAX) { D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex], pMeshContainer->m_pBoneMatrix[iMatrixIndex] ); m_pDevice->SetTransform( D3DTS_WORLDMATRIX( i ), &matTemp ); } } m_pDevice->SetRenderState(D3DRS_VERTEXBLEND, NumBlend); // lookup the material used for this subset of faces if ((AttribIdPrev != pBoneComb[iAttrib].AttribId) || (AttribIdPrev == UNUSED32)) { m_pDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D ); m_pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); // 확대 필터 m_pDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] ); AttribIdPrev = pBoneComb[iAttrib].AttribId; } // draw the subset now that the correct material and matrices are loaded pMeshContainer->MeshData.pMesh->DrawSubset(iAttrib); } } m_pDevice->SetSoftwareVertexProcessing(FALSE); } m_pDevice->SetRenderState(D3DRS_VERTEXBLEND, 0); }
/** * @brief skinned mesh * * Called to render a mesh in the hierarchy * */ void AnimationManager::renderMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase) { LPDIRECT3DDEVICE9 pd3dDevice = DXUTGetD3D9Device(); acut::AnimationMeshContainer* pMeshContainer = static_cast<acut::AnimationMeshContainer*>(pMeshContainerBase); acut::AnimationFrame* pFrame = static_cast<acut::AnimationFrame*>(pFrameBase); HRESULT hr; // first check for skinning if (NULL != pMeshContainer->pSkinInfo) { DWORD AttribIdPrev = UNUSED32; LPD3DXBONECOMBINATION pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>( pMeshContainer->m_pBoneCombinationTable->GetBufferPointer() ); D3DCAPS9 d3dCaps; pd3dDevice->GetDeviceCaps(&d3dCaps); // Draw using default vtx processing of the device (typically HW) for (UINT iAttrib = 0; iAttrib < pMeshContainer->m_numberOfBoneCombinations; ++iAttrib) { UINT NumBlend = 0; for (DWORD i = 0; i < pMeshContainer->m_maxNumberOfFaceInfl; ++i) { if (pBoneComb[iAttrib].BoneId[i] != UINT_MAX) { NumBlend = i; } } if (NumBlend + 1 <= d3dCaps.MaxVertexBlendMatrices) { // first calculate the world matrices for the current set of blend weights and get the accurate count of the number of blends for (DWORD i = 0; i < pMeshContainer->m_maxNumberOfFaceInfl; ++i) { UINT iMatrixIndex = pBoneComb[iAttrib].BoneId[i]; if (iMatrixIndex != UINT_MAX) { D3DXMATRIXA16 matTemp; D3DXMatrixMultiply( &matTemp, &pMeshContainer->m_boneOffsetMatrices[iMatrixIndex], pMeshContainer->m_boneMatrixPointers[iMatrixIndex] ); V(pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(i), &matTemp)); } } V(pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, NumBlend)); // lookup the material used for this subset of faces if ((AttribIdPrev != pBoneComb[iAttrib].AttribId) || (AttribIdPrev == UNUSED32)) { V(pd3dDevice->SetMaterial(&pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D)); V(pd3dDevice->SetTexture(0, pMeshContainer->m_textures[pBoneComb[iAttrib].AttribId])); AttribIdPrev = pBoneComb[iAttrib].AttribId; } // draw the subset now that the correct material and matrices are loaded V(pMeshContainer->MeshData.pMesh->DrawSubset(iAttrib)); } } V(pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, 0)); } else { // standard mesh, just draw it after setting material properties // ここは通らないらしい // throw acut::Exception(); V(pd3dDevice->SetTransform(D3DTS_WORLD, &pFrame->CombinedTransformationMatrix)); for (DWORD iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; ++iMaterial) { V(pd3dDevice->SetMaterial(&pMeshContainer->pMaterials[iMaterial].MatD3D)); V(pd3dDevice->SetTexture(0, pMeshContainer->m_textures[iMaterial])); V(pMeshContainer->MeshData.pMesh->DrawSubset(iMaterial)); } } }