diff options
-rw-r--r-- | src/AssetManager.cpp | 4 | ||||
-rw-r--r-- | src/AssetManager.hpp | 4 | ||||
-rw-r--r-- | src/Gal.hpp | 4 | ||||
-rw-r--r-- | src/GalOgl.cpp | 127 | ||||
-rw-r--r-- | src/Render.cpp | 6 | ||||
-rw-r--r-- | src/RendererWorld.cpp | 6 | ||||
-rw-r--r-- | src/TextureAtlas.cpp | 34 | ||||
-rw-r--r-- | src/TextureAtlas.hpp | 10 | ||||
-rw-r--r-- | src/Utility.cpp | 34 | ||||
-rw-r--r-- | src/Utility.hpp | 6 |
10 files changed, 141 insertions, 94 deletions
diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 9cbb6df..1a7e523 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -690,9 +690,9 @@ AssetTreeNode *AssetManager::GetAssetByAssetName(const std::string & assetName) return node; } -GLuint AssetManager::GetTextureAtlasId() +std::shared_ptr<Gal::Texture> AssetManager::GetTextureAtlas() { - return atlas->GetRawTextureId(); + return atlas->GetGalTexture(); } TextureCoord AssetManager::GetTexture(const std::string assetName) { diff --git a/src/AssetManager.hpp b/src/AssetManager.hpp index 7f6c4fb..6fe2eab 100644 --- a/src/AssetManager.hpp +++ b/src/AssetManager.hpp @@ -6,7 +6,6 @@ #include <functional> #include <memory> -#include <GL/glew.h> #include <glm/vec4.hpp> #include <glm/vec3.hpp> #include <glm/mat4x4.hpp> @@ -15,6 +14,7 @@ #include "Block.hpp" #include "TextureAtlas.hpp" #include "Shader.hpp" +#include "Gal.hpp" enum FaceDirection { down, @@ -189,7 +189,7 @@ namespace AssetManager { AssetTreeNode *GetAssetByAssetName(const std::string &assetName); - GLuint GetTextureAtlasId(); + std::shared_ptr<Gal::Texture> GetTextureAtlas(); TextureCoord GetTexture(const std::string assetName); }; diff --git a/src/Gal.hpp b/src/Gal.hpp index 51d3bd6..82ede78 100644 --- a/src/Gal.hpp +++ b/src/Gal.hpp @@ -161,6 +161,8 @@ namespace Gal { virtual ~Texture() = default; virtual void SetData(std::vector<std::byte>&& data, size_t mipLevel = 0) = 0; + + virtual void SetSubData(size_t x, size_t y, size_t z, size_t width, size_t height, size_t depth, std::vector<std::byte> &&data, size_t mipLevel = 0) = 0; }; struct PipelineConfig { @@ -172,6 +174,8 @@ namespace Gal { virtual void AddShaderParameter(std::string_view name, Type type) = 0; + virtual void AddStaticTexture(std::string_view name, std::shared_ptr<Texture> texture) = 0; + virtual void SetTarget(std::shared_ptr<Framebuffer> target) = 0; virtual void SetPrimitive(Primitive primitive) = 0; diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index 5643b4d..7ee6cf3 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -3,6 +3,7 @@ #include <easylogging++.h> #include <GL/glew.h> #include <glm/gtc/type_ptr.hpp> +#include <optick.h> #include "Utility.hpp" @@ -234,6 +235,41 @@ GLenum GalWrappingGetGlType(Wrapping wrapping) { return 0; } +GLenum glCheckError_(const char* file, int line) { + OPTICK_EVENT(); + GLenum errorCode; + while ((errorCode = glGetError()) != GL_NO_ERROR) { + std::string error; + switch (errorCode) { + case GL_INVALID_ENUM: + error = "INVALID_ENUM"; + break; + case GL_INVALID_VALUE: + error = "INVALID_VALUE"; + break; + case GL_INVALID_OPERATION: + error = "INVALID_OPERATION"; + break; + case GL_STACK_OVERFLOW: + error = "STACK_OVERFLOW"; + break; + case GL_STACK_UNDERFLOW: + error = "STACK_UNDERFLOW"; + break; + case GL_OUT_OF_MEMORY: + error = "OUT_OF_MEMORY"; + break; + case GL_INVALID_FRAMEBUFFER_OPERATION: + error = "INVALID_FRAMEBUFFER_OPERATION"; + break; + } + static int t = 0; + LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line; + } + return errorCode; +} +#define glCheckError() glCheckError_(__FILE__, __LINE__) + class ShaderOgl : public Shader { public: @@ -268,6 +304,7 @@ public: Format format; size_t width = 1, height = 1, depth = 1; bool interpolateLayers = false; + GLenum type; Filtering min = Filtering::Nearest, max = Filtering::Nearest; Wrapping wrap = Wrapping::Clamp; @@ -334,11 +371,51 @@ public: glBindTexture(type, 0); } + virtual void SetSubData(size_t x, size_t y, size_t z, size_t width, size_t height, size_t depth, std::vector<std::byte>&& data, size_t mipLevel = 0) override { + size_t expectedSize = width * height * depth * GalFormatGetSize(format); + if (data.size() != expectedSize) + throw std::logic_error("Size of data is not valid for this texture"); + + glBindTexture(type, texture); + glCheckError(); + + switch (type) { + case GL_TEXTURE_2D: + case GL_PROXY_TEXTURE_2D: + case GL_TEXTURE_1D_ARRAY: + case GL_PROXY_TEXTURE_1D_ARRAY: + case GL_TEXTURE_RECTANGLE: + case GL_PROXY_TEXTURE_RECTANGLE: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + case GL_PROXY_TEXTURE_CUBE_MAP: + glTexSubImage2D(type, mipLevel, x, y, width, height, GalFormatGetGlFormat(format), GalFormatGetGlType(format), data.data()); + break; + case GL_TEXTURE_3D: + case GL_PROXY_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + case GL_PROXY_TEXTURE_2D_ARRAY: + glTexSubImage3D(type, mipLevel, x, y, z, width, height, depth, GalFormatGetGlFormat(format), GalFormatGetGlType(format), data.data()); + break; + default: + throw std::runtime_error("Unknown texture type"); + } + + glCheckError(); + + glBindTexture(type, 0); + } + }; class PipelineConfigOgl : public PipelineConfig { public: std::shared_ptr<ShaderOgl> vertexShader, pixelShader; + std::map<std::string, std::shared_ptr<TextureOgl>> textures; std::map<std::string, Type> shaderParameters; std::shared_ptr<Framebuffer> targetFb; std::vector<std::vector<VertexAttribute>> vertexBuffers; @@ -356,6 +433,11 @@ public: shaderParameters.emplace(std::string(name), type); } + virtual void AddStaticTexture(std::string_view name, std::shared_ptr<Texture> texture) override { + auto tex = std::static_pointer_cast<TextureOgl, Texture>(texture); + textures.emplace(std::string(name), tex); + } + virtual void SetTarget(std::shared_ptr<Framebuffer> target) override { targetFb = target; } @@ -436,6 +518,7 @@ public: class PipelineOgl : public Pipeline { public: std::map<std::string, size_t> shaderParameters; + std::vector<std::shared_ptr<TextureOgl>> staticTextures; GLuint program; struct VertexBindingCommand { size_t bufferId; @@ -451,15 +534,21 @@ public: virtual void Activate() override { glUseProgram(program); + + for (size_t i = 0; i < staticTextures.size(); i++) { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(staticTextures[i]->type, staticTextures[i]->texture); + } + glCheckError(); } virtual void SetDynamicTexture(std::string_view name, std::shared_ptr<Texture> texture) override { Activate(); - glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0 + staticTextures.size()); auto tex = std::static_pointer_cast<TextureOgl>(texture); glBindTexture(tex->type, tex->texture); - SetShaderParameter(name, 0); + SetShaderParameter(name, static_cast<int>(staticTextures.size())); } virtual std::shared_ptr<PipelineInstance> CreateInstance(std::vector<std::pair<std::shared_ptr<BufferBinding>, std::shared_ptr<Buffer>>>&& buffers) override { @@ -665,6 +754,7 @@ public: virtual std::shared_ptr<TextureConfig> CreateTexture2DConfig(size_t width, size_t height, Format format) override { auto config = std::make_shared<TextureConfigOgl>(); + config->type = GL_TEXTURE_2D; config->width = width; config->height = height; config->depth = 1; @@ -676,6 +766,7 @@ public: virtual std::shared_ptr<TextureConfig> CreateTexture3DConfig(size_t width, size_t height, size_t depth, bool interpolateLayers, Format format) override { auto config = std::make_shared<TextureConfigOgl>(); + config->type = interpolateLayers ? GL_TEXTURE_3D : GL_TEXTURE_2D_ARRAY; config->width = width; config->height = height; config->depth = depth; @@ -689,7 +780,7 @@ public: auto texConfig = std::static_pointer_cast<TextureConfigOgl, TextureConfig>(config); auto texture = std::make_shared<TextureOgl>(); - texture->type = GL_TEXTURE_2D; + texture->type = texConfig->type; texture->format = texConfig->format; texture->width = texConfig->width; texture->height = texConfig->height; @@ -789,26 +880,26 @@ public: for (auto&& [name, type] : config->shaderParameters) { GLint location = glGetUniformLocation(program, name.c_str()); if (location < 0) { - glDeleteProgram(program); LOG(ERROR) << "Uniform name \"" << name << "\" not found in shader"; - throw std::runtime_error("Invalid uniform"); - } - switch (type) { - case Type::Vec2: - glUniform2f(location, 0.0f, 0.0f); - break; - case Type::Vec2u8: - case Type::Vec2u16: - case Type::Vec2u32: - glUniform2ui(location, 0, 0); - break; - case Type::Vec4u8: - glUniform4ui(location, 0, 0, 0, 0); - break; } pipeline->shaderParameters.insert({ name,location }); } + glCheckError(); + + //Static textures + + size_t usedTextureBlocks = 0; + for (auto&& [name, texture] : config->textures) { + GLint location = glGetUniformLocation(program, name.c_str()); + if (location < 0) { + LOG(ERROR) << "Texture uniform name \"" << name << "\" not found in shader"; + } + + glUniform1i(location, usedTextureBlocks); + pipeline->staticTextures.push_back(texture); + } + //Vertex attributes size_t bufferId = 0; diff --git a/src/Render.cpp b/src/Render.cpp index 8b78efb..74582a1 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -127,11 +127,7 @@ void Render::InitGlew() { } void Render::PrepareToRendering() { - //TextureAtlas texture - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D_ARRAY, AssetManager::GetTextureAtlasId()); - - int width, height; + int width, height; SDL_GL_GetDrawableSize(window, &width, &height); framebuffer = std::make_unique<Framebuffer>(width, height, true); Framebuffer::GetDefault().Activate(); diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index cadad3f..5970160 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -447,7 +447,7 @@ void RendererWorld::PrepareRender() { sectionsPLC->AddShaderParameter("DayTime", Gal::Type::Float); sectionsPLC->AddShaderParameter("GlobalTime", Gal::Type::Float); sectionsPLC->AddShaderParameter("MinLightLevel", Gal::Type::Float); - sectionsPLC->AddShaderParameter("textureAtlas", Gal::Type::Int32); + sectionsPLC->AddStaticTexture("textureAtlas", AssetManager::GetTextureAtlas()); sectionsPLC->SetVertexShader(gal->LoadVertexShader(sectionVertexSource)); sectionsPLC->SetPixelShader(gal->LoadPixelShader(sectionPixelSource)); sectionsPLC->SetPrimitive(Gal::Primitive::TriangleFan); @@ -462,7 +462,6 @@ void RendererWorld::PrepareRender() { }); sectionsPipeline = gal->BuildPipeline(sectionsPLC); sectionsPipeline->SetShaderParameter("MinLightLevel", 0.2f); - sectionsPipeline->SetShaderParameter("textureAtlas", 0); } { @@ -632,7 +631,6 @@ void RendererWorld::PrepareRender() { { auto skyPPC = gal->CreatePipelineConfig(); skyPPC->SetTarget(gal->GetDefaultFramebuffer()); - skyPPC->AddShaderParameter("textureAtlas", Gal::Type::Int32); skyPPC->AddShaderParameter("sunTexture", Gal::Type::Vec4); skyPPC->AddShaderParameter("sunTextureLayer", Gal::Type::Float); skyPPC->AddShaderParameter("moonTexture", Gal::Type::Vec4); @@ -640,6 +638,7 @@ void RendererWorld::PrepareRender() { skyPPC->AddShaderParameter("DayTime", Gal::Type::Float); skyPPC->AddShaderParameter("projView", Gal::Type::Mat4); skyPPC->AddShaderParameter("model", Gal::Type::Mat4); + skyPPC->AddStaticTexture("textureAtlas", AssetManager::GetTextureAtlas()); skyPPC->SetVertexShader(gal->LoadVertexShader(skyVertexSource)); skyPPC->SetPixelShader(gal->LoadPixelShader(skyPixelSource)); auto skyPosUvBB = skyPPC->BindVertexBuffer({ @@ -704,7 +703,6 @@ void RendererWorld::PrepareRender() { skyPipeline = gal->BuildPipeline(skyPPC); skyPipeline->Activate(); - skyPipeline->SetShaderParameter("textureAtlas", 0); skyPipeline->SetShaderParameter("sunTexture", glm::vec4(sunTexture.x, sunTexture.y, sunTexture.w, sunTexture.h)); skyPipeline->SetShaderParameter("sunTextureLayer", static_cast<float>(sunTexture.layer)); skyPipeline->SetShaderParameter("moonTexture", glm::vec4(moonTexture.x, moonTexture.y, moonTexture.w, moonTexture.h)); diff --git a/src/TextureAtlas.cpp b/src/TextureAtlas.cpp index 406418f..7e44a86 100644 --- a/src/TextureAtlas.cpp +++ b/src/TextureAtlas.cpp @@ -35,7 +35,7 @@ TextureAtlas::TextureAtlas(std::vector<TextureData> &textures) { textureCoords.resize(textures.size()); - int layer = 0; + size_t layer = 0; for (;;layer++) { stbrp_context context; std::vector<stbrp_node> nodes; @@ -81,18 +81,16 @@ TextureAtlas::TextureAtlas(std::vector<TextureData> &textures) { } LOG(INFO) << "Texture atlas size is " << textureSize << "x" << textureSize << "x" << layer; - //OpenGL + //Gal int mipLevelCount = 1; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D_ARRAY, texture); - glTexStorage3D(GL_TEXTURE_2D_ARRAY, mipLevelCount, GL_RGBA8, textureSize, textureSize, layer+1); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + auto gal = Gal::GetImplementation(); + auto texConfig = gal->CreateTexture3DConfig(textureSize, textureSize, layer + 1, false, Gal::Format::R8G8B8A8); + texConfig->SetWrapping(Gal::Wrapping::Clamp); + texConfig->SetMinFilter(Gal::Filtering::Nearest); + texConfig->SetMaxFilter(Gal::Filtering::Nearest); - glCheckError(); + texture = gal->BuildTexture(texConfig); //Uploading texture data for (int i = 0; i < textureCoords.size(); i++) { @@ -105,14 +103,16 @@ TextureAtlas::TextureAtlas(std::vector<TextureData> &textures) { std::swap(*(src + j), *(dst + j)); } } - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, textureCoords[i].pixelX, textureSize - textureCoords[i].pixelY - textureCoords[i].pixelH, textureCoords[i].layer, - textureCoords[i].pixelW, textureCoords[i].pixelH, 1, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textures[i].data.data()); - glCheckError(); + texture->SetSubData( + textureCoords[i].pixelX, + textureSize - textureCoords[i].pixelY - textureCoords[i].pixelH, + textureCoords[i].layer, + textureCoords[i].pixelW, + textureCoords[i].pixelH, + 1, + { reinterpret_cast<std::byte*>(textures[i].data.data()), reinterpret_cast<std::byte*>(textures[i].data.data()) + textures[i].data.size() } + ); } LOG(INFO) << "Texture atlas initialized"; } - -TextureAtlas::~TextureAtlas() { - glDeleteTextures(1, &texture); -} diff --git a/src/TextureAtlas.hpp b/src/TextureAtlas.hpp index 1e5c134..836ebf0 100644 --- a/src/TextureAtlas.hpp +++ b/src/TextureAtlas.hpp @@ -2,7 +2,7 @@ #include <vector> -#include <GL/glew.h> +#include "Gal.hpp" struct TextureData { std::vector<unsigned char> data; //expected format RGBA8888 @@ -16,16 +16,12 @@ struct TextureCoord { }; class TextureAtlas { - GLuint texture; + std::shared_ptr<Gal::Texture> texture; std::vector<TextureCoord> textureCoords; public: TextureAtlas(std::vector<TextureData> &textures); - TextureAtlas(const TextureAtlas &) = delete; - - ~TextureAtlas(); - - inline GLuint GetRawTextureId() { + std::shared_ptr<Gal::Texture> GetGalTexture() { return texture; } diff --git a/src/Utility.cpp b/src/Utility.cpp index 09696fd..28d920d 100644 --- a/src/Utility.cpp +++ b/src/Utility.cpp @@ -5,40 +5,6 @@ #include <optick.h> #include <easylogging++.h> -GLenum glCheckError_(const char *file, int line) { - OPTICK_EVENT(); - GLenum errorCode; - while ((errorCode = glGetError()) != GL_NO_ERROR) { - std::string error; - switch (errorCode) { - case GL_INVALID_ENUM: - error = "INVALID_ENUM"; - break; - case GL_INVALID_VALUE: - error = "INVALID_VALUE"; - break; - case GL_INVALID_OPERATION: - error = "INVALID_OPERATION"; - break; - case GL_STACK_OVERFLOW: - error = "STACK_OVERFLOW"; - break; - case GL_STACK_UNDERFLOW: - error = "STACK_UNDERFLOW"; - break; - case GL_OUT_OF_MEMORY: - error = "OUT_OF_MEMORY"; - break; - case GL_INVALID_FRAMEBUFFER_OPERATION: - error = "INVALID_FRAMEBUFFER_OPERATION"; - break; - } - static int t = 0; - LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line; - } - return errorCode; -} - LoopExecutionTimeController::LoopExecutionTimeController(duration delayLength) : delayLength(delayLength) { previousUpdate = clock::now(); diff --git a/src/Utility.hpp b/src/Utility.hpp index 9b90cb9..f16f49a 100644 --- a/src/Utility.hpp +++ b/src/Utility.hpp @@ -5,8 +5,6 @@ #include <chrono> #include <vector> -#include <GL/glew.h> - using Uuid = std::vector<unsigned char>; template<class T> @@ -45,9 +43,7 @@ inline void endswap(unsigned char *arr, size_t arrLen) { std::reverse(arr, arr + arrLen); } -GLenum glCheckError_(const char *file, int line); -#define glCheckError() glCheckError_(__FILE__, __LINE__) - +#define glCheckError() class LoopExecutionTimeController { using clock = std::chrono::steady_clock ; |