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