Performs texture uploads via DeviceCommandContext interface.
Tested By: Langbart, Stan Differential Revision: https://code.wildfiregames.com/D4415 This was SVN commit r26170.
This commit is contained in:
parent
07c0d95467
commit
fd976456d7
@ -243,7 +243,7 @@ void CGameView::BeginFrame()
|
||||
|
||||
void CGameView::Render()
|
||||
{
|
||||
g_Renderer.GetSceneRenderer().RenderScene(*this);
|
||||
g_Renderer.GetSceneRenderer().RenderScene(g_Renderer.GetDeviceCommandContext(), *this);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
@ -53,7 +53,7 @@ The blurred bitmap is then uploaded into a GL texture for use by the renderer.
|
||||
// Keep it in relation to the number of impassable tiles in MAP_EDGE_TILES.
|
||||
static const size_t g_BlurSize = 7;
|
||||
|
||||
// Alignment (in bytes) of the pixel data passed into glTexSubImage2D.
|
||||
// Alignment (in bytes) of the pixel data passed into texture uploading.
|
||||
// This must be a multiple of GL_UNPACK_ALIGNMENT, which ought to be 1 (since
|
||||
// that's what we set it to) but in some weird cases appears to have a different
|
||||
// value. (See Trac #2594). Multiples of 4 are possibly good for performance anyway.
|
||||
@ -61,7 +61,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_TextureSize(0), whichTex(true)
|
||||
m_smoothFbo(0), m_MapSize(0), m_WhichTex(true)
|
||||
{
|
||||
if (CRenderer::IsInitialised() && g_RenderingOptions.GetSmoothLOS())
|
||||
CreateShader();
|
||||
@ -112,35 +112,36 @@ Renderer::Backend::GL::CTexture* CLOSTexture::GetTextureSmooth()
|
||||
if (CRenderer::IsInitialised() && !g_RenderingOptions.GetSmoothLOS())
|
||||
return GetTexture();
|
||||
else
|
||||
return (whichTex ? m_TextureSmooth1 : m_TextureSmooth2).get();
|
||||
return (m_WhichTex ? m_TextureSmooth1 : m_TextureSmooth2).get();
|
||||
}
|
||||
|
||||
void CLOSTexture::InterpolateLOS()
|
||||
void CLOSTexture::InterpolateLOS(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
if (CRenderer::IsInitialised() && !g_RenderingOptions.GetSmoothLOS())
|
||||
return;
|
||||
|
||||
if (!m_ShaderInitialized)
|
||||
const bool skipSmoothLOS = CRenderer::IsInitialised() && !g_RenderingOptions.GetSmoothLOS();
|
||||
if (!skipSmoothLOS && !m_ShaderInitialized)
|
||||
{
|
||||
if (!CreateShader())
|
||||
return;
|
||||
|
||||
// RecomputeTexture(0) will not cause the ConstructTexture to run.
|
||||
// RecomputeTexture will not cause the ConstructTexture to run.
|
||||
// Force the textures to be created.
|
||||
DeleteTexture();
|
||||
ConstructTexture();
|
||||
ConstructTexture(deviceCommandContext);
|
||||
m_Dirty = true;
|
||||
}
|
||||
|
||||
if (m_Dirty)
|
||||
{
|
||||
RecomputeTexture();
|
||||
RecomputeTexture(deviceCommandContext);
|
||||
m_Dirty = false;
|
||||
}
|
||||
|
||||
if (skipSmoothLOS)
|
||||
return;
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_smoothFbo);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
|
||||
(whichTex ? m_TextureSmooth2 : m_TextureSmooth1)->GetHandle(), 0);
|
||||
(m_WhichTex ? m_TextureSmooth2 : m_TextureSmooth1)->GetHandle(), 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
@ -156,15 +157,21 @@ void CLOSTexture::InterpolateLOS()
|
||||
shader->Bind();
|
||||
|
||||
shader->BindTexture(str_losTex1, m_Texture.get());
|
||||
shader->BindTexture(str_losTex2, (whichTex ? m_TextureSmooth1 : m_TextureSmooth2).get());
|
||||
shader->BindTexture(str_losTex2, (m_WhichTex ? m_TextureSmooth1 : m_TextureSmooth2).get());
|
||||
|
||||
shader->Uniform(str_delta, (float)g_Renderer.GetTimeManager().GetFrameDelta() * 4.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
const SViewPort oldVp = g_Renderer.GetViewport();
|
||||
const SViewPort vp = { 0, 0, m_TextureSize, m_TextureSize };
|
||||
const SViewPort vp =
|
||||
{
|
||||
0, 0,
|
||||
static_cast<int>(m_Texture->GetWidth()),
|
||||
static_cast<int>(m_Texture->GetHeight())
|
||||
};
|
||||
g_Renderer.SetViewport(vp);
|
||||
|
||||
float quadVerts[] = {
|
||||
float quadVerts[] =
|
||||
{
|
||||
1.0f, 1.0f,
|
||||
-1.0f, 1.0f,
|
||||
-1.0f, -1.0f,
|
||||
@ -173,7 +180,8 @@ void CLOSTexture::InterpolateLOS()
|
||||
1.0f, -1.0f,
|
||||
1.0f, 1.0f
|
||||
};
|
||||
float quadTex[] = {
|
||||
float quadTex[] =
|
||||
{
|
||||
1.0f, 1.0f,
|
||||
0.0f, 1.0f,
|
||||
0.0f, 0.0f,
|
||||
@ -196,18 +204,13 @@ void CLOSTexture::InterpolateLOS()
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
whichTex = !whichTex;
|
||||
m_WhichTex = !m_WhichTex;
|
||||
}
|
||||
|
||||
|
||||
Renderer::Backend::GL::CTexture* CLOSTexture::GetTexture()
|
||||
{
|
||||
if (m_Dirty)
|
||||
{
|
||||
RecomputeTexture();
|
||||
m_Dirty = false;
|
||||
}
|
||||
|
||||
ENSURE(!m_Dirty);
|
||||
return m_Texture.get();
|
||||
}
|
||||
|
||||
@ -217,13 +220,13 @@ const CMatrix3D& CLOSTexture::GetTextureMatrix()
|
||||
return m_TextureMatrix;
|
||||
}
|
||||
|
||||
const CMatrix3D* CLOSTexture::GetMinimapTextureMatrix()
|
||||
const CMatrix3D& CLOSTexture::GetMinimapTextureMatrix()
|
||||
{
|
||||
ENSURE(!m_Dirty);
|
||||
return &m_MinimapTextureMatrix;
|
||||
return m_MinimapTextureMatrix;
|
||||
}
|
||||
|
||||
void CLOSTexture::ConstructTexture()
|
||||
void CLOSTexture::ConstructTexture(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
CmpPtr<ICmpRangeManager> cmpRangeManager(m_Simulation, SYSTEM_ENTITY);
|
||||
if (!cmpRangeManager)
|
||||
@ -231,7 +234,7 @@ void CLOSTexture::ConstructTexture()
|
||||
|
||||
m_MapSize = cmpRangeManager->GetVerticesPerSide();
|
||||
|
||||
m_TextureSize = (GLsizei)round_up_to_pow2(round_up((size_t)m_MapSize + g_BlurSize - 1, g_SubTextureAlignment));
|
||||
const size_t textureSize = round_up_to_pow2(round_up((size_t)m_MapSize + g_BlurSize - 1, g_SubTextureAlignment));
|
||||
|
||||
const Renderer::Backend::Sampler::Desc defaultSamplerDesc =
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
@ -239,31 +242,27 @@ void CLOSTexture::ConstructTexture()
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE);
|
||||
|
||||
m_Texture = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::A8, m_TextureSize, m_TextureSize, defaultSamplerDesc);
|
||||
Renderer::Backend::Format::A8, textureSize, textureSize, defaultSamplerDesc);
|
||||
|
||||
// Initialise texture with SoD color, 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);
|
||||
// overwrite with uploading later.
|
||||
std::unique_ptr<u8[]> texData = std::make_unique<u8[]>(textureSize * textureSize);
|
||||
memset(texData.get(), 0x00, textureSize * textureSize);
|
||||
|
||||
if (CRenderer::IsInitialised() && g_RenderingOptions.GetSmoothLOS())
|
||||
{
|
||||
m_TextureSmooth1 = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::R8G8B8A8, m_TextureSize, m_TextureSize, defaultSamplerDesc);
|
||||
Renderer::Backend::Format::A8, textureSize, textureSize, defaultSamplerDesc);
|
||||
m_TextureSmooth2 = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::R8G8B8A8, m_TextureSize, m_TextureSize, defaultSamplerDesc);
|
||||
Renderer::Backend::Format::A8, textureSize, textureSize, defaultSamplerDesc);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
deviceCommandContext->UploadTexture(m_Texture.get(), Renderer::Backend::Format::A8, texData.get(), textureSize * textureSize);
|
||||
|
||||
delete[] texData;
|
||||
texData.reset();
|
||||
|
||||
{
|
||||
// Texture matrix: We want to map
|
||||
@ -272,8 +271,8 @@ void CLOSTexture::ConstructTexture()
|
||||
// world pos ((mapsize-1)*cellsize, y, (mapsize-1)*cellsize) (i.e. last vertex)
|
||||
// onto texcoord ((mapsize-0.5) / texsize, (mapsize-0.5) / texsize) (i.e. middle of last texel)
|
||||
|
||||
float s = (m_MapSize-1) / (float)(m_TextureSize * (m_MapSize-1) * LOS_TILE_SIZE);
|
||||
float t = 0.5f / m_TextureSize;
|
||||
float s = (m_MapSize-1) / static_cast<float>(textureSize * (m_MapSize-1) * LOS_TILE_SIZE);
|
||||
float t = 0.5f / textureSize;
|
||||
m_TextureMatrix.SetZero();
|
||||
m_TextureMatrix._11 = s;
|
||||
m_TextureMatrix._23 = s;
|
||||
@ -285,7 +284,7 @@ void CLOSTexture::ConstructTexture()
|
||||
{
|
||||
// Minimap matrix: We want to map UV (0,0)-(1,1) onto (0,0)-(mapsize/texsize, mapsize/texsize)
|
||||
|
||||
float s = m_MapSize / (float)m_TextureSize;
|
||||
float s = m_MapSize / (float)textureSize;
|
||||
m_MinimapTextureMatrix.SetZero();
|
||||
m_MinimapTextureMatrix._11 = s;
|
||||
m_MinimapTextureMatrix._22 = s;
|
||||
@ -293,7 +292,7 @@ void CLOSTexture::ConstructTexture()
|
||||
}
|
||||
}
|
||||
|
||||
void CLOSTexture::RecomputeTexture()
|
||||
void CLOSTexture::RecomputeTexture(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
// If the map was resized, delete and regenerate the texture
|
||||
if (m_Texture)
|
||||
@ -306,15 +305,16 @@ void CLOSTexture::RecomputeTexture()
|
||||
bool recreated = false;
|
||||
if (!m_Texture)
|
||||
{
|
||||
ConstructTexture();
|
||||
ConstructTexture(deviceCommandContext);
|
||||
recreated = true;
|
||||
}
|
||||
|
||||
PROFILE("recompute LOS texture");
|
||||
|
||||
std::vector<u8> losData;
|
||||
size_t pitch;
|
||||
losData.resize(GetBitmapSize(m_MapSize, m_MapSize, &pitch));
|
||||
const size_t dataSize = GetBitmapSize(m_MapSize, m_MapSize, &pitch);
|
||||
ENSURE(pitch * m_MapSize <= dataSize);
|
||||
std::unique_ptr<u8[]> losData = std::make_unique<u8[]>(dataSize);
|
||||
|
||||
CmpPtr<ICmpRangeManager> cmpRangeManager(m_Simulation, SYSTEM_ENTITY);
|
||||
if (!cmpRangeManager)
|
||||
@ -326,14 +326,17 @@ void CLOSTexture::RecomputeTexture()
|
||||
|
||||
if (CRenderer::IsInitialised() && g_RenderingOptions.GetSmoothLOS() && recreated)
|
||||
{
|
||||
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(0, m_TextureSmooth2->GetHandle());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pitch, m_MapSize, GL_ALPHA, GL_UNSIGNED_BYTE, &losData[0]);
|
||||
deviceCommandContext->UploadTextureRegion(
|
||||
m_TextureSmooth1.get(), Renderer::Backend::Format::A8, losData.get(),
|
||||
pitch * m_MapSize, 0, 0, pitch, m_MapSize);
|
||||
deviceCommandContext->UploadTextureRegion(
|
||||
m_TextureSmooth2.get(), Renderer::Backend::Format::A8, losData.get(),
|
||||
pitch * m_MapSize, 0, 0, pitch, m_MapSize);
|
||||
}
|
||||
|
||||
g_Renderer.BindTexture(0, m_Texture->GetHandle());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pitch, m_MapSize, GL_ALPHA, GL_UNSIGNED_BYTE, &losData[0]);
|
||||
deviceCommandContext->UploadTextureRegion(
|
||||
m_Texture.get(), Renderer::Backend::Format::A8, losData.get(),
|
||||
pitch * m_MapSize, 0, 0, pitch, m_MapSize);
|
||||
}
|
||||
|
||||
size_t CLOSTexture::GetBitmapSize(size_t w, size_t h, size_t* pitch)
|
||||
|
@ -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
|
||||
@ -22,8 +22,11 @@
|
||||
|
||||
#include "graphics/ShaderTechniquePtr.h"
|
||||
#include "maths/Matrix3D.h"
|
||||
#include "renderer/backend/gl/DeviceCommandContext.h"
|
||||
#include "renderer/backend/gl/Texture.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class CLosQuerier;
|
||||
class CSimulation2;
|
||||
|
||||
@ -52,10 +55,10 @@ public:
|
||||
* The texture is in 8-bit ALPHA format.
|
||||
*/
|
||||
Renderer::Backend::GL::CTexture* GetTexture();
|
||||
|
||||
void InterpolateLOS();
|
||||
Renderer::Backend::GL::CTexture* GetTextureSmooth();
|
||||
|
||||
void InterpolateLOS(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
|
||||
/**
|
||||
* Returns a matrix to map (x,y,z) world coordinates onto (u,v) LOS texture
|
||||
* coordinates, in the form expected by a matrix uniform.
|
||||
@ -68,13 +71,13 @@ public:
|
||||
* coordinates, in the form expected by a matrix uniform.
|
||||
* This must only be called after BindTexture.
|
||||
*/
|
||||
const CMatrix3D* GetMinimapTextureMatrix();
|
||||
const CMatrix3D& GetMinimapTextureMatrix();
|
||||
|
||||
private:
|
||||
void DeleteTexture();
|
||||
bool CreateShader();
|
||||
void ConstructTexture();
|
||||
void RecomputeTexture();
|
||||
void ConstructTexture(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
void RecomputeTexture(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
|
||||
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);
|
||||
@ -88,13 +91,12 @@ private:
|
||||
std::unique_ptr<Renderer::Backend::GL::CTexture>
|
||||
m_Texture, m_TextureSmooth1, m_TextureSmooth2;
|
||||
|
||||
bool whichTex;
|
||||
bool m_WhichTex;
|
||||
|
||||
GLuint m_smoothFbo;
|
||||
CShaderTechniquePtr m_smoothShader;
|
||||
|
||||
size_t m_MapSize; // vertexes per side
|
||||
GLsizei m_TextureSize; // texels per side
|
||||
|
||||
CMatrix3D m_TextureMatrix;
|
||||
CMatrix3D m_MinimapTextureMatrix;
|
||||
|
@ -188,27 +188,28 @@ void CMiniMapTexture::Update(const float UNUSED(deltaRealTime))
|
||||
}
|
||||
}
|
||||
|
||||
void CMiniMapTexture::Render()
|
||||
void CMiniMapTexture::Render(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
const CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
||||
if (!terrain)
|
||||
return;
|
||||
|
||||
if (!m_TerrainTexture)
|
||||
CreateTextures(terrain);
|
||||
CreateTextures(deviceCommandContext, terrain);
|
||||
|
||||
if (m_TerrainTextureDirty)
|
||||
RebuildTerrainTexture(terrain);
|
||||
RebuildTerrainTexture(deviceCommandContext, terrain);
|
||||
|
||||
RenderFinalTexture();
|
||||
}
|
||||
|
||||
void CMiniMapTexture::CreateTextures(const CTerrain* terrain)
|
||||
void CMiniMapTexture::CreateTextures(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, const CTerrain* terrain)
|
||||
{
|
||||
DestroyTextures();
|
||||
|
||||
m_MapSize = terrain->GetVerticesPerSide();
|
||||
m_TextureSize = static_cast<GLsizei>(round_up_to_pow2(static_cast<size_t>(m_MapSize)));
|
||||
const size_t textureSize = round_up_to_pow2(static_cast<size_t>(m_MapSize));
|
||||
|
||||
const Renderer::Backend::Sampler::Desc defaultSamplerDesc =
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
@ -217,25 +218,23 @@ void CMiniMapTexture::CreateTextures(const CTerrain* terrain)
|
||||
|
||||
// Create terrain texture
|
||||
m_TerrainTexture = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::R8G8B8A8, m_TextureSize, m_TextureSize, defaultSamplerDesc);
|
||||
Renderer::Backend::Format::R8G8B8A8, textureSize, 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)
|
||||
// overwrite with uploading later.
|
||||
std::unique_ptr<u32[]> texData = std::make_unique<u32[]>(textureSize * textureSize);
|
||||
for (size_t i = 0; i < textureSize * textureSize; ++i)
|
||||
texData[i] = 0xFF000000;
|
||||
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;
|
||||
deviceCommandContext->UploadTexture(
|
||||
m_TerrainTexture.get(), Renderer::Backend::Format::R8G8B8A8,
|
||||
texData.get(), textureSize * textureSize * 4);
|
||||
texData.reset();
|
||||
|
||||
m_TerrainData = new u32[(m_MapSize - 1) * (m_MapSize - 1)];
|
||||
m_TerrainData = std::make_unique<u32[]>((m_MapSize - 1) * (m_MapSize - 1));
|
||||
|
||||
m_FinalTexture = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::R8G8B8A8, FINAL_TEXTURE_SIZE, FINAL_TEXTURE_SIZE, defaultSamplerDesc);
|
||||
|
||||
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->GetHandle(), 0);
|
||||
@ -253,11 +252,12 @@ void CMiniMapTexture::DestroyTextures()
|
||||
{
|
||||
m_TerrainTexture.reset();
|
||||
m_FinalTexture.reset();
|
||||
|
||||
SAFE_ARRAY_DELETE(m_TerrainData);
|
||||
m_TerrainData.reset();
|
||||
}
|
||||
|
||||
void CMiniMapTexture::RebuildTerrainTexture(const CTerrain* terrain)
|
||||
void CMiniMapTexture::RebuildTerrainTexture(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
|
||||
const CTerrain* terrain)
|
||||
{
|
||||
const u32 x = 0;
|
||||
const u32 y = 0;
|
||||
@ -269,7 +269,7 @@ void CMiniMapTexture::RebuildTerrainTexture(const CTerrain* terrain)
|
||||
|
||||
for (u32 j = 0; j < height; ++j)
|
||||
{
|
||||
u32* dataPtr = m_TerrainData + ((y + j) * width) + x;
|
||||
u32* dataPtr = m_TerrainData.get() + ((y + j) * width) + x;
|
||||
for (u32 i = 0; i < width; ++i)
|
||||
{
|
||||
const float avgHeight = ( terrain->GetVertexGroundLevel((int)i, (int)j)
|
||||
@ -316,9 +316,9 @@ void CMiniMapTexture::RebuildTerrainTexture(const CTerrain* terrain)
|
||||
}
|
||||
|
||||
// Upload the texture
|
||||
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);
|
||||
deviceCommandContext->UploadTextureRegion(
|
||||
m_TerrainTexture.get(), Renderer::Backend::Format::R8G8B8A8,
|
||||
m_TerrainData.get(), width * height * 4, 0, 0, width, height);
|
||||
}
|
||||
|
||||
void CMiniMapTexture::RenderFinalTexture()
|
||||
@ -346,7 +346,7 @@ void CMiniMapTexture::RenderFinalTexture()
|
||||
CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture();
|
||||
|
||||
const float invTileMapSize = 1.0f / static_cast<float>(TERRAIN_TILE_SIZE * m_MapSize);
|
||||
const float texCoordMax = (float)(m_MapSize - 1) / (float)m_TextureSize;
|
||||
const float texCoordMax = m_TerrainTexture ? static_cast<float>(m_MapSize - 1) / m_TerrainTexture->GetWidth() : 1.0f;
|
||||
|
||||
CShaderProgramPtr shader;
|
||||
CShaderTechniquePtr tech;
|
||||
@ -384,8 +384,7 @@ void CMiniMapTexture::RenderFinalTexture()
|
||||
|
||||
shader->BindTexture(str_baseTex, territoryTexture.GetTexture());
|
||||
shader->Uniform(str_transform, baseTransform);
|
||||
CMatrix3D territoryTransform = *territoryTexture.GetMinimapTextureMatrix();
|
||||
shader->Uniform(str_textureTransform, territoryTransform);
|
||||
shader->Uniform(str_textureTransform, territoryTexture.GetMinimapTextureMatrix());
|
||||
|
||||
DrawTexture(shader);
|
||||
|
||||
@ -393,9 +392,8 @@ void CMiniMapTexture::RenderFinalTexture()
|
||||
glColorMask(0, 0, 0, 1);
|
||||
|
||||
shader->BindTexture(str_baseTex, losTexture.GetTexture());
|
||||
CMatrix3D losTransform = *losTexture.GetMinimapTextureMatrix();
|
||||
shader->Uniform(str_transform, baseTransform);
|
||||
shader->Uniform(str_textureTransform, losTransform);
|
||||
shader->Uniform(str_textureTransform, losTexture.GetMinimapTextureMatrix());
|
||||
|
||||
DrawTexture(shader);
|
||||
|
||||
|
@ -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
|
||||
@ -19,9 +19,12 @@
|
||||
#define INCLUDED_MINIMAPTEXTURE
|
||||
|
||||
#include "lib/ogl.h"
|
||||
#include "renderer/backend/gl/DeviceCommandContext.h"
|
||||
#include "renderer/backend/gl/Texture.h"
|
||||
#include "renderer/VertexArray.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class CSimulation2;
|
||||
class CTerrain;
|
||||
|
||||
@ -40,7 +43,7 @@ public:
|
||||
/**
|
||||
* Redraws the texture if it's dirty.
|
||||
*/
|
||||
void Render();
|
||||
void Render(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
|
||||
Renderer::Backend::GL::CTexture* GetTexture() const { return m_FinalTexture.get(); }
|
||||
|
||||
@ -50,9 +53,13 @@ public:
|
||||
static float GetShallowPassageHeight();
|
||||
|
||||
private:
|
||||
void CreateTextures(const CTerrain* terrain);
|
||||
void CreateTextures(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
|
||||
const CTerrain* terrain);
|
||||
void DestroyTextures();
|
||||
void RebuildTerrainTexture(const CTerrain* terrain);
|
||||
void RebuildTerrainTexture(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
|
||||
const CTerrain* terrain);
|
||||
void RenderFinalTexture();
|
||||
|
||||
CSimulation2& m_Simulation;
|
||||
@ -68,14 +75,11 @@ private:
|
||||
GLuint m_FinalTextureFBO = 0;
|
||||
|
||||
// texture data
|
||||
u32* m_TerrainData = nullptr;
|
||||
std::unique_ptr<u32[]> m_TerrainData;
|
||||
|
||||
// map size
|
||||
ssize_t m_MapSize = 0;
|
||||
|
||||
// texture size
|
||||
GLsizei m_TextureSize = 0;
|
||||
|
||||
// Maximal water height to allow the passage of a unit (for underwater shallows).
|
||||
float m_ShallowPassageHeight = 0.0f;
|
||||
float m_WaterHeight = 0.0f;
|
||||
|
@ -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
|
||||
@ -57,9 +57,7 @@ bool CTerritoryTexture::UpdateDirty()
|
||||
|
||||
Renderer::Backend::GL::CTexture* CTerritoryTexture::GetTexture()
|
||||
{
|
||||
if (UpdateDirty())
|
||||
RecomputeTexture();
|
||||
|
||||
ENSURE(!UpdateDirty());
|
||||
return m_Texture.get();
|
||||
}
|
||||
|
||||
@ -69,13 +67,13 @@ const float* CTerritoryTexture::GetTextureMatrix()
|
||||
return &m_TextureMatrix._11;
|
||||
}
|
||||
|
||||
const CMatrix3D* CTerritoryTexture::GetMinimapTextureMatrix()
|
||||
const CMatrix3D& CTerritoryTexture::GetMinimapTextureMatrix()
|
||||
{
|
||||
ENSURE(!UpdateDirty());
|
||||
return &m_MinimapTextureMatrix;
|
||||
return m_MinimapTextureMatrix;
|
||||
}
|
||||
|
||||
void CTerritoryTexture::ConstructTexture()
|
||||
void CTerritoryTexture::ConstructTexture(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(m_Simulation, SYSTEM_ENTITY);
|
||||
if (!cmpTerrain)
|
||||
@ -93,12 +91,12 @@ void CTerritoryTexture::ConstructTexture()
|
||||
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[textureSize * textureSize * 4];
|
||||
memset(texData, 0x00, textureSize * textureSize * 4);
|
||||
g_Renderer.BindTexture(0, m_Texture->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureSize, textureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
|
||||
delete[] texData;
|
||||
// overwrite with uploading later.
|
||||
std::unique_ptr<u8[]> texData = std::make_unique<u8[]>(textureSize * textureSize * 4);
|
||||
memset(texData.get(), 0x00, textureSize * textureSize * 4);
|
||||
deviceCommandContext->UploadTexture(
|
||||
m_Texture.get(), Renderer::Backend::Format::R8G8B8A8, texData.get(), textureSize * textureSize * 4);
|
||||
texData.reset();
|
||||
|
||||
{
|
||||
// Texture matrix: We want to map
|
||||
@ -128,7 +126,7 @@ void CTerritoryTexture::ConstructTexture()
|
||||
}
|
||||
}
|
||||
|
||||
void CTerritoryTexture::RecomputeTexture()
|
||||
void CTerritoryTexture::RecomputeTexture(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
// If the map was resized, delete and regenerate the texture
|
||||
if (m_Texture)
|
||||
@ -139,7 +137,7 @@ void CTerritoryTexture::RecomputeTexture()
|
||||
}
|
||||
|
||||
if (!m_Texture)
|
||||
ConstructTexture();
|
||||
ConstructTexture(deviceCommandContext);
|
||||
|
||||
PROFILE("recompute territory texture");
|
||||
|
||||
@ -147,11 +145,12 @@ void CTerritoryTexture::RecomputeTexture()
|
||||
if (!cmpTerritoryManager)
|
||||
return;
|
||||
|
||||
std::vector<u8> bitmap(m_MapSize * m_MapSize * 4);
|
||||
GenerateBitmap(cmpTerritoryManager->GetTerritoryGrid(), &bitmap[0], m_MapSize, m_MapSize);
|
||||
std::unique_ptr<u8[]> bitmap = std::make_unique<u8[]>(m_MapSize * m_MapSize * 4);
|
||||
GenerateBitmap(cmpTerritoryManager->GetTerritoryGrid(), bitmap.get(), m_MapSize, m_MapSize);
|
||||
|
||||
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]);
|
||||
deviceCommandContext->UploadTextureRegion(
|
||||
m_Texture.get(), Renderer::Backend::Format::R8G8B8A8, bitmap.get(), m_MapSize * m_MapSize * 4,
|
||||
0, 0, m_MapSize, m_MapSize);
|
||||
}
|
||||
|
||||
void CTerritoryTexture::GenerateBitmap(const Grid<u8>& territories, u8* bitmap, ssize_t w, ssize_t h)
|
||||
@ -243,3 +242,9 @@ void CTerritoryTexture::GenerateBitmap(const Grid<u8>& territories, u8* bitmap,
|
||||
if (bitmap[(j*w+i)*4 + 3] == alphaMax)
|
||||
bitmap[(j*w+i)*4 + 3] = 0;
|
||||
}
|
||||
|
||||
void CTerritoryTexture::UpdateIfNeeded(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
|
||||
{
|
||||
if (UpdateDirty())
|
||||
RecomputeTexture(deviceCommandContext);
|
||||
}
|
||||
|
@ -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
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
#include "maths/Matrix3D.h"
|
||||
#include "renderer/backend/gl/Texture.h"
|
||||
#include "renderer/backend/gl/DeviceCommandContext.h"
|
||||
|
||||
class CSimulation2;
|
||||
template<typename T>
|
||||
@ -53,7 +54,13 @@ public:
|
||||
* coordinates, in the form expected by a matrix uniform.
|
||||
* This must only be called after BindTexture.
|
||||
*/
|
||||
const CMatrix3D* GetMinimapTextureMatrix();
|
||||
const CMatrix3D& GetMinimapTextureMatrix();
|
||||
|
||||
/**
|
||||
* Updates the texture if needed (territory was changed or the texture
|
||||
* wasn't created).
|
||||
*/
|
||||
void UpdateIfNeeded(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -62,8 +69,8 @@ private:
|
||||
bool UpdateDirty();
|
||||
|
||||
void DeleteTexture();
|
||||
void ConstructTexture();
|
||||
void RecomputeTexture();
|
||||
void ConstructTexture(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
void RecomputeTexture(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
|
||||
|
||||
void GenerateBitmap(const Grid<u8>& territories, u8* bitmap, ssize_t w, ssize_t h);
|
||||
|
||||
|
@ -120,9 +120,7 @@ void CPostprocManager::RecreateBuffers()
|
||||
Renderer::Backend::Format::R8G8B8A8, w, h, \
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler( \
|
||||
Renderer::Backend::Sampler::Filter::LINEAR, \
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE)); \
|
||||
glBindTexture(GL_TEXTURE_2D, name->GetHandle()); \
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE));
|
||||
|
||||
// Two fullscreen ping-pong textures.
|
||||
GEN_BUFFER_RGBA(m_ColorTex1, m_Width, m_Height);
|
||||
@ -149,12 +147,9 @@ void CPostprocManager::RecreateBuffers()
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE));
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_DepthTex->GetHandle());
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, m_Width, m_Height,
|
||||
0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// Set up the framebuffers with some initial textures.
|
||||
@ -682,10 +677,7 @@ void CPostprocManager::CreateMultisampleBuffer()
|
||||
Renderer::Backend::Format::R8G8B8A8, m_Width, m_Height,
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE), 1);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_MultisampleColorTex->GetHandle());
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_MultisampleCount, GL_RGBA, m_Width, m_Height, GL_TRUE);
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE), 1, m_MultisampleCount);
|
||||
|
||||
// Allocate the Depth/Stencil texture.
|
||||
m_MultisampleDepthTex = Renderer::Backend::GL::CTexture::Create(
|
||||
@ -693,15 +685,7 @@ void CPostprocManager::CreateMultisampleBuffer()
|
||||
Renderer::Backend::Format::D24_S8, m_Width, m_Height,
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE), 1);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_MultisampleDepthTex->GetHandle());
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, m_MultisampleCount, GL_DEPTH24_STENCIL8_EXT, m_Width, m_Height, GL_TRUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
|
||||
|
||||
ogl_WarnIfError();
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE), 1, m_MultisampleCount);
|
||||
|
||||
// Set up the framebuffers with some initial textures.
|
||||
glGenFramebuffersEXT(1, &m_MultisampleFBO);
|
||||
|
@ -270,6 +270,8 @@ public:
|
||||
|
||||
CFontManager fontManager;
|
||||
|
||||
std::unique_ptr<Renderer::Backend::GL::CDeviceCommandContext> deviceCommandContext;
|
||||
|
||||
Internals() :
|
||||
IsOpen(false), ShadersDirty(true), profileTable(g_Renderer.m_Stats), textureManager(g_VFS, false, false)
|
||||
{
|
||||
@ -398,6 +400,8 @@ bool CRenderer::Open(int width, int height)
|
||||
// Validate the currently selected render path
|
||||
SetRenderPath(g_RenderingOptions.GetRenderPath());
|
||||
|
||||
m->deviceCommandContext = Renderer::Backend::GL::CDeviceCommandContext::Create();
|
||||
|
||||
if (g_RenderingOptions.GetPostProc())
|
||||
m->postprocManager.Initialize();
|
||||
|
||||
@ -853,3 +857,8 @@ void CRenderer::MakeScreenShotOnNextFrame(ScreenShotType screenShotType)
|
||||
{
|
||||
m_ScreenShotType = screenShotType;
|
||||
}
|
||||
|
||||
Renderer::Backend::GL::CDeviceCommandContext* CRenderer::GetDeviceCommandContext()
|
||||
{
|
||||
return m->deviceCommandContext.get();
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "graphics/ShaderDefines.h"
|
||||
#include "graphics/ShaderProgramPtr.h"
|
||||
#include "ps/Singleton.h"
|
||||
#include "renderer/backend/gl/DeviceCommandContext.h"
|
||||
#include "renderer/RenderingOptions.h"
|
||||
#include "renderer/Scene.h"
|
||||
|
||||
@ -155,6 +156,8 @@ public:
|
||||
*/
|
||||
void MakeScreenShotOnNextFrame(ScreenShotType screenShotType);
|
||||
|
||||
Renderer::Backend::GL::CDeviceCommandContext* GetDeviceCommandContext();
|
||||
|
||||
protected:
|
||||
friend class CPatchRData;
|
||||
friend class CDecalRData;
|
||||
|
@ -19,14 +19,6 @@
|
||||
|
||||
#include "SceneRenderer.h"
|
||||
|
||||
#include "maths/Matrix3D.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/ConfigDB.h"
|
||||
#include "ps/CStrInternStatic.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "ps/World.h"
|
||||
#include "graphics/Camera.h"
|
||||
#include "graphics/Decal.h"
|
||||
#include "graphics/GameView.h"
|
||||
@ -39,10 +31,19 @@
|
||||
#include "graphics/ParticleManager.h"
|
||||
#include "graphics/Patch.h"
|
||||
#include "graphics/ShaderManager.h"
|
||||
#include "graphics/TerritoryTexture.h"
|
||||
#include "graphics/Terrain.h"
|
||||
#include "graphics/Texture.h"
|
||||
#include "graphics/TextureManager.h"
|
||||
#include "maths/Matrix3D.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/ConfigDB.h"
|
||||
#include "ps/CStrInternStatic.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "ps/VideoMode.h"
|
||||
#include "ps/World.h"
|
||||
#include "renderer/DebugRenderer.h"
|
||||
#include "renderer/HWLightingModelRenderer.h"
|
||||
#include "renderer/InstancingModelRenderer.h"
|
||||
@ -830,14 +831,16 @@ void CSceneRenderer::RenderParticles(int cullGroup)
|
||||
}
|
||||
|
||||
// RenderSubmissions: force rendering of any batched objects
|
||||
void CSceneRenderer::RenderSubmissions(const CBoundingBoxAligned& waterScissor)
|
||||
void CSceneRenderer::RenderSubmissions(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
|
||||
const CBoundingBoxAligned& waterScissor)
|
||||
{
|
||||
PROFILE3("render submissions");
|
||||
OGL_SCOPED_DEBUG_GROUP("Render submissions");
|
||||
|
||||
GetScene().GetLOSTexture().InterpolateLOS();
|
||||
|
||||
GetScene().GetMiniMapTexture().Render();
|
||||
GetScene().GetLOSTexture().InterpolateLOS(deviceCommandContext);
|
||||
GetScene().GetTerritoryTexture().UpdateIfNeeded(deviceCommandContext);
|
||||
GetScene().GetMiniMapTexture().Render(deviceCommandContext);
|
||||
|
||||
CShaderDefines context = m->globalContext;
|
||||
|
||||
@ -954,7 +957,7 @@ void CSceneRenderer::RenderSubmissions(const CBoundingBoxAligned& waterScissor)
|
||||
}
|
||||
|
||||
// render debug-related terrain overlays
|
||||
ITerrainOverlay::RenderOverlaysAfterWater(cullGroup);
|
||||
ITerrainOverlay::RenderOverlaysAfterWater(deviceCommandContext, cullGroup);
|
||||
ogl_WarnIfError();
|
||||
|
||||
// render some other overlays after water (so they can be displayed on top of water)
|
||||
@ -1172,7 +1175,8 @@ void CSceneRenderer::SubmitNonRecursive(CModel* model)
|
||||
}
|
||||
|
||||
// Render the given scene
|
||||
void CSceneRenderer::RenderScene(Scene& scene)
|
||||
void CSceneRenderer::RenderScene(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, Scene& scene)
|
||||
{
|
||||
m_CurrentScene = &scene;
|
||||
|
||||
@ -1245,7 +1249,7 @@ void CSceneRenderer::RenderScene(Scene& scene)
|
||||
|
||||
ogl_WarnIfError();
|
||||
|
||||
RenderSubmissions(waterScissor);
|
||||
RenderSubmissions(deviceCommandContext, waterScissor);
|
||||
|
||||
m_CurrentScene = NULL;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "graphics/ShaderDefines.h"
|
||||
#include "graphics/ShaderProgramPtr.h"
|
||||
#include "ps/Singleton.h"
|
||||
#include "renderer/backend/gl/DeviceCommandContext.h"
|
||||
#include "renderer/RenderingOptions.h"
|
||||
#include "renderer/Scene.h"
|
||||
|
||||
@ -95,7 +96,7 @@ public:
|
||||
* Render the given scene immediately.
|
||||
* @param scene a Scene object describing what should be rendered.
|
||||
*/
|
||||
void RenderScene(Scene& scene);
|
||||
void RenderScene(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, Scene& scene);
|
||||
|
||||
/**
|
||||
* Return the scene that is currently being rendered.
|
||||
@ -192,7 +193,9 @@ protected:
|
||||
void SubmitNonRecursive(CModel* model) override;
|
||||
|
||||
// render any batched objects
|
||||
void RenderSubmissions(const CBoundingBoxAligned& waterScissor);
|
||||
void RenderSubmissions(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
|
||||
const CBoundingBoxAligned& waterScissor);
|
||||
|
||||
// patch rendering stuff
|
||||
void RenderPatches(const CShaderDefines& context, int cullGroup);
|
||||
|
@ -526,20 +526,18 @@ void ShadowMapInternals::CreateTexture()
|
||||
EffectiveWidth = Width;
|
||||
EffectiveHeight = Height;
|
||||
|
||||
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"; 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;
|
||||
case 16: formatName = "Format::D16"; backendFormat = Renderer::Backend::Format::D16; break;
|
||||
case 24: formatName = "Format::D24"; backendFormat = Renderer::Backend::Format::D24; break;
|
||||
case 32: formatName = "Format::D32"; backendFormat = Renderer::Backend::Format::D32; break;
|
||||
default: formatName = "Format::D24"; backendFormat = Renderer::Backend::Format::D24; break;
|
||||
}
|
||||
#endif
|
||||
ENSURE(formatName);
|
||||
@ -554,9 +552,6 @@ void ShadowMapInternals::CreateTexture()
|
||||
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);
|
||||
}
|
||||
|
||||
Texture = Renderer::Backend::GL::CTexture::Create2D(
|
||||
@ -572,21 +567,19 @@ void ShadowMapInternals::CreateTexture()
|
||||
#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
|
||||
|
||||
#if !CONFIG2_GLES
|
||||
g_Renderer.BindTexture(0, Texture->GetHandle());
|
||||
// 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);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
#endif
|
||||
|
||||
ogl_WarnIfError();
|
||||
|
||||
// bind to framebuffer object
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Framebuffer);
|
||||
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, Texture->GetHandle(), 0);
|
||||
|
@ -115,7 +115,7 @@ void SkyManager::LoadSkyTextures()
|
||||
Renderer::Backend::Format::R8G8B8A8, textures[0].m_Width, textures[0].m_Height,
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE), 1);
|
||||
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE), 1, 1);
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_SkyCubeMap->GetHandle());
|
||||
|
||||
|
@ -74,7 +74,8 @@ void ITerrainOverlay::RenderOverlaysBeforeWater()
|
||||
g_TerrainOverlayList[i].first->RenderBeforeWater();
|
||||
}
|
||||
|
||||
void ITerrainOverlay::RenderOverlaysAfterWater(int cullGroup)
|
||||
void ITerrainOverlay::RenderOverlaysAfterWater(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, int cullGroup)
|
||||
{
|
||||
if (g_TerrainOverlayList.empty())
|
||||
return;
|
||||
@ -82,7 +83,7 @@ void ITerrainOverlay::RenderOverlaysAfterWater(int cullGroup)
|
||||
PROFILE3_GPU("terrain overlays (after)");
|
||||
|
||||
for (size_t i = 0; i < g_TerrainOverlayList.size(); ++i)
|
||||
g_TerrainOverlayList[i].first->RenderAfterWater(cullGroup);
|
||||
g_TerrainOverlayList[i].first->RenderAfterWater(deviceCommandContext, cullGroup);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -312,7 +313,8 @@ TerrainTextureOverlay::TerrainTextureOverlay(float texelsPerTile, int priority)
|
||||
|
||||
TerrainTextureOverlay::~TerrainTextureOverlay() = default;
|
||||
|
||||
void TerrainTextureOverlay::RenderAfterWater(int cullGroup)
|
||||
void TerrainTextureOverlay::RenderAfterWater(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, int cullGroup)
|
||||
{
|
||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
||||
|
||||
@ -332,16 +334,13 @@ void TerrainTextureOverlay::RenderAfterWater(int cullGroup)
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::NEAREST,
|
||||
Renderer::Backend::Sampler::AddressMode::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->GetHandle());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
deviceCommandContext->UploadTexture(
|
||||
m_Texture.get(), Renderer::Backend::Format::R8G8B8A8, data, w * h * 4);
|
||||
|
||||
free(data);
|
||||
|
||||
|
@ -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
|
||||
@ -23,6 +23,7 @@
|
||||
#ifndef INCLUDED_TERRAINOVERLAY
|
||||
#define INCLUDED_TERRAINOVERLAY
|
||||
|
||||
#include "renderer/backend/gl/DeviceCommandContext.h"
|
||||
#include "renderer/backend/gl/Texture.h"
|
||||
|
||||
struct CColor;
|
||||
@ -45,7 +46,8 @@ public:
|
||||
|
||||
virtual void RenderBeforeWater() { }
|
||||
|
||||
virtual void RenderAfterWater(int UNUSED(cullGroup)) { }
|
||||
virtual void RenderAfterWater(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* UNUSED(deviceCommandContext), int UNUSED(cullGroup)) { }
|
||||
|
||||
/**
|
||||
* Draw all ITerrainOverlay objects that exist
|
||||
@ -57,7 +59,8 @@ public:
|
||||
* Draw all ITerrainOverlay objects that exist
|
||||
* and that should be drawn after water.
|
||||
*/
|
||||
static void RenderOverlaysAfterWater(int cullGroup);
|
||||
static void RenderOverlaysAfterWater(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, int cullGroup);
|
||||
|
||||
protected:
|
||||
ITerrainOverlay(int priority);
|
||||
@ -176,7 +179,7 @@ class TerrainTextureOverlay : public ITerrainOverlay
|
||||
public:
|
||||
TerrainTextureOverlay(float texelsPerTile, int priority = 100);
|
||||
|
||||
virtual ~TerrainTextureOverlay();
|
||||
~TerrainTextureOverlay() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
@ -194,7 +197,8 @@ protected:
|
||||
SColor4ub GetColor(size_t idx, u8 alpha) const;
|
||||
|
||||
private:
|
||||
void RenderAfterWater(int cullGroup);
|
||||
void RenderAfterWater(
|
||||
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext, int cullGroup) override;
|
||||
|
||||
float m_TexelsPerTile;
|
||||
std::unique_ptr<Renderer::Backend::GL::CTexture> m_Texture;
|
||||
|
@ -214,9 +214,6 @@ int WaterManager::LoadWaterTextures()
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::MIRRORED_REPEAT));
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_ReflectionTexture->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
// Create refraction texture
|
||||
m_RefractionTexture = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::R8G8B8A8, m_RefTextureSize, m_RefTextureSize,
|
||||
@ -224,9 +221,6 @@ int WaterManager::LoadWaterTextures()
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::MIRRORED_REPEAT));
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_RefractionTexture->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
// Create depth textures
|
||||
m_ReflFboDepthTexture = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::D32, m_RefTextureSize, m_RefTextureSize,
|
||||
@ -234,20 +228,12 @@ int WaterManager::LoadWaterTextures()
|
||||
Renderer::Backend::Sampler::Filter::NEAREST,
|
||||
Renderer::Backend::Sampler::AddressMode::REPEAT));
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_ReflFboDepthTexture->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
|
||||
|
||||
m_RefrFboDepthTexture = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::D32, m_RefTextureSize, m_RefTextureSize,
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::NEAREST,
|
||||
Renderer::Backend::Sampler::AddressMode::REPEAT));
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_RefrFboDepthTexture->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, (GLsizei)m_RefTextureSize, (GLsizei)m_RefTextureSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
Resize();
|
||||
|
||||
// Create the water framebuffers
|
||||
@ -322,19 +308,11 @@ void WaterManager::Resize()
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::REPEAT));
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_FancyTexture->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)g_Renderer.GetWidth(), (GLsizei)g_Renderer.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_SHORT, NULL);
|
||||
|
||||
m_FancyTextureDepth = Renderer::Backend::GL::CTexture::Create2D(
|
||||
Renderer::Backend::Format::D32, g_Renderer.GetWidth(), g_Renderer.GetHeight(),
|
||||
Renderer::Backend::Sampler::MakeDefaultSampler(
|
||||
Renderer::Backend::Sampler::Filter::LINEAR,
|
||||
Renderer::Backend::Sampler::AddressMode::REPEAT));
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_FancyTextureDepth->GetHandle());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, (GLsizei)g_Renderer.GetWidth(), (GLsizei)g_Renderer.GetHeight(), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void WaterManager::ReloadWaterNormalTextures()
|
||||
|
84
source/renderer/backend/gl/DeviceCommandContext.cpp
Normal file
84
source/renderer/backend/gl/DeviceCommandContext.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/* 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
|
||||
* 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 "DeviceCommandContext.h"
|
||||
|
||||
#include "renderer/backend/gl/Texture.h"
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
|
||||
namespace Backend
|
||||
{
|
||||
|
||||
namespace GL
|
||||
{
|
||||
|
||||
// static
|
||||
std::unique_ptr<CDeviceCommandContext> CDeviceCommandContext::Create()
|
||||
{
|
||||
std::unique_ptr<CDeviceCommandContext> deviceCommandContext(new CDeviceCommandContext());
|
||||
|
||||
return deviceCommandContext;
|
||||
}
|
||||
|
||||
CDeviceCommandContext::CDeviceCommandContext() = default;
|
||||
|
||||
CDeviceCommandContext::~CDeviceCommandContext() = default;
|
||||
|
||||
void CDeviceCommandContext::UploadTexture(
|
||||
CTexture* texture, const Format format, const void* data, const size_t dataSize)
|
||||
{
|
||||
UploadTextureRegion(texture, format, data, dataSize, 0, 0, texture->GetWidth(), texture->GetHeight());
|
||||
}
|
||||
|
||||
void CDeviceCommandContext::UploadTextureRegion(CTexture* texture, const Format format, const void* data, const size_t dataSize,
|
||||
const uint32_t xOffset, const uint32_t yOffset, const uint32_t width, const uint32_t height)
|
||||
{
|
||||
if (texture->GetType() == CTexture::Type::TEXTURE_2D)
|
||||
{
|
||||
if (texture->GetFormat() == Format::R8G8B8A8 || texture->GetFormat() == Format::A8)
|
||||
{
|
||||
ENSURE(width > 0 && height > 0);
|
||||
ENSURE(texture->GetFormat() == format);
|
||||
const size_t bpp = format == Format::R8G8B8A8 ? 4 : 1;
|
||||
ENSURE(dataSize == width * height * bpp);
|
||||
ENSURE(xOffset + width <= texture->GetWidth());
|
||||
ENSURE(yOffset + height <= texture->GetHeight());
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->GetHandle());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
xOffset, yOffset, width, height,
|
||||
format == Format::R8G8B8A8 ? GL_RGBA : GL_ALPHA, GL_UNSIGNED_BYTE, data);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
ogl_WarnIfError();
|
||||
}
|
||||
else
|
||||
debug_warn("Unsupported format");
|
||||
}
|
||||
else
|
||||
debug_warn("Unsupported type");
|
||||
}
|
||||
|
||||
} // namespace GL
|
||||
|
||||
} // namespace Backend
|
||||
|
||||
} // namespace Renderer
|
57
source/renderer/backend/gl/DeviceCommandContext.h
Normal file
57
source/renderer/backend/gl/DeviceCommandContext.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* 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
|
||||
* 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_GL_DEVICECOMMANDCONTEXT
|
||||
#define INCLUDED_RENDERER_GL_DEVICECOMMANDCONTEXT
|
||||
|
||||
#include "renderer/backend/Format.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
|
||||
namespace Backend
|
||||
{
|
||||
|
||||
namespace GL
|
||||
{
|
||||
|
||||
class CTexture;
|
||||
|
||||
class CDeviceCommandContext
|
||||
{
|
||||
public:
|
||||
~CDeviceCommandContext();
|
||||
|
||||
static std::unique_ptr<CDeviceCommandContext> Create();
|
||||
|
||||
void UploadTexture(CTexture* texture, const Format format, const void* data, const size_t dataSize);
|
||||
void UploadTextureRegion(CTexture* texture, const Format format, const void* data, const size_t dataSize,
|
||||
const uint32_t xOffset, const uint32_t yOffset, const uint32_t width, const uint32_t height);
|
||||
|
||||
private:
|
||||
CDeviceCommandContext();
|
||||
};
|
||||
|
||||
} // namespace GL
|
||||
|
||||
} // namespace Backend
|
||||
|
||||
} // namespace Renderer
|
||||
|
||||
#endif // INCLUDED_RENDERER_GL_DEVICECOMMANDCONTEXT
|
@ -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
|
||||
@ -19,6 +19,7 @@
|
||||
|
||||
#include "Texture.h"
|
||||
|
||||
#include "lib/code_annotation.h"
|
||||
#include "lib/config2.h"
|
||||
#include "lib/res/graphics/ogl_tex.h"
|
||||
#include "renderer/backend/gl/Device.h"
|
||||
@ -85,20 +86,21 @@ GLenum TypeToGLEnum(CTexture::Type type)
|
||||
// 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)
|
||||
const Sampler::Desc& defaultSamplerDesc, const uint32_t mipCount, const uint32_t sampleCount)
|
||||
{
|
||||
return Create(Type::TEXTURE_2D, format, width, height, defaultSamplerDesc, mipCount);
|
||||
return Create(Type::TEXTURE_2D, format, width, height, defaultSamplerDesc, mipCount, sampleCount);
|
||||
}
|
||||
|
||||
// static
|
||||
std::unique_ptr<CTexture> CTexture::Create(const Type type, const Format format,
|
||||
const uint32_t width, const uint32_t height,
|
||||
const Sampler::Desc& defaultSamplerDesc, const uint32_t mipCount)
|
||||
const Sampler::Desc& defaultSamplerDesc, const uint32_t mipCount, const uint32_t sampleCount)
|
||||
{
|
||||
std::unique_ptr<CTexture> texture(new CTexture());
|
||||
|
||||
ENSURE(format != Format::UNDEFINED);
|
||||
ENSURE(width > 0 && height > 0 && mipCount > 0);
|
||||
ENSURE((type == Type::TEXTURE_2D_MULTISAMPLE && sampleCount > 1) || sampleCount == 1);
|
||||
|
||||
texture->m_Format = format;
|
||||
texture->m_Width = width;
|
||||
@ -154,6 +156,85 @@ std::unique_ptr<CTexture> CTexture::Create(const Type type, const Format format,
|
||||
|
||||
ogl_WarnIfError();
|
||||
|
||||
ENSURE(mipCount == 1);
|
||||
|
||||
if (type == CTexture::Type::TEXTURE_2D)
|
||||
{
|
||||
GLint internalFormat = GL_RGBA;
|
||||
// Actually pixel data is nullptr so it doesn't make sense to account
|
||||
// it, but in theory some buggy drivers might complain about invalid
|
||||
// pixel format.
|
||||
GLenum pixelFormat = GL_RGBA;
|
||||
GLenum pixelType = GL_UNSIGNED_BYTE;
|
||||
switch (format)
|
||||
{
|
||||
case Format::UNDEFINED:
|
||||
debug_warn("Texture should defined format");
|
||||
break;
|
||||
case Format::R8G8B8A8:
|
||||
break;
|
||||
case Format::A8:
|
||||
internalFormat = GL_ALPHA;
|
||||
pixelFormat = GL_ALPHA;
|
||||
pixelType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
#if CONFIG2_GLES
|
||||
// GLES requires pixel type == UNSIGNED_SHORT or UNSIGNED_INT for depth.
|
||||
case Format::D16: FALLTHROUGH;
|
||||
case Format::D24: FALLTHROUGH;
|
||||
case Format::D32:
|
||||
internalFormat = GL_DEPTH_COMPONENT;
|
||||
pixelFormat = GL_DEPTH_COMPONENT;
|
||||
pixelType = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case Format::D24_S8:
|
||||
debug_warn("Unsupported format");
|
||||
break;
|
||||
#else
|
||||
case Format::D16:
|
||||
internalFormat = GL_DEPTH_COMPONENT16;
|
||||
pixelFormat = GL_DEPTH_COMPONENT;
|
||||
pixelType = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case Format::D24:
|
||||
internalFormat = GL_DEPTH_COMPONENT24;
|
||||
pixelFormat = GL_DEPTH_COMPONENT;
|
||||
pixelType = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case Format::D32:
|
||||
internalFormat = GL_DEPTH_COMPONENT32;
|
||||
pixelFormat = GL_DEPTH_COMPONENT;
|
||||
pixelType = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case Format::D24_S8:
|
||||
internalFormat = GL_DEPTH24_STENCIL8_EXT;
|
||||
pixelFormat = GL_DEPTH_STENCIL_EXT;
|
||||
pixelType = GL_UNSIGNED_INT_24_8_EXT;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
glTexImage2D(target, 0, internalFormat, width, height, 0, pixelFormat, pixelType, nullptr);
|
||||
}
|
||||
else if (type == CTexture::Type::TEXTURE_2D_MULTISAMPLE)
|
||||
{
|
||||
#if !CONFIG2_GLES
|
||||
if (format == Format::R8G8B8A8)
|
||||
{
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, GL_RGBA8, width, height, GL_TRUE);
|
||||
}
|
||||
else if (format == Format::D24_S8)
|
||||
{
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, GL_DEPTH24_STENCIL8_EXT, width, height, GL_TRUE);
|
||||
}
|
||||
else
|
||||
#endif // !CONFIG2_GLES
|
||||
{
|
||||
debug_warn("Unsupported format");
|
||||
}
|
||||
}
|
||||
|
||||
ogl_WarnIfError();
|
||||
|
||||
glBindTexture(target, 0);
|
||||
|
||||
return texture;
|
||||
|
@ -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
|
||||
@ -52,12 +52,12 @@ public:
|
||||
// an own default sampler.
|
||||
static std::unique_ptr<CTexture> Create(const Type type, const Format format,
|
||||
const uint32_t width, const uint32_t height,
|
||||
const Sampler::Desc& defaultSamplerDesc, const uint32_t mipCount);
|
||||
const Sampler::Desc& defaultSamplerDesc, const uint32_t mipCount, const uint32_t sampleCount);
|
||||
|
||||
// Shorthands for particular types.
|
||||
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);
|
||||
const Sampler::Desc& defaultSamplerDesc, const uint32_t mipCount = 1, const uint32_t sampleCount = 1);
|
||||
|
||||
GLuint GetHandle() const { return m_Handle; }
|
||||
|
||||
|
@ -523,7 +523,7 @@ void ActorViewer::Render()
|
||||
|
||||
g_Renderer.GetSceneRenderer().SetSceneCamera(camera, camera);
|
||||
|
||||
g_Renderer.GetSceneRenderer().RenderScene(m);
|
||||
g_Renderer.GetSceneRenderer().RenderScene(g_Renderer.GetDeviceCommandContext(), m);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
g_Logger->Render();
|
||||
|
Loading…
Reference in New Issue
Block a user