1
0
forked from 0ad/0ad

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.
This commit is contained in:
Vladislav Belov 2021-12-26 09:48:48 +00:00
parent 6c2b9e72a0
commit c2c3a3b663
4 changed files with 69 additions and 81 deletions

View File

@ -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<Renderer::Backend::GL::CTexture> 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<Renderer::Backend::GL::CTexture> 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

View File

@ -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

View File

@ -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<Renderer::Backend::GL::CTexture> m_Texture;
};
#endif // INCLUDED_TERRAINOVERLAY

View File

@ -29,6 +29,9 @@ enum class Format
UNDEFINED,
R8G8B8A8,
A8,
D16,
D24,
D32
};
} // namespace Backend