Optimizes FBO usages for LOSTexture and water shore foam.
Tested By: Stan Differential Revision: https://code.wildfiregames.com/D4418 This was SVN commit r26180.
This commit is contained in:
parent
dfafdcd792
commit
b061a7ead4
@ -60,8 +60,7 @@ static const size_t g_BlurSize = 7;
|
||||
static const size_t g_SubTextureAlignment = 4;
|
||||
|
||||
CLOSTexture::CLOSTexture(CSimulation2& simulation)
|
||||
: m_Simulation(simulation), m_Dirty(true), m_ShaderInitialized(false),
|
||||
m_SmoothFBO(0), m_MapSize(0), m_WhichTex(true)
|
||||
: m_Simulation(simulation)
|
||||
{
|
||||
if (CRenderer::IsInitialised() && g_RenderingOptions.GetSmoothLOS())
|
||||
CreateShader();
|
||||
@ -69,8 +68,10 @@ CLOSTexture::CLOSTexture(CSimulation2& simulation)
|
||||
|
||||
CLOSTexture::~CLOSTexture()
|
||||
{
|
||||
if (m_SmoothFBO)
|
||||
glDeleteFramebuffersEXT(1, &m_SmoothFBO);
|
||||
if (m_SmoothFBO1)
|
||||
glDeleteFramebuffersEXT(1, &m_SmoothFBO1);
|
||||
if (m_SmoothFBO2)
|
||||
glDeleteFramebuffersEXT(1, &m_SmoothFBO2);
|
||||
|
||||
if (m_Texture)
|
||||
DeleteTexture();
|
||||
@ -79,10 +80,10 @@ CLOSTexture::~CLOSTexture()
|
||||
// Create the LOS texture engine. Should be ran only once.
|
||||
bool CLOSTexture::CreateShader()
|
||||
{
|
||||
m_smoothShader = g_Renderer.GetShaderManager().LoadEffect(str_los_interp);
|
||||
CShaderProgramPtr shader = m_smoothShader->GetShader();
|
||||
m_SmoothTech = g_Renderer.GetShaderManager().LoadEffect(str_los_interp);
|
||||
CShaderProgramPtr shader = m_SmoothTech->GetShader();
|
||||
|
||||
m_ShaderInitialized = m_smoothShader && shader;
|
||||
m_ShaderInitialized = m_SmoothTech && shader;
|
||||
|
||||
if (!m_ShaderInitialized)
|
||||
{
|
||||
@ -91,7 +92,8 @@ bool CLOSTexture::CreateShader()
|
||||
return false;
|
||||
}
|
||||
|
||||
glGenFramebuffersEXT(1, &m_SmoothFBO);
|
||||
glGenFramebuffersEXT(1, &m_SmoothFBO1);
|
||||
glGenFramebuffersEXT(1, &m_SmoothFBO2);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -139,18 +141,10 @@ void CLOSTexture::InterpolateLOS(Renderer::Backend::GL::CDeviceCommandContext* d
|
||||
if (skipSmoothLOS)
|
||||
return;
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_SmoothFBO);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
|
||||
(m_WhichTex ? m_TextureSmooth2 : m_TextureSmooth1)->GetHandle(), 0);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (m_WhichTex ? m_SmoothFBO2 : m_SmoothFBO1));
|
||||
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
{
|
||||
LOGWARNING("LOS framebuffer object incomplete: 0x%04X", status);
|
||||
}
|
||||
|
||||
m_smoothShader->BeginPass();
|
||||
CShaderProgramPtr shader = m_smoothShader->GetShader();
|
||||
m_SmoothTech->BeginPass();
|
||||
CShaderProgramPtr shader = m_SmoothTech->GetShader();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
@ -198,9 +192,7 @@ void CLOSTexture::InterpolateLOS(Renderer::Backend::GL::CDeviceCommandContext* d
|
||||
g_Renderer.SetViewport(oldVp);
|
||||
|
||||
shader->Unbind();
|
||||
m_smoothShader->EndPass();
|
||||
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0);
|
||||
m_SmoothTech->EndPass();
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
@ -256,6 +248,20 @@ void CLOSTexture::ConstructTexture(Renderer::Backend::GL::CDeviceCommandContext*
|
||||
m_TextureSmooth2 = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::A8, textureSize, textureSize, defaultSamplerDesc);
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_SmoothFBO1);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
|
||||
m_TextureSmooth1->GetHandle(), 0);
|
||||
GLenum status1 = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_SmoothFBO2);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
|
||||
m_TextureSmooth2->GetHandle(), 0);
|
||||
GLenum status2 = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
if (status1 != GL_FRAMEBUFFER_COMPLETE_EXT || status2 != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
{
|
||||
LOGWARNING("LOS framebuffer object incomplete: 0x%04X 0x%04X", status1, status2);
|
||||
}
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
deviceCommandContext->UploadTexture(m_TextureSmooth1.get(), Renderer::Backend::Format::A8, texData.get(), textureSize * textureSize);
|
||||
deviceCommandContext->UploadTexture(m_TextureSmooth2.get(), Renderer::Backend::Format::A8, texData.get(), textureSize * textureSize);
|
||||
}
|
||||
|
@ -84,19 +84,22 @@ private:
|
||||
|
||||
CSimulation2& m_Simulation;
|
||||
|
||||
bool m_Dirty;
|
||||
bool m_Dirty = true;
|
||||
|
||||
bool m_ShaderInitialized;
|
||||
bool m_ShaderInitialized = false;
|
||||
|
||||
std::unique_ptr<Renderer::Backend::GL::CTexture>
|
||||
m_Texture, m_TextureSmooth1, m_TextureSmooth2;
|
||||
|
||||
bool m_WhichTex;
|
||||
bool m_WhichTex = true;
|
||||
|
||||
GLuint m_SmoothFBO;
|
||||
CShaderTechniquePtr m_smoothShader;
|
||||
// We update textures once a frame, so we change a FBO once a frame. That
|
||||
// allows us to use two ping-pong FBOs instead of checking completeness of
|
||||
// FBO each frame.
|
||||
GLuint m_SmoothFBO1 = 0, m_SmoothFBO2 = 0;
|
||||
CShaderTechniquePtr m_SmoothTech;
|
||||
|
||||
size_t m_MapSize; // vertexes per side
|
||||
size_t m_MapSize = 0; // vertexes per side
|
||||
|
||||
CMatrix3D m_TextureMatrix;
|
||||
CMatrix3D m_MinimapTextureMatrix;
|
||||
|
@ -880,11 +880,15 @@ void CSceneRenderer::RenderSubmissions(
|
||||
{
|
||||
if (waterScissor.GetVolume() > 0 && m->waterManager.WillRenderFancyWater())
|
||||
{
|
||||
m->waterManager.UpdateQuality();
|
||||
|
||||
PROFILE3_GPU("water scissor");
|
||||
RenderReflections(context, waterScissor);
|
||||
|
||||
if (g_RenderingOptions.GetWaterRefraction())
|
||||
RenderRefractions(context, waterScissor);
|
||||
|
||||
m->terrainRenderer.RenderWaterFoamOccluders(cullGroup);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,8 @@
|
||||
* TerrainRenderer keeps track of which phase it is in, to detect
|
||||
* when Submit, PrepareForRendering etc. are called in the wrong order.
|
||||
*/
|
||||
enum Phase {
|
||||
enum Phase
|
||||
{
|
||||
Phase_Submit,
|
||||
Phase_Render
|
||||
};
|
||||
@ -400,38 +401,6 @@ bool TerrainRenderer::RenderFancyWater(const CShaderDefines& context, int cullGr
|
||||
const double time = waterManager.m_WaterTexTimer;
|
||||
const float repeatPeriod = waterManager.m_RepeatPeriod;
|
||||
|
||||
// Render normals and foam to a framebuffer if we're in fancy effects
|
||||
if (waterManager.m_WaterFancyEffects)
|
||||
{
|
||||
// Save the post-processing framebuffer.
|
||||
GLint fbo;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fbo);
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, waterManager.m_FancyEffectsFBO);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
// Overwrite waves that would be behind the ground.
|
||||
CShaderTechniquePtr dummyTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
|
||||
dummyTech->BeginPass();
|
||||
CShaderProgramPtr dummyShader = dummyTech->GetShader();
|
||||
|
||||
dummyShader->Uniform(str_transform, sceneRenderer.GetViewCamera().GetViewProjection());
|
||||
dummyShader->Uniform(str_color, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
std::vector<CPatchRData*>& visiblePatches = m->visiblePatches[cullGroup];
|
||||
for (size_t i = 0; i < visiblePatches.size(); ++i)
|
||||
{
|
||||
CPatchRData* data = visiblePatches[i];
|
||||
data->RenderWater(dummyShader, true, true);
|
||||
}
|
||||
dummyTech->EndPass();
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
|
||||
}
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
@ -580,9 +549,7 @@ void TerrainRenderer::RenderSimpleWater(int cullGroup)
|
||||
// Render water that is part of the terrain
|
||||
void TerrainRenderer::RenderWater(const CShaderDefines& context, int cullGroup, ShadowMap* shadow)
|
||||
{
|
||||
WaterManager& waterManager = g_Renderer.GetSceneRenderer().GetWaterManager();
|
||||
|
||||
waterManager.UpdateQuality();
|
||||
const WaterManager& waterManager = g_Renderer.GetSceneRenderer().GetWaterManager();
|
||||
|
||||
if (!waterManager.WillRenderFancyWater())
|
||||
RenderSimpleWater(cullGroup);
|
||||
@ -590,6 +557,36 @@ void TerrainRenderer::RenderWater(const CShaderDefines& context, int cullGroup,
|
||||
RenderFancyWater(context, cullGroup, shadow);
|
||||
}
|
||||
|
||||
void TerrainRenderer::RenderWaterFoamOccluders(int cullGroup)
|
||||
{
|
||||
CSceneRenderer& sceneRenderer = g_Renderer.GetSceneRenderer();
|
||||
const WaterManager& waterManager = sceneRenderer.GetWaterManager();
|
||||
if (!waterManager.WillRenderFancyWater())
|
||||
return;
|
||||
|
||||
// Render normals and foam to a framebuffer if we're using fancy effects.
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, waterManager.m_FancyEffectsFBO);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
// Overwrite waves that would be behind the ground.
|
||||
CShaderTechniquePtr dummyTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
|
||||
dummyTech->BeginPass();
|
||||
CShaderProgramPtr dummyShader = dummyTech->GetShader();
|
||||
|
||||
dummyShader->Uniform(str_transform, sceneRenderer.GetViewCamera().GetViewProjection());
|
||||
dummyShader->Uniform(str_color, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
for (CPatchRData* data : m->visiblePatches[cullGroup])
|
||||
data->RenderWater(dummyShader, true, true);
|
||||
dummyTech->EndPass();
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
void TerrainRenderer::RenderPriorities(int cullGroup)
|
||||
{
|
||||
PROFILE("priorities");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
/* Copyright (C) 2022 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -130,6 +130,11 @@ public:
|
||||
*/
|
||||
void RenderWater(const CShaderDefines& context, int cullGroup, ShadowMap* shadow);
|
||||
|
||||
/**
|
||||
* Renders terrain to a framebuffer to occlude shore foams.
|
||||
*/
|
||||
void RenderWaterFoamOccluders(int cullGroup);
|
||||
|
||||
/**
|
||||
* Calculate a scissor rectangle for the visible water patches.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user