Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/renderer/WaterManager.cpp
Show First 20 Lines • Show All 411 Lines • ▼ Show 20 Lines | void WaterManager::UnloadWaterTextures() | ||||
pglDeleteFramebuffersEXT(1, &m_RefractionFbo); | pglDeleteFramebuffersEXT(1, &m_RefractionFbo); | ||||
pglDeleteFramebuffersEXT(1, &m_ReflectionFbo); | pglDeleteFramebuffersEXT(1, &m_ReflectionFbo); | ||||
} | } | ||||
/////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////// | ||||
// Calculate our binary heightmap from the terrain heightmap. | // Calculate our binary heightmap from the terrain heightmap. | ||||
void WaterManager::RecomputeDistanceHeightmap() | void WaterManager::RecomputeDistanceHeightmap() | ||||
{ | { | ||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | |||||
if (!terrain || !terrain->GetHeightMap()) | |||||
return; | |||||
size_t SideSize = m_MapSize*2; | size_t SideSize = m_MapSize*2; | ||||
if (m_DistanceHeightmap == NULL) | if (m_DistanceHeightmap == NULL) | ||||
m_DistanceHeightmap = new float[SideSize*SideSize]; | m_DistanceHeightmap = new float[SideSize*SideSize]; | ||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | |||||
// Create a manhattan-distance heightmap. | // Create a manhattan-distance heightmap. | ||||
// This is currently upsampled by a factor of 2 to get more precision | // This is currently upsampled by a factor of 2 to get more precision | ||||
// This could be refined to only be done near the coast itself, but it's probably not necessary. | // This could be refined to only be done near the coast itself, but it's probably not necessary. | ||||
for (size_t z = 0; z < SideSize; ++z) | for (size_t z = 0; z < SideSize; ++z) | ||||
{ | { | ||||
float level = SideSize; | float level = SideSize; | ||||
for (size_t x = 0; x < SideSize; ++x) | for (size_t x = 0; x < SideSize; ++x) | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | void WaterManager::RecomputeDistanceHeightmap() | ||||
} | } | ||||
} | } | ||||
// This requires m_DistanceHeightmap to be defined properly. | // This requires m_DistanceHeightmap to be defined properly. | ||||
void WaterManager::CreateWaveMeshes() | void WaterManager::CreateWaveMeshes() | ||||
{ | { | ||||
size_t SideSize = m_MapSize*2; | size_t SideSize = m_MapSize*2; | ||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | ||||
if (!terrain || !terrain->GetHeightMap()) | |||||
return; | |||||
for (WaveObject* const& obj : m_ShoreWaves) | for (WaveObject* const& obj : m_ShoreWaves) | ||||
{ | { | ||||
if (obj->m_VBvertices) | if (obj->m_VBvertices) | ||||
g_VBMan.Release(obj->m_VBvertices); | g_VBMan.Release(obj->m_VBvertices); | ||||
delete obj; | delete obj; | ||||
} | } | ||||
m_ShoreWaves.clear(); | m_ShoreWaves.clear(); | ||||
▲ Show 20 Lines • Show All 445 Lines • ▼ Show 20 Lines | #else | ||||
glDepthFunc(GL_LEQUAL); | glDepthFunc(GL_LEQUAL); | ||||
#endif | #endif | ||||
} | } | ||||
/////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////// | ||||
// Calculate The blurred normal map to get an idea of where water ought to go. | // Calculate The blurred normal map to get an idea of where water ought to go. | ||||
void WaterManager::RecomputeBlurredNormalMap() | void WaterManager::RecomputeBlurredNormalMap() | ||||
{ | { | ||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | |||||
if (!terrain || !terrain->GetHeightMap()) | |||||
return; | |||||
// used to cache terrain normals since otherwise we'd recalculate them a lot (I'm blurring the "normal" map). | // 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. | // this might be updated to actually cache in the terrain manager but that's not for now. | ||||
if (m_BlurredNormalMap == NULL) | if (m_BlurredNormalMap == NULL) | ||||
m_BlurredNormalMap = new CVector3D[m_MapSize*m_MapSize]; | m_BlurredNormalMap = new CVector3D[m_MapSize*m_MapSize]; | ||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | |||||
// It's really slow to calculate normals so cache them first. | // It's really slow to calculate normals so cache them first. | ||||
CVector3D* normals = new CVector3D[m_MapSize*m_MapSize]; | CVector3D* normals = new CVector3D[m_MapSize*m_MapSize]; | ||||
// Not the edges, we won't care about them. | // Not the edges, we won't care about them. | ||||
float ii = 8.0f, jj = 8.0f; | float ii = 8.0f, jj = 8.0f; | ||||
for (size_t j = 2; j < m_MapSize-2; ++j, jj += 4.0f) | for (size_t j = 2; j < m_MapSize-2; ++j, jj += 4.0f) | ||||
for (size_t i = 2; i < m_MapSize-2; ++i, ii += 4.0f) | for (size_t i = 2; i < m_MapSize-2; ++i, ii += 4.0f) | ||||
{ | { | ||||
Show All 30 Lines | for (size_t j = 2; j < m_MapSize-2; ++j, jj += 4.0f) | ||||
blurValue += normals[(j+2)*m_MapSize + i]; | blurValue += normals[(j+2)*m_MapSize + i]; | ||||
m_BlurredNormalMap[j*m_MapSize + i] = blurValue * 0.2f; | m_BlurredNormalMap[j*m_MapSize + i] = blurValue * 0.2f; | ||||
} | } | ||||
} | } | ||||
delete[] normals; | delete[] normals; | ||||
} | } | ||||
void WaterManager::RecomputeWaterData() | |||||
{ | |||||
if (!m_MapSize) | |||||
return; | |||||
RecomputeBlurredNormalMap(); | |||||
RecomputeDistanceHeightmap(); | |||||
RecomputeWindStrength(); | |||||
CreateWaveMeshes(); | |||||
} | |||||
/////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////// | ||||
// Calculate the strength of the wind at a given point on the map. | // Calculate the strength of the wind at a given point on the map. | ||||
// This is too slow and should support limited recomputation. | // This is too slow and should support limited recomputation. | ||||
void WaterManager::RecomputeWindStrength() | void WaterManager::RecomputeWindStrength() | ||||
{ | { | ||||
if (m_WindStrength == NULL) | if (m_WindStrength == NULL) | ||||
m_WindStrength = new float[m_MapSize*m_MapSize]; | m_WindStrength = new float[m_MapSize*m_MapSize]; | ||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); | ||||
if (!terrain || !terrain->GetHeightMap()) | |||||
return; | |||||
float waterLevel = m_WaterHeight; | float waterLevel = m_WaterHeight; | ||||
CVector2D windDir = CVector2D(cos(m_WindAngle),sin(m_WindAngle)); | CVector2D windDir = CVector2D(cos(m_WindAngle),sin(m_WindAngle)); | ||||
CVector2D perp = CVector2D(-windDir.Y, windDir.X); | CVector2D perp = CVector2D(-windDir.Y, windDir.X); | ||||
// Our kernel will sample 5 points going towards the wind (generally). | // Our kernel will sample 5 points going towards the wind (generally). | ||||
int kernel[5][2] = { {(int)windDir.X*2,(int)windDir.Y*2}, {(int)windDir.X*5,(int)windDir.Y*5}, {(int)windDir.X*9,(int)windDir.Y*9}, {(int)windDir.X*16,(int)windDir.Y*16}, {(int)windDir.X*25,(int)windDir.Y*25} }; | int kernel[5][2] = { {(int)windDir.X*2,(int)windDir.Y*2}, {(int)windDir.X*5,(int)windDir.Y*5}, {(int)windDir.X*9,(int)windDir.Y*9}, {(int)windDir.X*16,(int)windDir.Y*16}, {(int)windDir.X*25,(int)windDir.Y*25} }; | ||||
▲ Show 20 Lines • Show All 119 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator