#include "RenderPCH.h" #include "i3dengine.h" #include "cryheaders.h" void CLeafBuffer::AddRE(CCObject *obj, IShader *ef, int nNumSort, IShader * pStateEff) { if(!m_NumIndices || !m_pMats->Count()) return; int nGlobalShaderTemplateId = gRenDev->GetGlobalShaderTemplateId(); IShader *e; SRenderShaderResources *sr; for(int i=0; i<(*m_pMats).Count(); i++) // if(!CRenderer::CV_r_draw_phys_only || ((*m_pMats)[i].m_Flags & MIF_PHYSIC)) { if (!(*m_pMats)[i].pRE) continue; if (!ef) e = (*m_pMats)[i].shaderItem.m_pShader; else e = ef; sr = (*m_pMats)[i].shaderItem.m_pShaderResources; if (e) { assert((*m_pMats)[i].pRE->m_pChunk->nFirstIndexId<60000); if (e->GetREs()->Num()) gRenDev->EF_AddEf_NotVirtual(0, e->GetREs()->Get(0), e, sr, obj, nGlobalShaderTemplateId, pStateEff, nNumSort); else gRenDev->EF_AddEf_NotVirtual(0, (*m_pMats)[i].pRE, e, sr, obj, nGlobalShaderTemplateId, pStateEff, nNumSort); } } } void CLeafBuffer::UpdateCustomLighting(float fBackSideLevel, Vec3d vStatObjAmbientColor, const Vec3d & vLight, bool bCalcLighting) { bool bRGB = (gRenDev->GetFeatures() & RFT_RGBA) != 0; vStatObjAmbientColor*=0.5f; // compensate overbrightness to make it work same as other objects Vec3d vSunColor = iSystem->GetI3DEngine()->GetSunColor(); byte *pData = (byte *)m_pSecVertBuffer->m_VS[VSF_GENERAL].m_VData; int nPosStride = m_VertexSize[m_pSecVertBuffer->m_vertexformat]; int nNormStride, nColorStride, nInfoStride; bool * arrCullInfo = new bool[m_SecVertCount]; ushort *pInds = GetIndices(NULL); bool bWasBark = false; for(int i=0; i<(*m_pMats).Count(); i++) { if (!(*m_pMats)[i].pRE) continue; CMatInfo *mi = &(*m_pMats)[i]; IShader *ef = mi->shaderItem.m_pShader->GetTemplate(-1); int nFl = ef->GetFlags3(); bool bTwoSided; if (nFl & EF3_HASVCOLORS) bTwoSided = (nFl & EF3_HASALPHATEST) != 0; else bTwoSided = (mi->shaderItem.m_pShaderResources->m_ResFlags & MTLFLAG_2SIDED)!=0;//ef && (ef->GetCull() == e CULL_None); if (!bTwoSided) bWasBark = true; for (int j=mi->nFirstIndexId; jnNumIndices+mi->nFirstIndexId; j++) { int nIndex = pInds[j]; assert(nIndex>=0 && nIndexGet(0)->fAlpha; for(int i=0; iReleaseBuffer(m_pVertexBuffer); delete [] arrCullInfo; m_pVertexBuffer=0; } /* void CLeafBuffer::UpdateColorInBufer(const Vec3d & vColor) { byte *pData = (byte *)m_pSecVertBuffer->m_data; int nColorStride; uchar*pColor = GetColorPtr(nColorStride); for(int i=0; iReleaseBuffer(m_pVertexBuffer); m_pVertexBuffer=0; } */ void CLeafBuffer::AddRenderElements(CCObject * pObj, int DLightMask, int nTemplate, int nFogVolumeID, int nSortId, IMatInfo * pIMatInfo) { if(!m_NumIndices || !m_pMats->Count()) return; assert(m_pMats); if(nTemplate<0) { int nGlobalShaderTemplateId = gRenDev->GetGlobalShaderTemplateId(); if(nGlobalShaderTemplateId>=0) nTemplate = nGlobalShaderTemplateId; } for (int i=0; iCount(); i++) { CMatInfo * pMat = m_pMats->Get(i); // if(!pMat->nNumIndices) // stops rendering detail grass // continue; CREOcLeaf * pOrigRE = pMat->pRE; // Override object material. if (pIMatInfo) { // Assume that the root material is the first material, sub materials start from index 1. if (i == 0) pMat = (CMatInfo*)pIMatInfo; else if (i-1 < pIMatInfo->GetSubMtlCount()) pMat = (CMatInfo*)pIMatInfo->GetSubMtl(i-1); } IShader * e = pMat->shaderItem.m_pShader; SRenderShaderResources *sr = pMat->shaderItem.m_pShaderResources; if (e && pOrigRE)// && pMat->nNumIndices) { TArray *pREs = e->GetREs(); if(nTemplate < EFT_USER_FIRST) e->AddTemplate(sr, nTemplate); assert(pOrigRE->m_pChunk->nFirstIndexId<60000); if (pREs && pREs->Num()) gRenDev->EF_AddEf_NotVirtual(nFogVolumeID, pREs->Get(0), e, sr, pObj, nTemplate, 0, nSortId); else gRenDev->EF_AddEf_NotVirtual(nFogVolumeID, pOrigRE, e, sr, pObj, nTemplate, 0, nSortId); if(m_nClientTextureBindID) break; } } //i } /* void CLeafBuffer::GenerateParticles(CCObject * pObj, ParticleParams * pParticleParams) { I3DEngine * pEng = (I3DEngine *)iSystem->GetIProcess(); // spawn particles PipVertex * pDst = (PipVertex *)m_pSecVertBuffer->m_data; for(int sn=0; snnor.nz>0.5) { pParticleParams->vPosition.x = pDst->pos.x + pObj->m_Trans.x; pParticleParams->vPosition.y = pDst->pos.y + pObj->m_Trans.y; pParticleParams->vPosition.z = pDst->pos.z + pObj->m_Trans.z; pEng->SpawnParticles( *pParticleParams ); } } } */ void CLeafBuffer::Render(const SRendParams & rParams, CCObject * pObj, TArray & ShaderTemplates, int e_overlay_geometry, bool bNotCurArea, IMatInfo *pMaterial, bool bSupportDefaultShaderTemplates) { int nSortValue = (rParams.dwFObjFlags & FOB_NEAREST) ? eS_Nearest : rParams.nSortValue; CCObject * pObjTransp = NULL; for (int i=0; iCount(); i++) { CMatInfo * pMat = m_pMats->Get(i); CRendElement * pREOcLeaf = pMat->pRE; // Override default material if (pMaterial) { int nMatId = pMat->m_nCGFMaterialID; if(nMatId<0) continue; // Assume that the root material is the first material, sub materials start from index 1. if (nMatId == 0) pMat = (CMatInfo*)pMaterial; else if (nMatId-1 < pMaterial->GetSubMtlCount()) { pMat = (CMatInfo*)pMaterial->GetSubMtl(nMatId-1); } } SShader * pShader = (SShader *)pMat->shaderItem.m_pShader; SRenderShaderResources* sr = pMat->shaderItem.m_pShaderResources; if (pREOcLeaf && pShader) { int nTempl = rParams.nShaderTemplate; if (bSupportDefaultShaderTemplates && nTempl == -2 && i0) pShader->AddTemplate((SRenderShaderResources*)sr, (int&)rParams.nShaderTemplate,(const char *)NULL); if(rParams.dwFObjFlags & FOB_FOGPASS) if(pShader->mfGetTemplate(-1)->m_Flags & EF_OVERLAY) continue; // skip overlays during fog pass - it will be fogged by base geometry fog pass bool bTransparent = (pObj->m_Color.a<1.f || !(pShader->mfGetTemplate(-1)->m_Flags2 & EF2_OPAQUE) || (sr && sr->m_Opacity != 1.0f)); IShader * pStateShader = rParams.pStateShader; if(bTransparent) { if((rParams.dwFObjFlags & FOB_LIGHTPASS) || (rParams.dwFObjFlags & FOB_FOGPASS) || (nTempl == EFT_INVLIGHT)) continue; if(nSortValue==eS_FogShader) nSortValue=eS_FogShader_Trans; if(!e_overlay_geometry) { if(pShader->mfGetTemplate(-1)->m_Flags & EF_OVERLAY) continue; } else if(e_overlay_geometry >= 2 && pShader->mfGetTemplate(-1)->m_Flags & EF_OVERLAY) { if(bNotCurArea) continue; if(e_overlay_geometry == 2) { if(int(iTimer->GetCurrTime()*5)&1) pStateShader = gRenDev->EF_LoadShader("NoZTestState", eSH_World, EF_SYSTEM ); } else pStateShader = gRenDev->EF_LoadShader("ZTestGreaterState", eSH_World, EF_SYSTEM ); } if(!pObjTransp && pObj->m_DynLMMask != rParams.nStrongestDLightMask) { // make object for transparent geometry since it will use different light mask and pObjTransp = gRenDev->EF_GetObject(true); pObjTransp->CloneObject(pObj); pObjTransp->m_DynLMMask = rParams.nStrongestDLightMask; } } if( rParams.dwFObjFlags & FOB_RENDER_INTO_SHADOWMAP && (pMat->m_Flags & MIF_NOCASTSHADOWS) ) continue; if( nSortValue == EFSLIST_STENCIL && bTransparent ) gRenDev->EF_AddEf_NotVirtual(rParams.nFogVolumeID, pREOcLeaf, pShader, sr, (bTransparent&&pObjTransp) ? pObjTransp : pObj, nTempl, pStateShader, 0); else gRenDev->EF_AddEf_NotVirtual(rParams.nFogVolumeID, pREOcLeaf, pShader, sr, (bTransparent&&pObjTransp) ? pObjTransp : pObj, nTempl, pStateShader, nSortValue); } } //i } void CLeafBuffer::RenderDebugLightPass(const Matrix44 & mat, int nLightMask, float fAlpha) { int nLightsNum = 0; for(int i=0; i<32; i++) if(nLightMask & (1<EF_GetObject(true); pObj->m_Matrix = mat; IShader * pShader = gRenDev->EF_LoadShader("ObjectColor_VP",eSH_World,EF_SYSTEM); pObj->m_Color = CFColor(nLightsNum>=3,nLightsNum==2,nLightsNum==1,fAlpha); for (int i=0; iCount(); i++) { CRendElement * pREOcLeaf = m_pMats->Get(i)->pRE; if (pREOcLeaf) gRenDev->EF_AddEf_NotVirtual(0, pREOcLeaf, pShader, 0, pObj, 0); } } /* void CLeafBuffer::CopyVertices(byte * pVertsNew, int nVertFormatNew, int nNewVertsCount) { SBufInfoTable *pOffsNew = &gBufInfoTable[nVertFormatNew]; int nVertSizeNew = m_VertexSize[nVertFormatNew]; int nPosStride=0; if(byte * pPosPtr = GetPosPtr(nPosStride)) for(int i=0; iOffsColor) if(byte * pColorPtr = GetColorPtr(nColorStride)) for(int i=0; iOffsColor + nVertSizeNew*i]; int nSecColorStride=0; if(pOffsNew->OffsSecColor) if(byte * pSecColorPtr = GetSecColorPtr(nSecColorStride)) for(int i=0; iOffsSecColor + nVertSizeNew*i]; int nNormalStride=0; if(pOffsNew->OffsNormal) if(byte * pNormalPtr = GetNormalPtr(nNormalStride)) for(int i=0; iOffsNormal + nVertSizeNew*i]; int nTCStride=0; if(pOffsNew->OffsTC) if(byte * pTCPtr = GetUVPtr(nTCStride)) for(int i=0; iOffsTC + nVertSizeNew*i]; } */