Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/renderer/WaterManager.cpp
/* Copyright (C) 2020 Wildfire Games. | /* Copyright (C) 2021 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
Show All 10 Lines | |||||
*/ | */ | ||||
#include "precompiled.h" | #include "precompiled.h" | ||||
#include "graphics/Terrain.h" | #include "graphics/Terrain.h" | ||||
#include "graphics/TextureManager.h" | #include "graphics/TextureManager.h" | ||||
#include "graphics/ShaderManager.h" | #include "graphics/ShaderManager.h" | ||||
#include "graphics/ShaderProgram.h" | #include "graphics/ShaderProgram.h" | ||||
#include "lib/bits.h" | #include "lib/bits.h" | ||||
#include "lib/timer.h" | #include "lib/timer.h" | ||||
#include "lib/tex/tex.h" | #include "lib/tex/tex.h" | ||||
#include "lib/res/graphics/ogl_tex.h" | #include "lib/res/graphics/ogl_tex.h" | ||||
#include "maths/MathUtil.h" | #include "maths/MathUtil.h" | ||||
#include "maths/Vector2D.h" | #include "maths/Vector2D.h" | ||||
#include "ps/CLogger.h" | #include "ps/CLogger.h" | ||||
#include "ps/Game.h" | #include "ps/Game.h" | ||||
#include "ps/World.h" | #include "ps/World.h" | ||||
#include "renderer/WaterManager.h" | #include "renderer/WaterManager.h" | ||||
#include "renderer/Renderer.h" | #include "renderer/Renderer.h" | ||||
#include "renderer/RenderingOptions.h" | #include "renderer/RenderingOptions.h" | ||||
#include "simulation2/Simulation2.h" | #include "simulation2/Simulation2.h" | ||||
#include "simulation2/components/ICmpWaterManager.h" | #include "simulation2/components/ICmpWaterManager.h" | ||||
#include "simulation2/components/ICmpRangeManager.h" | #include "simulation2/components/ICmpRangeManager.h" | ||||
/////////////////////////////////////////////////////////////////////////////////////////////// | |||||
// WaterManager implementation | |||||
struct CoastalPoint | struct CoastalPoint | ||||
{ | { | ||||
CoastalPoint(int idx, CVector2D pos) : index(idx), position(pos) {}; | CoastalPoint(int idx, CVector2D pos) : index(idx), position(pos) {}; | ||||
int index; | int index; | ||||
CVector2D position; | CVector2D position; | ||||
}; | }; | ||||
struct SWavesVertex { | struct SWavesVertex { | ||||
Show All 14 Lines | |||||
struct WaveObject | struct WaveObject | ||||
{ | { | ||||
CVertexBuffer::VBChunk* m_VBvertices; | CVertexBuffer::VBChunk* m_VBvertices; | ||||
CBoundingBoxAligned m_AABB; | CBoundingBoxAligned m_AABB; | ||||
size_t m_Width; | size_t m_Width; | ||||
float m_TimeDiff; | float m_TimeDiff; | ||||
}; | }; | ||||
/////////////////////////////////////////////////////////////////// | |||||
// Construction/Destruction | |||||
WaterManager::WaterManager() | WaterManager::WaterManager() | ||||
{ | { | ||||
// water | // water | ||||
m_RenderWater = false; // disabled until textures are successfully loaded | m_RenderWater = false; // disabled until textures are successfully loaded | ||||
m_WaterHeight = 5.0f; | m_WaterHeight = 5.0f; | ||||
m_WaterCurrentTex = 0; | m_WaterCurrentTex = 0; | ||||
Show All 20 Lines | WaterManager::WaterManager() | ||||
m_ShoreWaves_VBIndices = NULL; | m_ShoreWaves_VBIndices = NULL; | ||||
m_WaterEffects = true; | m_WaterEffects = true; | ||||
m_WaterFancyEffects = false; | m_WaterFancyEffects = false; | ||||
m_WaterRealDepth = false; | m_WaterRealDepth = false; | ||||
m_WaterRefraction = false; | m_WaterRefraction = false; | ||||
m_WaterReflection = false; | m_WaterReflection = false; | ||||
m_WaterShadows = false; | |||||
m_WaterType = L"ocean"; | m_WaterType = L"ocean"; | ||||
m_NeedsReloading = false; | m_NeedsReloading = false; | ||||
m_NeedInfoUpdate = true; | m_NeedInfoUpdate = true; | ||||
m_FancyTexture = 0; | m_FancyTexture = 0; | ||||
m_FancyTextureDepth = 0; | m_FancyTextureDepth = 0; | ||||
m_ReflFboDepthTexture = 0; | m_ReflFboDepthTexture = 0; | ||||
▲ Show 20 Lines • Show All 740 Lines • ▼ Show 20 Lines | #else | ||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||
glEnable(GL_BLEND); | glEnable(GL_BLEND); | ||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
glEnable(GL_DEPTH_TEST); | glEnable(GL_DEPTH_TEST); | ||||
glDepthFunc(GL_ALWAYS); | glDepthFunc(GL_ALWAYS); | ||||
CShaderDefines none; | CShaderDefines none; | ||||
CShaderProgramPtr shad = g_Renderer.GetShaderManager().LoadProgram("glsl/waves", none); | CShaderProgramPtr shader = g_Renderer.GetShaderManager().LoadProgram("glsl/waves", none); | ||||
shad->Bind(); | shader->Bind(); | ||||
shad->BindTexture(str_waveTex, m_WaveTex); | shader->BindTexture(str_waveTex, m_WaveTex); | ||||
shad->BindTexture(str_foamTex, m_FoamTex); | shader->BindTexture(str_foamTex, m_FoamTex); | ||||
shad->Uniform(str_time, (float)m_WaterTexTimer); | shader->Uniform(str_time, (float)m_WaterTexTimer); | ||||
shad->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection()); | shader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection()); | ||||
for (size_t a = 0; a < m_ShoreWaves.size(); ++a) | for (size_t a = 0; a < m_ShoreWaves.size(); ++a) | ||||
{ | { | ||||
if (!frustrum.IsBoxVisible(m_ShoreWaves[a]->m_AABB)) | if (!frustrum.IsBoxVisible(m_ShoreWaves[a]->m_AABB)) | ||||
continue; | continue; | ||||
CVertexBuffer::VBChunk* VBchunk = m_ShoreWaves[a]->m_VBvertices; | CVertexBuffer::VBChunk* VBchunk = m_ShoreWaves[a]->m_VBvertices; | ||||
SWavesVertex* base = (SWavesVertex*)VBchunk->m_Owner->Bind(); | SWavesVertex* base = (SWavesVertex*)VBchunk->m_Owner->Bind(); | ||||
// setup data pointers | // setup data pointers | ||||
GLsizei stride = sizeof(SWavesVertex); | GLsizei stride = sizeof(SWavesVertex); | ||||
shad->VertexPointer(3, GL_FLOAT, stride, &base[VBchunk->m_Index].m_BasePosition); | shader->VertexPointer(3, GL_FLOAT, stride, &base[VBchunk->m_Index].m_BasePosition); | ||||
shad->TexCoordPointer(GL_TEXTURE0, 2, GL_UNSIGNED_BYTE, stride, &base[VBchunk->m_Index].m_UV); | shader->TexCoordPointer(GL_TEXTURE0, 2, GL_UNSIGNED_BYTE, stride, &base[VBchunk->m_Index].m_UV); | ||||
// NormalPointer(gl_FLOAT, stride, &base[m_VBWater->m_Index].m_UV) | // NormalPointer(gl_FLOAT, stride, &base[m_VBWater->m_Index].m_UV) | ||||
pglVertexAttribPointerARB(2, 2, GL_FLOAT, GL_TRUE, stride, &base[VBchunk->m_Index].m_PerpVect); // replaces commented above because my normal is vec2 | pglVertexAttribPointerARB(2, 2, GL_FLOAT, GL_TRUE, stride, &base[VBchunk->m_Index].m_PerpVect); // replaces commented above because my normal is vec2 | ||||
shad->VertexAttribPointer(str_a_apexPosition, 3, GL_FLOAT, false, stride, &base[VBchunk->m_Index].m_ApexPosition); | shader->VertexAttribPointer(str_a_apexPosition, 3, GL_FLOAT, false, stride, &base[VBchunk->m_Index].m_ApexPosition); | ||||
shad->VertexAttribPointer(str_a_splashPosition, 3, GL_FLOAT, false, stride, &base[VBchunk->m_Index].m_SplashPosition); | shader->VertexAttribPointer(str_a_splashPosition, 3, GL_FLOAT, false, stride, &base[VBchunk->m_Index].m_SplashPosition); | ||||
shad->VertexAttribPointer(str_a_retreatPosition, 3, GL_FLOAT, false, stride, &base[VBchunk->m_Index].m_RetreatPosition); | shader->VertexAttribPointer(str_a_retreatPosition, 3, GL_FLOAT, false, stride, &base[VBchunk->m_Index].m_RetreatPosition); | ||||
shad->AssertPointersBound(); | shader->AssertPointersBound(); | ||||
shad->Uniform(str_translation, m_ShoreWaves[a]->m_TimeDiff); | shader->Uniform(str_translation, m_ShoreWaves[a]->m_TimeDiff); | ||||
shad->Uniform(str_width, (int)m_ShoreWaves[a]->m_Width); | shader->Uniform(str_width, (int)m_ShoreWaves[a]->m_Width); | ||||
u8* indexBase = m_ShoreWaves_VBIndices->m_Owner->Bind(); | u8* indexBase = m_ShoreWaves_VBIndices->m_Owner->Bind(); | ||||
glDrawElements(GL_TRIANGLES, (GLsizei) (m_ShoreWaves[a]->m_Width-1)*(7*6), | glDrawElements(GL_TRIANGLES, (GLsizei) (m_ShoreWaves[a]->m_Width-1)*(7*6), | ||||
GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_ShoreWaves_VBIndices->m_Index)); | GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_ShoreWaves_VBIndices->m_Index)); | ||||
shad->Uniform(str_translation, m_ShoreWaves[a]->m_TimeDiff + 6.0f); | shader->Uniform(str_translation, m_ShoreWaves[a]->m_TimeDiff + 6.0f); | ||||
// TODO: figure out why this doesn't work. | // TODO: figure out why this doesn't work. | ||||
//g_Renderer.m_Stats.m_DrawCalls++; | //g_Renderer.m_Stats.m_DrawCalls++; | ||||
//g_Renderer.m_Stats.m_WaterTris += m_ShoreWaves_VBIndices->m_Count / 3; | //g_Renderer.m_Stats.m_WaterTris += m_ShoreWaves_VBIndices->m_Count / 3; | ||||
CVertexBuffer::Unbind(); | CVertexBuffer::Unbind(); | ||||
} | } | ||||
shad->Unbind(); | shader->Unbind(); | ||||
pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | ||||
glDisable(GL_BLEND); | glDisable(GL_BLEND); | ||||
glDepthFunc(GL_LEQUAL); | glDepthFunc(GL_LEQUAL); | ||||
#endif | #endif | ||||
} | } | ||||
void WaterManager::RecomputeWaterData() | void WaterManager::RecomputeWaterData() | ||||
▲ Show 20 Lines • Show All 142 Lines • ▼ Show 20 Lines | |||||
// This will set the bools properly | // This will set the bools properly | ||||
void WaterManager::UpdateQuality() | void WaterManager::UpdateQuality() | ||||
{ | { | ||||
if (g_RenderingOptions.GetWaterEffects() != m_WaterEffects) | if (g_RenderingOptions.GetWaterEffects() != m_WaterEffects) | ||||
{ | { | ||||
m_WaterEffects = g_RenderingOptions.GetWaterEffects(); | m_WaterEffects = g_RenderingOptions.GetWaterEffects(); | ||||
m_NeedsReloading = true; | m_NeedsReloading = true; | ||||
} | } | ||||
if (g_RenderingOptions.GetWaterFancyEffects() != m_WaterFancyEffects) { | if (g_RenderingOptions.GetWaterFancyEffects() != m_WaterFancyEffects) | ||||
{ | |||||
m_WaterFancyEffects = g_RenderingOptions.GetWaterFancyEffects(); | m_WaterFancyEffects = g_RenderingOptions.GetWaterFancyEffects(); | ||||
m_NeedsReloading = true; | m_NeedsReloading = true; | ||||
} | } | ||||
if (g_RenderingOptions.GetWaterRealDepth() != m_WaterRealDepth) { | if (g_RenderingOptions.GetWaterRealDepth() != m_WaterRealDepth) | ||||
{ | |||||
m_WaterRealDepth = g_RenderingOptions.GetWaterRealDepth(); | m_WaterRealDepth = g_RenderingOptions.GetWaterRealDepth(); | ||||
m_NeedsReloading = true; | m_NeedsReloading = true; | ||||
} | } | ||||
if (g_RenderingOptions.GetWaterRefraction() != m_WaterRefraction) { | if (g_RenderingOptions.GetWaterRefraction() != m_WaterRefraction) | ||||
{ | |||||
m_WaterRefraction = g_RenderingOptions.GetWaterRefraction(); | m_WaterRefraction = g_RenderingOptions.GetWaterRefraction(); | ||||
m_NeedsReloading = true; | m_NeedsReloading = true; | ||||
} | } | ||||
if (g_RenderingOptions.GetWaterReflection() != m_WaterReflection) { | if (g_RenderingOptions.GetWaterReflection() != m_WaterReflection) | ||||
{ | |||||
m_WaterReflection = g_RenderingOptions.GetWaterReflection(); | m_WaterReflection = g_RenderingOptions.GetWaterReflection(); | ||||
m_NeedsReloading = true; | m_NeedsReloading = true; | ||||
} | } | ||||
if (g_RenderingOptions.GetWaterShadows() != m_WaterShadows) { | |||||
m_WaterShadows = g_RenderingOptions.GetWaterShadows(); | |||||
m_NeedsReloading = true; | |||||
} | |||||
} | } | ||||
bool WaterManager::WillRenderFancyWater() | bool WaterManager::WillRenderFancyWater() | ||||
{ | { | ||||
return m_RenderWater && g_RenderingOptions.GetWaterEffects() && g_Renderer.GetCapabilities().m_PrettyWater; | return m_RenderWater && g_RenderingOptions.GetWaterEffects() && g_Renderer.GetCapabilities().m_PrettyWater; | ||||
} | } |
Wildfire Games · Phabricator