Index: ps/trunk/source/renderer/SceneRenderer.cpp =================================================================== --- ps/trunk/source/renderer/SceneRenderer.cpp +++ ps/trunk/source/renderer/SceneRenderer.cpp @@ -838,6 +838,8 @@ 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); Index: ps/trunk/source/renderer/SkyManager.h =================================================================== --- ps/trunk/source/renderer/SkyManager.h +++ ps/trunk/source/renderer/SkyManager.h @@ -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 #include /** @@ -54,7 +56,7 @@ } /** - * Set the sky set name, potentially loading the textures. + * Set the sky set name. */ void SetSkySet(const CStrW& name); @@ -74,10 +76,14 @@ 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; Index: ps/trunk/source/renderer/SkyManager.cpp =================================================================== --- ps/trunk/source/renderer/SkyManager.cpp +++ ps/trunk/source/renderer/SkyManager.cpp @@ -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 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 @@ } } - 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 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 @@ } } - 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 @@ m_SkyCubeMap.reset(); m_SkySet = newSet; - - LoadSkyTextures(); } -/////////////////////////////////////////////////////////////////// -// Generate list of available skies std::vector SkyManager::GetSkySets() const { std::vector skies; @@ -202,8 +188,6 @@ return skies; } -/////////////////////////////////////////////////////////////////// -// Render sky void SkyManager::RenderSky() { OGL_SCOPED_DEBUG_GROUP("Render Sky"); Index: ps/trunk/source/renderer/backend/gl/DeviceCommandContext.h =================================================================== --- ps/trunk/source/renderer/backend/gl/DeviceCommandContext.h +++ ps/trunk/source/renderer/backend/gl/DeviceCommandContext.h @@ -40,9 +40,14 @@ static std::unique_ptr 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(); Index: ps/trunk/source/renderer/backend/gl/DeviceCommandContext.cpp =================================================================== --- ps/trunk/source/renderer/backend/gl/DeviceCommandContext.cpp +++ ps/trunk/source/renderer/backend/gl/DeviceCommandContext.cpp @@ -43,16 +43,24 @@ 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 @@ 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 @@ 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"); } Index: ps/trunk/source/renderer/backend/gl/Texture.cpp =================================================================== --- ps/trunk/source/renderer/backend/gl/Texture.cpp +++ ps/trunk/source/renderer/backend/gl/Texture.cpp @@ -103,6 +103,7 @@ 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;