Sped up LOS rendering.
This was SVN commit r2880.
This commit is contained in:
parent
57cfc7c6ac
commit
c468eedbbb
@ -172,16 +172,19 @@ void CGameView::RenderModels(CUnitManager *pUnitMan, CProjectileManager *pProjec
|
||||
if (frustum.IsBoxVisible(CVector3D(0,0,0), units[i]->GetModel()->GetBounds())
|
||||
&& status != UNIT_HIDDEN)
|
||||
{
|
||||
CColor color;
|
||||
if(status == UNIT_VISIBLE)
|
||||
if(units[i] != g_BuildingPlacer.m_actor)
|
||||
{
|
||||
color = CColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
CColor color;
|
||||
if(status == UNIT_VISIBLE)
|
||||
{
|
||||
color = CColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
else // status == UNIT_REMEMBERED
|
||||
{
|
||||
color = CColor(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
}
|
||||
units[i]->GetModel()->SetShadingColor(color);
|
||||
}
|
||||
else // status == UNIT_REMEMBERED
|
||||
{
|
||||
color = CColor(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
}
|
||||
units[i]->GetModel()->SetShadingColor(color);
|
||||
|
||||
PROFILE( "submit models" );
|
||||
SubmitModelRecursive(units[i]->GetModel());
|
||||
|
@ -47,7 +47,7 @@ static SColor4ub ConvertColor(const RGBColor& src)
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// CPatchRData constructor
|
||||
CPatchRData::CPatchRData(CPatch* patch) : m_Patch(patch), m_VBBase(0), m_VBBlends(0), m_Vertices(0)
|
||||
CPatchRData::CPatchRData(CPatch* patch) : m_Patch(patch), m_VBBase(0), m_VBBlends(0), m_Vertices(0), m_LightingColors(0)
|
||||
{
|
||||
debug_assert(patch);
|
||||
Build();
|
||||
@ -59,6 +59,7 @@ CPatchRData::~CPatchRData()
|
||||
{
|
||||
// delete copy of vertex data
|
||||
delete[] m_Vertices;
|
||||
delete[] m_LightingColors;
|
||||
// release vertex buffer chunks
|
||||
if (m_VBBase) g_VBMan.Release(m_VBBase);
|
||||
if (m_VBBlends) g_VBMan.Release(m_VBBlends);
|
||||
@ -213,6 +214,7 @@ void CPatchRData::BuildBlends()
|
||||
dst.m_Color=vtx0.m_Color;
|
||||
dst.m_Position=vtx0.m_Position;
|
||||
m_BlendVertices.push_back(dst);
|
||||
m_BlendVertexIndices.push_back((j*vsize)+i);
|
||||
|
||||
const SBaseVertex& vtx1=m_Vertices[(j*vsize)+i+1];
|
||||
dst.m_UVs[0]=(i+1)*0.125f;
|
||||
@ -222,6 +224,7 @@ void CPatchRData::BuildBlends()
|
||||
dst.m_Color=vtx1.m_Color;
|
||||
dst.m_Position=vtx1.m_Position;
|
||||
m_BlendVertices.push_back(dst);
|
||||
m_BlendVertexIndices.push_back((j*vsize)+i+1);
|
||||
|
||||
const SBaseVertex& vtx2=m_Vertices[((j+1)*vsize)+i+1];
|
||||
dst.m_UVs[0]=(i+1)*0.125f;
|
||||
@ -231,6 +234,7 @@ void CPatchRData::BuildBlends()
|
||||
dst.m_Color=vtx2.m_Color;
|
||||
dst.m_Position=vtx2.m_Position;
|
||||
m_BlendVertices.push_back(dst);
|
||||
m_BlendVertexIndices.push_back(((j+1)*vsize)+i+1);
|
||||
|
||||
const SBaseVertex& vtx3=m_Vertices[((j+1)*vsize)+i];
|
||||
dst.m_UVs[0]=i*0.125f;
|
||||
@ -240,6 +244,7 @@ void CPatchRData::BuildBlends()
|
||||
dst.m_Color=vtx3.m_Color;
|
||||
dst.m_Position=vtx3.m_Position;
|
||||
m_BlendVertices.push_back(dst);
|
||||
m_BlendVertexIndices.push_back(((j+1)*vsize)+i);
|
||||
|
||||
// build a splat for this quad
|
||||
STmpSplat splat;
|
||||
@ -360,14 +365,17 @@ void CPatchRData::BuildIndices()
|
||||
|
||||
void CPatchRData::BuildVertices()
|
||||
{
|
||||
// create both vertices and lighting colors
|
||||
|
||||
CVector3D normal;
|
||||
RGBColor c;
|
||||
SColor4ub black = ConvertColor(RGBColor(0,0,0));
|
||||
|
||||
// number of vertices in each direction in each patch
|
||||
int vsize=PATCH_SIZE+1;
|
||||
|
||||
if (!m_Vertices) {
|
||||
m_Vertices=new SBaseVertex[vsize*vsize];
|
||||
m_LightingColors=new RGBColor[vsize*vsize];
|
||||
}
|
||||
SBaseVertex* vertices=m_Vertices;
|
||||
|
||||
@ -377,9 +385,6 @@ void CPatchRData::BuildVertices()
|
||||
u32 pz=m_Patch->m_Z;
|
||||
|
||||
CTerrain* terrain=m_Patch->m_Parent;
|
||||
int mapSize=terrain->GetVerticesPerSide();
|
||||
|
||||
CLOSManager* losMgr = g_Game->GetWorld()->GetLOSManager();
|
||||
|
||||
// build vertices
|
||||
for (int j=0;j<vsize;j++) {
|
||||
@ -388,37 +393,20 @@ void CPatchRData::BuildVertices()
|
||||
int iz=pz*PATCH_SIZE+j;
|
||||
int v=(j*vsize)+i;
|
||||
|
||||
terrain->CalcPosition(ix,iz,vertices[v].m_Position);
|
||||
terrain->CalcNormal(ix,iz,normal);
|
||||
|
||||
const int DX[] = {1,1,0,0};
|
||||
const int DZ[] = {0,1,1,0};
|
||||
float losMod = 1.0f;
|
||||
for(int k=0; k<4; k++)
|
||||
{
|
||||
int tx = ix - DX[k];
|
||||
int tz = iz - DZ[k];
|
||||
|
||||
if(tx >= 0 && tz >= 0 && tx <= mapSize-2 && tz <= mapSize-2)
|
||||
{
|
||||
ELOSStatus s = losMgr->GetStatus(tx, tz, g_Game->GetLocalPlayer());
|
||||
if(s==LOS_EXPLORED && losMod > 0.7f)
|
||||
losMod = 0.7f;
|
||||
else if(s==LOS_UNEXPLORED && losMod > 0.0f)
|
||||
losMod = 0.0f;
|
||||
}
|
||||
}
|
||||
RGBColor losModColor(losMod, losMod, losMod);
|
||||
|
||||
g_Renderer.m_SHCoeffsTerrain.Evaluate(normal, c, losModColor);
|
||||
|
||||
vertices[v].m_Color=ConvertColor(c);
|
||||
|
||||
// calculate vertex data
|
||||
terrain->CalcPosition(ix,iz,vertices[v].m_Position);
|
||||
vertices[v].m_Color=black; // will be set to the proper value in Update()
|
||||
vertices[v].m_UVs[0]=i*0.125f;
|
||||
vertices[v].m_UVs[1]=j*0.125f;
|
||||
|
||||
// calculate lighting into the separate m_LightingColors array, which will
|
||||
// be used to set the vertex colors in Update()
|
||||
terrain->CalcNormal(ix,iz,normal);
|
||||
g_Renderer.m_SHCoeffsTerrain.Evaluate(normal, m_LightingColors[v]);
|
||||
}
|
||||
}
|
||||
|
||||
// upload to vertex buffer
|
||||
if (!m_VBBase) {
|
||||
m_VBBase=g_VBMan.Allocate(sizeof(SBaseVertex),vsize*vsize,false);
|
||||
}
|
||||
@ -438,16 +426,69 @@ void CPatchRData::Update()
|
||||
// TODO,RC 11/04/04 - need to only rebuild necessary bits of renderdata rather
|
||||
// than everything; it's complicated slightly because the blends are dependent
|
||||
// on both vertex and index data
|
||||
//BuildVertices();
|
||||
BuildVertices();
|
||||
BuildIndices();
|
||||
///BuildBlends();
|
||||
BuildBlends();
|
||||
|
||||
m_UpdateFlags=0;
|
||||
}
|
||||
|
||||
// Always build vertices (due to LOS)
|
||||
BuildVertices();
|
||||
BuildBlends();
|
||||
// Update vertex colors, which are affected by LOS
|
||||
|
||||
u32 px=m_Patch->m_X;
|
||||
u32 pz=m_Patch->m_Z;
|
||||
|
||||
CTerrain* terrain=m_Patch->m_Parent;
|
||||
int mapSize=terrain->GetVerticesPerSide();
|
||||
CLOSManager* losMgr = g_Game->GetWorld()->GetLOSManager();
|
||||
int vsize=PATCH_SIZE+1;
|
||||
|
||||
// this is very similar to BuildVertices(), but just for color
|
||||
for (int j=0;j<vsize;j++) {
|
||||
for (int i=0;i<vsize;i++) {
|
||||
int ix=px*PATCH_SIZE+i;
|
||||
int iz=pz*PATCH_SIZE+j;
|
||||
int v=(j*vsize)+i;
|
||||
|
||||
const int DX[] = {1,1,0,0};
|
||||
const int DZ[] = {0,1,1,0};
|
||||
float losMod = 1.0f;
|
||||
for(int k=0; k<4; k++)
|
||||
{
|
||||
int tx = ix - DX[k];
|
||||
int tz = iz - DZ[k];
|
||||
|
||||
if(tx >= 0 && tz >= 0 && tx <= mapSize-2 && tz <= mapSize-2)
|
||||
{
|
||||
ELOSStatus s = losMgr->GetStatus(tx, tz, g_Game->GetLocalPlayer());
|
||||
if(s==LOS_EXPLORED && losMod > 0.7f)
|
||||
losMod = 0.7f;
|
||||
else if(s==LOS_UNEXPLORED && losMod > 0.0f)
|
||||
losMod = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
RGBColor c = m_LightingColors[v];
|
||||
c *= losMod;
|
||||
|
||||
m_Vertices[v].m_Color=ConvertColor(c);
|
||||
}
|
||||
}
|
||||
|
||||
// upload base vertices into their vertex buffer
|
||||
m_VBBase->m_Owner->UpdateChunkVertices(m_VBBase,m_Vertices);
|
||||
|
||||
// update blend colors by copying them from vertex colors
|
||||
for(uint i=0; i<m_BlendVertices.size(); i++)
|
||||
{
|
||||
m_BlendVertices[i].m_Color = m_Vertices[m_BlendVertexIndices[i]].m_Color;
|
||||
}
|
||||
|
||||
// upload blend vertices into their vertex buffer too
|
||||
if(m_BlendVertices.size())
|
||||
{
|
||||
m_VBBlends->m_Owner->UpdateChunkVertices(m_VBBlends,&m_BlendVertices[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void CPatchRData::RenderBase()
|
||||
|
@ -87,7 +87,6 @@ private:
|
||||
Handle m_Handle;
|
||||
int m_Priority;
|
||||
};
|
||||
|
||||
|
||||
// build this renderdata object
|
||||
void Build();
|
||||
@ -98,26 +97,46 @@ private:
|
||||
|
||||
// owner patch
|
||||
CPatch* m_Patch;
|
||||
|
||||
// vertex buffer handle for base vertices
|
||||
CVertexBuffer::VBChunk* m_VBBase;
|
||||
|
||||
// vertex buffer handle for blend vertices
|
||||
CVertexBuffer::VBChunk* m_VBBlends;
|
||||
|
||||
// patch render vertices
|
||||
SBaseVertex* m_Vertices;
|
||||
|
||||
// precomputed lighting colors at each vertex; these are the multiplied by a LOS modifier
|
||||
// (black for shroud of darkness, half-darkened for fog of war), to compute the colors in
|
||||
// m_Vertices, which are passed to the graphics card
|
||||
RGBColor* m_LightingColors;
|
||||
|
||||
// indices into base vertices for the base splats
|
||||
std::vector<unsigned short> m_Indices;
|
||||
|
||||
// indices into base vertices for the shadow map pass
|
||||
std::vector<unsigned short> m_ShadowMapIndices;
|
||||
|
||||
// list of base splats to apply to this patch
|
||||
std::vector<SSplat> m_Splats;
|
||||
|
||||
// vertices to use for blending transition texture passes
|
||||
std::vector<SBlendVertex> m_BlendVertices;
|
||||
|
||||
// remembers the index in the m_Vertices array of each blend vertex, so that we can
|
||||
// properly update its color for fog of war and shroud of darkness
|
||||
std::vector<uint> m_BlendVertexIndices;
|
||||
|
||||
// indices into blend vertices for the blend splats
|
||||
std::vector<unsigned short> m_BlendIndices;
|
||||
|
||||
// splats used in blend pass
|
||||
std::vector<SSplat> m_BlendSplats;
|
||||
|
||||
// index of the next blend splat to render
|
||||
u32 m_NextBlendSplat;
|
||||
|
||||
// list of all submitted patches
|
||||
static std::vector<CPatch*> m_Patches;
|
||||
};
|
||||
|
@ -151,9 +151,15 @@ EUnitLOSStatus CLOSManager::GetUnitStatus(CUnit* unit, CPlayer* player)
|
||||
}
|
||||
else if(status == LOS_EXPLORED)
|
||||
{
|
||||
if(unit->GetEntity() != 0 && unit->GetEntity()->m_permanent)
|
||||
if(unit->GetEntity() == 0 || unit->GetEntity()->m_permanent)
|
||||
{
|
||||
// both actors (which are usually for decoration) and units with the
|
||||
// permanent flag should be remembered
|
||||
return UNIT_REMEMBERED;
|
||||
|
||||
// TODO: the unit status system will have to be replaced with a "ghost actor"
|
||||
// system so that we can't remember units that we haven't seen and so we can
|
||||
// see permanent units that have died but that we haven't been near lately
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5,7 +5,12 @@
|
||||
// Maintains and updates line of sight data (including Shroud of Darkness
|
||||
// and Fog of War).
|
||||
//
|
||||
// Usage: Doesn't do anything useful right now.
|
||||
// Usage:
|
||||
// - Initialize() is called when the game is started to allocate the visibility arrays
|
||||
// - Update() is called each frame by CSimulation::Update() to update the visibility arrays
|
||||
// - m_MapRevealed can be set to true to reveal the entire map (remove both LOS and FOW)
|
||||
// - GetStatus can be used to obtain the LOS status of a tile or a world-space point
|
||||
// - GetUnitStatus returns the LOS status of an entity or actor
|
||||
|
||||
|
||||
#ifndef LOS_MANAGER_INCLUDED
|
||||
|
Loading…
Reference in New Issue
Block a user