LTRESULT CRenderTarget::InstallOnDevice() { if(m_pRenderTarget == NULL || m_pDepthStencilBuffer == NULL) { return LT_ERROR; } IDirect3DSurface9* pRTSurface; if(FAILED(m_pRenderTarget->GetSurfaceLevel(0, &pRTSurface))) { return LT_ERROR; } if(FAILED(PD3DDEVICE->SetRenderTarget(pRTSurface, m_pDepthStencilBuffer))) { dsi_ConsolePrint("Failed to set the new render target!"); pRTSurface->Release(); return LT_ERROR; } // We need to clear to make it a valid render target. if(FAILED(PD3DDEVICE->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DRGBA_255(0, 0, 0, 0), 1.0f, 0))) { PD3DDEVICE->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DRGBA_255(0, 0, 0, 0), 1.0f, 0); } pRTSurface->Release(); return LT_OK; }
static void d3d_SetEnvMapTextureStates(const ViewParams& Params, uint32 envMapType, LTPolyGrid* pGrid, bool bCubic) { //use the T-Factor for the overall translucency of the polygrid D3D_CALL(PD3DDEVICE->SetRenderState(D3DRS_TEXTUREFACTOR, D3DRGBA_255(255, 255, 255, pGrid->m_ColorA))); PD3DDEVICE->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE2X); PD3DDEVICE->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); PD3DDEVICE->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); PD3DDEVICE->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); PD3DDEVICE->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT); PD3DDEVICE->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); PD3DDEVICE->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); PD3DDEVICE->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_DIFFUSE); PD3DDEVICE->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); PD3DDEVICE->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE); PD3DDEVICE->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); PD3DDEVICE->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); PD3DDEVICE->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); PD3DDEVICE->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); //now we need to set up the environment map transform //get the basis vectors for world space LTVector vRight, vUp, vForward; Params.m_mView.GetBasisVectors(&vRight, &vUp, &vForward); //now setup the transpose, thus converting the normals into worldspace D3DXMATRIX mCamToWorld( vRight.x, vUp.x, vForward.x, 0.0f, vRight.y, vUp.y, vForward.y, 0.0f, vRight.z, vUp.z, vForward.z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); if(!bCubic) { //setup our texture channel 1 to generate environment maps D3DXMATRIX mTex1Trans( 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.0f, 1.0f ); mCamToWorld = mCamToWorld * mTex1Trans; } //setup our input parameters for the texture coordinates PD3DDEVICE->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, bCubic ? D3DTTFF_COUNT3 : D3DTTFF_COUNT2); PD3DDEVICE->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR | 1); //setup our texture transform PD3DDEVICE->SetTransform(D3DTS_TEXTURE1, &mCamToWorld); }
static void d3d_SetDefaultBlendStates() { //disable the fancier approach D3D_CALL(PD3DDEVICE->SetRenderState(D3DRS_TEXTUREFACTOR, D3DRGBA_255(255, 255, 255, 255))); PD3DDEVICE->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); PD3DDEVICE->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); PD3DDEVICE->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); PD3DDEVICE->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); PD3DDEVICE->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); PD3DDEVICE->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); PD3DDEVICE->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); PD3DDEVICE->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); PD3DDEVICE->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); PD3DDEVICE->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); PD3DDEVICE->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); PD3DDEVICE->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT); }
void d3d_DrawPolyGrid(const ViewParams &Params, LTObject *pObj) { //the global pixel shader to be used for the water bumpmapping and a flag indicating if //creation failed bool s_bPixelShaderFailed = false; //make sure that the polygrid is valid assert(pObj); //get our polygrid LTPolyGrid *pGrid = (LTPolyGrid*)pObj; // Make sure it's initialized. if(!pGrid->m_Data) return; //must have an index buffer if(!pGrid->m_Indices || (pGrid->m_nIndices == 0)) return; //and of course, make sure that the size is reasonable if((pGrid->m_Width < 2) || (pGrid->m_Height < 2)) return; IncFrameStat(eFS_PolyGridTriangles, pGrid->m_nTris); //cache the half dimensions float fHalfGridWidth = ((float)pGrid->m_Width - 1) * 0.5f; float fHalfGridHeight = ((float)pGrid->m_Height - 1) * 0.5f; //now we need to build our color lookup table for this polygrid, this is faster for any //polygrid that is larger than 8x8, and even then we can get a nice tight loop that //should still be rather optimal // Set the blending mode based on the flags. uint32 nSrcBlend, nDestBlend, nFog, nFogColor; d3d_GetBlendStates(pGrid, nSrcBlend, nDestBlend, nFog, nFogColor); StateSet ssSrcBlend(D3DRS_SRCBLEND, nSrcBlend); StateSet ssDestBlend(D3DRS_DESTBLEND, nDestBlend); StateSet ssFog(D3DRS_FOGENABLE, nFog); StateSet ssFogColor(D3DRS_FOGCOLOR, nFogColor); //flag indicating whether or not bool bEnvMap = false; bool bCubicEnvMap = false; bool bBumpMap = false; //vertex information uint32 nVertexSize = sizeof(CPolyGridVertex); uint32 nVertexFVF = POLYGRIDVERTEX_FORMAT; //UV scales to adjust the texture by (defaults to 1, but if we are bump mapping, this will //be set to the detail texture scale) float fPGUScale = 1.0f; float fPGVScale = 1.0f; // Set the texture if necessary. SpriteTracker* pTracker; LTPixelShader *pPixelShader = NULL; if(pGrid->m_pSprite) { pTracker = &pGrid->m_SpriteTracker; if(pTracker->m_pCurFrame) { SharedTexture* pTex = pTracker->m_pCurFrame->m_pTex; if(pTex) { //get the type of this texture ESharedTexType eTexType = pTex->m_eTexType; //the base texture SharedTexture* pBaseTex = NULL; //the environment map SharedTexture* pEnvMapTex = pGrid->m_pEnvMap; //the bumpmap SharedTexture* pBumpMapTex = NULL; //determine our texture data if(pGrid->m_nPGFlags & PG_NORMALMAPSPRITE) { //only use a bump map texture if we actually have an environment map if(pEnvMapTex) pBumpMapTex = pTex; } else { //we have a normal texture pBaseTex = pTex; } // Set up the environment mapping texture if applicable if( pEnvMapTex && g_CV_EnvMapPolyGrids.m_Val) { //see if the is a cubic environment map RTexture *pRenderTexture = (RTexture*)pEnvMapTex->m_pRenderData; if(pRenderTexture && pRenderTexture->IsCubeMap()) { bCubicEnvMap = true; } bEnvMap = true; } if( pBumpMapTex && g_CV_BumpMapPolyGrids.m_Val) { //we now need to make sure that the bump map shader is valid //see if we need to load it if (!s_bPixelShaderFailed) { // Get the pixel shader. pPixelShader = LTPixelShaderMgr::GetSingleton().GetPixelShader(LTPixelShader::PIXELSHADER_ENVBUMPMAP); if (NULL == pPixelShader) { FileRef ref; ref.m_FileType = FILE_ANYFILE; ref.m_pFilename = "ps\\envbumpmap.psh"; // Try to load it. ILTStream *pStream = g_pIClientFileMgr->OpenFile(&ref); if (NULL != pStream) { if (LTPixelShaderMgr::GetSingleton().AddPixelShader(pStream, ref.m_pFilename, LTPixelShader::PIXELSHADER_ENVBUMPMAP, true)) { pPixelShader = LTPixelShaderMgr::GetSingleton().GetPixelShader(LTPixelShader::PIXELSHADER_ENVBUMPMAP); } // Close the file. pStream->Release(); } } } // See if we can continue. if (NULL != pPixelShader && pPixelShader->IsValidShader()) { bBumpMap = true; nVertexSize = sizeof(CPolyGridBumpVertex); nVertexFVF = POLYGRIDBUMPVERTEX_FORMAT; fPGUScale = ((RTexture*)pBumpMapTex->m_pRenderData)->m_DetailTextureScale; fPGVScale = fPGUScale; } else { //we failed to create the shader, the device can't support it s_bPixelShaderFailed = true; } } //setup the textures based upon the configuration if(bBumpMap) { d3d_SetTexture(pBumpMapTex, 0, eFS_PolyGridBumpMapTexMemory); d3d_SetTexture(pEnvMapTex, 3, eFS_PolyGridEnvMapTexMemory); } else { LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { nVertexSize = sizeof(CPolyGridEffectVertex); RTexture* pRTexture = (RTexture*)pBaseTex->m_pRenderData; pD3DEffect->SetTexture("texture0", pRTexture->m_pD3DTexture); if(bEnvMap) { pRTexture = (RTexture*)pEnvMapTex->m_pRenderData; pD3DEffect->SetTexture("texture1", pRTexture->m_pD3DTexture); } } }else { d3d_SetTexture(pBaseTex, 0, eFS_PolyGridBaseTexMemory); if(bEnvMap) { d3d_SetTexture(pEnvMapTex, 1, eFS_PolyGridEnvMapTexMemory); } } } } else { //if we didn't set any texture, we need to make sure and clear out the texture //channel d3d_DisableTexture(0); } } } //specify that we were visible pGrid->m_Flags |= FLAG_INTERNAL1; // Build the vertex list. uint32 nBufferSize = pGrid->m_Width * pGrid->m_Height * nVertexSize; if(nBufferSize > g_TriVertListSize) { //we need to reallocate our list of vertices dfree(g_TriVertList); LT_MEM_TRACK_ALLOC(g_TriVertList = dalloc(nBufferSize),LT_MEM_TYPE_RENDERER); //check the allocation if(!g_TriVertList) { g_TriVertListSize = 0; return; } g_TriVertListSize = nBufferSize; } //determine if this polygrid should be lit or not bool bFresnel = (pGrid->m_nPGFlags & PG_FRESNEL) && (g_CV_FresnelPolyGrids.m_Val) ? true : false; //determine what alpha value we should use uint8 nColorAlpha = 0; if(!bEnvMap) nColorAlpha = 255; else if(!bFresnel) nColorAlpha = 128; float fScaledR = pGrid->m_ColorR * MATH_ONE_OVER_255; float fScaledG = pGrid->m_ColorG * MATH_ONE_OVER_255; float fScaledB = pGrid->m_ColorB * MATH_ONE_OVER_255; uint32 nColorTable[256]; for(uint32 nCurrColor = 0; nCurrColor < 256; nCurrColor++) { //Note that the color table is 0..255, object color is 0..255 as well nColorTable[nCurrColor] = D3DRGBA_255( pGrid->m_ColorTable[nCurrColor].x * fScaledR, pGrid->m_ColorTable[nCurrColor].y * fScaledG, pGrid->m_ColorTable[nCurrColor].z * fScaledB, nColorAlpha); } //setup our world matrix to represent a space that holds the orientation of the polygrid //as well as the center position. This allows all operations to take place //as if performed on the XZ plane (note that we don't do the scale as that tends //to mess up normals) LTMatrix mWorldTrans; LTVector vUnitScale(1.0f, 1.0f, 1.0f); d3d_SetupTransformation(&pGrid->GetPos(), (float*)&pGrid->m_Rotation, &vUnitScale, &mWorldTrans); d3d_SetD3DMat(D3DTS_WORLD, &mWorldTrans); //calculate our position increments float fXInc = pGrid->GetDims().x * 2.0f / (pGrid->m_Width - 1); float fZInc = pGrid->GetDims().z * 2.0f / (pGrid->m_Height - 1); float fYScale = pGrid->GetDims().y / 127.0f; float fXStart = -fHalfGridWidth * fXInc; float fCurrX = fXStart; float fCurrZ = -fHalfGridHeight * fZInc; int8* pDataPos = (int8*)pGrid->m_Data; int8* pDataEnd = pDataPos + pGrid->m_Width * pGrid->m_Height; int8* pLineDataEnd = pDataPos + pGrid->m_Width; uint32* pColor = nColorTable + 128; float fXScale = pGrid->m_xScale / ((pGrid->m_Width - 1) * fXInc); float fZScale = pGrid->m_yScale / ((pGrid->m_Height - 1) * fZInc); float fStartU = (float)fmod(pGrid->m_xPan * fPGUScale, 1.0f); float fStartV = (float)fmod(pGrid->m_yPan * fPGVScale, 1.0f); float fCurrU = fStartU; float fCurrV = fStartV; float fUInc = fXInc * fXScale * fPGUScale; float fVInc = fZInc * fZScale * fPGVScale; int32 nWidth = pGrid->m_Width; float fSpacingX = fXInc * 2.0f; float fSpacingZ = fZInc * 2.0f; uint32 nNumVerts; bool bEffect = false; LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { bEffect = true; } } if(bBumpMap) { CPolyGridBumpVertex* pVertexPos = (CPolyGridBumpVertex*)g_TriVertList; if(pGrid->m_pValidMask) { //this polygrid has a valid mask, meaning that we need to skip over vertices //as needed uint32* pCurrMask = pGrid->m_pValidMask; //amount to adjust the mask at the end of a line uint32 nMaskLineAdjust = (pGrid->m_Width % 32) ? 1 : 0; uint32 nShift; uint32 nNormalY1 = 0; uint32 nNormalY2 = nWidth; float fWidthTimesHeight = fSpacingX * fSpacingZ; while(pDataPos < pDataEnd) { nShift = 0x1; while(pDataPos < pLineDataEnd) { if(*pCurrMask & nShift) { //this is valid, add this vertex d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); //generate a normal for it GenerateBasisSpace(pDataPos, pVertexPos, -1, 1, nNormalY1, nNormalY2, fSpacingX, fSpacingZ, fWidthTimesHeight, fYScale); //move along to the next vertex pVertexPos++; } pDataPos++; fCurrX += fXInc; fCurrU += fUInc; if(nShift == 0x80000000) { pCurrMask++; nShift = 1; } else { nShift <<= 1; } } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; pCurrMask += nMaskLineAdjust; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; //update the normal offsets to ensure we don't go outside of our buffer nNormalY1 = -nWidth; if(pLineDataEnd >= pDataEnd) nNormalY2 = 0; } nNumVerts = pVertexPos - (CPolyGridBumpVertex*)g_TriVertList; } else { nNumVerts = pGrid->m_Width * pGrid->m_Height; while(pDataPos < pDataEnd) { while(pDataPos < pLineDataEnd) { d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); pDataPos++; pVertexPos++; fCurrX += fXInc; fCurrU += fUInc; } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; } //now we need to generate the normals for the polygrid GeneratePolyGridVectors(pGrid, (CPolyGridBumpVertex*)g_TriVertList, GenerateBasisSpace); } } else if(bEffect) { CPolyGridEffectVertex* pVertexPos = (CPolyGridEffectVertex*)g_TriVertList; if(pGrid->m_pValidMask) { //this polygrid has a valid mask, meaning that we need to skip over vertices //as needed uint32* pCurrMask = pGrid->m_pValidMask; //amount to adjust the mask at the end of a line uint32 nMaskLineAdjust = (pGrid->m_Width % 32) ? 1 : 0; uint32 nShift; uint32 nNormalY1 = 0; uint32 nNormalY2 = nWidth; float fWidthTimesHeight = fSpacingX * fSpacingZ; while(pDataPos < pDataEnd) { nShift = 0x1; while(pDataPos < pLineDataEnd) { if(*pCurrMask & nShift) { //this is valid, add this vertex d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); //generate a normal for it GenerateEffectBasisSpace(pDataPos, pVertexPos, -1, 1, nNormalY1, nNormalY2, fSpacingX, fSpacingZ, fWidthTimesHeight, fYScale); //move along to the next vertex pVertexPos++; } pDataPos++; fCurrX += fXInc; fCurrU += fUInc; if(nShift == 0x80000000) { pCurrMask++; nShift = 1; } else { nShift <<= 1; } } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; pCurrMask += nMaskLineAdjust; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; //update the normal offsets to ensure we don't go outside of our buffer nNormalY1 = -nWidth; if(pLineDataEnd >= pDataEnd) nNormalY2 = 0; } nNumVerts = pVertexPos - (CPolyGridEffectVertex*)g_TriVertList; } else { nNumVerts = pGrid->m_Width * pGrid->m_Height; while(pDataPos < pDataEnd) { while(pDataPos < pLineDataEnd) { d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); pDataPos++; pVertexPos++; fCurrX += fXInc; fCurrU += fUInc; } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; } //now we need to generate the normals for the polygrid LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { GeneratePolyGridVectors(pGrid, (CPolyGridEffectVertex*)g_TriVertList, GenerateEffectBasisSpace); } } else { GeneratePolyGridVectors(pGrid, (CPolyGridVertex*)g_TriVertList, GenerateNormal); } } } else //fixed function { CPolyGridVertex* pVertexPos = (CPolyGridVertex*)g_TriVertList; if(pGrid->m_pValidMask) { //this polygrid has a valid mask, meaning that we need to skip over vertices //as needed uint32* pCurrMask = pGrid->m_pValidMask; //amount to adjust the mask at the end of a line uint32 nMaskLineAdjust = (pGrid->m_Width % 32) ? 1 : 0; uint32 nShift; uint32 nNormalY1 = 0; uint32 nNormalY2 = nWidth; float fWidthTimesHeight = fSpacingX * fSpacingZ; while(pDataPos < pDataEnd) { nShift = 0x1; while(pDataPos < pLineDataEnd) { if(*pCurrMask & nShift) { //this is valid, add this vertex d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); //generate a normal for it GenerateNormal(pDataPos, pVertexPos, -1, 1, nNormalY1, nNormalY2, fSpacingX, fSpacingZ, fWidthTimesHeight, fYScale); //move along to the next vertex pVertexPos++; } pDataPos++; fCurrX += fXInc; fCurrU += fUInc; if(nShift == 0x80000000) { pCurrMask++; nShift = 1; } else { nShift <<= 1; } } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; pCurrMask += nMaskLineAdjust; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; //update the normal offsets to ensure we don't go outside of our buffer nNormalY1 = -nWidth; if(pLineDataEnd >= pDataEnd) nNormalY2 = 0; } nNumVerts = pVertexPos - (CPolyGridVertex*)g_TriVertList; } else { nNumVerts = pGrid->m_Width * pGrid->m_Height; while(pDataPos < pDataEnd) { while(pDataPos < pLineDataEnd) { d3d_SetupVertexPos(pVertexPos, fCurrX, *pDataPos * fYScale, fCurrZ, pColor[*pDataPos], fCurrU, fCurrV); pDataPos++; pVertexPos++; fCurrX += fXInc; fCurrU += fUInc; } //reset the line fCurrX = fXStart; //update our threshold for when to move onto the next line pLineDataEnd += pGrid->m_Width; //update our position fCurrZ += fZInc; fCurrU = fStartU; fCurrV += fVInc; } //now we need to generate the normals for the polygrid LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { GeneratePolyGridVectors(pGrid, (CPolyGridEffectVertex*)g_TriVertList, GenerateEffectBasisSpace); } } else { GeneratePolyGridVectors(pGrid, (CPolyGridVertex*)g_TriVertList, GenerateNormal); } } } // Set environment map texture coordinates. if(bEnvMap && !bBumpMap) { d3d_SetEnvMapTextureStates(Params, pTracker->m_pCurFrame->m_pTex->m_eTexType, pGrid, bCubicEnvMap); } //see if we are just doing a base texture if(!bEnvMap && !bBumpMap) { d3d_SetDefaultBlendStates(); } //generate the alpha if we can use it if(bBumpMap) { GeneratePolyGridFresnelAlphaAndCamera(Params.m_Pos, (CPolyGridBumpVertex*)g_TriVertList, pGrid, nNumVerts); } else if(bFresnel) { GeneratePolyGridFresnelAlpha(Params.m_Pos, (CPolyGridVertex*)g_TriVertList, pGrid, nNumVerts); } //make the backfacing polygons cull StateSet ssCullMode(D3DRS_CULLMODE, (pGrid->m_nPGFlags & PG_NOBACKFACECULL) ? D3DCULL_NONE : D3DCULL_CCW); //setup the pixel shader if we are bumpmapping if(bBumpMap) { assert(NULL != pPixelShader && pPixelShader->IsValidShader()); // Set the pixel shader constants. float *pConstants = pPixelShader->GetConstants(); pConstants[0] = 0.0f; pConstants[1] = 0.0f; pConstants[2] = 0.0f; pConstants[3] = pGrid->m_ColorA / 255.0f; LTPixelShaderMgr::GetSingleton().SetPixelShaderConstants(pPixelShader); // Install the pixel shader. LTPixelShaderMgr::GetSingleton().InstallPixelShader(pPixelShader); //now actually draw the polygrid D3D_CALL(PD3DDEVICE->SetVertexShader(NULL)); D3D_CALL(PD3DDEVICE->SetFVF(nVertexFVF)); int nNumPolies = (pGrid->m_nIndices/3); // Is this polygrid larger than our buffer? If so, break it into smaller patches. if(nNumPolies > g_CV_PolyGridBufferSize) { int32 nRemainingPolies = nNumPolies; uint32 nCurrentVertPosition = 0; while(nRemainingPolies > 0) { uint32 nPoliesThisFrame = (nRemainingPolies > g_CV_PolyGridBufferSize) ? g_CV_PolyGridBufferSize: nRemainingPolies; D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,nPoliesThisFrame,&pGrid->m_Indices[nCurrentVertPosition],D3DFMT_INDEX16,g_TriVertList, nVertexSize)); nCurrentVertPosition += nPoliesThisFrame*3; nRemainingPolies -= nPoliesThisFrame; } } else { D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,(pGrid->m_nIndices)/3,pGrid->m_Indices,D3DFMT_INDEX16,g_TriVertList, nVertexSize)); } // Uninstall the pixel shader. LTPixelShaderMgr::GetSingleton().UninstallPixelShader(); d3d_DisableTexture(0); d3d_DisableTexture(3); } else { //now actually draw the polygrid D3D_CALL(PD3DDEVICE->SetVertexShader(NULL)); D3D_CALL(PD3DDEVICE->SetFVF(nVertexFVF)); int nNumPolies = (pGrid->m_nIndices/3); // Is this polygrid larger than our buffer? If so, break it into smaller patches. if(nNumPolies > g_CV_PolyGridBufferSize) { int32 nRemainingPolies = nNumPolies; uint32 nCurrentVertPosition = 0; while(nRemainingPolies > 0) { uint32 nPoliesThisFrame = (nRemainingPolies > g_CV_PolyGridBufferSize) ? g_CV_PolyGridBufferSize: nRemainingPolies; LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { pEffect->UploadVertexDeclaration(); ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { i_client_shell->OnEffectShaderSetParams(pEffect, NULL, NULL, LTShaderDeviceStateImp::GetSingleton()); UINT nPasses = 0; pD3DEffect->Begin(&nPasses, 0); for(UINT i = 0; i < nPasses; ++i) { pD3DEffect->BeginPass(i); D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,nPoliesThisFrame,&pGrid->m_Indices[nCurrentVertPosition],D3DFMT_INDEX16,g_TriVertList, nVertexSize)); pD3DEffect->EndPass(); } pD3DEffect->End(); } } else { D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,nPoliesThisFrame,&pGrid->m_Indices[nCurrentVertPosition],D3DFMT_INDEX16,g_TriVertList, nVertexSize)); } nCurrentVertPosition += nPoliesThisFrame*3; nRemainingPolies -= nPoliesThisFrame; } } else { LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pGrid->m_nEffectShaderID); if(pEffect) { pEffect->UploadVertexDeclaration(); ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { i_client_shell->OnEffectShaderSetParams(pEffect, NULL, NULL, LTShaderDeviceStateImp::GetSingleton()); UINT nPasses = 0; pD3DEffect->Begin(&nPasses, 0); for(UINT i = 0; i < nPasses; ++i) { pD3DEffect->BeginPass(i); D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,(pGrid->m_nIndices)/3,pGrid->m_Indices,D3DFMT_INDEX16,g_TriVertList, nVertexSize)); pD3DEffect->EndPass(); } pD3DEffect->End(); } } else { // No Effect Shader, just fixed function. D3D_CALL(PD3DDEVICE->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,0,nNumVerts,(pGrid->m_nIndices)/3,pGrid->m_Indices,D3DFMT_INDEX16,g_TriVertList, nVertexSize)); } } d3d_DisableTexture(0); d3d_DisableTexture(1); } if (bEnvMap) d3d_UnsetEnvMapTextureStates(); //reset our world transform so that it won't mess up the rendering of other objects d3d_SetD3DMat(D3DTS_WORLD, &Params.m_mIdentity); }