123
This commit is contained in:
324
Cry3DEngine/terrain_render.cpp
Normal file
324
Cry3DEngine/terrain_render.cpp
Normal file
@@ -0,0 +1,324 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: terrain_render.cpp
|
||||
// Version: v1.00
|
||||
// Created: 28/5/2001 by Vladimir Kajalin
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description: draw vis sectors
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "terrain_sector.h"
|
||||
#include "objman.h"
|
||||
#include "visareas.h"
|
||||
#include "cbuffer.h"
|
||||
|
||||
bool CTerrain::IsSectorNonMergable(CSectorInfo * info)
|
||||
{
|
||||
if( info->m_cGeometryMML<MAX_MML_LEVEL ||
|
||||
info->m_fDistance<MIN_ALLOWED_MERGED_SECTORS_DISTANCE ||
|
||||
!(GetCVars()->e_terrain_merge_far_sectors && CTerrain::GetHeightMapUnitSize()>=2)||
|
||||
info->m_pFogVolume ||
|
||||
(m_nRenderStackLevel && info->m_nLastMergedFrameID != GetFrameID()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CTerrain::DrawVisibleSectors()
|
||||
{
|
||||
FUNCTION_PROFILER( GetSystem(),PROFILE_3DENGINE );
|
||||
|
||||
if(!GetCVars()->e_terrain)
|
||||
return;
|
||||
|
||||
if(!(GetFrameID() % TEXTURE_UPDATE_PERIOD_IN_FRAMES))
|
||||
m_nUploadsInFrame = 0; // allow to update texture only every x frames
|
||||
|
||||
const float dCSS = 1.f/CTerrain::GetSectorSize();
|
||||
// const float fDistFadeK = 1.f/(2.f*fMaxViewDist);
|
||||
const Vec3d & vCamPos = m_pViewCamera->GetPos();
|
||||
|
||||
// m_lstReflectedTerrainIdxArray.Clear();
|
||||
m_lstLowResTerrainIdxArray.Clear();
|
||||
|
||||
CCObject * pTerrainCCObject = GetRenderer()->EF_GetObject(true);
|
||||
if(GetRenderer()->EF_GetHeatVision())
|
||||
pTerrainCCObject->m_ObjFlags |= FOB_HEATVISION;
|
||||
pTerrainCCObject->m_Matrix.SetIdentity();
|
||||
|
||||
if(!m_pObjManager->m_nRenderStackLevel)
|
||||
{
|
||||
pTerrainCCObject->m_nScissorX1 = GetViewCamera().m_ScissorInfo.x1;
|
||||
pTerrainCCObject->m_nScissorY1 = GetViewCamera().m_ScissorInfo.y1;
|
||||
pTerrainCCObject->m_nScissorX2 = GetViewCamera().m_ScissorInfo.x2;
|
||||
pTerrainCCObject->m_nScissorY2 = GetViewCamera().m_ScissorInfo.y2;
|
||||
}
|
||||
|
||||
const CVars * pCVars = GetCVars();
|
||||
|
||||
bool bOutdoorsVisible = GetVisAreaManager()->IsOutdoorAreasVisible();
|
||||
|
||||
int cCurrTime = fastftol_positive(GetCurTimeSec());
|
||||
|
||||
float fZoomFactor = 0.1f+0.9f*(RAD2DEG(GetViewCamera().GetFov())/90.f);
|
||||
|
||||
for(int i=0; i<m_lstVisSectors.Count(); i++)
|
||||
{
|
||||
CSectorInfo * info = m_lstVisSectors[i];
|
||||
|
||||
if(info->m_fDistance<8) // make sure near sectors are always potentialy visible
|
||||
info->m_cLastTimeUsed = cCurrTime;
|
||||
|
||||
if(!info->m_bGroundVisible)
|
||||
continue;
|
||||
|
||||
info->m_cLastTimeRendered = info->m_cLastTimeUsed = cCurrTime;
|
||||
|
||||
if(!bOutdoorsVisible)
|
||||
continue;
|
||||
|
||||
// set texgen offset
|
||||
if(info->m_fDistance*fZoomFactor > MIN_ALLOWED_MERGED_SECTORS_DISTANCE)
|
||||
{
|
||||
info->m_arrTexOffsets[0] = 0;
|
||||
info->m_arrTexOffsets[1] = 0;
|
||||
info->m_arrTexOffsets[2] = 1.f/CTerrain::GetTerrainSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
info->m_arrTexOffsets[0] = -dCSS*info->m_nOriginY;
|
||||
info->m_arrTexOffsets[1] = -dCSS*info->m_nOriginX;
|
||||
info->m_arrTexOffsets[2] = 1.f/CTerrain::GetSectorSize();
|
||||
}
|
||||
|
||||
// set shader for zoom mode
|
||||
/* if(!pCVars->e_terrain_single_pass &&
|
||||
m_pViewCamera->GetFov() < DETAIL_TEXTURE_MIN_FOV &&
|
||||
pCVars->e_detail_texture) // zoom
|
||||
info->m_pCurShader = m_pTerrainEf_WithDefaultDetailTexture;
|
||||
else*/
|
||||
if(GetCVars()->e_detail_texture_quality)
|
||||
{
|
||||
if(!info->m_nDynLightMaskNoSun && info->m_pFogVolume &&
|
||||
GetCVars()->e_terrain_single_pass_vol_fog && info->m_fDistance>32)
|
||||
info->m_pCurShader = m_pTerrainWithFog;
|
||||
else
|
||||
info->m_pCurShader = m_pTerrainEf;
|
||||
}
|
||||
else
|
||||
info->m_pCurShader = m_pTerrainEf_WithDefaultDetailTexture;
|
||||
|
||||
// check when we can't use lowest lod (and sectors merging)
|
||||
if(IsSectorNonMergable(info))
|
||||
{
|
||||
info->SetTextures();
|
||||
|
||||
/* if( m_pTerrainCausticsEf &&
|
||||
info->m_fMinZ < m_fGlobalWaterLevel &&
|
||||
info->m_pCurShader == m_pTerrainEf &&
|
||||
info->m_fDistance < 80.f &&
|
||||
GetCVars()->e_terrain_caustics &&
|
||||
!GetCVars()->e_terrain_single_pass)
|
||||
{ // do caustics
|
||||
info->m_pCurShader = m_pTerrainCausticsEf;
|
||||
info->RenderSector(pTerrainCCObject);
|
||||
}
|
||||
else*/
|
||||
info->RenderSector(pTerrainCCObject);
|
||||
}
|
||||
else if(!m_nRenderStackLevel) // do not calc low res indices in recursion //if((GetFrameID()%64)==0)
|
||||
info->MergeSectorIntoLowResTerrain(true);
|
||||
|
||||
// if(!m_nRenderStackLevel)
|
||||
// info->MergeSectorIntoLowResTerrain(false);
|
||||
|
||||
if(pCVars->e_terrain_debug==1)
|
||||
{
|
||||
GetRenderer()->ResetToDefault();
|
||||
|
||||
GetRenderer()->SetMaterialColor(1,0,0,1);
|
||||
GetRenderer()->Draw3dBBox(info->m_vBoxMin, info->m_vBoxMax);
|
||||
|
||||
GetRenderer()->SetMaterialColor(0,1,0,1);
|
||||
GetRenderer()->Draw3dBBox(
|
||||
Vec3d((float)info->m_nOriginX-TERRAIN_SECTORS_MAX_OVERLAPPING,
|
||||
(float)info->m_nOriginY-TERRAIN_SECTORS_MAX_OVERLAPPING,0),
|
||||
Vec3d((float)info->m_nOriginX+CTerrain::GetSectorSize()+TERRAIN_SECTORS_MAX_OVERLAPPING,
|
||||
(float)info->m_nOriginY+CTerrain::GetSectorSize()+TERRAIN_SECTORS_MAX_OVERLAPPING,512.f));
|
||||
|
||||
GetRenderer()->ResetToDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// if(!m_nRenderStackLevel)
|
||||
RenderLowResTerrain();
|
||||
}
|
||||
|
||||
void CTerrain::MergeLowResTerrainSectorIndices(list2<unsigned short> * pIndices)
|
||||
{
|
||||
m_lstLowResTerrainIdxArray.AddList(*pIndices);
|
||||
}
|
||||
|
||||
void CTerrain::MergeReflectedTerrainSectorIndices(list2<unsigned short> * pIndices)
|
||||
{
|
||||
m_lstReflectedTerrainIdxArray.AddList(*pIndices);
|
||||
}
|
||||
|
||||
void CTerrain::RenderLowResTerrain()
|
||||
{
|
||||
FUNCTION_PROFILER( GetSystem(),PROFILE_3DENGINE );
|
||||
|
||||
if(CTerrain::GetHeightMapUnitSize()<2)
|
||||
return;
|
||||
|
||||
if(!m_pLowResTerrainLeafBuffer)
|
||||
{
|
||||
int nStep = (1<<MAX_MML_LEVEL)*CTerrain::GetHeightMapUnitSize();
|
||||
|
||||
// fill vert buffer
|
||||
list2<struct_VERTEX_FORMAT_P3F> lstLowResTerrainVertArray;
|
||||
for( int x=0; x<=CTerrain::GetTerrainSize(); x+=nStep )
|
||||
for( int y=0; y<=CTerrain::GetTerrainSize(); y+=nStep )
|
||||
{
|
||||
struct_VERTEX_FORMAT_P3F vert;
|
||||
vert.xyz.x = (float)(x);
|
||||
vert.xyz.y = (float)(y);
|
||||
vert.xyz.z = (GetZ(x,y));
|
||||
lstLowResTerrainVertArray.Add(vert);
|
||||
}
|
||||
|
||||
// make leaf buffer
|
||||
m_pLowResTerrainLeafBuffer = GetRenderer()->CreateLeafBufferInitialized(
|
||||
lstLowResTerrainVertArray.GetElements(), lstLowResTerrainVertArray.Count(), VERTEX_FORMAT_P3F,
|
||||
m_lstLowResTerrainIdxArray.GetElements(), m_lstLowResTerrainIdxArray.Count(),
|
||||
R_PRIMV_TRIANGLES,"LowResTerrain", eBT_Dynamic, 1,m_pLowLodCoverMapTex->GetTextureID());
|
||||
|
||||
// m_pLowResTerrainShader = GetRenderer()->EF_LoadShader("TerrainLowLOD", eSH_World, EF_SYSTEM);
|
||||
|
||||
assert(m_pLowResTerrainLeafBuffer);
|
||||
|
||||
m_nLowResTerrainVertCount = lstLowResTerrainVertArray.Count();
|
||||
}
|
||||
|
||||
if(!m_nRenderStackLevel)
|
||||
{
|
||||
m_pLowResTerrainLeafBuffer->UpdateSysIndices(m_lstLowResTerrainIdxArray.GetElements(), m_lstLowResTerrainIdxArray.Count());
|
||||
m_pLowResTerrainLeafBuffer->SetChunk(m_pLowResTerrainShader,0,m_nLowResTerrainVertCount,
|
||||
0, m_lstLowResTerrainIdxArray.Count());
|
||||
|
||||
m_lstLowResTerrainIdxArray.Clear();
|
||||
}
|
||||
|
||||
m_arrLowResTerrainShaderCustomData[0] = 1;
|
||||
m_arrLowResTerrainShaderCustomData[1] = 1;
|
||||
m_arrLowResTerrainShaderCustomData[2] = 1.f/CTerrain::GetTerrainSize();
|
||||
m_arrLowResTerrainShaderCustomData[3] = 0;
|
||||
m_arrLowResTerrainShaderCustomData[4] = 0;
|
||||
m_pLowResTerrainLeafBuffer->SetRECustomData(m_arrLowResTerrainShaderCustomData,1);
|
||||
|
||||
m_pLowResTerrainLeafBuffer->m_vBoxMin = Vec3d(0,0,0);
|
||||
m_pLowResTerrainLeafBuffer->m_vBoxMax = Vec3d((float)CTerrain::GetTerrainSize(),(float)CTerrain::GetTerrainSize(),255);
|
||||
|
||||
CCObject * pObj = GetRenderer()->EF_GetObject(true);
|
||||
pObj->m_Matrix.SetIdentity();
|
||||
if(GetRenderer()->EF_GetHeatVision())
|
||||
pObj->m_ObjFlags |= FOB_HEATVISION;
|
||||
|
||||
if(!m_pObjManager->m_nRenderStackLevel)
|
||||
{
|
||||
pObj->m_nScissorX1 = GetViewCamera().m_ScissorInfo.x1;
|
||||
pObj->m_nScissorY1 = GetViewCamera().m_ScissorInfo.y1;
|
||||
pObj->m_nScissorX2 = GetViewCamera().m_ScissorInfo.x2;
|
||||
pObj->m_nScissorY2 = GetViewCamera().m_ScissorInfo.y2;
|
||||
}
|
||||
|
||||
m_pLowResTerrainLeafBuffer->AddRenderElements( pObj );
|
||||
}
|
||||
|
||||
void CTerrain::RenderReflectedTerrain()
|
||||
{
|
||||
FUNCTION_PROFILER( GetSystem(),PROFILE_3DENGINE );
|
||||
|
||||
if(CTerrain::GetHeightMapUnitSize()<2)
|
||||
return;
|
||||
|
||||
if(!GetCVars()->e_terrain)
|
||||
return;
|
||||
|
||||
if( !m_pLowResTerrainLeafBuffer ||
|
||||
// !m_pReflectedTerrainLeafBuffer ||
|
||||
!m_pLowResTerrainLeafBuffer->m_SecVertCount ||
|
||||
!m_lstReflectedTerrainIdxArray.Count())
|
||||
return;
|
||||
|
||||
if(!m_pReflectedTerrainLeafBuffer)
|
||||
{
|
||||
int nStep = (1<<MAX_MML_LEVEL)*CTerrain::GetHeightMapUnitSize();
|
||||
|
||||
// fill vert buffer
|
||||
/* list2<struct_VERTEX_FORMAT_P3F> lstLowResTerrainVertArray;
|
||||
// for( int x=0; x<=CTerrain::GetTerrainSize(); x+=nStep )
|
||||
// for( int y=0; y<=CTerrain::GetTerrainSize(); y+=nStep )
|
||||
{
|
||||
struct_VERTEX_FORMAT_P3F vert;
|
||||
vert.x = 0;//(float)(x);
|
||||
vert.y = 0;//(float)(y);
|
||||
vert.z = 0;//(GetZ(x,y));
|
||||
lstLowResTerrainVertArray.Add(vert);
|
||||
}
|
||||
*/
|
||||
// make leaf buffer
|
||||
m_pReflectedTerrainLeafBuffer = GetRenderer()->CreateLeafBufferInitialized(
|
||||
/*&lstLowResTerrainVertArray[0], lstLowResTerrainVertArray.Count(), */0,0,VERTEX_FORMAT_P3F,
|
||||
m_lstReflectedTerrainIdxArray.GetElements(), m_lstReflectedTerrainIdxArray.Count(),
|
||||
R_PRIMV_TRIANGLES, "ReflectedTerrain", eBT_Dynamic, 1,m_pLowLodCoverMapTex->GetTextureID());
|
||||
|
||||
// m_pLowResTerrainShader = GetRenderer()->EF_LoadShader("TerrainLowLOD", eSH_World);
|
||||
|
||||
assert(m_pReflectedTerrainLeafBuffer);
|
||||
|
||||
// m_nLowResTerrainVertCount = lstLowResTerrainVertArray.Count();
|
||||
}
|
||||
|
||||
m_pReflectedTerrainLeafBuffer->SetVertexContainer(m_pLowResTerrainLeafBuffer);
|
||||
|
||||
// if(!m_nRenderStackLevel)
|
||||
{
|
||||
if(m_lstReflectedTerrainIdxArray.Count()>60000)
|
||||
Warning( 0,0,"Warning: CTerrain::RenderReflectedTerrain: m_lstReflectedTerrainIdxArray.Count()>60000");
|
||||
|
||||
while(m_lstReflectedTerrainIdxArray.Count()>60000)
|
||||
m_lstReflectedTerrainIdxArray.DeleteLast();
|
||||
m_pReflectedTerrainLeafBuffer->UpdateSysIndices(m_lstReflectedTerrainIdxArray.GetElements(), m_lstReflectedTerrainIdxArray.Count());
|
||||
m_pReflectedTerrainLeafBuffer->SetChunk(m_pLowResTerrainShader,0,m_nLowResTerrainVertCount,
|
||||
0, m_lstReflectedTerrainIdxArray.Count());
|
||||
|
||||
// m_lstReflectedTerrainIdxArray.Clear();
|
||||
}
|
||||
|
||||
m_arrLowResTerrainShaderCustomData[0] = 1;
|
||||
m_arrLowResTerrainShaderCustomData[1] = 1;
|
||||
m_arrLowResTerrainShaderCustomData[2] = 1.f/CTerrain::GetTerrainSize();
|
||||
m_arrLowResTerrainShaderCustomData[3] = 0;
|
||||
m_arrLowResTerrainShaderCustomData[4] = 0;
|
||||
m_pReflectedTerrainLeafBuffer->SetRECustomData(m_arrLowResTerrainShaderCustomData,1);
|
||||
|
||||
m_pReflectedTerrainLeafBuffer->m_vBoxMin = Vec3d(0,0,0);
|
||||
m_pReflectedTerrainLeafBuffer->m_vBoxMax = Vec3d((float)CTerrain::GetTerrainSize(),(float)CTerrain::GetTerrainSize(),255);
|
||||
|
||||
// CCObject * pObj = GetRenderer()->EF_GetObject(true);
|
||||
// if(GetRenderer()->EF_GetHeatVision())
|
||||
// pObj->m_ObjFlags |= FOB_HEATVISION;
|
||||
|
||||
if(m_pReflectedTerrainLeafBuffer->m_Indices.m_nItems)
|
||||
m_pReflectedTerrainLeafBuffer->AddRenderElements();
|
||||
|
||||
/// m_lstReflectedTerrainIdxArray.Clear();
|
||||
}
|
||||
Reference in New Issue
Block a user