bool RenderCoronaFace (CSegment *segP, CSegFace *faceP, int bDepthOnly) { if (!(faceP->widFlags & WID_RENDER_FLAG)) return false; if (!faceP->nCorona) return false; #if DBG if ((faceP->nSegment == nDbgSeg) && ((nDbgSide < 0) || (faceP->nSide == nDbgSide))) nDbgSeg = nDbgSeg; #endif RenderCorona (faceP->nSegment, faceP->nSide, CoronaVisibility (faceP->nCorona), faceP->fRads [0]); return true; }
void RenderCoronaFaceList (CFaceListIndex& flx, int nPass) { tFaceListItem* fliP; CSegFace* faceP; int i, j, nSegment; for (i = 0; i < flx.nUsedKeys; i++) { for (j = flx.roots [flx.usedKeys [i]]; j >= 0; j = fliP->nNextItem) { fliP = gameData.render.faceList + j; faceP = fliP->faceP; if (!faceP->nCorona) continue; nSegment = faceP->nSegment; if (automap.m_bDisplay) { if (!(automap.m_bFull || automap.m_visible [nSegment])) return; if (!gameOpts->render.automap.bSkybox && (SEGMENTS [nSegment].m_nType == SEGMENT_IS_SKYBOX)) continue; } if (nPass == 1) { #if DBG if ((nSegment == nDbgSeg) && ((nDbgSide < 0) || (faceP->nSide == nDbgSide))) nDbgSeg = nDbgSeg; # if 0 else if (nDbgSeg >= 0) continue; # endif #endif CoronaVisibility (faceP->nCorona); } else if (nPass == 2) { #if DBG if ((nSegment == nDbgSeg) && ((nDbgSide < 0) || (faceP->nSide == nDbgSide))) nDbgSeg = nDbgSeg; # if 0 else if (nDbgSeg >= 0) continue; # endif #endif glBeginQuery (GL_SAMPLES_PASSED_ARB, gameData.render.lights.coronaQueries [faceP->nCorona - 1]); if (!glGetError ()) RenderCorona (nSegment, faceP->nSide, 1, faceP->fRads [0]); glEndQuery (GL_SAMPLES_PASSED_ARB); } else { #if DBG if ((nSegment == nDbgSeg) && ((nDbgSide < 0) || (faceP->nSide == nDbgSide))) nDbgSeg = nDbgSeg; # if 0 else if (nDbgSeg >= 0) continue; # endif #endif glBeginQuery (GL_SAMPLES_PASSED_ARB, gameData.render.lights.coronaQueries [faceP->nCorona - 1]); ogl.ClearError (1); RenderCorona (nSegment, faceP->nSide, 1, faceP->fRads [0]); ogl.ClearError (1); glEndQuery (GL_SAMPLES_PASSED_ARB); ogl.ClearError (1); } } } }
void RenderSide (CSegment *segP, short nSide) { CSide *sideP = segP->m_sides + nSide; tFaceProps props; #if LIGHTMAPS #define LMAP_SIZE (1.0 / 16.0) static tUVL uvl_lMaps [4] = { {F2X (LMAP_SIZE), F2X (LMAP_SIZE), 0}, {F2X (1.0 - LMAP_SIZE), F2X (LMAP_SIZE), 0}, {F2X (1.0 - LMAP_SIZE), F2X (1.0 - LMAP_SIZE), 0}, {F2X (LMAP_SIZE), F2X (1.0 - LMAP_SIZE), 0} }; #endif props.segNum = segP->Index (); props.sideNum = nSide; #if DBG if ((props.segNum == nDbgSeg) && ((nDbgSide < 0) || (props.sideNum == nDbgSide))) segP = segP; #endif props.widFlags = segP->IsDoorWay (props.sideNum, NULL); if (!(gameOpts->render.debug.bWalls || IsMultiGame) && IS_WALL (segP->WallNum (props.sideNum))) return; switch (gameStates.render.nType) { case -1: if (!(props.widFlags & WID_RENDER_FLAG) && (SEGMENTS [props.segNum].m_nType < SEGMENT_IS_WATER)) //if (WALL_IS_DOORWAY(segP, props.sideNum) == WID_NO_WALL) return; break; case 0: if (segP->m_children [props.sideNum] >= 0) //&& IS_WALL (WallNumP (segP, props.sideNum))) return; break; case 1: if (!IS_WALL (segP->WallNum (props.sideNum))) return; break; case 2: if ((SEGMENTS [props.segNum].m_nType < SEGMENT_IS_WATER) && (SEGMENTS [props.segNum].m_owner < 1)) return; break; case 3: if ((IsLight (sideP->m_nBaseTex) || (sideP->m_nOvlTex && IsLight (sideP->m_nOvlTex)))) RenderCorona (props.segNum, props.sideNum, 1, 20); return; } #if LIGHTMAPS if (gameStates.render.bDoLightmaps) { float Xs = 8; float h = 0.5f / (float) Xs; props.uvl_lMaps [0].u = props.uvl_lMaps [0].v = props.uvl_lMaps [1].v = props.uvl_lMaps [3].u = F2X (h); props.uvl_lMaps [1].u = props.uvl_lMaps [2].u = props.uvl_lMaps [2].v = props.uvl_lMaps [3].v = F2X (1-h); } #endif props.nBaseTex = sideP->m_nBaseTex; props.nOvlTex = sideP->m_nOvlTex; props.nOvlOrient = sideP->m_nOvlOrient; // ========== Mark: Here is the change...beginning here: ========== #if LIGHTMAPS if (gameStates.render.bDoLightmaps) { memcpy (props.uvl_lMaps, uvl_lMaps, sizeof (tUVL) * 4); #if LMAP_LIGHTADJUST props.uvls [0].l = props.uvls [1].l = props.uvls [2].l = props.uvls [3].l = I2X (1) / 2; # endif } #endif #if DBG //convenient place for a debug breakpoint if (props.segNum == nDbgSeg && props.sideNum == nDbgSide) props.segNum = props.segNum; if (props.nBaseTex == nDbgBaseTex) props.segNum = props.segNum; if (props.nOvlTex == nDbgOvlTex) props.segNum = props.segNum; # if 0 else return; # endif #endif if (!FaceIsVisible (props.segNum, props.sideNum)) return; if (sideP->m_nType == SIDE_IS_QUAD) { props.vNormal = sideP->m_normals [0]; props.nVertices = 4; memcpy (props.uvls, sideP->m_uvls, sizeof (tUVL) * 4); memcpy (props.vp, SEGMENTS [props.segNum].Corners (props.sideNum), 4 * sizeof (ushort)); RenderFace (&props); } else { // new code // non-planar faces are still passed as quads to the renderer as it will render triangles (GL_TRIANGLE_FAN) anyway // just need to make sure the vertices come in the proper order depending of the the orientation of the two non-planar triangles props.vNormal = sideP->m_normals [0] + sideP->m_normals [1]; props.vNormal *= (I2X (1) / 2); props.nVertices = 4; if (sideP->m_nType == SIDE_IS_TRI_02) { memcpy (props.uvls, sideP->m_uvls, sizeof (tUVL) * 4); memcpy (props.vp, SEGMENTS [props.segNum].Corners (props.sideNum), 4 * sizeof (ushort)); RenderFace (&props); } else if (sideP->m_nType == SIDE_IS_TRI_13) { //just rendering the fan with vertex 1 instead of 0 memcpy (props.uvls + 1, sideP->m_uvls, sizeof (tUVL) * 3); props.uvls [0] = sideP->m_uvls [3]; memcpy (props.vp + 1, SEGMENTS [props.segNum].Corners (props.sideNum), 4 * sizeof (ushort)); props.vp [0] = props.vp [4]; RenderFace (&props); } else { Error("Illegal CSide nType in RenderSide, nType = %i, CSegment # = %i, CSide # = %i\n", sideP->m_nType, segP->Index (), props.sideNum); return; } } }
void VCoronaManager::RenderAllVisibleCoronas() { #ifdef SUPPORTS_CORONAS VisRenderContext_cl* pContext = VisRenderContext_cl::GetCurrentContext(); // Determine relevant render context and visibility collector IVisVisibilityCollector_cl *pVisCollector = pContext->GetVisibilityCollector(); if (!pVisCollector) return; VisRenderContext_cl *pOQContext = pVisCollector->GetOcclusionQueryRenderContext(); if (pOQContext != NULL) pContext = pOQContext; if ((pContext->GetRenderFlags() & VIS_RENDERCONTEXT_FLAG_USE_PIXELCOUNTER) == 0) return; if ((pContext->GetRenderFlags() & VIS_RENDERCONTEXT_FLAG_RENDER_CORONAS) == 0) return; INSERT_PERF_MARKER_SCOPE("VCoronaManager::RenderAllVisibleCoronas"); VISION_PROFILE_FUNCTION(PROFILING_CORONA_RENDER); // Force for the queries to finish so they are available in this frame. if (m_bTeleportedLastFrame && m_bForceQueryOnTeleport) { UpdateCoronas(VCUF_UPDATE | VCUF_FORCE_FETCH | VCUF_USE_OC_CONTEXT); } // Ensure size of corona state structure. int iContextIndex = pContext->GetNumber(); if (iContextIndex + 1 > m_State.GetSize()) m_State.SetSize(iContextIndex + 1, -1); VCoronaRenderContextState& state = m_State[iContextIndex]; int iCapacity = m_Instances.GetCapacity(); state.EnsureSize(iCapacity); const int iCoronasToRender = state.m_Candidates.GetSize(); // Sort candidates by texture? VTextureObject* pTexture = NULL; // Render all corona components Vision::RenderLoopHelper.BeginMeshRendering(); Vision::RenderLoopHelper.AddMeshStreams(m_spBillboardMesh,VERTEX_STREAM_POSITION); for (int i=0; i < iCoronasToRender; ++i) { VCoronaCandidate& coronaCandidate = state.m_Candidates.ElementAt(i); if (coronaCandidate.m_fCurrentVisibility > 0.0f) { RenderCorona (coronaCandidate, pTexture); } } Vision::RenderLoopHelper.EndMeshRendering(); m_bTeleportedLastFrame = (pContext->GetCamera()->GetLastTeleported() >= pContext->GetLastRenderedFrame()); #endif }