/*============================================================================= EvalFuncs_RE.cpp : RE specific effectors pipeline implementation. Copyright 2001 Crytek Studios. All Rights Reserved. Revision history: * Created by Honitch Andrey =============================================================================*/ #include "RenderPCH.h" #include "shadow_renderer.h" #include #undef THIS_FILE static char THIS_FILE[] = __FILE__; #ifdef WIN64 #pragma warning( push ) //AMD Port #pragma warning( disable : 4311 ) // 'type cast' : pointer truncation from 'byte *' to 'int' #endif //============================================================================ _inline void Deform(float val, float* vrt, float *norm) { vrt[0] += val * norm[0]; vrt[1] += val * norm[1]; vrt[2] += val * norm[2]; } void SEvalFuncs_RE::WaveDeform(SDeform *df) { int i, val; float f; int Str, StrNRM; byte *verts = (byte *)gRenDev->EF_GetPointer(eSrcPointer_Vert, &Str, GL_FLOAT, eSrcPointer_Vert, FGP_REAL | FGP_WAIT); byte *norms = (byte *)gRenDev->EF_GetPointer(eSrcPointer_TNormal, &StrNRM, GL_FLOAT, eSrcPointer_TNormal, FGP_SRC | FGP_REAL); if ((int)verts < 256) return; gRenDev->m_RP.m_pRE->mfUpdateFlags(FCEF_MODIF_VERT); int nv = gRenDev->m_RP.m_RendNumVerts; float *WaveTable; switch (df->m_DeformGen.m_eWFType) { case eWF_Sin: default: WaveTable = gRenDev->m_RP.m_tSinTable; break; case eWF_Triangle: WaveTable = gRenDev->m_RP.m_tTriTable; break; case eWF_Square: WaveTable = gRenDev->m_RP.m_tSquareTable; break; case eWF_SawTooth: WaveTable = gRenDev->m_RP.m_tSawtoothTable; break; case eWF_InvSawTooth: WaveTable = gRenDev->m_RP.m_tInvSawtoothTable; break; case eWF_Hill: WaveTable = gRenDev->m_RP.m_tHillTable; break; } for (i=0; im_ScaleVerts + gRenDev->m_RP.m_RealTime*df->m_DeformGen.m_Freq + df->m_DeformGen.m_Phase; f *= 1024.0; val = QRound(f); f = df->m_DeformGen.m_Amp * CRenderer::CV_r_wavescale * WaveTable[val&0x3ff] + df->m_DeformGen.m_Level; Deform(f, v, vnrm); } } static int sTrisIndsToPolyInds(ushort *indsSrc, int nInds, int nVerts, ushort *indsDst) { int i, j, ii, jj, n; indsDst[0] = indsSrc[0]; int nTris = nInds / 3; int nDstVerts = 1; do { for (i=0; iEF_GetPointer(eSrcPointer_Vert, &Str, GL_FLOAT, eSrcPointer_Vert, FGP_SRC); // [Sergiy] Probably because the characters don't have system buffers, // this is NULL for C:\MASTERCD\Objects\glm\ww2_indust_set1\lights\light_indust3\light_indust3.cgf if (!vbSrc) return; int nv = rd->m_RP.m_RendNumVerts; if (rd->m_RP.m_pRE->mfGetType() != eDATA_OcLeaf) return; if (!CRenderer::CV_r_procflares) { rd->m_RP.m_pRE = NULL; rd->m_RP.m_RendNumIndices = 0; rd->m_RP.m_RendNumVerts = 0; return; } CREOcLeaf *re = (CREOcLeaf *)rd->m_RP.m_pRE; if ((nv != 4 && nv != 6) || re->m_pChunk->nNumIndices != 6) return; Vec3d vbSrcData[4]; ushort *indsS = &re->m_pBuffer->GetIndices(NULL)[re->m_pChunk->nFirstIndexId]; if (nv == 6) { for (i=0; i<3; i++) { vbSrcData[i] = *(Vec3d *)(&vbSrc[(i+re->m_pChunk->nFirstVertId)*Str]); } vbSrcData[i] = *(Vec3d *)(&vbSrc[(3+re->m_pChunk->nFirstVertId)*Str]); } else { for (i=0; i<4; i++) { vbSrcData[i] = *(Vec3d *)(&vbSrc[(i+re->m_pChunk->nFirstVertId)*Str]); } } int n = rd->m_RP.m_CurTempMeshes->Num(); rd->m_RP.m_CurTempMeshes->GrowReset(1); CRETempMesh *tm = rd->m_RP.m_CurTempMeshes->Get(n); if (!tm) { tm = new CRETempMesh; rd->m_RP.m_CurTempMeshes->Get(n) = tm; } assert (!tm->m_VBuffer); tm->m_VBuffer = rd->CreateBuffer(16, VERTEX_FORMAT_P3F_COL4UB_TEX2F, "CRETempMesh", true); rd->CreateIndexBuffer(&tm->m_Inds, &sFlareIndices[0][0], 54); rd->m_RP.m_pRE = tm; ushort indsSrc[6]; if (nv == 6) { indsSrc[0] = 0; indsSrc[1] = 1; indsSrc[2] = 2; indsSrc[3] = 3; indsSrc[4] = 2; indsSrc[5] = 1; nv = 4; } else { for (i=0; i<6; i++) { indsSrc[i] = indsS[i] - re->m_pChunk->nFirstVertId; } } /*for (i=0; i<2; i++) { Exchange(indsSrc[i*3+0], indsSrc[i*3+2]); }*/ struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vbDstData = new struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F[16]; Vec3d v0 = vbSrcData[indsSrc[2]] - vbSrcData[indsSrc[1]]; Vec3d v1 = vbSrcData[indsSrc[0]] - vbSrcData[indsSrc[1]]; Vec3d vCross = v0.Cross(v1); float fDot = vCross.Dot(vCross); float fLen = cry_sqrtf(fDot); vCross *= 1.0f / fLen; if (vCross.x == 0 && vCross.y == 0) { if (vCross.z <= 0) vCross.z = -1.0f; else vCross.z = 1.0f; } else if (vCross.x == 0 && vCross.z == 0) { if (vCross.y <= 0) vCross.y = -1.0f; else vCross.y = 1.0f; } else if (vCross.y == 0 && vCross.z == 0) { if (vCross.x <= 0) vCross.x = -1.0f; else vCross.x = 1.0f; } else { if (fabs(vCross.x) == 1.0f) { vCross.y = 0; vCross.z = 0; } else if (fabs(vCross.y) == 1.0f) { vCross.x = 0; vCross.z = 0; } else if (fabs(vCross.z) == 1.0f) { vCross.x = 0; vCross.y = 0; } } float f = -vCross.Dot(vbSrcData[indsSrc[1]]); Vec3d vOrg; SCoord crd; Matrix44 mat = rd->m_RP.m_pCurObject->GetInvMatrix(); TransformPosition(vOrg, rd->m_RP.m_ViewOrg, mat); fDot = vOrg.Dot(vCross) + f; if (fDot <= 0) { gRenDev->ReleaseIndexBuffer(&tm->m_Inds); delete [] vbDstData; rd->m_RP.m_RendNumIndices = 0; rd->m_RP.m_RendNumVerts = 0; return; } Vec3d v = vbSrcData[0]; for (i=1; i 1.0f) fIntens = 1.0f; SShader *lsh = rd->m_RP.m_pShader; float r, g, b; r = g = b = fIntens; if (lsh && lsh->m_EvalLights) { SLightEval *le = lsh->m_EvalLights; if (le->m_LightStyle && le->m_LightStyleGetCurrTime(); CLightStyle *ls = CLightStyle::m_LStyles[le->m_LightStyle]; ls->mfUpdate(fTime); switch (le->m_EStyleType) { case eLS_Intensity: default: r = fIntens * ls->m_fIntensity; g = fIntens * ls->m_fIntensity; b = fIntens * ls->m_fIntensity; break; case eLS_RGB: r = ls->m_Color.r * fIntens; g = ls->m_Color.g * fIntens; b = ls->m_Color.b * fIntens; break; } } } if (gRenDev->m_RP.m_pShaderResources && gRenDev->m_RP.m_pShaderResources->m_LMaterial) { r *= gRenDev->m_RP.m_pShaderResources->m_LMaterial->Front.m_Ambient.r; g *= gRenDev->m_RP.m_pShaderResources->m_LMaterial->Front.m_Ambient.g; b *= gRenDev->m_RP.m_pShaderResources->m_LMaterial->Front.m_Ambient.b; } r = CLAMP(r, 0.0f, 1.0f); g = CLAMP(g, 0.0f, 1.0f); b = CLAMP(b, 0.0f, 1.0f); byte br = (byte)(r*255.0f); byte bg = (byte)(g*255.0f); byte bb = (byte)(b*255.0f); for (i=0; im_VBuffer->m_NumVerts; i++) { if (!gRenDev->m_TexMan->m_bRGBA) { vbDstData[i].color.bcolor[0] = bb; vbDstData[i].color.bcolor[1] = bg; vbDstData[i].color.bcolor[2] = br; vbDstData[i].color.bcolor[3] = 255; } else { vbDstData[i].color.bcolor[2] = br; vbDstData[i].color.bcolor[1] = bg; vbDstData[i].color.bcolor[0] = bb; vbDstData[i].color.bcolor[3] = 255; } } float flareSize = df->m_fFlareSize * CRenderer::CV_r_flaresize; ushort iPolyInds[16]; int m = sTrisIndsToPolyInds(indsSrc, re->m_pChunk->nNumIndices, nv, iPolyInds); if (m != 4) { gRenDev->ReleaseIndexBuffer(&tm->m_Inds); delete [] vbDstData; rd->m_RP.m_RendNumIndices = 0; rd->m_RP.m_RendNumVerts = 0; return; } Vec3d vFlareVecs[4][3]; for (i=0; i<4; i++) { int n = 3-i; vbDstData[i].xyz = vbSrcData[iPolyInds[i]]; vbDstData[i].st[0] = 0.5f; vbDstData[i].st[1] = 0.5f; Vec3d v0 = vbSrcData[iPolyInds[i]] - vOrg; v0.Normalize(); Vec3d v1 = vbSrcData[iPolyInds[(i+1)%4]] - vOrg; v1.Normalize(); vFlareVecs[i][1] = v1.Cross(v0); vFlareVecs[i][1].Normalize(); vFlareVecs[i][1].Flip(); Vec3d v2 = vbSrcData[iPolyInds[(i+3)%4]] - vOrg; v2.Normalize(); vFlareVecs[i][0] = v2.Cross(v0); vFlareVecs[i][0].Normalize(); vFlareVecs[i][2] = vFlareVecs[i][0] + vFlareVecs[i][1]; vFlareVecs[i][2].Normalize(); } vbDstData[4].xyz = vFlareVecs[0][0] * flareSize + vbSrcData[iPolyInds[0]]; vbDstData[5].xyz = vFlareVecs[0][2] * flareSize + vbSrcData[iPolyInds[0]]; vbDstData[6].xyz = vFlareVecs[0][1] * flareSize + vbSrcData[iPolyInds[0]]; vbDstData[7].xyz = vFlareVecs[1][0] * flareSize + vbSrcData[iPolyInds[1]]; vbDstData[8].xyz = vFlareVecs[1][2] * flareSize + vbSrcData[iPolyInds[1]]; vbDstData[9].xyz = vFlareVecs[1][1] * flareSize + vbSrcData[iPolyInds[1]]; vbDstData[10].xyz = vFlareVecs[2][0] * flareSize + vbSrcData[iPolyInds[2]]; vbDstData[11].xyz = vFlareVecs[2][2] * flareSize + vbSrcData[iPolyInds[2]]; vbDstData[12].xyz = vFlareVecs[2][1] * flareSize + vbSrcData[iPolyInds[2]]; vbDstData[13].xyz = vFlareVecs[3][0] * flareSize + vbSrcData[iPolyInds[3]]; vbDstData[14].xyz = vFlareVecs[3][2] * flareSize + vbSrcData[iPolyInds[3]]; vbDstData[15].xyz = vFlareVecs[3][1] * flareSize + vbSrcData[iPolyInds[3]]; for (i=0; i<12; i++) { vDir = vbDstData[i+4].xyz - vOrg; float fLength = vDir.Length(); vDir *= 1.0f / fLength; float f = -(fDot / vDir.Dot(vCross)); if (f > 0 && fLength > f) { v = vOrg + vDir * f; vbDstData[i+4].xyz = v; } vbDstData[i+4].st[0] = 0; vbDstData[i+4].st[1] = 0.5f; } rd->UpdateBuffer(tm->m_VBuffer, vbDstData, 16, true); delete [] vbDstData; rd->m_RP.m_FirstVertex = 0; rd->m_RP.m_FirstIndex = 0; rd->m_RP.m_RendNumIndices = 54; rd->m_RP.m_RendNumVerts = 16; #if defined (DIRECT3D8) || defined (DIRECT3D9) rd->m_RP.m_CurVFormat = VERTEX_FORMAT_P3F_COL4UB_TEX2F; #endif } void SEvalFuncs_RE::BeamDeform(SDeform *df) { int StrV, StrN, StrT, i; CRenderer *rd = gRenDev; byte *vbV = (byte *)rd->EF_GetPointer(eSrcPointer_Vert, &StrV, GL_FLOAT, eSrcPointer_Vert, FGP_SRC); byte *vbN = (byte *)rd->EF_GetPointer(eSrcPointer_Normal, &StrN, GL_FLOAT, eSrcPointer_Normal, FGP_SRC); byte *vbT = (byte *)rd->EF_GetPointer(eSrcPointer_Tex, &StrT, GL_FLOAT, eSrcPointer_Tex, FGP_SRC); // [Sergiy] Probably because the characters don't have system buffers, // this is NULL for C:\MASTERCD\Objects\glm\ww2_indust_set1\lights\light_indust3\light_indust3.cgf if (!vbV || !vbN || !vbT || !CRenderer::CV_r_beams || !rd->m_RP.m_pRE || rd->m_RP.m_pRE->mfGetType() != eDATA_OcLeaf) { rd->m_RP.m_pRE = NULL; rd->m_RP.m_RendNumIndices = 0; rd->m_RP.m_RendNumVerts = 0; return; } int nv = rd->m_RP.m_RendNumVerts; int ni = rd->m_RP.m_RendNumIndices; CREOcLeaf *pRE = (CREOcLeaf *)rd->m_RP.m_pRE; CLeafBuffer *pLB = pRE->m_pBuffer; int n = rd->m_RP.m_CurTempMeshes->Num(); rd->m_RP.m_CurTempMeshes->GrowReset(1); CRETempMesh *tm = rd->m_RP.m_CurTempMeshes->Get(n); if (!tm) { tm = new CRETempMesh; rd->m_RP.m_CurTempMeshes->Get(n) = tm; } assert (!tm->m_VBuffer); tm->m_VBuffer = rd->CreateBuffer(nv, VERTEX_FORMAT_P3F_COL4UB_TEX2F, "CRETempMesh", true); rd->CreateIndexBuffer(&tm->m_Inds, &pLB->m_SecIndices[0], ni); rd->m_RP.m_pRE = tm; CFColor StartColor, EndColor; Vec3d CameraPos; SParamComp_User pu; pu.m_Name = "startcolor[0]"; StartColor[0] = pu.mfGet(); pu.m_Name = "startcolor[1]"; StartColor[1] = pu.mfGet(); pu.m_Name = "startcolor[2]"; StartColor[2] = pu.mfGet(); pu.m_Name = "startcolor[3]"; StartColor[3] = pu.mfGet(); pu.m_Name = "endcolor[0]"; EndColor[0] = pu.mfGet(); pu.m_Name = "endcolor[1]"; EndColor[1] = pu.mfGet(); pu.m_Name = "endcolor[2]"; EndColor[2] = pu.mfGet(); pu.m_Name = "endcolor[3]"; EndColor[3] = pu.mfGet(); Matrix44& im = rd->m_RP.m_pCurObject->GetInvMatrix(); TransformPosition(CameraPos, rd->m_RP.m_ViewOrg, im); pu.m_Name = "origlength"; float OrigLength = pu.mfGet(); pu.m_Name = "origwidth"; float OrigWidth = pu.mfGet(); pu.m_Name = "startradius"; float StartRadius = pu.mfGet(); pu.m_Name = "endradius"; float EndRadius = pu.mfGet(); pu.m_Name = "length"; float Length = pu.mfGet(); float fiOrigLength = 1.0f/OrigLength; float fiOrigWidth = 1.0f/OrigWidth; struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F *vbDst = new struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F [nv]; for (i=0; ix/OrigLength float fLerp = vPos->x * fiOrigLength; vbDst[i].xyz.x = fLerp * Length; float fCurRadius = LERP(StartRadius, EndRadius, fLerp); vbDst[i].xyz.y = vPos->y * fiOrigWidth * fCurRadius; vbDst[i].xyz.z = vPos->z * fiOrigWidth * fCurRadius; CFColor color = LERP(StartColor, EndColor, fLerp); color.Clamp(); Vec3 camVec = CameraPos - *vPos; camVec.Normalize(); float d = camVec.Dot(*vNormal); d = d * d; d *= min(fLerp*10.0f, 1.0f); color.a = color.a * d; if (gbRgb) { vbDst[i].color.bcolor[0] = (byte)(color.r*255.0f); vbDst[i].color.bcolor[1] = (byte)(color.g*255.0f); vbDst[i].color.bcolor[2] = (byte)(color.b*255.0f); vbDst[i].color.bcolor[3] = (byte)(color.a*255.0f); } else { vbDst[i].color.bcolor[2] = (byte)(color.r*255.0f); vbDst[i].color.bcolor[1] = (byte)(color.g*255.0f); vbDst[i].color.bcolor[0] = (byte)(color.b*255.0f); vbDst[i].color.bcolor[3] = (byte)(color.a*255.0f); } vbDst[i].st[0] = *(float *)(vbT+0); vbDst[i].st[1] = *(float *)(vbT+4); } rd->UpdateBuffer(tm->m_VBuffer, vbDst, nv, true); delete [] vbDst; rd->m_RP.m_FirstVertex = 0; rd->m_RP.m_FirstIndex = 0; #if defined (DIRECT3D8) || defined (DIRECT3D9) rd->m_RP.m_CurVFormat = VERTEX_FORMAT_P3F_COL4UB_TEX2F; #endif } void SEvalFuncs_RE::VerticalWaveDeform(SDeform *df) { int i, val; float f; int Str; byte *verts = (byte *)gRenDev->EF_GetPointer(eSrcPointer_Vert, &Str, GL_FLOAT, eSrcPointer_Vert, FGP_REAL | FGP_WAIT); if ((int)verts < 256) return; gRenDev->m_RP.m_pRE->mfUpdateFlags(FCEF_MODIF_VERT); int nv = gRenDev->m_RP.m_RendNumVerts; float *WaveTable; switch (df->m_DeformGen.m_eWFType) { case eWF_Sin: default: WaveTable = gRenDev->m_RP.m_tSinTable; break; case eWF_Triangle: WaveTable = gRenDev->m_RP.m_tTriTable; break; case eWF_Square: WaveTable = gRenDev->m_RP.m_tSquareTable; break; case eWF_SawTooth: WaveTable = gRenDev->m_RP.m_tSawtoothTable; break; case eWF_InvSawTooth: WaveTable = gRenDev->m_RP.m_tInvSawtoothTable; break; case eWF_Hill: WaveTable = gRenDev->m_RP.m_tHillTable; break; } for (i=0; im_ScaleVerts + gRenDev->m_RP.m_RealTime*df->m_DeformGen.m_Freq + df->m_DeformGen.m_Phase; f *= 1024.0; val = QRound(f); f = df->m_DeformGen.m_Amp * CRenderer::CV_r_wavescale * WaveTable[val&0x3ff] + df->m_DeformGen.m_Level; Deform(f, v, vnrm); } } void SEvalFuncs_RE::SqueezeDeform(SDeform *df) { int i; float f; int Str, StrNRM; byte *verts = (byte *)gRenDev->EF_GetPointer(eSrcPointer_Vert, &Str, GL_FLOAT, eSrcPointer_Vert, FGP_REAL | FGP_WAIT); if ((int)verts < 256) return; byte *norms = (byte *)gRenDev->EF_GetPointer(eSrcPointer_TNormal, &StrNRM, GL_FLOAT, eSrcPointer_TNormal, FGP_SRC | FGP_REAL); gRenDev->m_RP.m_pRE->mfUpdateFlags(FCEF_MODIF_VERT); int nv = gRenDev->m_RP.m_RendNumVerts; f = EvalWaveForm(&df->m_DeformGen); for (i=0; iEF_GetPointer(eSrcPointer_Vert, &Str, GL_FLOAT, eSrcPointer_Vert, FGP_REAL | FGP_WAIT); if ((int)verts < 256) return; byte *norms = (byte *)gRenDev->EF_GetPointer(eSrcPointer_TNormal, &StrNRM, GL_FLOAT, eSrcPointer_TNormal, FGP_SRC | FGP_REAL); byte *tc = (byte *)gRenDev->EF_GetPointer(eSrcPointer_Tex, &StrTC, GL_FLOAT, eSrcPointer_Tex, FGP_SRC | FGP_REAL); gRenDev->m_RP.m_pRE->mfUpdateFlags(FCEF_MODIF_VERT); int nv = gRenDev->m_RP.m_RendNumVerts; for (i=0; im_ScaleVerts + df->m_DeformGen.m_Phase + gRenDev->m_RP.m_RealTime*df->m_DeformGen.m_Freq; f *= 1024; val = QRound(f); val &= 0x3ff; f = df->m_DeformGen.m_Amp * CRenderer::CV_r_wavescale * gRenDev->m_RP.m_tSinTable[val] + df->m_DeformGen.m_Level; v[0] += f * n[0]; v[1] += f * n[1]; v[2] += f * n[2]; } } //================================================================================================== // Texture coords generate void SEvalFuncs_RE::ETC_Environment(int ns) { int i; float f, d; Vec3d v; int StrTC; int Str, StrNRM; byte *ptr = (byte *)gRenDev->EF_GetPointer((ESrcPointer)(eSrcPointer_Tex+ns), &StrTC, GL_FLOAT, (ESrcPointer)(eSrcPointer_Tex+ns), FGP_REAL | FGP_WAIT); if ((int)ptr < 256) return; byte *norms = (byte *)gRenDev->EF_GetPointer(eSrcPointer_TNormal, &StrNRM, GL_FLOAT, eSrcPointer_TNormal, FGP_SRC | FGP_REAL); byte *verts = (byte *)gRenDev->EF_GetPointer(eSrcPointer_Vert, &Str, GL_FLOAT, eSrcPointer_Vert, FGP_SRC | FGP_REAL); int nv = gRenDev->m_RP.m_RendNumVerts; gRenDev->m_RP.m_pRE->mfUpdateFlags(FCEF_MODIF_TC); Vec3d oTr = gRenDev->m_RP.m_pCurObject->GetTranslation(); for (i=0; im_RP.m_pCurObject; float r00 = gRenDev->m_ViewMatrix(0,0), r01 = gRenDev->m_ViewMatrix(0,1), r02 = gRenDev->m_ViewMatrix(0,2); float r10 = gRenDev->m_ViewMatrix(1,0), r11 = gRenDev->m_ViewMatrix(1,1), r12 = gRenDev->m_ViewMatrix(1,2); float r20 = gRenDev->m_ViewMatrix(2,0), r21 = gRenDev->m_ViewMatrix(2,1), r22 = gRenDev->m_ViewMatrix(2,2); // Loop through the vertices, transforming each one and calculating // the correct texture coordinates. int StrTC, StrNRM; byte *ptr = (byte *)gRenDev->EF_GetPointer((ESrcPointer)(eSrcPointer_Tex+ns), &StrTC, GL_FLOAT, (ESrcPointer)(eSrcPointer_Tex+ns), FGP_REAL | FGP_WAIT); if ((int)ptr < 256) return; byte *norms = (byte *)gRenDev->EF_GetPointer(eSrcPointer_TNormal, &StrNRM, GL_FLOAT, eSrcPointer_TNormal, FGP_SRC | FGP_REAL); int nv = gRenDev->m_RP.m_RendNumVerts; gRenDev->m_RP.m_pRE->mfUpdateFlags(FCEF_MODIF_TC); for( i=0; i 0.0f ) // continue; // Assign the spheremap's texture coordinates *(float *)(ptr) = 0.5f * ( 1.0f + ( nx*r00 + ny*r10 + nz*r20 ) ); *(float *)(ptr+4) = 0.5f * ( 1.0f - ( nx*r01 + ny*r11 + nz*r21 ) ); } } void SEvalFuncs_RE::ETC_SphereMapEnvironment(int ns) { int i; SCoord c; float r00 = gRenDev->m_RP.m_pCurObject->m_Matrix(0,0), r01 = gRenDev->m_RP.m_pCurObject->m_Matrix(0,1), r02 = gRenDev->m_RP.m_pCurObject->m_Matrix(0,2); float r10 = gRenDev->m_RP.m_pCurObject->m_Matrix(1,0), r11 = gRenDev->m_RP.m_pCurObject->m_Matrix(1,1), r12 = gRenDev->m_RP.m_pCurObject->m_Matrix(1,2); float r20 = gRenDev->m_RP.m_pCurObject->m_Matrix(2,0), r21 = gRenDev->m_RP.m_pCurObject->m_Matrix(2,1), r22 = gRenDev->m_RP.m_pCurObject->m_Matrix(2,2); // Loop through the vertices, transforming each one and calculating // the correct texture coordinates. int StrTC, StrNRM; byte *ptr = (byte *)gRenDev->EF_GetPointer((ESrcPointer)(eSrcPointer_Tex+ns), &StrTC, GL_FLOAT, (ESrcPointer)(eSrcPointer_Tex+ns), FGP_REAL | FGP_WAIT); if ((int)ptr < 256) return; byte *norms = (byte *)gRenDev->EF_GetPointer(eSrcPointer_TNormal, &StrNRM, GL_FLOAT, eSrcPointer_TNormal, FGP_SRC | FGP_REAL); int nv = gRenDev->m_RP.m_RendNumVerts; gRenDev->m_RP.m_pRE->mfUpdateFlags(FCEF_MODIF_TC); for( i=0; i 0.0f ) // continue; // Assign the spheremap's texture coordinates *(float *)(ptr) = 0.5f * ( 1.0f + ( nx*r00 + ny*r10 + nz*r20 ) ); *(float *)(ptr+4) = 0.5f * ( 1.0f - ( nx*r01 + ny*r11 + nz*r21 ) ); } } void SEvalFuncs_RE::ETC_ShadowMap(int ns) { CRenderer *rd = gRenDev; rd->m_RP.m_pRE->m_CustomTexBind[ns] = -1; if (!rd->m_RP.m_pCurObject) return; assert(rd->m_RP.m_FlagsPerFlush & RBSI_SHADOWPASS); int nsFrust; if (rd->m_RP.m_pShader->m_eSort == eS_TerrainShadowPass) nsFrust = 0; else nsFrust = ns + rd->m_RP.m_nCurStartCaster; list2 * lsources = (list2*)rd->m_RP.m_pCurObject->m_pShadowCasters; // bool bActiveShadowReceiving = false; // skip this stage if this entity was used to create this shadow map if(!lsources || nsFrust>=lsources->Count()) { if(!lsources) Warning( 0,0,"Warning: SEvalFuncs_RE::ETC_ShadowMap: !lsources"); else if(nsFrustCount()) Warning( 0,0,"Warning: SEvalFuncs_RE::ETC_ShadowMap: nsFrustCount()"); if ((rd->GetFeatures() & RFT_SHADOWMAP_SELFSHADOW) && !(rd->GetFeatures() & RFT_DEPTHMAPS)) rd->m_RP.m_pRE->m_CustomTexBind[ns] = rd->m_TexMan->m_Text_Depth->m_Bind; else rd->m_RP.m_pRE->m_CustomTexBind[ns] = rd->m_TexMan->m_Text_WhiteShadow->m_Bind; if ((rd->GetFeatures() & RFT_SHADOWMAP_SELFSHADOW) && !(rd->GetFeatures() & RFT_DEPTHMAPS)) { Matrix44 *mt = &rd->m_cEF.m_TempMatrices[ns][7]; mt->SetIdentity(); } rd->SelectTMU(0); return; // cancel this stage } if(!(*lsources)[nsFrust].m_pLS) return; // get projection frustum ShadowMapFrustum * pShadowMapFrustum = (*lsources)[nsFrust].m_pLS->GetShadowMapFrustum(0); // if(bActiveShadowReceiving) // pShadowMapFrustum = (*lsources)[nsFrust].m_pLS->GetShadowMapFrustumPassiveCasters(0); if(!pShadowMapFrustum) return; // detect usage of same lsource second time -> use penumbra frustum if( nsFrust>0 && (*lsources)[nsFrust].m_pLS == (*lsources)[nsFrust-1].m_pLS && pShadowMapFrustum->pPenumbra) pShadowMapFrustum = pShadowMapFrustum->pPenumbra; Matrix44 *m = NULL; Vec3d vObjTrans; if (rd->m_RP.m_ObjFlags & FOB_TRANS_MASK) { m = &gRenDev->m_RP.m_pCurObject->m_Matrix; vObjTrans = rd->m_RP.m_pCurObject->GetTranslation(); } else vObjTrans = Vec3(0,0,0); // setup projection gRenDev->SetupShadowOnlyPass(ns, pShadowMapFrustum, &((*lsources)[nsFrust].m_vProjTranslation), (*lsources)[nsFrust].m_fProjScale, vObjTrans, 1.f, Vec3d(0,0,0), m); } void SEvalFuncs_RE::ETC_Projection(int ns, float *Mat, float wdt, float hgt) { int i; int Str, StrTC; byte *ptr = (byte *)gRenDev->EF_GetPointer((ESrcPointer)(eSrcPointer_Tex+ns), &StrTC, GL_FLOAT, (ESrcPointer)(eSrcPointer_Tex+ns), FGP_REAL | FGP_WAIT); if ((int)ptr < 256) return; byte *verts = (byte *)gRenDev->EF_GetPointer(eSrcPointer_Vert, &Str, GL_FLOAT, eSrcPointer_Vert, FGP_SRC | FGP_REAL); int nv = gRenDev->m_RP.m_RendNumVerts; Vec3d Pos = gRenDev->m_RP.m_pCurObject->GetTranslation(); for (i=0; iEF_GetPointer(eSrcPointer_Vert, &StrV, GL_FLOAT, eSrcPointer_Vert, FGP_NOCALC | FGP_SRC | FGP_REAL); if ((int)verts < 256) return; byte *norms = (byte *)gRenDev->EF_GetPointer(eSrcPointer_TNormal, &StrN, GL_FLOAT, eSrcPointer_TNormal, FGP_NOCALC | FGP_SRC | FGP_REAL); if (RefractIndex < -1000.0f || RefractIndex > 1000.0f) RefractIndex = 0; int numVerts = gRenDev->m_RP.m_RendNumVerts; RefractIndex = CLAMP(RefractIndex, -5.0f, 5.0f); if (type == GL_UNSIGNED_BYTE) { } else if (type == GL_FLOAT) { for (int i=0; im_RP.m_pCurObject; if (!obj) return; CDLight *dl; for (i=0; im_RP.m_DLights[SRendItem::m_RecurseLevel].Num(); i++) { dl = gRenDev->m_RP.m_DLights[SRendItem::m_RecurseLevel][i]; if (dl->m_pObject[0][0] == obj) break; } if (i == gRenDev->m_RP.m_DLights[SRendItem::m_RecurseLevel].Num()) return; Vec3d Pos; CCamera cam = gRenDev->GetCamera(); Vec3d p = cam.GetPos(); TransformPosition(Pos, p, gRenDev->m_RP.m_pCurObject->GetInvMatrix()); Vec3d lightForWard = Vec3d(1,0,0); //dl->m_Orientation.m_vForward; CREBeam *rb = (CREBeam *)obj->m_RE; if (!rb) return; int StrRGBA; int Str, StrVD, StrNRM; byte *ptr = (byte *)gRenDev->EF_GetPointer(eSrcPointer_Color, &StrRGBA, GL_BYTE, eSrcPointer_Color, FGP_REAL | FGP_WAIT); if ((int)ptr < 256) return; byte *norms = (byte *)gRenDev->EF_GetPointer(eSrcPointer_TNormal, &StrNRM, GL_FLOAT, eSrcPointer_TNormal, FGP_SRC | FGP_REAL); byte *verts = (byte *)gRenDev->EF_GetPointer(eSrcPointer_Vert, &Str, GL_FLOAT, eSrcPointer_Vert, FGP_SRC | FGP_REAL); byte *vertsDst = (byte *)gRenDev->EF_GetPointer(eSrcPointer_Vert, &StrVD, GL_FLOAT, eSrcPointer_Vert, FGP_REAL); int nv = gRenDev->m_RP.m_RendNumVerts; gRenDev->m_RP.m_pRE->mfUpdateFlags(FCEF_MODIF_COL | FCEF_MODIF_VERT); for (i=0; ix / rb->m_fLengthScale * rb->m_fLength; float fLerp = vrt->x / rb->m_fLengthScale; CFColor col = LERP(rb->m_StartColor, rb->m_EndColor, fLerp); float fCurRadius = LERP(rb->m_fStartRadius, rb->m_fEndRadius, fLerp); v.y = vrt->y / rb->m_fWidthScale * fCurRadius; v.z = vrt->z / rb->m_fWidthScale * fCurRadius; *vrtD = v; Vec3d *nrm = (Vec3d *)norms; Vec3d p = Pos - v; p.Normalize(); float fd = p.Dot(lightForWard); if (fd < 0) fd = -fd; float d = p.Dot(*nrm); if (d < 0) d = -d; fd *= fd; d *= d; d += fd; d *= col.a; d = CLAMP(d, 0.0f, 1.0f); ptr[0] = (byte)(col.r * 255.0f); ptr[1] = (byte)(col.g * 255.0f); ptr[2] = (byte)(col.b * 255.0f); ptr[3] = (byte)(d * 255.0f); } } //======================================================================================= #ifdef WIN64 #pragma warning( pop ) //AMD Port #endif