Change the water manager so incremental updates to the water information is possible. Streamline a few things (and removes a not-really-used calculation to speed things up further). Fixes #2063 , refs #1743.
This was SVN commit r13698.
This commit is contained in:
parent
557c1fc067
commit
a4707bcc16
@ -45,10 +45,6 @@
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpWaterManager.h"
|
||||
|
||||
#include "tools/atlas/GameInterface/GameLoop.h"
|
||||
|
||||
extern GameLoopState* g_AtlasGameLoop;
|
||||
|
||||
const ssize_t BlendOffsets[9][2] = {
|
||||
{ 0, -1 },
|
||||
{ -1, -1 },
|
||||
@ -1311,9 +1307,9 @@ void CPatchRData::BuildWater()
|
||||
// TODO: This is not (yet) exported via the ICmp interface so... we stick to these values which can be compiled in defaults
|
||||
WaterManager* WaterMgr = g_Renderer.GetWaterManager();
|
||||
|
||||
if (WaterMgr->m_NeedsFullReloading && !g_AtlasGameLoop->running)
|
||||
if (WaterMgr->m_NeedInfoUpdate)
|
||||
{
|
||||
WaterMgr->m_NeedsFullReloading = false;
|
||||
WaterMgr->m_NeedInfoUpdate = false;
|
||||
WaterMgr->CreateSuperfancyInfo(m_Simulation);
|
||||
}
|
||||
CPatch* patch = m_Patch;
|
||||
|
@ -649,7 +649,7 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, ShadowMap*
|
||||
WaterManager* WaterMgr = g_Renderer.GetWaterManager();
|
||||
CShaderDefines defines = context;
|
||||
|
||||
WaterMgr->updateQuality();
|
||||
WaterMgr->UpdateQuality();
|
||||
|
||||
// If we're using fancy water, make sure its shader is loaded
|
||||
if (!m->fancyWaterShader || WaterMgr->m_NeedsReloading)
|
||||
@ -689,18 +689,9 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, ShadowMap*
|
||||
WaterMgr->m_RenderWater = false;
|
||||
return false;
|
||||
}
|
||||
// we need to actually recompute the whole map settings.
|
||||
if (WaterMgr->m_NeedsFullReloading)
|
||||
{
|
||||
WaterMgr->m_waveTT = 0;
|
||||
WaterMgr->m_depthTT = 0;
|
||||
}
|
||||
WaterMgr->m_NeedsReloading = false;
|
||||
}
|
||||
|
||||
if (g_AtlasGameLoop->running)
|
||||
WaterMgr->m_TerrainChangeThisTurn = false;
|
||||
|
||||
CLOSTexture& losTexture = g_Renderer.GetScene().GetLOSTexture();
|
||||
|
||||
GLuint depthTex;
|
||||
@ -728,9 +719,9 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, ShadowMap*
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
// Calculating the advanced informations about Foam and all if the quality calls for it.
|
||||
/*if (WaterMgr->m_NeedsFullReloading && (WaterMgr->m_WaterFoam || WaterMgr->m_WaterCoastalWaves))
|
||||
/*if (WaterMgr->m_NeedInfoUpdate && (WaterMgr->m_WaterFoam || WaterMgr->m_WaterCoastalWaves))
|
||||
{
|
||||
WaterMgr->m_NeedsFullReloading = false;
|
||||
WaterMgr->m_NeedInfoUpdate = false;
|
||||
WaterMgr->CreateSuperfancyInfo();
|
||||
}*/
|
||||
|
||||
|
@ -92,8 +92,7 @@ WaterManager::WaterManager()
|
||||
m_WaterShadows = false;
|
||||
|
||||
m_NeedsReloading = false;
|
||||
m_NeedsFullReloading = true;
|
||||
m_TerrainChangeThisTurn = false;
|
||||
m_NeedInfoUpdate = true;
|
||||
|
||||
m_VBWaves = NULL;
|
||||
m_VBWavesIndices = NULL;
|
||||
@ -101,6 +100,12 @@ WaterManager::WaterManager()
|
||||
m_depthTT = 0;
|
||||
m_waveTT = 0;
|
||||
|
||||
m_MapSize = 0;
|
||||
|
||||
m_updatei0 = 0;
|
||||
m_updatej0 = 0;
|
||||
m_updatei1 = 0;
|
||||
m_updatej1 = 0;
|
||||
}
|
||||
|
||||
WaterManager::~WaterManager()
|
||||
@ -245,7 +250,6 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
|
||||
}
|
||||
|
||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
||||
ssize_t mapSize = terrain->GetVerticesPerSide();
|
||||
|
||||
CmpPtr<ICmpWaterManager> cmpWaterManager(*simulation, SYSTEM_ENTITY);
|
||||
if (!cmpWaterManager)
|
||||
@ -256,34 +260,38 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
|
||||
if (!cmpRangeManager)
|
||||
return;
|
||||
bool circular = cmpRangeManager->GetLosCircular();
|
||||
float mSize = mapSize*mapSize;
|
||||
float halfSize = (mapSize/2.0);
|
||||
float mSize = m_MapSize*m_MapSize;
|
||||
float halfSize = (m_MapSize/2.0);
|
||||
|
||||
// Warning: this won't work with multiple water planes
|
||||
m_WaterHeight = cmpWaterManager->GetExactWaterLevel(0,0);
|
||||
|
||||
// TODO: change this whenever we incrementally update because it's def. not too efficient
|
||||
delete[] m_WaveX;
|
||||
delete[] m_WaveZ;
|
||||
delete[] m_DistanceToShore;
|
||||
delete[] m_FoamFactor;
|
||||
|
||||
m_WaveX = new float[mapSize*mapSize];
|
||||
m_WaveZ = new float[mapSize*mapSize];
|
||||
m_DistanceToShore = new float[mapSize*mapSize];
|
||||
m_FoamFactor = new float[mapSize*mapSize];
|
||||
// Get the square we want to work on.
|
||||
i32 Xstart = m_updatei0;
|
||||
i32 Xend = m_updatei1;
|
||||
i32 Zstart = m_updatej0;
|
||||
i32 Zend = m_updatej1;
|
||||
|
||||
if (m_WaveX == NULL)
|
||||
{
|
||||
m_WaveX = new float[m_MapSize*m_MapSize];
|
||||
m_WaveZ = new float[m_MapSize*m_MapSize];
|
||||
m_DistanceToShore = new float[m_MapSize*m_MapSize];
|
||||
m_FoamFactor = new float[m_MapSize*m_MapSize];
|
||||
}
|
||||
|
||||
u16* heightmap = terrain->GetHeightMap();
|
||||
|
||||
// some temporary stuff for wave intensity
|
||||
// not really used too much right now.
|
||||
u8* waveForceHQ = new u8[mapSize*mapSize];
|
||||
u16 waterHeightInu16 = m_WaterHeight/HEIGHT_SCALE;
|
||||
//u8* waveForceHQ = new u8[mapSize*mapSize];
|
||||
|
||||
// used to cache terrain normals since otherwise we'd recalculate them a lot (I'm blurring the "normal" map).
|
||||
// this might be updated to actually cache in the terrain manager but that's not for now.
|
||||
CVector3D* normals = new CVector3D[mapSize*mapSize];
|
||||
CVector3D* normals = new CVector3D[m_MapSize*m_MapSize];
|
||||
|
||||
// TODO: reactivate?
|
||||
/*
|
||||
// calculate wave force (not really used right now)
|
||||
// and puts into "normals" the terrain normal at that point
|
||||
// so as to avoid recalculating terrain normals too often.
|
||||
@ -310,20 +318,21 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
|
||||
waveForceHQ[j*mapSize + i] = 255 - color * 40;
|
||||
}
|
||||
}
|
||||
*/
|
||||
// this creates information for waves and stores it in float arrays. PatchRData then puts it in the vertex info for speed.
|
||||
for (ssize_t i = 0; i < mapSize; ++i)
|
||||
for (ssize_t i = Xstart; i < Xend; ++i)
|
||||
{
|
||||
for (ssize_t j = 0; j < mapSize; ++j)
|
||||
for (ssize_t j = Zstart; j < Zend; ++j)
|
||||
{
|
||||
if (circular && (i-halfSize)*(i-halfSize)+(j-halfSize)*(j-halfSize) > mSize)
|
||||
{
|
||||
m_WaveX[j*mapSize + i] = 0.0f;
|
||||
m_WaveZ[j*mapSize + i] = 0.0f;
|
||||
m_DistanceToShore[j*mapSize + i] = 100;
|
||||
m_FoamFactor[j*mapSize + i] = 0.0f;
|
||||
m_WaveX[j*m_MapSize + i] = 0.0f;
|
||||
m_WaveZ[j*m_MapSize + i] = 0.0f;
|
||||
m_DistanceToShore[j*m_MapSize + i] = 100;
|
||||
m_FoamFactor[j*m_MapSize + i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
float depth = m_WaterHeight - heightmap[j*mapSize + i]*HEIGHT_SCALE;
|
||||
float depth = m_WaterHeight - heightmap[j*m_MapSize + i]*HEIGHT_SCALE;
|
||||
int distanceToShore = 10000;
|
||||
|
||||
// calculation of the distance to the shore.
|
||||
@ -336,10 +345,10 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
|
||||
{
|
||||
for (int yy = -5; yy <= 5; ++yy)
|
||||
{
|
||||
if (i+xx >= 0 && i + xx < mapSize)
|
||||
if (j + yy >= 0 && j + yy < mapSize)
|
||||
if (i+xx >= 0 && i + xx < (long)m_MapSize)
|
||||
if (j + yy >= 0 && j + yy < (long)m_MapSize)
|
||||
{
|
||||
float hereDepth = m_WaterHeight - heightmap[(j+yy)*mapSize + (i+xx)]*HEIGHT_SCALE;
|
||||
float hereDepth = m_WaterHeight - heightmap[(j+yy)*m_MapSize + (i+xx)]*HEIGHT_SCALE;
|
||||
if (hereDepth < 0 && xx*xx + yy*yy < distanceToShore)
|
||||
distanceToShore = xx*xx + yy*yy;
|
||||
}
|
||||
@ -375,10 +384,10 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
|
||||
// speedup with default values for land squares
|
||||
if (distanceToShore == 10000)
|
||||
{
|
||||
m_WaveX[j*mapSize + i] = 0.0f;
|
||||
m_WaveZ[j*mapSize + i] = 0.0f;
|
||||
m_DistanceToShore[j*mapSize + i] = 100;
|
||||
m_FoamFactor[j*mapSize + i] = 0.0f;
|
||||
m_WaveX[j*m_MapSize + i] = 0.0f;
|
||||
m_WaveZ[j*m_MapSize + i] = 0.0f;
|
||||
m_DistanceToShore[j*m_MapSize + i] = 100;
|
||||
m_FoamFactor[j*m_MapSize + i] = 0.0f;
|
||||
continue;
|
||||
}
|
||||
// We'll compute the normals and the "water raise", to know about foam
|
||||
@ -389,10 +398,10 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
|
||||
{
|
||||
for (int yy = -4; yy <= 4; yy += 2)
|
||||
{
|
||||
if (j+yy < mapSize && i+xx < mapSize && i+xx >= 0 && j+yy >= 0)
|
||||
normal += normals[(j+yy)*mapSize + (i+xx)];
|
||||
if (terrain->GetVertexGroundLevel(i+xx,j+yy) < heightmap[j*mapSize + i]*HEIGHT_SCALE)
|
||||
waterRaise += heightmap[j*mapSize + i]*HEIGHT_SCALE - terrain->GetVertexGroundLevel(i+xx,j+yy);
|
||||
if (j+yy < (long)m_MapSize && i+xx < (long)m_MapSize && i+xx >= 0 && j+yy >= 0)
|
||||
normal += normals[(j+yy)*m_MapSize + (i+xx)];
|
||||
if (terrain->GetVertexGroundLevel(i+xx,j+yy) < heightmap[j*m_MapSize + i]*HEIGHT_SCALE)
|
||||
waterRaise += heightmap[j*m_MapSize + i]*HEIGHT_SCALE - terrain->GetVertexGroundLevel(i+xx,j+yy);
|
||||
}
|
||||
}
|
||||
// normalizes the terrain info to avoid foam moving at too different speeds.
|
||||
@ -400,25 +409,25 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
|
||||
normal[1] = 0.1f;
|
||||
normal = normal.Normalized();
|
||||
|
||||
m_WaveX[j*mapSize + i] = normal[0];
|
||||
m_WaveZ[j*mapSize + i] = normal[2];
|
||||
m_WaveX[j*m_MapSize + i] = normal[0];
|
||||
m_WaveZ[j*m_MapSize + i] = normal[2];
|
||||
// distance is /5.0 to be a [0,1] value.
|
||||
|
||||
m_DistanceToShore[j*mapSize + i] = sqrtf(distanceToShore)/5.0f; // TODO: this can probably be cached as I'm integer here.
|
||||
m_DistanceToShore[j*m_MapSize + i] = sqrtf(distanceToShore)/5.0f; // TODO: this can probably be cached as I'm integer here.
|
||||
|
||||
// computing the amount of foam I want
|
||||
|
||||
depth = clamp(depth,0.0f,10.0f);
|
||||
float foamAmount = (waterRaise/255.0f) * (1.0f - depth/10.0f) * (waveForceHQ[j*mapSize+i]/255.0f) * (m_Waviness/8.0f);
|
||||
float foamAmount = (waterRaise/255.0f) * (1.0f - depth/10.0f) /** (waveForceHQ[j*m_MapSize+i]/255.0f)*/ * (m_Waviness/8.0f);
|
||||
foamAmount += clamp(m_Waviness/2.0f - distanceToShore,0.0f,m_Waviness/2.0f)/(m_Waviness/2.0f) * clamp(m_Waviness/9.0f,0.3f,1.0f);
|
||||
foamAmount = foamAmount > 1.0f ? 1.0f: foamAmount;
|
||||
|
||||
m_FoamFactor[j*mapSize + i] = foamAmount;
|
||||
m_FoamFactor[j*m_MapSize + i] = foamAmount;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] normals;
|
||||
delete[] waveForceHQ;
|
||||
//delete[] waveForceHQ;
|
||||
|
||||
// TODO: The rest should be cleaned up
|
||||
|
||||
@ -430,9 +439,9 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
|
||||
std::vector<CVector2D> waveSquares;
|
||||
|
||||
int size = 8; // I think this is the size of the squares.
|
||||
for (int i = 0; i < mapSize/size; ++i)
|
||||
for (size_t i = 0; i < m_MapSize/size; ++i)
|
||||
{
|
||||
for (int j = 0; j < mapSize/size; ++j)
|
||||
for (size_t j = 0; j < m_MapSize/size; ++j)
|
||||
{
|
||||
|
||||
int landTexel = 0;
|
||||
@ -575,9 +584,27 @@ void WaterManager::CreateSuperfancyInfo(CSimulation2* simulation)
|
||||
m_VBWavesIndices->m_Owner->UpdateChunkVertices(m_VBWavesIndices, &waves_indices[0]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// This will always recalculate for now
|
||||
void WaterManager::SetMapSize(size_t size)
|
||||
{
|
||||
// TODO: Im' blindly trusting the user here.
|
||||
m_MapSize = size;
|
||||
m_NeedInfoUpdate = true;
|
||||
m_updatei0 = 0;
|
||||
m_updatei1 = size;
|
||||
m_updatej0 = 0;
|
||||
m_updatej1 = size;
|
||||
|
||||
SAFE_ARRAY_DELETE(m_WaveX);
|
||||
SAFE_ARRAY_DELETE(m_WaveZ);
|
||||
SAFE_ARRAY_DELETE(m_DistanceToShore);
|
||||
SAFE_ARRAY_DELETE(m_FoamFactor);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// This will set the bools properly
|
||||
void WaterManager::updateQuality()
|
||||
void WaterManager::UpdateQuality()
|
||||
{
|
||||
if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERNORMAL) != m_WaterNormal) {
|
||||
m_WaterNormal = g_Renderer.GetOptionBool(CRenderer::OPT_WATERNORMAL);
|
||||
@ -590,12 +617,12 @@ void WaterManager::updateQuality()
|
||||
if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERFOAM) != m_WaterFoam) {
|
||||
m_WaterFoam = g_Renderer.GetOptionBool(CRenderer::OPT_WATERFOAM);
|
||||
m_NeedsReloading = true;
|
||||
m_NeedsFullReloading = true;
|
||||
m_NeedInfoUpdate = true;
|
||||
}
|
||||
if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERCOASTALWAVES) != m_WaterCoastalWaves) {
|
||||
m_WaterCoastalWaves = g_Renderer.GetOptionBool(CRenderer::OPT_WATERCOASTALWAVES);
|
||||
m_NeedsReloading = true;
|
||||
m_NeedsFullReloading = true;
|
||||
m_NeedInfoUpdate = true;
|
||||
}
|
||||
if (g_Renderer.GetOptionBool(CRenderer::OPT_WATERREFRACTION) != m_WaterRefraction) {
|
||||
m_WaterRefraction = g_Renderer.GetOptionBool(CRenderer::OPT_WATERREFRACTION);
|
||||
|
@ -58,11 +58,17 @@ public:
|
||||
float* m_DistanceToShore;
|
||||
float* m_FoamFactor;
|
||||
|
||||
size_t m_MapSize;
|
||||
ssize_t m_TexSize;
|
||||
|
||||
GLuint m_depthTT;
|
||||
GLuint m_waveTT;
|
||||
|
||||
// used to know what to update when updating parts of the terrain only.
|
||||
i32 m_updatei0;
|
||||
i32 m_updatej0;
|
||||
i32 m_updatei1;
|
||||
i32 m_updatej1;
|
||||
|
||||
int m_WaterCurrentTex;
|
||||
CColor m_WaterColor;
|
||||
@ -79,9 +85,7 @@ public:
|
||||
|
||||
bool m_NeedsReloading;
|
||||
// requires also recreating the super fancy information.
|
||||
bool m_NeedsFullReloading;
|
||||
// used only by Atlas to know when to update the water map.
|
||||
bool m_TerrainChangeThisTurn;
|
||||
bool m_NeedInfoUpdate;
|
||||
|
||||
bool m_WaterScroll;
|
||||
float m_WaterHeight;
|
||||
@ -147,10 +151,15 @@ public:
|
||||
*/
|
||||
void CreateSuperfancyInfo(CSimulation2* simulation);
|
||||
|
||||
/**
|
||||
* Updates the map size. Will trigger a complete recalculation of fancy water information the next turn.
|
||||
*/
|
||||
void SetMapSize(size_t size);
|
||||
|
||||
/**
|
||||
* Updates the settings to the one from the renderer, and sets m_NeedsReloading.
|
||||
*/
|
||||
void updateQuality();
|
||||
void UpdateQuality();
|
||||
|
||||
/**
|
||||
* Returns true if fancy water shaders will be used (i.e. the hardware is capable
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "simulation2/MessageTypes.h"
|
||||
|
||||
#include "graphics/Terrain.h"
|
||||
#include "Renderer/Renderer.h"
|
||||
#include "Renderer/WaterManager.h"
|
||||
#include "maths/Vector3D.h"
|
||||
|
||||
class CCmpTerrain : public ICmpTerrain
|
||||
@ -132,6 +134,9 @@ public:
|
||||
entity_pos_t::FromInt(tiles*(int)TERRAIN_TILE_SIZE),
|
||||
vertices);
|
||||
}
|
||||
|
||||
if (CRenderer::IsInitialised())
|
||||
g_Renderer.GetWaterManager()->SetMapSize(vertices);
|
||||
|
||||
MakeDirty(0, 0, tiles+1, tiles+1);
|
||||
}
|
||||
|
@ -83,9 +83,14 @@ public:
|
||||
// Tell the renderer to redraw the map.
|
||||
if (CRenderer::IsInitialised())
|
||||
{
|
||||
g_Renderer.GetWaterManager()->m_NeedsFullReloading = true;
|
||||
g_Renderer.GetWaterManager()->m_NeedsReloading = true;
|
||||
g_Renderer.GetWaterManager()->m_TerrainChangeThisTurn = true;
|
||||
const CMessageTerrainChanged& msgData = static_cast<const CMessageTerrainChanged&> (msg);
|
||||
g_Renderer.GetWaterManager()->m_NeedInfoUpdate = true;
|
||||
g_Renderer.GetWaterManager()->m_updatei0 = msgData.i0;
|
||||
g_Renderer.GetWaterManager()->m_updatej0 = msgData.j0;
|
||||
g_Renderer.GetWaterManager()->m_updatei1 = msgData.i1;
|
||||
g_Renderer.GetWaterManager()->m_updatej1 = msgData.j1;
|
||||
|
||||
GetSimContext().GetTerrain().MakeDirty(msgData.i0,msgData.j0,msgData.i1,msgData.j1,RENDERDATA_UPDATE_VERTICES);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user