1
0
forked from 0ad/0ad

Uploads cube textures in SkyManager via DeviceCommandContext.

Commented By: Stan
Differential Revision: https://code.wildfiregames.com/D4421
This was SVN commit r26185.
This commit is contained in:
Vladislav Belov 2022-01-07 20:00:41 +00:00
parent 15c40861b4
commit f715b73f4f
6 changed files with 85 additions and 48 deletions

View File

@ -838,6 +838,8 @@ void CSceneRenderer::RenderSubmissions(
PROFILE3("render submissions");
OGL_SCOPED_DEBUG_GROUP("Render submissions");
m->skyManager.LoadAndUploadSkyTexturesIfNeeded(deviceCommandContext);
GetScene().GetLOSTexture().InterpolateLOS(deviceCommandContext);
GetScene().GetTerritoryTexture().UpdateIfNeeded(deviceCommandContext);
GetScene().GetMiniMapTexture().Render(deviceCommandContext);

View File

@ -24,7 +24,6 @@
#include "graphics/Terrain.h"
#include "graphics/TextureManager.h"
#include "lib/bits.h"
#include "lib/ogl.h"
#include "lib/tex/tex.h"
#include "lib/timer.h"
#include "maths/MathUtil.h"
@ -43,23 +42,24 @@
#include <algorithm>
SkyManager::SkyManager()
: m_RenderSky(true)
{
CFG_GET_VAL("showsky", m_RenderSky);
}
///////////////////////////////////////////////////////////////////
// Load all sky textures
void SkyManager::LoadSkyTextures()
void SkyManager::LoadAndUploadSkyTexturesIfNeeded(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext)
{
if (m_SkyCubeMap)
return;
OGL_SCOPED_DEBUG_GROUP("Load Sky Textures");
static const CStrW images[NUMBER_OF_TEXTURES + 1] = {
L"front",
L"back",
L"right",
L"left",
L"top",
L"top"
L"top",
L"right",
L"left"
};
/*for (size_t i = 0; i < ARRAY_SIZE(m_SkyTexture); ++i)
@ -111,30 +111,21 @@ void SkyManager::LoadSkyTextures()
}
}
m_SkyCubeMap = Renderer::Backend::GL::CTexture::Create(Renderer::Backend::GL::CTexture::Type::TEXTURE_CUBE,
m_SkyCubeMap = Renderer::Backend::GL::CTexture::Create(
Renderer::Backend::GL::CTexture::Type::TEXTURE_CUBE,
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, 1);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_SkyCubeMap->GetHandle());
static const int types[] =
{
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
};
std::vector<u8> rotated;
for (size_t i = 0; i < NUMBER_OF_TEXTURES + 1; ++i)
{
u8* data = textures[i].get_data();
if (types[i] == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y || types[i] == GL_TEXTURE_CUBE_MAP_POSITIVE_Y)
// We need to rotate the side if it's looking up or down.
// TODO: maybe it should be done during texture conversion.
if (i == 2 || i == 3)
{
rotated.resize(textures[i].m_DataSize);
@ -152,21 +143,20 @@ void SkyManager::LoadSkyTextures()
}
}
glTexImage2D(types[i], 0, GL_RGBA, textures[i].m_Width, textures[i].m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &rotated[0]);
deviceCommandContext->UploadTexture(
m_SkyCubeMap.get(), Renderer::Backend::Format::R8G8B8A8,
&rotated[0], textures[i].m_DataSize, 0, i);
}
else
{
glTexImage2D(types[i], 0, GL_RGBA, textures[i].m_Width, textures[i].m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
deviceCommandContext->UploadTexture(
m_SkyCubeMap.get(), Renderer::Backend::Format::R8G8B8A8,
data, textures[i].m_DataSize, 0, i);
}
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
///////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////
// Switch to a different sky set (while the game is running)
void SkyManager::SetSkySet(const CStrW& newSet)
{
if (newSet == m_SkySet)
@ -175,12 +165,8 @@ void SkyManager::SetSkySet(const CStrW& newSet)
m_SkyCubeMap.reset();
m_SkySet = newSet;
LoadSkyTextures();
}
///////////////////////////////////////////////////////////////////
// Generate list of available skies
std::vector<CStrW> SkyManager::GetSkySets() const
{
std::vector<CStrW> skies;
@ -202,8 +188,6 @@ std::vector<CStrW> SkyManager::GetSkySets() const
return skies;
}
///////////////////////////////////////////////////////////////////
// Render sky
void SkyManager::RenderSky()
{
OGL_SCOPED_DEBUG_GROUP("Render Sky");

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,8 +23,10 @@
#define INCLUDED_SKYMANAGER
#include "graphics/Texture.h"
#include "renderer/backend/gl/DeviceCommandContext.h"
#include "renderer/backend/gl/Texture.h"
#include <memory>
#include <vector>
/**
@ -54,7 +56,7 @@ public:
}
/**
* Set the sky set name, potentially loading the textures.
* Set the sky set name.
*/
void SetSkySet(const CStrW& name);
@ -74,10 +76,14 @@ public:
m_RenderSky = value;
}
private:
void LoadSkyTextures();
/**
* Load all sky textures from files and upload to GPU.
*/
void LoadAndUploadSkyTexturesIfNeeded(
Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
bool m_RenderSky;
private:
bool m_RenderSky = true;
/// Name of current skyset (a directory within art/textures/skies)
CStrW m_SkySet;

View File

@ -43,16 +43,24 @@ CDeviceCommandContext::CDeviceCommandContext() = default;
CDeviceCommandContext::~CDeviceCommandContext() = default;
void CDeviceCommandContext::UploadTexture(
CTexture* texture, const Format format, const void* data, const size_t dataSize)
CTexture* texture, const Format format,
const void* data, const size_t dataSize,
const uint32_t level, const uint32_t layer)
{
UploadTextureRegion(texture, format, data, dataSize, 0, 0, texture->GetWidth(), texture->GetHeight());
UploadTextureRegion(texture, format, data, dataSize,
0, 0, texture->GetWidth(), texture->GetHeight(), level, layer);
}
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)
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,
const uint32_t level, const uint32_t layer)
{
if (texture->GetType() == CTexture::Type::TEXTURE_2D)
{
ENSURE(level == 0 && layer == 0);
if (texture->GetFormat() == Format::R8G8B8A8 || texture->GetFormat() == Format::A8)
{
ENSURE(width > 0 && height > 0);
@ -63,7 +71,7 @@ void CDeviceCommandContext::UploadTextureRegion(CTexture* texture, const Format
ENSURE(yOffset + height <= texture->GetHeight());
glBindTexture(GL_TEXTURE_2D, texture->GetHandle());
glTexSubImage2D(GL_TEXTURE_2D, 0,
glTexSubImage2D(GL_TEXTURE_2D, level,
xOffset, yOffset, width, height,
format == Format::R8G8B8A8 ? GL_RGBA : GL_ALPHA, GL_UNSIGNED_BYTE, data);
glBindTexture(GL_TEXTURE_2D, 0);
@ -73,6 +81,37 @@ void CDeviceCommandContext::UploadTextureRegion(CTexture* texture, const Format
else
debug_warn("Unsupported format");
}
else if (texture->GetType() == CTexture::Type::TEXTURE_CUBE)
{
if (texture->GetFormat() == Format::R8G8B8A8)
{
ENSURE(texture->GetFormat() == format);
ENSURE(level == 0 && 0 <= layer && layer < 6);
ENSURE(xOffset == 0 && yOffset == 0 && texture->GetWidth() == width && texture->GetHeight() == height);
const size_t bpp = 4;
ENSURE(dataSize == width * height * bpp);
// The order of layers should be the following:
// front, back, top, bottom, right, left
static const GLenum targets[6] =
{
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};
glBindTexture(GL_TEXTURE_CUBE_MAP, texture->GetHandle());
glTexImage2D(targets[layer], level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
ogl_WarnIfError();
}
else
debug_warn("Unsupported format");
}
else
debug_warn("Unsupported type");
}

View File

@ -40,9 +40,14 @@ public:
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);
void UploadTexture(CTexture* texture, const Format format,
const void* data, const size_t dataSize,
const uint32_t level = 0, const uint32_t layer = 0);
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,
const uint32_t level = 0, const uint32_t layer = 0);
private:
CDeviceCommandContext();

View File

@ -103,6 +103,7 @@ std::unique_ptr<CTexture> CTexture::Create(const Type type, const Format format,
ENSURE((type == Type::TEXTURE_2D_MULTISAMPLE && sampleCount > 1) || sampleCount == 1);
texture->m_Format = format;
texture->m_Type = type;
texture->m_Width = width;
texture->m_Height = height;
texture->m_MipCount = mipCount;