forked from 0ad/0ad
Encapsulates GL texture creation in a separate class.
Tested By: Stan Differential Revision: https://code.wildfiregames.com/D4389 This was SVN commit r26107.
This commit is contained in:
parent
381bbb59e8
commit
57ba7c4a1c
@ -61,8 +61,7 @@ static const size_t g_SubTextureAlignment = 4;
|
||||
|
||||
CLOSTexture::CLOSTexture(CSimulation2& simulation)
|
||||
: m_Simulation(simulation), m_Dirty(true), m_ShaderInitialized(false),
|
||||
m_Texture(0), m_TextureSmooth1(0), m_TextureSmooth2(0), m_smoothFbo(0),
|
||||
m_MapSize(0), m_TextureSize(0), whichTex(true)
|
||||
m_smoothFbo(0), m_MapSize(0), m_TextureSize(0), whichTex(true)
|
||||
{
|
||||
if (CRenderer::IsInitialised() && g_RenderingOptions.GetSmoothLOS())
|
||||
CreateShader();
|
||||
@ -98,17 +97,9 @@ bool CLOSTexture::CreateShader()
|
||||
|
||||
void CLOSTexture::DeleteTexture()
|
||||
{
|
||||
glDeleteTextures(1, &m_Texture);
|
||||
|
||||
if (m_TextureSmooth1)
|
||||
glDeleteTextures(1, &m_TextureSmooth1);
|
||||
|
||||
if (m_TextureSmooth2)
|
||||
glDeleteTextures(1, &m_TextureSmooth2);
|
||||
|
||||
m_Texture = 0;
|
||||
m_TextureSmooth1 = 0;
|
||||
m_TextureSmooth2 = 0;
|
||||
m_Texture.reset();
|
||||
m_TextureSmooth1.reset();
|
||||
m_TextureSmooth2.reset();
|
||||
}
|
||||
|
||||
void CLOSTexture::MakeDirty()
|
||||
@ -116,23 +107,12 @@ void CLOSTexture::MakeDirty()
|
||||
m_Dirty = true;
|
||||
}
|
||||
|
||||
void CLOSTexture::BindTexture(int unit)
|
||||
{
|
||||
if (m_Dirty)
|
||||
{
|
||||
RecomputeTexture(unit);
|
||||
m_Dirty = false;
|
||||
}
|
||||
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
}
|
||||
|
||||
GLuint CLOSTexture::GetTextureSmooth()
|
||||
{
|
||||
if (CRenderer::IsInitialised() && !g_RenderingOptions.GetSmoothLOS())
|
||||
return GetTexture();
|
||||
else
|
||||
return whichTex ? m_TextureSmooth1 : m_TextureSmooth2;
|
||||
return (whichTex ? m_TextureSmooth1 : m_TextureSmooth2)->GetHandle();
|
||||
}
|
||||
|
||||
void CLOSTexture::InterpolateLOS()
|
||||
@ -148,19 +128,19 @@ void CLOSTexture::InterpolateLOS()
|
||||
// RecomputeTexture(0) will not cause the ConstructTexture to run.
|
||||
// Force the textures to be created.
|
||||
DeleteTexture();
|
||||
ConstructTexture(0);
|
||||
ConstructTexture();
|
||||
m_Dirty = true;
|
||||
}
|
||||
|
||||
if (m_Dirty)
|
||||
{
|
||||
RecomputeTexture(0);
|
||||
RecomputeTexture();
|
||||
m_Dirty = false;
|
||||
}
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_smoothFbo);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
|
||||
whichTex ? m_TextureSmooth2 : m_TextureSmooth1, 0);
|
||||
(whichTex ? m_TextureSmooth2 : m_TextureSmooth1)->GetHandle(), 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
@ -175,8 +155,8 @@ void CLOSTexture::InterpolateLOS()
|
||||
|
||||
shader->Bind();
|
||||
|
||||
shader->BindTexture(str_losTex1, m_Texture);
|
||||
shader->BindTexture(str_losTex2, whichTex ? m_TextureSmooth1 : m_TextureSmooth2);
|
||||
shader->BindTexture(str_losTex1, m_Texture->GetHandle());
|
||||
shader->BindTexture(str_losTex2, (whichTex ? m_TextureSmooth1 : m_TextureSmooth2)->GetHandle());
|
||||
|
||||
shader->Uniform(str_delta, (float)g_Renderer.GetTimeManager().GetFrameDelta() * 4.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
@ -224,11 +204,11 @@ GLuint CLOSTexture::GetTexture()
|
||||
{
|
||||
if (m_Dirty)
|
||||
{
|
||||
RecomputeTexture(0);
|
||||
RecomputeTexture();
|
||||
m_Dirty = false;
|
||||
}
|
||||
|
||||
return m_Texture;
|
||||
return m_Texture->GetHandle();
|
||||
}
|
||||
|
||||
const CMatrix3D& CLOSTexture::GetTextureMatrix()
|
||||
@ -243,7 +223,7 @@ const CMatrix3D* CLOSTexture::GetMinimapTextureMatrix()
|
||||
return &m_MinimapTextureMatrix;
|
||||
}
|
||||
|
||||
void CLOSTexture::ConstructTexture(int unit)
|
||||
void CLOSTexture::ConstructTexture()
|
||||
{
|
||||
CmpPtr<ICmpRangeManager> cmpRangeManager(m_Simulation, SYSTEM_ENTITY);
|
||||
if (!cmpRangeManager)
|
||||
@ -253,7 +233,13 @@ void CLOSTexture::ConstructTexture(int unit)
|
||||
|
||||
m_TextureSize = (GLsizei)round_up_to_pow2(round_up((size_t)m_MapSize + g_BlurSize - 1, g_SubTextureAlignment));
|
||||
|
||||
glGenTextures(1, &m_Texture);
|
||||
const Renderer::Backend::Sampler::Desc defaultSamplerDesc =
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE);
|
||||
|
||||
m_Texture = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::A8, m_TextureSize, m_TextureSize, defaultSamplerDesc);
|
||||
|
||||
// Initialise texture with SoD color, for the areas we don't
|
||||
// overwrite with glTexSubImage2D later
|
||||
@ -262,30 +248,20 @@ void CLOSTexture::ConstructTexture(int unit)
|
||||
|
||||
if (CRenderer::IsInitialised() && g_RenderingOptions.GetSmoothLOS())
|
||||
{
|
||||
glGenTextures(1, &m_TextureSmooth1);
|
||||
glGenTextures(1, &m_TextureSmooth2);
|
||||
m_TextureSmooth1 = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::R8G8B8A8, m_TextureSize, m_TextureSize, defaultSamplerDesc);
|
||||
m_TextureSmooth2 = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::R8G8B8A8, m_TextureSize, m_TextureSize, defaultSamplerDesc);
|
||||
|
||||
g_Renderer.BindTexture(unit, m_TextureSmooth1);
|
||||
g_Renderer.BindTexture(0, m_TextureSmooth1->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureSize, m_TextureSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texData);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
g_Renderer.BindTexture(unit, m_TextureSmooth2);
|
||||
g_Renderer.BindTexture(0, m_TextureSmooth2->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureSize, m_TextureSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texData);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
g_Renderer.BindTexture(0, m_Texture->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, m_TextureSize, m_TextureSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texData);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
delete[] texData;
|
||||
|
||||
@ -317,7 +293,7 @@ void CLOSTexture::ConstructTexture(int unit)
|
||||
}
|
||||
}
|
||||
|
||||
void CLOSTexture::RecomputeTexture(int unit)
|
||||
void CLOSTexture::RecomputeTexture()
|
||||
{
|
||||
// If the map was resized, delete and regenerate the texture
|
||||
if (m_Texture)
|
||||
@ -330,7 +306,7 @@ void CLOSTexture::RecomputeTexture(int unit)
|
||||
bool recreated = false;
|
||||
if (!m_Texture)
|
||||
{
|
||||
ConstructTexture(unit);
|
||||
ConstructTexture();
|
||||
recreated = true;
|
||||
}
|
||||
|
||||
@ -350,13 +326,13 @@ void CLOSTexture::RecomputeTexture(int unit)
|
||||
|
||||
if (CRenderer::IsInitialised() && g_RenderingOptions.GetSmoothLOS() && recreated)
|
||||
{
|
||||
g_Renderer.BindTexture(unit, m_TextureSmooth1);
|
||||
g_Renderer.BindTexture(0, m_TextureSmooth1->GetHandle());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pitch, m_MapSize, GL_ALPHA, GL_UNSIGNED_BYTE, &losData[0]);
|
||||
g_Renderer.BindTexture(unit, m_TextureSmooth2);
|
||||
g_Renderer.BindTexture(0, m_TextureSmooth2->GetHandle());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pitch, m_MapSize, GL_ALPHA, GL_UNSIGNED_BYTE, &losData[0]);
|
||||
}
|
||||
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
g_Renderer.BindTexture(0, m_Texture->GetHandle());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pitch, m_MapSize, GL_ALPHA, GL_UNSIGNED_BYTE, &losData[0]);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "graphics/ShaderTechniquePtr.h"
|
||||
#include "maths/Matrix3D.h"
|
||||
#include "renderer/backend/gl/Texture.h"
|
||||
|
||||
class CLosQuerier;
|
||||
class CSimulation2;
|
||||
@ -45,14 +46,6 @@ public:
|
||||
*/
|
||||
void MakeDirty();
|
||||
|
||||
/**
|
||||
* Recomputes the LOS texture if necessary, and binds it to the requested
|
||||
* texture unit.
|
||||
* Also switches the current active texture unit, and enables texturing on it.
|
||||
* The texture is in 8-bit ALPHA format.
|
||||
*/
|
||||
void BindTexture(int unit);
|
||||
|
||||
/**
|
||||
* Recomputes the LOS texture if necessary, and returns the texture handle.
|
||||
* Also potentially switches the current active texture unit, and enables texturing on it.
|
||||
@ -80,8 +73,8 @@ public:
|
||||
private:
|
||||
void DeleteTexture();
|
||||
bool CreateShader();
|
||||
void ConstructTexture(int unit);
|
||||
void RecomputeTexture(int unit);
|
||||
void ConstructTexture();
|
||||
void RecomputeTexture();
|
||||
|
||||
size_t GetBitmapSize(size_t w, size_t h, size_t* pitch);
|
||||
void GenerateBitmap(const CLosQuerier& los, u8* losData, size_t w, size_t h, size_t pitch);
|
||||
@ -92,8 +85,8 @@ private:
|
||||
|
||||
bool m_ShaderInitialized;
|
||||
|
||||
GLuint m_Texture;
|
||||
GLuint m_TextureSmooth1, m_TextureSmooth2;
|
||||
std::unique_ptr<Renderer::Backend::GL::CTexture>
|
||||
m_Texture, m_TextureSmooth1, m_TextureSmooth2;
|
||||
|
||||
bool whichTex;
|
||||
|
||||
@ -107,4 +100,4 @@ private:
|
||||
CMatrix3D m_MinimapTextureMatrix;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_LOSTEXTURE
|
||||
#endif // INCLUDED_LOSTEXTURE
|
||||
|
@ -210,36 +210,35 @@ void CMiniMapTexture::CreateTextures(const CTerrain* terrain)
|
||||
m_MapSize = terrain->GetVerticesPerSide();
|
||||
m_TextureSize = static_cast<GLsizei>(round_up_to_pow2(static_cast<size_t>(m_MapSize)));
|
||||
|
||||
const Renderer::Backend::Sampler::Desc defaultSamplerDesc =
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE);
|
||||
|
||||
// Create terrain texture
|
||||
glGenTextures(1, &m_TerrainTexture);
|
||||
g_Renderer.BindTexture(0, m_TerrainTexture);
|
||||
m_TerrainTexture = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::R8G8B8A8, m_TextureSize, m_TextureSize, defaultSamplerDesc);
|
||||
|
||||
// Initialise texture with solid black, for the areas we don't
|
||||
// overwrite with glTexSubImage2D later
|
||||
u32* texData = new u32[m_TextureSize * m_TextureSize];
|
||||
for (ssize_t i = 0; i < m_TextureSize * m_TextureSize; ++i)
|
||||
texData[i] = 0xFF000000;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureSize, m_TextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
|
||||
g_Renderer.BindTexture(0, m_TerrainTexture->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_TextureSize, m_TextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
|
||||
delete[] texData;
|
||||
|
||||
m_TerrainData = new u32[(m_MapSize - 1) * (m_MapSize - 1)];
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glGenTextures(1, &m_FinalTexture);
|
||||
g_Renderer.BindTexture(0, m_FinalTexture);
|
||||
m_FinalTexture = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::R8G8B8A8, FINAL_TEXTURE_SIZE, FINAL_TEXTURE_SIZE, defaultSamplerDesc);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FINAL_TEXTURE_SIZE, FINAL_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
g_Renderer.BindTexture(0, m_FinalTexture->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, FINAL_TEXTURE_SIZE, FINAL_TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
glGenFramebuffersEXT(1, &m_FinalTextureFBO);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FinalTextureFBO);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_FinalTexture, 0);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_FinalTexture->GetHandle(), 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
@ -252,17 +251,8 @@ void CMiniMapTexture::CreateTextures(const CTerrain* terrain)
|
||||
|
||||
void CMiniMapTexture::DestroyTextures()
|
||||
{
|
||||
if (m_TerrainTexture)
|
||||
{
|
||||
glDeleteTextures(1, &m_TerrainTexture);
|
||||
m_TerrainTexture = 0;
|
||||
}
|
||||
|
||||
if (m_FinalTexture)
|
||||
{
|
||||
glDeleteTextures(1, &m_FinalTexture);
|
||||
m_FinalTexture = 0;
|
||||
}
|
||||
m_TerrainTexture.reset();
|
||||
m_FinalTexture.reset();
|
||||
|
||||
SAFE_ARRAY_DELETE(m_TerrainData);
|
||||
}
|
||||
@ -326,7 +316,7 @@ void CMiniMapTexture::RebuildTerrainTexture(const CTerrain* terrain)
|
||||
}
|
||||
|
||||
// Upload the texture
|
||||
g_Renderer.BindTexture(0, m_TerrainTexture);
|
||||
g_Renderer.BindTexture(0, m_TerrainTexture->GetHandle());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, m_TerrainData);
|
||||
g_Renderer.BindTexture(0, 0);
|
||||
}
|
||||
@ -369,7 +359,7 @@ void CMiniMapTexture::RenderFinalTexture()
|
||||
shader = tech->GetShader();
|
||||
|
||||
if (m_TerrainTexture)
|
||||
shader->BindTexture(str_baseTex, m_TerrainTexture);
|
||||
shader->BindTexture(str_baseTex, m_TerrainTexture->GetHandle());
|
||||
|
||||
CMatrix3D baseTransform;
|
||||
baseTransform.SetIdentity();
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define INCLUDED_MINIMAPTEXTURE
|
||||
|
||||
#include "lib/ogl.h"
|
||||
#include "renderer/backend/gl/Texture.h"
|
||||
#include "renderer/VertexArray.h"
|
||||
|
||||
class CSimulation2;
|
||||
@ -41,7 +42,7 @@ public:
|
||||
*/
|
||||
void Render();
|
||||
|
||||
GLuint GetTexture() const { return m_FinalTexture; }
|
||||
GLuint GetTexture() const { return m_FinalTexture->GetHandle(); }
|
||||
|
||||
/**
|
||||
* @return The maximum height for unit passage in water.
|
||||
@ -61,8 +62,8 @@ private:
|
||||
double m_LastFinalTextureUpdate = 0.0;
|
||||
|
||||
// minimap texture handles
|
||||
GLuint m_TerrainTexture = 0;
|
||||
GLuint m_FinalTexture = 0;
|
||||
std::unique_ptr<Renderer::Backend::GL::CTexture>
|
||||
m_TerrainTexture, m_FinalTexture;
|
||||
|
||||
GLuint m_FinalTextureFBO = 0;
|
||||
|
||||
|
@ -35,20 +35,18 @@
|
||||
// TODO: There's a lot of duplication with CLOSTexture - might be nice to refactor a bit
|
||||
|
||||
CTerritoryTexture::CTerritoryTexture(CSimulation2& simulation) :
|
||||
m_Simulation(simulation), m_DirtyID(0), m_Texture(0), m_MapSize(0), m_TextureSize(0)
|
||||
m_Simulation(simulation), m_DirtyID(0), m_MapSize(0), m_TextureSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
CTerritoryTexture::~CTerritoryTexture()
|
||||
{
|
||||
if (m_Texture)
|
||||
DeleteTexture();
|
||||
DeleteTexture();
|
||||
}
|
||||
|
||||
void CTerritoryTexture::DeleteTexture()
|
||||
{
|
||||
glDeleteTextures(1, &m_Texture);
|
||||
m_Texture = 0;
|
||||
m_Texture.reset();
|
||||
}
|
||||
|
||||
bool CTerritoryTexture::UpdateDirty()
|
||||
@ -57,20 +55,12 @@ bool CTerritoryTexture::UpdateDirty()
|
||||
return cmpTerritoryManager && cmpTerritoryManager->NeedUpdateTexture(&m_DirtyID);
|
||||
}
|
||||
|
||||
void CTerritoryTexture::BindTexture(int unit)
|
||||
{
|
||||
if (UpdateDirty())
|
||||
RecomputeTexture(unit);
|
||||
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
}
|
||||
|
||||
GLuint CTerritoryTexture::GetTexture()
|
||||
{
|
||||
if (UpdateDirty())
|
||||
RecomputeTexture(0);
|
||||
RecomputeTexture();
|
||||
|
||||
return m_Texture;
|
||||
return m_Texture->GetHandle();
|
||||
}
|
||||
|
||||
const float* CTerritoryTexture::GetTextureMatrix()
|
||||
@ -85,7 +75,7 @@ const CMatrix3D* CTerritoryTexture::GetMinimapTextureMatrix()
|
||||
return &m_MinimapTextureMatrix;
|
||||
}
|
||||
|
||||
void CTerritoryTexture::ConstructTexture(int unit)
|
||||
void CTerritoryTexture::ConstructTexture()
|
||||
{
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(m_Simulation, SYSTEM_ENTITY);
|
||||
if (!cmpTerrain)
|
||||
@ -96,21 +86,20 @@ void CTerritoryTexture::ConstructTexture(int unit)
|
||||
|
||||
m_TextureSize = (GLsizei)round_up_to_pow2((size_t)m_MapSize);
|
||||
|
||||
glGenTextures(1, &m_Texture);
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
m_Texture = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::R8G8B8A8, m_TextureSize, m_TextureSize,
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE));
|
||||
|
||||
// Initialise texture with transparency, for the areas we don't
|
||||
// overwrite with glTexSubImage2D later
|
||||
u8* texData = new u8[m_TextureSize * m_TextureSize * 4];
|
||||
memset(texData, 0x00, m_TextureSize * m_TextureSize * 4);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureSize, m_TextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
|
||||
g_Renderer.BindTexture(0, m_Texture->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_TextureSize, m_TextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
|
||||
delete[] texData;
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
{
|
||||
// Texture matrix: We want to map
|
||||
// world pos (0, y, 0) (i.e. bottom-left of first tile)
|
||||
@ -139,7 +128,7 @@ void CTerritoryTexture::ConstructTexture(int unit)
|
||||
}
|
||||
}
|
||||
|
||||
void CTerritoryTexture::RecomputeTexture(int unit)
|
||||
void CTerritoryTexture::RecomputeTexture()
|
||||
{
|
||||
// If the map was resized, delete and regenerate the texture
|
||||
if (m_Texture)
|
||||
@ -150,7 +139,7 @@ void CTerritoryTexture::RecomputeTexture(int unit)
|
||||
}
|
||||
|
||||
if (!m_Texture)
|
||||
ConstructTexture(unit);
|
||||
ConstructTexture();
|
||||
|
||||
PROFILE("recompute territory texture");
|
||||
|
||||
@ -161,7 +150,7 @@ void CTerritoryTexture::RecomputeTexture(int unit)
|
||||
std::vector<u8> bitmap(m_MapSize * m_MapSize * 4);
|
||||
GenerateBitmap(cmpTerritoryManager->GetTerritoryGrid(), &bitmap[0], m_MapSize, m_MapSize);
|
||||
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
g_Renderer.BindTexture(0, m_Texture->GetHandle());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_MapSize, m_MapSize, GL_RGBA, GL_UNSIGNED_BYTE, &bitmap[0]);
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,8 @@
|
||||
*/
|
||||
|
||||
#include "lib/ogl.h"
|
||||
|
||||
#include "maths/Matrix3D.h"
|
||||
#include "renderer/backend/gl/Texture.h"
|
||||
|
||||
class CSimulation2;
|
||||
template<typename T>
|
||||
@ -35,14 +35,6 @@ public:
|
||||
CTerritoryTexture(CSimulation2& simulation);
|
||||
~CTerritoryTexture();
|
||||
|
||||
/**
|
||||
* Recomputes the territory texture if necessary, and binds it to the requested
|
||||
* texture unit.
|
||||
* Also switches the current active texture unit, and enables texturing on it.
|
||||
* The texture is in 32-bit BGRA format.
|
||||
*/
|
||||
void BindTexture(int unit);
|
||||
|
||||
/**
|
||||
* Recomputes the territory texture if necessary, and returns the texture handle.
|
||||
* Also potentially switches the current active texture unit, and enables texturing on it.
|
||||
@ -71,8 +63,8 @@ private:
|
||||
bool UpdateDirty();
|
||||
|
||||
void DeleteTexture();
|
||||
void ConstructTexture(int unit);
|
||||
void RecomputeTexture(int unit);
|
||||
void ConstructTexture();
|
||||
void RecomputeTexture();
|
||||
|
||||
void GenerateBitmap(const Grid<u8>& territories, u8* bitmap, ssize_t w, ssize_t h);
|
||||
|
||||
@ -80,7 +72,7 @@ private:
|
||||
|
||||
size_t m_DirtyID;
|
||||
|
||||
GLuint m_Texture;
|
||||
std::unique_ptr<Renderer::Backend::GL::CTexture> m_Texture;
|
||||
|
||||
ssize_t m_MapSize; // tiles per side
|
||||
GLsizei m_TextureSize; // texels per side
|
||||
|
@ -76,6 +76,7 @@
|
||||
|
||||
// GL_OES_texture_border_clamp
|
||||
#define GL_CLAMP_TO_BORDER GL_CLAMP_TO_BORDER_OES
|
||||
#define GL_TEXTURE_BORDER_COLOR GL_TEXTURE_BORDER_COLOR_OES
|
||||
|
||||
// GL_OES_rgb8_rgba8
|
||||
#define GL_RGBA8 GL_RGBA8_OES
|
||||
|
38
source/renderer/backend/Format.h
Normal file
38
source/renderer/backend/Format.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_RENDERER_BACKEND_FORMAT
|
||||
#define INCLUDED_RENDERER_BACKEND_FORMAT
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
|
||||
namespace Backend
|
||||
{
|
||||
|
||||
enum class Format
|
||||
{
|
||||
UNDEFINED,
|
||||
R8G8B8A8,
|
||||
A8,
|
||||
};
|
||||
|
||||
} // namespace Backend
|
||||
|
||||
} // namespace Renderer
|
||||
|
||||
#endif // INCLUDED_RENDERER_BACKEND_FORMAT
|
49
source/renderer/backend/Sampler.cpp
Normal file
49
source/renderer/backend/Sampler.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
/* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "Sampler.h"
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
|
||||
namespace Backend
|
||||
{
|
||||
|
||||
namespace Sampler
|
||||
{
|
||||
|
||||
Desc MakeDefaultSampler(Filter filter, AddressMode addressMode)
|
||||
{
|
||||
Desc desc{};
|
||||
desc.minFilter = filter;
|
||||
desc.magFilter = filter;
|
||||
desc.mipFilter = filter;
|
||||
desc.addressModeU = addressMode;
|
||||
desc.addressModeV = addressMode;
|
||||
desc.addressModeW = addressMode;
|
||||
desc.anisotropyEnabled = false;
|
||||
desc.mipLODBias = 0.0f;
|
||||
return desc;
|
||||
}
|
||||
|
||||
} // namespace Sampler
|
||||
|
||||
} // namespace Backend
|
||||
|
||||
} // namespace Renderer
|
71
source/renderer/backend/Sampler.h
Normal file
71
source/renderer/backend/Sampler.h
Normal file
@ -0,0 +1,71 @@
|
||||
/* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_RENDERER_BACKEND_SAMPLER
|
||||
#define INCLUDED_RENDERER_BACKEND_SAMPLER
|
||||
|
||||
#include "graphics/Color.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
|
||||
namespace Backend
|
||||
{
|
||||
|
||||
namespace Sampler
|
||||
{
|
||||
|
||||
enum class Filter
|
||||
{
|
||||
NEAREST,
|
||||
LINEAR
|
||||
};
|
||||
|
||||
enum class AddressMode
|
||||
{
|
||||
REPEAT,
|
||||
MIRRORED_REPEAT,
|
||||
CLAMP_TO_EDGE,
|
||||
CLAMP_TO_BORDER,
|
||||
};
|
||||
|
||||
struct Desc
|
||||
{
|
||||
Filter magFilter;
|
||||
Filter minFilter;
|
||||
Filter mipFilter;
|
||||
AddressMode addressModeU;
|
||||
AddressMode addressModeV;
|
||||
AddressMode addressModeW;
|
||||
float mipLODBias;
|
||||
bool anisotropyEnabled;
|
||||
float maxAnisotropy;
|
||||
// When some filter is CLAMP_TO_BORDER.
|
||||
CColor borderColor;
|
||||
};
|
||||
|
||||
Desc MakeDefaultSampler(Filter filter, AddressMode addressMode);
|
||||
|
||||
} // namespace Sampler
|
||||
|
||||
} // namespace Backend
|
||||
|
||||
} // namespace Renderer
|
||||
|
||||
#endif // INCLUDED_RENDERER_BACKEND_SAMPLER
|
120
source/renderer/backend/gl/Texture.cpp
Normal file
120
source/renderer/backend/gl/Texture.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
/* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "Texture.h"
|
||||
|
||||
#include "lib/config2.h"
|
||||
#include "renderer/backend/gl/Device.h"
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
|
||||
namespace Backend
|
||||
{
|
||||
|
||||
namespace GL
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
GLint CalculateMinFilter(const Sampler::Desc& defaultSamplerDesc, const uint32_t mipCount)
|
||||
{
|
||||
if (mipCount == 1)
|
||||
return defaultSamplerDesc.minFilter == Sampler::Filter::LINEAR ? GL_LINEAR : GL_NEAREST;
|
||||
|
||||
if (defaultSamplerDesc.minFilter == Sampler::Filter::LINEAR)
|
||||
return defaultSamplerDesc.mipFilter == Sampler::Filter::LINEAR ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST;
|
||||
|
||||
return defaultSamplerDesc.mipFilter == Sampler::Filter::LINEAR ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST;
|
||||
}
|
||||
|
||||
GLint AddressModeToGLEnum(Sampler::AddressMode addressMode)
|
||||
{
|
||||
switch (addressMode)
|
||||
{
|
||||
case Sampler::AddressMode::REPEAT: return GL_REPEAT;
|
||||
case Sampler::AddressMode::MIRRORED_REPEAT: return GL_MIRRORED_REPEAT;
|
||||
case Sampler::AddressMode::CLAMP_TO_EDGE: return GL_CLAMP_TO_EDGE;
|
||||
case Sampler::AddressMode::CLAMP_TO_BORDER: return GL_CLAMP_TO_BORDER;
|
||||
}
|
||||
return GL_REPEAT;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
std::unique_ptr<CTexture> CTexture::Create2D(const Format format,
|
||||
const uint32_t width, const uint32_t height,
|
||||
const Sampler::Desc& defaultSamplerDesc, const uint32_t mipCount)
|
||||
{
|
||||
std::unique_ptr<CTexture> texture(new CTexture());
|
||||
|
||||
ENSURE(format != Format::UNDEFINED);
|
||||
ENSURE(width > 0 && height > 0 && mipCount > 0);
|
||||
|
||||
texture->m_Format = format;
|
||||
texture->m_Width = width;
|
||||
texture->m_Height = height;
|
||||
texture->m_MipCount = mipCount;
|
||||
|
||||
glGenTextures(1, &texture->m_Handle);
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->m_Handle);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, CalculateMinFilter(defaultSamplerDesc, mipCount));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, defaultSamplerDesc.magFilter == Sampler::Filter::LINEAR ? GL_LINEAR : GL_NEAREST);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, AddressModeToGLEnum(defaultSamplerDesc.addressModeU));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, AddressModeToGLEnum(defaultSamplerDesc.addressModeV));
|
||||
|
||||
#if !CONFIG2_GLES
|
||||
if (defaultSamplerDesc.mipLODBias != 0.0f)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, defaultSamplerDesc.mipLODBias);
|
||||
#endif
|
||||
|
||||
if (defaultSamplerDesc.anisotropyEnabled)
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, defaultSamplerDesc.maxAnisotropy);
|
||||
|
||||
if (defaultSamplerDesc.addressModeU == Sampler::AddressMode::CLAMP_TO_BORDER ||
|
||||
defaultSamplerDesc.addressModeV == Sampler::AddressMode::CLAMP_TO_BORDER ||
|
||||
defaultSamplerDesc.addressModeW == Sampler::AddressMode::CLAMP_TO_BORDER)
|
||||
{
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, defaultSamplerDesc.borderColor.AsFloatArray());
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
CTexture::CTexture() = default;
|
||||
|
||||
CTexture::~CTexture()
|
||||
{
|
||||
if (m_Handle)
|
||||
glDeleteTextures(1, &m_Handle);
|
||||
}
|
||||
|
||||
} // namespace GL
|
||||
|
||||
} // namespace Backend
|
||||
|
||||
} // namespace Renderer
|
74
source/renderer/backend/gl/Texture.h
Normal file
74
source/renderer/backend/gl/Texture.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_RENDERER_BACKEND_GL_TEXTURE
|
||||
#define INCLUDED_RENDERER_BACKEND_GL_TEXTURE
|
||||
|
||||
#include "lib/ogl.h"
|
||||
#include "renderer/backend/Format.h"
|
||||
#include "renderer/backend/Sampler.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
|
||||
namespace Backend
|
||||
{
|
||||
|
||||
namespace GL
|
||||
{
|
||||
|
||||
/**
|
||||
* Represents a low-level GL texture, encapsulates all properties initialization.
|
||||
*/
|
||||
class CTexture
|
||||
{
|
||||
public:
|
||||
~CTexture();
|
||||
|
||||
// GL before 3.3 doesn't support sampler objects, so each texture should have
|
||||
// an own default sampler.
|
||||
static std::unique_ptr<CTexture> Create2D(const Format format,
|
||||
const uint32_t width, const uint32_t height,
|
||||
const Sampler::Desc& defaultSamplerDesc, const uint32_t mipCount = 1);
|
||||
|
||||
GLuint GetHandle() const { return m_Handle; }
|
||||
|
||||
Format GetFormat() const { return m_Format; }
|
||||
uint32_t GetWidth() const { return m_Width; }
|
||||
uint32_t GetHeight() const { return m_Height; }
|
||||
uint32_t GetMipCount() const { return m_MipCount; }
|
||||
|
||||
private:
|
||||
CTexture();
|
||||
|
||||
GLuint m_Handle = 0;
|
||||
|
||||
Format m_Format = Format::UNDEFINED;
|
||||
uint32_t m_Width = 0;
|
||||
uint32_t m_Height = 0;
|
||||
uint32_t m_MipCount = 0;
|
||||
};
|
||||
|
||||
} // namespace GL
|
||||
|
||||
} // namespace Backend
|
||||
|
||||
} // namespace Renderer
|
||||
|
||||
#endif // INCLUDED_RENDERER_BACKEND_GL_TEXTURE
|
Loading…
Reference in New Issue
Block a user