From c2c3a3b66365ed3807563e0ed7e0df91e4190ade Mon Sep 17 00:00:00 2001 From: vladislavbelov Date: Sun, 26 Dec 2021 09:48:48 +0000 Subject: [PATCH] Moves shadow map and terrain overlay to GL texture class continuing 57ba7c4a1c. Tested By: Stan Differential Revision: https://code.wildfiregames.com/D4393 This was SVN commit r26117. --- source/renderer/ShadowMap.cpp | 103 +++++++++++++---------------- source/renderer/TerrainOverlay.cpp | 37 +++++------ source/renderer/TerrainOverlay.h | 7 +- source/renderer/backend/Format.h | 3 + 4 files changed, 69 insertions(+), 81 deletions(-) diff --git a/source/renderer/ShadowMap.cpp b/source/renderer/ShadowMap.cpp index fdc29b1893..cf78f7d1f8 100644 --- a/source/renderer/ShadowMap.cpp +++ b/source/renderer/ShadowMap.cpp @@ -35,6 +35,7 @@ #include "ps/CStrInternStatic.h" #include "ps/Profile.h" #include "ps/VideoMode.h" +#include "renderer/backend/gl/Texture.h" #include "renderer/DebugRenderer.h" #include "renderer/Renderer.h" #include "renderer/RenderingOptions.h" @@ -59,7 +60,7 @@ struct ShadowMapInternals // the EXT_framebuffer_object framebuffer GLuint Framebuffer; // handle of shadow map - GLuint Texture; + std::unique_ptr Texture; // bit depth for the depth texture int DepthTextureBits; @@ -109,7 +110,7 @@ struct ShadowMapInternals // incorrectly when the FBO has only a depth attachment. // When m_ShadowAlphaFix is true, we use DummyTexture to store a useless // alpha texture which is attached to the FBO as a workaround. - GLuint DummyTexture; + std::unique_ptr DummyTexture; // Copy of renderer's standard view camera, saved between // BeginRender and EndRender while we replace it with the shadow camera @@ -213,10 +214,9 @@ ShadowMap::ShadowMap() ShadowMap::~ShadowMap() { - if (m->Texture) - glDeleteTextures(1, &m->Texture); - if (m->DummyTexture) - glDeleteTextures(1, &m->DummyTexture); + m->Texture.reset(); + m->DummyTexture.reset(); + if (m->Framebuffer) glDeleteFramebuffersEXT(1, &m->Framebuffer); @@ -227,10 +227,9 @@ ShadowMap::~ShadowMap() // size has changed void ShadowMap::RecreateTexture() { - if (m->Texture) - glDeleteTextures(1, &m->Texture); - if (m->DummyTexture) - glDeleteTextures(1, &m->DummyTexture); + m->Texture.reset(); + m->DummyTexture.reset(); + if (m->Framebuffer) glDeleteFramebuffersEXT(1, &m->Framebuffer); @@ -483,16 +482,9 @@ void ShadowMapInternals::CalculateShadowMatrices(const int cascade) void ShadowMapInternals::CreateTexture() { // Cleanup - if (Texture) - { - glDeleteTextures(1, &Texture); - Texture = 0; - } - if (DummyTexture) - { - glDeleteTextures(1, &DummyTexture); - DummyTexture = 0; - } + Texture.reset(); + DummyTexture.reset(); + if (Framebuffer) { glDeleteFramebuffersEXT(1, &Framebuffer); @@ -539,16 +531,18 @@ void ShadowMapInternals::CreateTexture() GLenum format; const char* formatName; + Renderer::Backend::Format backendFormat = Renderer::Backend::Format::UNDEFINED; #if CONFIG2_GLES format = GL_DEPTH_COMPONENT; formatName = "DEPTH_COMPONENT"; + backendFormat = Renderer::Backend::Format::D24; #else switch (DepthTextureBits) { - case 16: format = GL_DEPTH_COMPONENT16; formatName = "DEPTH_COMPONENT16"; break; - case 24: format = GL_DEPTH_COMPONENT24; formatName = "DEPTH_COMPONENT24"; break; - case 32: format = GL_DEPTH_COMPONENT32; formatName = "DEPTH_COMPONENT32"; break; - default: format = GL_DEPTH_COMPONENT; formatName = "DEPTH_COMPONENT"; break; + case 16: format = GL_DEPTH_COMPONENT16; formatName = "DEPTH_COMPONENT16"; backendFormat = Renderer::Backend::Format::D16; break; + case 24: format = GL_DEPTH_COMPONENT24; formatName = "DEPTH_COMPONENT24"; backendFormat = Renderer::Backend::Format::D24; break; + case 32: format = GL_DEPTH_COMPONENT32; formatName = "DEPTH_COMPONENT32"; backendFormat = Renderer::Backend::Format::D32; break; + default: format = GL_DEPTH_COMPONENT; formatName = "DEPTH_COMPONENT"; backendFormat = Renderer::Backend::Format::D24; break; } #endif ENSURE(formatName); @@ -558,39 +552,38 @@ void ShadowMapInternals::CreateTexture() if (g_RenderingOptions.GetShadowAlphaFix()) { - glGenTextures(1, &DummyTexture); - g_Renderer.BindTexture(0, DummyTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + DummyTexture = Renderer::Backend::GL::CTexture::Create2D( + Renderer::Backend::Format::R8G8B8A8, Width, Height, + Renderer::Backend::Sampler::MakeDefaultSampler( + Renderer::Backend::Sampler::Filter::NEAREST, + Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE)); + + g_Renderer.BindTexture(0, DummyTexture->GetHandle()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } - glGenTextures(1, &Texture); - g_Renderer.BindTexture(0, Texture); + Texture = Renderer::Backend::GL::CTexture::Create2D( + backendFormat, Width, Height, + Renderer::Backend::Sampler::MakeDefaultSampler( +#if CONFIG2_GLES + // GLES doesn't do depth comparisons, so treat it as a + // basic unfiltered depth texture + Renderer::Backend::Sampler::Filter::NEAREST, +#else + // Use GL_LINEAR to trigger automatic PCF on some devices + Renderer::Backend::Sampler::Filter::LINEAR, +#endif + Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE)); + g_Renderer.BindTexture(0, Texture->GetHandle()); glTexImage2D(GL_TEXTURE_2D, 0, format, Width, Height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL); // GLES requires type == UNSIGNED_SHORT or UNSIGNED_INT - // set texture parameters - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - -#if CONFIG2_GLES - // GLES doesn't do depth comparisons, so treat it as a - // basic unfiltered depth texture - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); -#else +#if !CONFIG2_GLES // Enable automatic depth comparisons glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - - // Use GL_LINEAR to trigger automatic PCF on some devices - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); #endif ogl_WarnIfError(); @@ -599,11 +592,11 @@ void ShadowMapInternals::CreateTexture() glBindTexture(GL_TEXTURE_2D, 0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Framebuffer); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, Texture, 0); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, Texture->GetHandle(), 0); if (g_RenderingOptions.GetShadowAlphaFix()) { - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, DummyTexture, 0); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, DummyTexture->GetHandle(), 0); } else { @@ -704,7 +697,7 @@ void ShadowMap::BindTo(const CShaderProgramPtr& shader) const if (!shader->GetTextureBinding(str_shadowTex).Active()) return; - shader->BindTexture(str_shadowTex, m->Texture); + shader->BindTexture(str_shadowTex, m->Texture->GetHandle()); shader->Uniform(str_shadowScale, m->Width, m->Height, 1.0f / m->Width, 1.0f / m->Height); const CVector3D cameraForward = g_Renderer.GetCullCamera().GetOrientation().GetIn(); shader->Uniform(str_cameraForward, cameraForward.X, cameraForward.Y, cameraForward.Z, @@ -740,11 +733,7 @@ void ShadowMap::SetDepthTextureBits(int bits) { if (bits != m->DepthTextureBits) { - if (m->Texture) - { - glDeleteTextures(1, &m->Texture); - m->Texture = 0; - } + m->Texture.reset(); m->Width = m->Height = 0; m->DepthTextureBits = bits; @@ -801,7 +790,7 @@ void ShadowMap::RenderDebugTexture() glDisable(GL_DEPTH_TEST); #if !CONFIG2_GLES - g_Renderer.BindTexture(0, m->Texture); + g_Renderer.BindTexture(0, m->Texture->GetHandle()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); #endif @@ -810,7 +799,7 @@ void ShadowMap::RenderDebugTexture() CShaderProgramPtr texShader = texTech->GetShader(); texShader->Uniform(str_transform, GetDefaultGuiMatrix()); - texShader->BindTexture(str_tex, m->Texture); + texShader->BindTexture(str_tex, m->Texture->GetHandle()); texShader->Uniform(str_colorAdd, CColor(0.0f, 0.0f, 0.0f, 1.0f)); texShader->Uniform(str_colorMul, CColor(1.0f, 1.0f, 1.0f, 0.0f)); texShader->Uniform(str_grayscaleFactor, 0.0f); @@ -833,7 +822,7 @@ void ShadowMap::RenderDebugTexture() texTech->EndPass(); #if !CONFIG2_GLES - g_Renderer.BindTexture(0, m->Texture); + g_Renderer.BindTexture(0, m->Texture->GetHandle()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); #endif diff --git a/source/renderer/TerrainOverlay.cpp b/source/renderer/TerrainOverlay.cpp index 29ab524c7e..29b6bf9cd7 100644 --- a/source/renderer/TerrainOverlay.cpp +++ b/source/renderer/TerrainOverlay.cpp @@ -303,15 +303,11 @@ void TerrainOverlay::RenderTileOutline(const CColor& color, int line_width, bool ////////////////////////////////////////////////////////////////////////// TerrainTextureOverlay::TerrainTextureOverlay(float texelsPerTile, int priority) : - ITerrainOverlay(priority), m_TexelsPerTile(texelsPerTile), m_Texture(0), m_TextureW(0), m_TextureH(0) + ITerrainOverlay(priority), m_TexelsPerTile(texelsPerTile) { - glGenTextures(1, &m_Texture); } -TerrainTextureOverlay::~TerrainTextureOverlay() -{ - glDeleteTextures(1, &m_Texture); -} +TerrainTextureOverlay::~TerrainTextureOverlay() = default; void TerrainTextureOverlay::RenderAfterWater(int cullGroup) { @@ -320,38 +316,39 @@ void TerrainTextureOverlay::RenderAfterWater(int cullGroup) ssize_t w = (ssize_t)(terrain->GetTilesPerSide() * m_TexelsPerTile); ssize_t h = (ssize_t)(terrain->GetTilesPerSide() * m_TexelsPerTile); + const uint32_t requiredWidth = round_up_to_pow2(w); + const uint32_t requiredHeight = round_up_to_pow2(h); + glActiveTextureARB(GL_TEXTURE0); // Recreate the texture with new size if necessary - if (round_up_to_pow2(w) != m_TextureW || round_up_to_pow2(h) != m_TextureH) + if (!m_Texture || m_Texture->GetWidth() != requiredWidth || m_Texture->GetHeight() != requiredHeight) { - m_TextureW = round_up_to_pow2(w); - m_TextureH = round_up_to_pow2(h); + m_Texture = Renderer::Backend::GL::CTexture::Create2D( + Renderer::Backend::Format::R8G8B8A8, requiredWidth, requiredHeight, + Renderer::Backend::Sampler::MakeDefaultSampler( + Renderer::Backend::Sampler::Filter::NEAREST, + Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE)); - glBindTexture(GL_TEXTURE_2D, m_Texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureW, m_TextureH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glBindTexture(GL_TEXTURE_2D, m_Texture->GetHandle()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_Texture->GetWidth(), m_Texture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } u8* data = (u8*)calloc(w * h, 4); BuildTextureRGBA(data, w, h); - glBindTexture(GL_TEXTURE_2D, m_Texture); + glBindTexture(GL_TEXTURE_2D, m_Texture->GetHandle()); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data); free(data); CMatrix3D matrix; matrix.SetZero(); - matrix._11 = m_TexelsPerTile / (m_TextureW * TERRAIN_TILE_SIZE); - matrix._23 = m_TexelsPerTile / (m_TextureH * TERRAIN_TILE_SIZE); + matrix._11 = m_TexelsPerTile / (m_Texture->GetWidth() * TERRAIN_TILE_SIZE); + matrix._23 = m_TexelsPerTile / (m_Texture->GetHeight() * TERRAIN_TILE_SIZE); matrix._44 = 1; - g_Renderer.GetTerrainRenderer().RenderTerrainOverlayTexture(cullGroup, matrix, m_Texture); + g_Renderer.GetTerrainRenderer().RenderTerrainOverlayTexture(cullGroup, matrix, m_Texture->GetHandle()); } SColor4ub TerrainTextureOverlay::GetColor(size_t idx, u8 alpha) const diff --git a/source/renderer/TerrainOverlay.h b/source/renderer/TerrainOverlay.h index 10097d681a..d20407c4f2 100644 --- a/source/renderer/TerrainOverlay.h +++ b/source/renderer/TerrainOverlay.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2012 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -23,7 +23,7 @@ #ifndef INCLUDED_TERRAINOVERLAY #define INCLUDED_TERRAINOVERLAY -#include "lib/ogl.h" +#include "renderer/backend/gl/Texture.h" struct CColor; struct SColor4ub; @@ -197,8 +197,7 @@ private: void RenderAfterWater(int cullGroup); float m_TexelsPerTile; - GLuint m_Texture; - GLsizei m_TextureW, m_TextureH; + std::unique_ptr m_Texture; }; #endif // INCLUDED_TERRAINOVERLAY diff --git a/source/renderer/backend/Format.h b/source/renderer/backend/Format.h index 26368cb27c..4a8e239abc 100644 --- a/source/renderer/backend/Format.h +++ b/source/renderer/backend/Format.h @@ -29,6 +29,9 @@ enum class Format UNDEFINED, R8G8B8A8, A8, + D16, + D24, + D32 }; } // namespace Backend