1
0
forked from 0ad/0ad

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:
Vladislav Belov 2022-01-05 14:49:54 +00:00
parent 07c0d95467
commit fd976456d7
22 changed files with 435 additions and 217 deletions

View File

@ -243,7 +243,7 @@ void CGameView::BeginFrame()
void CGameView::Render()
{
g_Renderer.GetSceneRenderer().RenderScene(*this);
g_Renderer.GetSceneRenderer().RenderScene(g_Renderer.GetDeviceCommandContext(), *this);
}
///////////////////////////////////////////////////////////

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
}

View File

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

View File

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

View File

@ -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();
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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());

View File

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

View File

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

View File

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

View 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

View 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

View File

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

View File

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

View File

@ -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();