diff options
author | LaG1924 <12997935+LaG1924@users.noreply.github.com> | 2021-12-25 07:42:52 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-25 07:42:52 +0100 |
commit | 40421159568518bb7573903d14a2c69c64dead95 (patch) | |
tree | 15c830dce151bf0b427123efd214173742887e8e | |
parent | Merge pull request #70 from LaG1924/ftr/build-3 (diff) | |
parent | Fixed missing APIENTRY linux build (diff) | |
download | AltCraft-40421159568518bb7573903d14a2c69c64dead95.tar AltCraft-40421159568518bb7573903d14a2c69c64dead95.tar.gz AltCraft-40421159568518bb7573903d14a2c69c64dead95.tar.bz2 AltCraft-40421159568518bb7573903d14a2c69c64dead95.tar.lz AltCraft-40421159568518bb7573903d14a2c69c64dead95.tar.xz AltCraft-40421159568518bb7573903d14a2c69c64dead95.tar.zst AltCraft-40421159568518bb7573903d14a2c69c64dead95.zip |
33 files changed, 2343 insertions, 1183 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbb377c..c99d4f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: - uses: seanmiddleditch/gha-setup-ninja@master - name: Prepare Linux if: ${{ runner.os == 'Linux' }} - run: sudo apt install libgl1-mesa-dev libglu1-mesa-dev + run: sudo apt update && sudo apt install libgl1-mesa-dev libglu1-mesa-dev - name: Set up cache uses: actions/cache@v2 with: @@ -69,4 +69,4 @@ jobs: with: name: AltCraft-nightly-b${{ github.run_number }}-${{ matrix.platform.name }}-${{ matrix.build_type }} path: ${{ github.workspace }}/package -
\ No newline at end of file + diff --git a/cwd/assets/altcraft/shaders/entity.json b/cwd/assets/altcraft/shaders/entity.json index 0b65c72..33a32e9 100644 --- a/cwd/assets/altcraft/shaders/entity.json +++ b/cwd/assets/altcraft/shaders/entity.json @@ -3,8 +3,7 @@ "frag": "/altcraft/shaders/frag/entity", "uniforms": [ "color", - "view", - "projection", + "projView", "model" ] }
\ No newline at end of file diff --git a/cwd/assets/altcraft/shaders/frag/entity.fs b/cwd/assets/altcraft/shaders/frag/entity.fs index 6a11c96..06d5759 100644 --- a/cwd/assets/altcraft/shaders/frag/entity.fs +++ b/cwd/assets/altcraft/shaders/frag/entity.fs @@ -1,10 +1,9 @@ #version 330 core -uniform vec3 color; -in vec2 uvPos; out vec4 fragColor; -void main(){ - //if (uvPos.x < 0.9 && uvPos.x > 0.1 && uvPos.y < 0.9 && uvPos.y > 0.1) discard; - fragColor = vec4(color,1); -}
\ No newline at end of file +uniform vec3 color; + +void main() { + fragColor = vec4(color, 1); +} diff --git a/cwd/assets/altcraft/shaders/frag/sky.fs b/cwd/assets/altcraft/shaders/frag/sky.fs index 2f51267..53e0cf4 100644 --- a/cwd/assets/altcraft/shaders/frag/sky.fs +++ b/cwd/assets/altcraft/shaders/frag/sky.fs @@ -1,6 +1,5 @@ #version 330 core -in vec2 uvPos; in vec3 pos; out vec4 fragColor; @@ -12,11 +11,11 @@ uniform float sunTextureLayer; uniform vec4 moonTexture; uniform float moonTextureLayer; -const vec4 DaySkyColor = vec4(0.49,0.66,1, 1); +const vec4 DaySkyColor = vec4(0.49, 0.66, 1, 1); -const vec3 SunPos = vec3(0,0.1,0.5); +const vec3 SunPos = vec3(0, 0.1, 0.5); -const vec3 MoonPos = vec3(0,0.1,-0.5); +const vec3 MoonPos = vec3(0, 0.1, -0.5); vec3 TransformTextureCoord(vec4 TextureAtlasCoords, vec2 UvCoords, float Layer) { float x = TextureAtlasCoords.x; @@ -25,23 +24,23 @@ vec3 TransformTextureCoord(vec4 TextureAtlasCoords, vec2 UvCoords, float Layer) float h = TextureAtlasCoords.w; vec2 A = vec2(x, 1 - y - h); vec2 B = vec2(x + w, 1 - y); - vec2 transformed = A + UvCoords * (B - A); + vec2 transformed = A + UvCoords * (B - A); return vec3(transformed.x, transformed.y, Layer); } vec4 Sun() { - vec3 sunDelta = (pos - SunPos)*3.0f; + vec3 sunDelta = (pos - SunPos) * 3.0f; float distanceToSun = length(sunDelta); - vec4 sunColor = texture(textureAtlas,TransformTextureCoord(sunTexture,(vec2(sunDelta.xy)+0.5f),sunTextureLayer)); - vec4 sun = mix(vec4(0,0,0,1),sunColor,clamp(1-distanceToSun*2.0f,0,1)); + vec4 sunColor = texture(textureAtlas, TransformTextureCoord(sunTexture, (vec2(sunDelta.xy) + 0.5f), sunTextureLayer)); + vec4 sun = mix(vec4(0, 0, 0, 1), sunColor, clamp(1 - distanceToSun * 2.0f, 0, 1)); return sun; } vec4 Moon() { - vec3 moonDelta = (pos - MoonPos)*4.5f; + vec3 moonDelta = (pos - MoonPos) * 4.5f; float distanceToMoon = length(moonDelta); - vec4 moonColor = texture(textureAtlas,TransformTextureCoord(moonTexture,(vec2(moonDelta.xy)+0.5f),moonTextureLayer)); - vec4 moon = mix(vec4(0,0,0,1),moonColor,clamp(1-distanceToMoon*2.0f,0,1)); + vec4 moonColor = texture(textureAtlas, TransformTextureCoord(moonTexture, (vec2(moonDelta.xy) + 0.5f), moonTextureLayer)); + vec4 moon = mix(vec4(0, 0, 0, 1),moonColor, clamp(1 - distanceToMoon * 2.0f, 0, 1)); return moon; } @@ -50,4 +49,4 @@ void main() { fragColor = mix(starColor, DaySkyColor, DayTime); fragColor += Sun(); fragColor += Moon(); -}
\ No newline at end of file +} diff --git a/cwd/assets/altcraft/shaders/sky.json b/cwd/assets/altcraft/shaders/sky.json index 6e53db6..f4c8813 100644 --- a/cwd/assets/altcraft/shaders/sky.json +++ b/cwd/assets/altcraft/shaders/sky.json @@ -2,8 +2,7 @@ "vert": "/altcraft/shaders/vert/sky", "frag": "/altcraft/shaders/frag/sky", "uniforms": [ - "view", - "projection", + "projView", "model", "textureAtlas", "DayTime", diff --git a/cwd/assets/altcraft/shaders/vert/entity.vs b/cwd/assets/altcraft/shaders/vert/entity.vs index baa25e5..e38c54c 100644 --- a/cwd/assets/altcraft/shaders/vert/entity.vs +++ b/cwd/assets/altcraft/shaders/vert/entity.vs @@ -1,13 +1,10 @@ #version 330 core -uniform mat4 view; -uniform mat4 projection; -uniform mat4 model; -layout (location = 0) in vec3 position; -layout (location = 1) in vec2 uvPosition; -out vec2 uvPos; +in vec3 position; -void main(){ - uvPos = uvPosition; - gl_Position = projection*view*model*vec4(position,1); -}
\ No newline at end of file +uniform mat4 projView; +uniform mat4 model; + +void main() { + gl_Position = projView * model * vec4(position, 1); +} diff --git a/cwd/assets/altcraft/shaders/vert/sky.vs b/cwd/assets/altcraft/shaders/vert/sky.vs index 983e1f3..0ab261c 100644 --- a/cwd/assets/altcraft/shaders/vert/sky.vs +++ b/cwd/assets/altcraft/shaders/vert/sky.vs @@ -1,17 +1,13 @@ #version 330 core -uniform mat4 view; -uniform mat4 projection; -uniform mat4 model; +in vec3 position; -layout (location = 0) in vec3 position; -layout (location = 1) in vec2 uvPosition; - -out vec2 uvPos; out vec3 pos; -void main(){ - uvPos = uvPosition; +uniform mat4 projView; +uniform mat4 model; + +void main() { pos = position; - gl_Position = projection*view*model*vec4(position,1); -}
\ No newline at end of file + gl_Position = projView * model * vec4(position, 1); +} diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 9cbb6df..0976e30 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -392,34 +392,7 @@ void ParseAssetBlockState(AssetTreeNode &node) { } void ParseAssetShader(AssetTreeNode &node) { - try { - nlohmann::json j = nlohmann::json::parse(node.data); - std::string vertPath = j["vert"].get<std::string>(); - std::string fragPath = j["frag"].get<std::string>(); - - AssetTreeNode* vertAsset = AssetManager::GetAssetByAssetName(vertPath); - AssetTreeNode* fragAsset = AssetManager::GetAssetByAssetName(fragPath); - std::string vertSource((char*)vertAsset->data.data(), (char*)vertAsset->data.data() + vertAsset->data.size()); - std::string fragSource((char*)fragAsset->data.data(), (char*)fragAsset->data.data() + fragAsset->data.size()); - - std::vector<std::string> uniforms; - - for (auto& it : j["uniforms"]) { - uniforms.push_back(it.get<std::string>()); - } - - node.asset = std::make_unique<AssetShader>(); - AssetShader* asset = dynamic_cast<AssetShader*>(node.asset.get()); - asset->shader = std::make_unique<Shader>(vertSource, fragSource, uniforms); - } catch (std::exception &e) { - glCheckError(); - LOG(ERROR) << "Shader asset parsing failed: " << e.what(); - } catch (...) { - glCheckError(); - LOG(ERROR) << "Shader asset parsing failed with unknown reason"; - return; - } } void ParseAssetScript(AssetTreeNode &node) { @@ -690,9 +663,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..2bee47c 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> @@ -14,7 +13,7 @@ #include "Vector.hpp" #include "Block.hpp" #include "TextureAtlas.hpp" -#include "Shader.hpp" +#include "Gal.hpp" enum FaceDirection { down, @@ -164,7 +163,7 @@ struct AssetTexture : Asset { }; struct AssetShader : Asset { - std::unique_ptr<Shader> shader; + }; struct AssetScript : Asset { @@ -189,7 +188,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/Framebuffer.cpp b/src/Framebuffer.cpp deleted file mode 100644 index d81b0e0..0000000 --- a/src/Framebuffer.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "Framebuffer.hpp" -#include "Shader.hpp" -#include <string> -#include "Utility.hpp" -#include "AssetManager.hpp" -#include <optick.h> - -const GLuint magic = 316784; -GLuint quadVao = magic, quadVbo = magic; - -Framebuffer::Framebuffer(unsigned int width, unsigned int height, bool createDepthStencilBuffer) : width(width), height(height) { - OPTICK_EVENT(); - if (quadVao == magic) { - float quadVertices[] = { - // positions // texCoords - -1.0f, 1.0f, 0.0f, 1.0f, - -1.0f, -1.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 0.0f, - - -1.0f, 1.0f, 0.0f, 1.0f, - 1.0f, -1.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 1.0f, 1.0f - }; - - glGenVertexArrays(1, &quadVao); - glGenBuffers(1, &quadVbo); - glBindVertexArray(quadVao); - glBindBuffer(GL_ARRAY_BUFFER, quadVbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/fbo")->shader->Activate(); - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/fbo")->shader->SetUniform("inputTexture", 1); - glActiveTexture(GL_TEXTURE1); - glCheckError(); - } - - glGenTextures(1, &texColor); - glBindTexture(GL_TEXTURE_2D, texColor); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glCheckError(); - - if (createDepthStencilBuffer) { - glGenRenderbuffers(1, &rboDepthStencil); - glBindRenderbuffer(GL_RENDERBUFFER, rboDepthStencil); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); - } - - glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0); - if(createDepthStencilBuffer) - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboDepthStencil); - glCheckError(); - - GLenum framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (framebufferStatus != GL_FRAMEBUFFER_COMPLETE) - throw std::runtime_error("Failed to initialize framebuffer: " + std::to_string(framebufferStatus)); -} - -Framebuffer::~Framebuffer() { - if (rboDepthStencil) - glDeleteRenderbuffers(1, &rboDepthStencil); - if (texColor) - glDeleteTextures(1, &texColor); - - glDeleteFramebuffers(1, &fbo); -} - -void Framebuffer::Activate() { - OPTICK_EVENT(); - glViewport(0, 0, width, height); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); -} - -void Framebuffer::RenderTo(Framebuffer &target) { - OPTICK_EVENT(); - glBindFramebuffer(GL_FRAMEBUFFER, target.fbo); - glViewport(0, 0, target.width, target.height); - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/fbo")->shader->Activate(); - glBindVertexArray(quadVao); - glBindTexture(GL_TEXTURE_2D, texColor); - glDrawArrays(GL_TRIANGLES, 0, 6); -} - -void Framebuffer::Resize(unsigned int newWidth, unsigned int newHeight) { - width = newWidth; - height = newHeight; - if (texColor) { - glBindTexture(GL_TEXTURE_2D, texColor); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, newWidth, newHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); - } - if (rboDepthStencil) { - glBindRenderbuffer(GL_RENDERBUFFER, rboDepthStencil); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); - } -} - -Framebuffer &Framebuffer::GetDefault() { - OPTICK_EVENT(); - static char fboDefaultData[sizeof(Framebuffer)]; - static Framebuffer *fboDefault = nullptr; - if (fboDefault == nullptr) { - fboDefault = reinterpret_cast<Framebuffer*>(fboDefaultData); - fboDefault->fbo = 0; - fboDefault->width = 1; - fboDefault->height = 1; - fboDefault->texColor = 0; - fboDefault->rboDepthStencil = 0; - } - return *fboDefault; -} - -void Framebuffer::Clear(bool color, bool depth, bool stencil) { - OPTICK_EVENT(); - Activate(); - GLbitfield clearBits = 0; - if (color) - clearBits |= GL_COLOR_BUFFER_BIT; - if (depth) - clearBits |= GL_DEPTH_BUFFER_BIT; - if (stencil) - clearBits |= GL_STENCIL_BUFFER_BIT; - glClear(clearBits); -} diff --git a/src/Framebuffer.hpp b/src/Framebuffer.hpp deleted file mode 100644 index f5c102d..0000000 --- a/src/Framebuffer.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include <GL/glew.h> - -class Framebuffer { - unsigned int width, height; - GLuint fbo, texColor = 0, rboDepthStencil = 0; -public: - Framebuffer(unsigned int width, unsigned int height, bool createDepthStencilBuffer); - ~Framebuffer(); - Framebuffer(const Framebuffer&) = delete; - Framebuffer(Framebuffer &&) = delete; - Framebuffer &operator=(const Framebuffer &) = delete; - Framebuffer &operator=(Framebuffer &&) = delete; - - void Activate(); - - void RenderTo(Framebuffer &target); - - void Resize(unsigned int newWidth, unsigned int newHeight); - - inline GLuint GetColor() { - return texColor; - } - - static Framebuffer &GetDefault(); - - void Clear(bool color = true, bool depth = true, bool stencil = true); -}; diff --git a/src/Gal.hpp b/src/Gal.hpp new file mode 100644 index 0000000..f448c89 --- /dev/null +++ b/src/Gal.hpp @@ -0,0 +1,284 @@ +#pragma once + +#include <cstdint> +#include <memory> +#include <vector> +#include <string> +#include <string_view> + +#include <glm/glm.hpp> + +namespace Gal { + + struct Impl; + struct Buffer; + struct BufferBinding; + struct TextureConfig; + struct Texture; + struct PipelineConfig; + struct Pipeline; + struct PipelineInstance; + struct FramebufferConfig; + struct Framebuffer; + struct ShaderParameters; + struct Shader; + + + enum class Type { + Float, + Double, + Uint8, + Uint16, + Uint32, + Int8, + Int16, + Int32, + Vec2, + Vec2u8, + Vec2u16, + Vec2u32, + Vec2i8, + Vec2i16, + Vec2i32, + Vec3, + Vec3u8, + Vec3u16, + Vec3u32, + Vec3i8, + Vec3i16, + Vec3i32, + Vec4, + Vec4u8, + Vec4u16, + Vec4u32, + Vec4i8, + Vec4i16, + Vec4i32, + Mat2, + Mat3, + Mat4, + }; + + enum class Format { + D24S8, + R8G8B8, + R8G8B8A8, + }; + + enum class Filtering { + Nearest, + Bilinear, + Trilinear, + Anisotropy, + }; + + enum class Wrapping { + Repeat, + Mirror, + Clamp, + }; + + enum class Primitive { + Line, + Triangle, + TriangleStrip, + TriangleFan, + }; + + struct VertexAttribute { + std::string name; + Type type; + size_t count = 1; + size_t instances = 0; + }; + + Impl* GetImplementation(); + + struct Impl { + + virtual void Init() = 0; + + virtual void DeInit() = 0; + + virtual void Cleanup() = 0; + + virtual void SetScissor(size_t x=0, size_t y=0, size_t width=0, size_t height=0) = 0; + + virtual void SetScissor(bool enabled) = 0; + + + virtual std::shared_ptr<Buffer> CreateBuffer() = 0; + + + virtual std::shared_ptr<TextureConfig> CreateTexture2DConfig(size_t width, size_t height, Format format) = 0; + + virtual std::shared_ptr<TextureConfig> CreateTexture3DConfig(size_t width, size_t height, size_t depth, bool interpolateLayers, Format format) = 0; + + virtual std::shared_ptr<Texture> BuildTexture(std::shared_ptr<TextureConfig> config) = 0; + + + virtual std::shared_ptr<PipelineConfig> CreatePipelineConfig() = 0; + + virtual std::shared_ptr<Pipeline> BuildPipeline(std::shared_ptr<PipelineConfig> config) = 0; + + + virtual std::shared_ptr<FramebufferConfig> CreateFramebufferConfig() = 0; + + virtual std::shared_ptr<Framebuffer> BuildFramebuffer(std::shared_ptr<FramebufferConfig> config) = 0; + + virtual std::shared_ptr<Framebuffer> GetDefaultFramebuffer() = 0; + + + virtual std::shared_ptr<ShaderParameters> GetGlobalShaderParameters() = 0; + + virtual std::shared_ptr<Shader> LoadVertexShader(std::string_view code) = 0; + + virtual std::shared_ptr<Shader> LoadPixelShader(std::string_view code) = 0; + + }; + + struct Buffer { + virtual ~Buffer() = default; + + virtual void SetData(std::vector<std::byte>&& data) = 0; + }; + + struct BufferBinding { + virtual ~BufferBinding() = default; + }; + + struct TextureConfig { + virtual ~TextureConfig() = default; + + virtual void SetMinFilter(Filtering filter) = 0; + + virtual void SetMaxFilter(Filtering filter) = 0; + + virtual void SetWrapping(Wrapping wrapping) = 0; + + }; + + struct Texture { + 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 { + virtual ~PipelineConfig() = default; + + virtual void SetVertexShader(std::shared_ptr<Shader> shader) = 0; + + virtual void SetPixelShader(std::shared_ptr<Shader> shader) = 0; + + 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; + + virtual std::shared_ptr<BufferBinding> BindVertexBuffer(std::vector<VertexAttribute> &&bufferLayout) = 0; + + virtual std::shared_ptr<BufferBinding> BindIndexBuffer() = 0; + }; + + struct Pipeline { + virtual ~Pipeline() = default; + + virtual void Activate() = 0; + + virtual std::shared_ptr<PipelineInstance> CreateInstance(std::vector<std::pair<std::shared_ptr<BufferBinding>, std::shared_ptr<Buffer>>> &&buffers) = 0; + + virtual void SetDynamicTexture(std::string_view name, std::shared_ptr<Texture> texture) = 0; + + virtual void SetShaderParameter(std::string_view name, float value) = 0; + + virtual void SetShaderParameter(std::string_view name, double value) = 0; + + virtual void SetShaderParameter(std::string_view name, int8_t value) = 0; + + virtual void SetShaderParameter(std::string_view name, int16_t value) = 0; + + virtual void SetShaderParameter(std::string_view name, int32_t value) = 0; + + virtual void SetShaderParameter(std::string_view name, uint8_t value) = 0; + + virtual void SetShaderParameter(std::string_view name, uint16_t value) = 0; + + virtual void SetShaderParameter(std::string_view name, uint32_t value) = 0; + + virtual void SetShaderParameter(std::string_view name, glm::vec2 value) = 0; + + virtual void SetShaderParameter(std::string_view name, glm::uvec2 value) = 0; + + virtual void SetShaderParameter(std::string_view name, glm::vec3 value) = 0; + + virtual void SetShaderParameter(std::string_view name, glm::vec4 value) = 0; + + virtual void SetShaderParameter(std::string_view name, glm::mat4 value) = 0; + }; + + struct PipelineInstance { + virtual ~PipelineInstance() = default; + + virtual void Activate() = 0; + + virtual void Render(size_t offset = 0, size_t count = -1) = 0; + + virtual void SetInstancesCount(size_t count) = 0; + }; + + struct Framebuffer { + virtual ~Framebuffer() = default; + + virtual void Clear() = 0; + + virtual void SetViewport(size_t x, size_t y, size_t w, size_t h) = 0; + }; + + struct FramebufferConfig { + virtual ~FramebufferConfig() = default; + + virtual void SetDepthStencil(std::shared_ptr<Texture> texture) = 0; + + virtual void SetTexture(size_t location, std::shared_ptr<Texture> texture) = 0; + }; + + struct ShaderParameters { + virtual ~ShaderParameters() = default; + + virtual void AddGlobalShaderParameter(std::string_view name, Type type) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, float value) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, double value) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, int8_t value) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, int16_t value) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, int32_t value) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, uint8_t value) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, uint16_t value) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, uint32_t value) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, glm::vec2 value) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, glm::vec3 value) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, glm::vec4 value) = 0; + + virtual void SetGlobalShaderParameter(std::string_view name, glm::mat4 value) = 0; + }; + + struct Shader { + virtual ~Shader() = default; + }; +} diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp new file mode 100644 index 0000000..052c68a --- /dev/null +++ b/src/GalOgl.cpp @@ -0,0 +1,1344 @@ +#include "Gal.hpp" + +#include <easylogging++.h> +#include <GL/glew.h> +#include <glm/gtc/type_ptr.hpp> +#include <optick.h> + +#include "Utility.hpp" + +enum class GlResourceType { + Vbo, + Vao, + Texture, + Fbo, + Program, + None, +}; + +class GlResource { + GlResourceType type = GlResourceType::None; + GLuint res = 0; +public: + GlResource() = default; + + GlResource(GLuint resource, GlResourceType resType) noexcept : res(resource), type(resType) {} + + GlResource(const GlResource&) = delete; + + GlResource(GlResource&& rhs) noexcept { + std::swap(this->res, rhs.res); + std::swap(this->type, rhs.type); + } + + GlResource& operator=(const GlResource&) = delete; + + GlResource& operator=(GlResource&& rhs) noexcept { + std::swap(this->res, rhs.res); + std::swap(this->type, rhs.type); + return *this; + } + + ~GlResource() { + switch (type) { + case GlResourceType::Vbo: + glDeleteBuffers(1, &res); + break; + case GlResourceType::Vao: + glDeleteVertexArrays(1, &res); + break; + case GlResourceType::Texture: + glDeleteTextures(1, &res); + break; + case GlResourceType::Fbo: + glDeleteFramebuffers(1, &res); + break; + case GlResourceType::Program: + glDeleteProgram(res); + break; + case GlResourceType::None: + default: + break; + } + } + + operator GLuint() const noexcept { + return res; + } + + GLuint Get() const noexcept { + return res; + } +}; + + +using namespace Gal; + +class ImplOgl; +class ShaderOgl; +class FramebufferOgl; + +class OglState { + GLuint activeFbo = 0; + GLuint activeVao = 0; + GLuint activeVbo = 0; + GLuint activeEbo = 0; + GLuint activeProgram = 0; + GLuint activeTexture[16] = { 0 }; + GLuint activeTextureUnit = 0; + GLint vpX = 0, vpY = 0; + GLsizei vpW = 0, vpH = 0; + +public: + + void BindFbo(GLuint fbo) { + if (fbo != activeFbo) { + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + activeFbo = fbo; + } + glCheckError(); + } + + void BindVao(GLuint vao) { + if (vao != activeVao) { + glBindVertexArray(vao); + activeVao = vao; + } + glCheckError(); + } + + void BindVbo(GLuint vbo) { + if (vbo != activeVbo) { + glBindBuffer(GL_ARRAY_BUFFER, vbo); + activeVbo = vbo; + } + glCheckError(); + } + + void BindEbo(GLuint ebo) { + if (ebo != activeEbo) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + activeEbo = ebo; + } + glCheckError(); + } + + void SetTextureUnit(size_t textureUnit) { + if (textureUnit != activeTextureUnit) { + glActiveTexture(GL_TEXTURE0 + textureUnit); + activeTextureUnit = textureUnit; + } + glCheckError(); + } + + void BindTexture(GLenum type, GLuint texture, size_t textureUnit = 17) { + if (textureUnit >= 16) + textureUnit = activeTextureUnit; + if (activeTexture[textureUnit] != texture) { + SetTextureUnit(textureUnit); + glBindTexture(type, texture); + } + glCheckError(); + } + + void UseProgram(GLuint program) { + if (program != activeProgram) { + glUseProgram(program); + activeProgram = program; + } + glCheckError(); + } + + void SetViewport(GLint x, GLint y, GLsizei w, GLsizei h) { + if (x != vpX || y != vpY || w != vpW || h != vpH) { + glViewport(x, y, w, h); + vpX = x; + vpY = y; + vpW = w; + vpH = h; + } + glCheckError(); + } + +} oglState; + +std::unique_ptr<ImplOgl> impl; +std::shared_ptr<FramebufferOgl> fbDefault; + +size_t GalTypeGetComponents(Gal::Type type) { + switch (type) { + case Type::Float: + case Type::Double: + case Type::Uint8: + case Type::Uint16: + case Type::Uint32: + case Type::Int8: + case Type::Int16: + case Type::Int32: + return 1; + case Type::Vec2: + case Type::Vec2u8: + case Type::Vec2u16: + case Type::Vec2u32: + case Type::Vec2i8: + case Type::Vec2i16: + case Type::Vec2i32: + return 2; + case Type::Vec3: + case Type::Vec3u8: + case Type::Vec3u16: + case Type::Vec3u32: + case Type::Vec3i8: + case Type::Vec3i16: + case Type::Vec3i32: + return 3; + case Type::Vec4: + case Type::Vec4u8: + case Type::Vec4u16: + case Type::Vec4u32: + case Type::Vec4i8: + case Type::Vec4i16: + case Type::Vec4i32: + case Type::Mat2: + return 4; + case Type::Mat3: + return 9; + case Type::Mat4: + return 16; + default: + return 0; + } + return 0; +} + +size_t GalTypeGetComponentSize(Gal::Type type) { + switch (type) { + case Type::Uint8: + case Type::Int8: + case Type::Vec2u8: + case Type::Vec2i8: + case Type::Vec3u8: + case Type::Vec3i8: + case Type::Vec4u8: + case Type::Vec4i8: + return 1; + case Type::Uint16: + case Type::Int16: + case Type::Vec2u16: + case Type::Vec2i16: + case Type::Vec3u16: + case Type::Vec3i16: + case Type::Vec4u16: + case Type::Vec4i16: + return 2; + case Type::Float: + case Type::Uint32: + case Type::Int32: + case Type::Vec2: + case Type::Vec2u32: + case Type::Vec2i32: + case Type::Vec3: + case Type::Vec3u32: + case Type::Vec3i32: + case Type::Vec4: + case Type::Vec4u32: + case Type::Vec4i32: + case Type::Mat2: + case Type::Mat3: + case Type::Mat4: + return 4; + case Type::Double: + return 8; + default: + return 0; + } +} + +size_t GalTypeGetSize(Gal::Type type) { + return GalTypeGetComponents(type) * GalTypeGetComponentSize(type); +} + +GLenum GalTypeGetComponentGlType(Gal::Type type) { + switch (type) { + case Type::Float: + case Type::Vec2: + case Type::Vec3: + case Type::Vec4: + case Type::Mat2: + case Type::Mat3: + case Type::Mat4: + return GL_FLOAT; + case Type::Double: + return GL_DOUBLE; + case Type::Uint8: + case Type::Vec2u8: + case Type::Vec3u8: + case Type::Vec4u8: + return GL_UNSIGNED_BYTE; + case Type::Uint16: + case Type::Vec2u16: + case Type::Vec3u16: + case Type::Vec4u16: + return GL_UNSIGNED_SHORT; + case Type::Uint32: + case Type::Vec2u32: + case Type::Vec3u32: + case Type::Vec4u32: + return GL_UNSIGNED_INT; + case Type::Int8: + case Type::Vec2i8: + case Type::Vec3i8: + case Type::Vec4i8: + return GL_BYTE; + case Type::Int16: + case Type::Vec2i16: + case Type::Vec3i16: + case Type::Vec4i16: + return GL_SHORT; + case Type::Int32: + case Type::Vec2i32: + case Type::Vec3i32: + case Type::Vec4i32: + return GL_INT; + default: + return 0; + } + return 0; +} + +size_t GalFormatGetSize(Format format) { + switch (format) { + case Format::R8G8B8: + return 3; + case Format::R8G8B8A8: + return 4; + default: + return 0; + } + return 0; +} + +GLenum GalFormatGetGlInternalFormat(Format format) { + switch (format) { + case Format::D24S8: + return GL_DEPTH24_STENCIL8; + case Format::R8G8B8: + return GL_RGB8; + case Format::R8G8B8A8: + return GL_RGBA8; + default: + return 0; + } + return 0; +} + +GLenum GalFormatGetGlFormat(Format format) { + switch (format) { + case Format::D24S8: + return GL_DEPTH_STENCIL; + case Format::R8G8B8: + return GL_RGB; + case Format::R8G8B8A8: + return GL_RGBA; + default: + return 0; + } + return 0; +} + +GLenum GalFormatGetGlType(Format format) { + switch (format) { + case Format::D24S8: + return GL_UNSIGNED_INT_24_8; + case Format::R8G8B8: + return GL_UNSIGNED_BYTE; + case Format::R8G8B8A8: + return GL_UNSIGNED_BYTE; + default: + return 0; + } + return 0; +} + +GLenum GalFilteringGetGlType(Filtering filtering) { + switch (filtering) { + case Filtering::Nearest: + return GL_NEAREST; + case Filtering::Bilinear: + return GL_LINEAR; + case Filtering::Trilinear: + return GL_LINEAR_MIPMAP_LINEAR; + case Filtering::Anisotropy: + return GL_LINEAR; + default: + return 0; + } + return 0; +} + +GLenum GalWrappingGetGlType(Wrapping wrapping) { + switch (wrapping) { + case Wrapping::Repeat: + return GL_REPEAT; + case Wrapping::Clamp: + return GL_CLAMP_TO_EDGE; + case Wrapping::Mirror: + return GL_MIRRORED_REPEAT; + default: + return 0; + } + 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; + } + LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line; + } + return errorCode; +} + +#ifndef NDEBUG +#define glCheckError() glCheckError_(__FILE__, __LINE__) +#else +#define glCheckError() +#endif // !NDEBUG + + +void GLAPIENTRY glDebugOutput(GLenum source, + GLenum type, + unsigned int id, + GLenum severity, + GLsizei length, + const char* message, + const void* userParam) +{ + // ignore non-significant error/warning codes + if (id == 131169 || id == 131185 || id == 131218 || id == 131204) return; + + el::Level level = el::Level::Error; + std::string sourceText; + std::string typeText; + std::string severityText; + + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH: + severityText = "HIGH"; + break; + case GL_DEBUG_SEVERITY_MEDIUM: + severityText = "MEDIUM"; + break; + case GL_DEBUG_SEVERITY_LOW: + severityText = "LOW"; + level = el::Level::Warning; + break; + case GL_DEBUG_SEVERITY_NOTIFICATION: + severityText = "NOTIFY"; + level = el::Level::Info; + break; + } + + switch (source) + { + case GL_DEBUG_SOURCE_API: + sourceText = "API"; + break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: + sourceText = "Window System"; + break; + case GL_DEBUG_SOURCE_SHADER_COMPILER: + sourceText = "Shader Compiler"; + break; + case GL_DEBUG_SOURCE_THIRD_PARTY: + sourceText = "Third Party"; + break; + case GL_DEBUG_SOURCE_APPLICATION: + sourceText = "Application"; + break; + case GL_DEBUG_SOURCE_OTHER: + sourceText = "Other"; + break; + default: + sourceText = std::to_string(source); + break; + } + + switch (type) + { + case GL_DEBUG_TYPE_ERROR: + typeText = "Error"; + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + typeText = "Deprecated Behaviour"; + break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + typeText = "Undefined Behaviour"; + break; + case GL_DEBUG_TYPE_PORTABILITY: + typeText = "Portability"; + break; + case GL_DEBUG_TYPE_PERFORMANCE: + typeText = "Performance"; + break; + case GL_DEBUG_TYPE_MARKER: + typeText = "Marker"; + break; + case GL_DEBUG_TYPE_PUSH_GROUP: + typeText = "Push Group"; + break; + case GL_DEBUG_TYPE_POP_GROUP: + typeText = "Pop Group"; + break; + case GL_DEBUG_TYPE_OTHER: + typeText = "Other"; + break; + default: + typeText = std::to_string(type); + break; + } + + std::string log = "OpenGL debug (" + std::to_string(id) + ") [" + severityText + "][" + sourceText + "][" + typeText + "]: \n" + message; + + switch (level) { + case el::Level::Error: + LOG(ERROR) << log; + break; + case el::Level::Warning: + LOG(WARNING) << log; + break; + case el::Level::Info: + LOG(INFO) << log; + break; + default: + LOG(ERROR) << log; + break; + } +} + + +struct ShaderOgl : public Shader { + + bool isVertex = true; + std::string code; + +}; + +struct BufferBindingOgl : public BufferBinding { + + BufferBindingOgl(size_t id) : bufferId(id) {} + + const size_t bufferId; + + static constexpr size_t indexValue = (std::numeric_limits<size_t>::max)(); //parenthess for windows' max macro + +}; + +struct BufferOgl : public Buffer { + + GlResource vbo; + + virtual void SetData(std::vector<std::byte>&& data) override { + oglState.BindVbo(vbo); + glBufferData(GL_ARRAY_BUFFER, data.size(), data.data(), GL_STATIC_DRAW); + oglState.BindVbo(0); + glCheckError(); + } + +}; + +struct TextureConfigOgl : public TextureConfig { + + 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; + + virtual void SetMinFilter(Filtering filter) override { + min = filter; + } + + virtual void SetMaxFilter(Filtering filter) override { + max = filter; + } + + virtual void SetWrapping(Wrapping wrapping) override { + wrap = wrapping; + } + +}; + +struct TextureOgl : public Texture { + + GLenum type; + GlResource texture; + Format format; + size_t width, height, depth; + + virtual void SetData(std::vector<std::byte>&& data, size_t mipLevel = 0) override { + size_t expectedSize = width * height * depth * GalFormatGetSize(format); + if (data.size() != expectedSize && !data.empty()) + throw std::logic_error("Size of data is not valid for this texture"); + + oglState.BindTexture(type, texture); + + switch (type) { + case GL_TEXTURE_1D: + case GL_PROXY_TEXTURE_1D: + break; + 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: + glTexImage2D(type, mipLevel, GalFormatGetGlInternalFormat(format), width, height, 0, GalFormatGetGlFormat(format), GalFormatGetGlType(format), data.empty() ? nullptr : data.data()); + break; + case GL_TEXTURE_3D: + case GL_PROXY_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + case GL_PROXY_TEXTURE_2D_ARRAY: + glTexImage3D(type, mipLevel, GalFormatGetGlInternalFormat(format), width, height, depth, 0, GalFormatGetGlFormat(format), GalFormatGetGlType(format), data.empty() ? nullptr : data.data()); + break; + default: + throw std::runtime_error("Unknown texture type"); + } + + glCheckError(); + oglState.BindTexture(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"); + + oglState.BindTexture(type, texture); + + switch (type) { + case GL_TEXTURE_1D: + case GL_PROXY_TEXTURE_1D: + break; + 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(); + oglState.BindTexture(type, 0); + } + +}; + +struct FramebufferOgl : public Framebuffer { + + size_t vpX = 0, vpY = 0, vpW = 1, vpH = 1; + std::shared_ptr<TextureOgl> depthStencil; + std::vector<std::shared_ptr<TextureOgl>> colors; + + GlResource fbo; + + virtual void Clear() override { + oglState.BindFbo(fbo ? fbo : 0); + GLbitfield clearBits = 0; + clearBits |= GL_COLOR_BUFFER_BIT; + clearBits |= GL_DEPTH_BUFFER_BIT; + if (depthStencil) + clearBits |= GL_STENCIL_BUFFER_BIT; + glClear(clearBits); + glCheckError(); + } + + virtual void SetViewport(size_t x, size_t y, size_t w, size_t h) override { + vpX = x; + vpY = y; + vpW = w; + vpH = h; + } + +}; + +struct FramebufferConfigOgl : public FramebufferConfig { + + std::shared_ptr<TextureOgl> depthStencil; + std::map<size_t, std::shared_ptr<TextureOgl>> colors; + + virtual void SetDepthStencil(std::shared_ptr<Texture> texture) override { + auto tex = std::static_pointer_cast<TextureOgl, Texture>(texture); + depthStencil = tex; + } + + virtual void SetTexture(size_t location, std::shared_ptr<Texture> texture) override { + auto tex = std::static_pointer_cast<TextureOgl, Texture>(texture); + colors.emplace(location, tex); + } +}; + +struct PipelineConfigOgl : public PipelineConfig { + + std::shared_ptr<ShaderOgl> vertexShader, pixelShader; + std::map<std::string, std::shared_ptr<TextureOgl>> textures; + std::map<std::string, Type> shaderParameters; + std::shared_ptr<FramebufferOgl> targetFb; + std::vector<std::vector<VertexAttribute>> vertexBuffers; + Primitive vertexPrimitive = Primitive::Triangle; + + virtual void SetVertexShader(std::shared_ptr<Shader> shader) override { + vertexShader = std::static_pointer_cast<ShaderOgl,Shader>(shader); + } + + virtual void SetPixelShader(std::shared_ptr<Shader> shader) override { + pixelShader = std::static_pointer_cast<ShaderOgl, Shader>(shader); + } + + virtual void AddShaderParameter(std::string_view name, Type type) override { + 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 { + auto fb = std::static_pointer_cast<FramebufferOgl, Framebuffer>(target); + targetFb = fb; + } + + virtual void SetPrimitive(Primitive primitive) override { + vertexPrimitive = primitive; + } + + virtual std::shared_ptr<BufferBinding> BindVertexBuffer(std::vector<VertexAttribute> &&bufferLayout) override { + auto binding = std::make_shared<BufferBindingOgl>(vertexBuffers.size()); + vertexBuffers.push_back(bufferLayout); + return std::static_pointer_cast<BufferBinding, BufferBindingOgl>(binding); + } + + virtual std::shared_ptr<BufferBinding> BindIndexBuffer() override { + auto binding = std::make_shared<BufferBindingOgl>(BufferBindingOgl::indexValue); + return std::static_pointer_cast<BufferBinding, BufferBindingOgl>(binding); + } + +}; + +struct PipelineInstanceOgl : public PipelineInstance { + + GlResource vao; + bool useIndex = false; + Primitive primitive; + size_t instances = 0; + + virtual void Activate() override { + oglState.BindVao(vao); + } + + virtual void Render(size_t offset = 0, size_t count = -1) override { + GLenum vertexMode; + switch (primitive) { + case Primitive::Line: + vertexMode = GL_LINES; + break; + case Primitive::Triangle: + vertexMode = GL_TRIANGLES; + break; + case Primitive::TriangleFan: + vertexMode = GL_TRIANGLE_FAN; + break; + case Primitive::TriangleStrip: + vertexMode = GL_TRIANGLE_STRIP; + break; + default: + vertexMode = GL_TRIANGLES; + } + + if (useIndex) { + if (instances) { + glDrawElementsInstanced(vertexMode, instances, GL_UNSIGNED_INT, nullptr, instances); + } + else { + glDrawElements(vertexMode, count, GL_UNSIGNED_INT, nullptr); + } + } + else { + if (instances) { + glDrawArraysInstanced(vertexMode, offset, instances, count); + } + else { + glDrawArrays(vertexMode, offset, count); + } + } + } + + virtual void SetInstancesCount(size_t count) override { + instances = count; + } + +}; + +struct PipelineOgl : public Pipeline { + + std::map<std::string, size_t> shaderParameters; + std::vector<std::shared_ptr<TextureOgl>> staticTextures; + GlResource program; + struct VertexBindingCommand { + size_t bufferId; + size_t location; + GLenum type; + size_t count; + size_t stride; + size_t offset; + size_t instances; + }; + std::vector<VertexBindingCommand> vertexBindCmds; + Primitive primitive; + std::shared_ptr<FramebufferOgl> target; + + virtual void Activate() override { + oglState.UseProgram(program); + oglState.BindFbo(target->fbo); + oglState.SetViewport(target->vpX, target->vpY, target->vpW, target->vpH); + + for (size_t i = 0; i < staticTextures.size(); i++) { + oglState.BindTexture(staticTextures[i]->type, staticTextures[i]->texture, i); + } + } + + virtual void SetDynamicTexture(std::string_view name, std::shared_ptr<Texture> texture) override { + Activate(); + auto tex = std::static_pointer_cast<TextureOgl>(texture); + oglState.BindTexture(tex->type, tex->texture, staticTextures.size()); + SetShaderParameter(name, static_cast<int>(staticTextures.size())); + glCheckError(); + } + + virtual std::shared_ptr<PipelineInstance> CreateInstance(std::vector<std::pair<std::shared_ptr<BufferBinding>, std::shared_ptr<Buffer>>>&& buffers) override { + auto instance = std::make_shared<PipelineInstanceOgl>(); + + instance->primitive = primitive; + + size_t indexBuffer = BufferBindingOgl::indexValue; + std::map<size_t, size_t> bufferBindingId; + + for (auto&& [binding, buffer] : buffers) { + auto bind = std::static_pointer_cast<BufferBindingOgl, BufferBinding>(binding); + auto buff = std::static_pointer_cast<BufferOgl, Buffer>(buffer); + + if (bind->bufferId == BufferBindingOgl::indexValue) + indexBuffer = buff->vbo; + else + bufferBindingId.insert({ bind->bufferId,buff->vbo }); + } + + GLuint newVao; + glGenVertexArrays(1, &newVao); + instance->vao = GlResource(newVao, GlResourceType::Vao); + oglState.BindVao(instance->vao); + + for (const auto& cmd : vertexBindCmds) { + oglState.BindVbo(bufferBindingId.find(cmd.bufferId)->second); + switch (cmd.type) { + case GL_FLOAT: + case GL_DOUBLE: + glVertexAttribPointer(cmd.location, cmd.count, cmd.type, GL_FALSE, cmd.offset, reinterpret_cast<void*>(cmd.stride)); + break; + case GL_UNSIGNED_BYTE: + case GL_BYTE: + case GL_UNSIGNED_SHORT: + case GL_SHORT: + case GL_UNSIGNED_INT: + case GL_INT: + glVertexAttribIPointer(cmd.location, cmd.count, cmd.type, cmd.offset, reinterpret_cast<void*>(cmd.stride)); + break; + } + + glEnableVertexAttribArray(cmd.location); + if (cmd.instances) { + glVertexAttribDivisor(cmd.location, cmd.instances); + } + } + + if (indexBuffer != BufferBindingOgl::indexValue) { + oglState.BindEbo(indexBuffer); + instance->useIndex = true; + } + + glCheckError(); + + oglState.BindVao(0); + oglState.BindVbo(0); + oglState.BindEbo(0); + + return instance; + } + + virtual void SetShaderParameter(std::string_view name, float value) override { + Activate(); + glUniform1f(shaderParameters.at(std::string(name)), value); + } + + virtual void SetShaderParameter(std::string_view name, double value) override { + Activate(); + glUniform1d(shaderParameters.at(std::string(name)), value); + } + + virtual void SetShaderParameter(std::string_view name, int8_t value) override { + Activate(); + glUniform1i(shaderParameters.at(std::string(name)), value); + } + + virtual void SetShaderParameter(std::string_view name, int16_t value) override { + Activate(); + glUniform1i(shaderParameters.at(std::string(name)), value); + } + + virtual void SetShaderParameter(std::string_view name, int32_t value) override { + Activate(); + glUniform1i(shaderParameters.at(std::string(name)), value); + } + + virtual void SetShaderParameter(std::string_view name, uint8_t value) override { + Activate(); + glUniform1ui(shaderParameters.at(std::string(name)), value); + } + + virtual void SetShaderParameter(std::string_view name, uint16_t value) override { + Activate(); + glUniform1ui(shaderParameters.at(std::string(name)), value); + } + + virtual void SetShaderParameter(std::string_view name, uint32_t value) override { + Activate(); + glUniform1ui(shaderParameters.at(std::string(name)), value); + } + + virtual void SetShaderParameter(std::string_view name, glm::vec2 value) override { + Activate(); + glUniform2f(shaderParameters.at(std::string(name)), value.x, value.y); + } + + virtual void SetShaderParameter(std::string_view name, glm::uvec2 value) override { + Activate(); + glUniform2ui(shaderParameters.at(std::string(name)), value.x, value.y); + } + + virtual void SetShaderParameter(std::string_view name, glm::vec3 value) override { + Activate(); + glUniform3f(shaderParameters.at(std::string(name)), value.x, value.y, value.z); + } + + virtual void SetShaderParameter(std::string_view name, glm::vec4 value) override { + Activate(); + glUniform4f(shaderParameters.at(std::string(name)), value.x, value.y, value.z, value.w); + } + + virtual void SetShaderParameter(std::string_view name, glm::mat4 value) override { + Activate(); + glUniformMatrix4fv(shaderParameters.at(std::string(name)), 1, GL_FALSE, glm::value_ptr(value)); + } + +}; + +struct ImplOgl : public Impl { + + virtual void Init() override { + LOG(INFO) << "Initalizing Gal:OpenGL..."; + LOG(INFO) << "Initializing GLEW"; + glewExperimental = GL_TRUE; + GLenum glewStatus = glewInit(); + if (glewStatus != GLEW_OK) { + LOG(FATAL) << "Failed to initialize GLEW: " << glewGetErrorString(glewStatus); + } + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glCheckError(); + if (glActiveTexture == nullptr) { + throw std::runtime_error("GLEW initialization failed with unknown reason"); + } + + GLint flags; + glGetIntegerv(GL_CONTEXT_FLAGS, &flags); + if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) + { + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glDebugMessageCallback(glDebugOutput, nullptr); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); + } + glCheckError(); + } + + virtual void DeInit() override { + LOG(INFO) << "Destroying Gal:OpenGL..."; + glCheckError(); + } + + virtual void Cleanup() override { + + } + + virtual void SetScissor(size_t x = 0, size_t y = 0, size_t width = 0, size_t height = 0) override { + glEnable(GL_SCISSOR_TEST); + glScissor(x, y, width, height); + glCheckError(); + } + + virtual void SetScissor(bool enabled) override { + if (enabled) + glEnable(GL_SCISSOR_TEST); + else + glDisable(GL_SCISSOR_TEST); + glCheckError(); + } + + + virtual std::shared_ptr<Buffer> CreateBuffer() override { + auto buff = std::make_shared<BufferOgl>(); + GLuint newVbo; + glGenBuffers(1, &newVbo); + buff->vbo = GlResource(newVbo, GlResourceType::Vbo); + buff->SetData({}); + glCheckError(); + return std::static_pointer_cast<Buffer, BufferOgl>(buff); + } + + + 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; + config->format = format; + + return std::static_pointer_cast<TextureConfig, TextureConfigOgl>(config); + } + + 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; + config->interpolateLayers = interpolateLayers; + config->format = format; + + return std::static_pointer_cast<TextureConfig, TextureConfigOgl>(config); + } + + virtual std::shared_ptr<Texture> BuildTexture(std::shared_ptr<TextureConfig> config) override { + auto texConfig = std::static_pointer_cast<TextureConfigOgl, TextureConfig>(config); + auto texture = std::make_shared<TextureOgl>(); + + texture->type = texConfig->type; + texture->format = texConfig->format; + texture->width = texConfig->width; + texture->height = texConfig->height; + texture->depth = texConfig->depth; + + GLuint newTex; + glGenTextures(1, &newTex); + texture->texture = GlResource(newTex, GlResourceType::Texture); + + oglState.BindTexture(texture->type, texture->texture); + + glTexParameteri(texture->type, GL_TEXTURE_MIN_FILTER, GalFilteringGetGlType(texConfig->min)); + glTexParameteri(texture->type, GL_TEXTURE_MAG_FILTER, GalFilteringGetGlType(texConfig->max)); + glTexParameteri(texture->type, GL_TEXTURE_WRAP_S, GalWrappingGetGlType(texConfig->wrap)); + glTexParameteri(texture->type, GL_TEXTURE_WRAP_T, GalWrappingGetGlType(texConfig->wrap)); + + oglState.BindTexture(texture->type, 0); + texture->SetData(std::vector<std::byte>(texture->width * texture->height * texture->depth * GalFormatGetSize(texture->format))); + glCheckError(); + + return std::static_pointer_cast<Texture, TextureOgl>(texture); + } + + + virtual std::shared_ptr<PipelineConfig> CreatePipelineConfig() override { + auto pipelineConfig = std::make_shared<PipelineConfigOgl>(); + return std::static_pointer_cast<PipelineConfig, PipelineConfigOgl>(pipelineConfig); + } + + virtual std::shared_ptr<Pipeline> BuildPipeline(std::shared_ptr<PipelineConfig> pipelineConfig) override { + auto pipeline = std::make_shared<PipelineOgl>(); + auto config = std::static_pointer_cast<PipelineConfigOgl, PipelineConfig>(pipelineConfig); + + pipeline->primitive = config->vertexPrimitive; + + pipeline->target = config->targetFb; + if (!pipeline->target) + pipeline->target = std::static_pointer_cast<FramebufferOgl, Framebuffer>(GetDefaultFramebuffer()); + + + /* + * Shader compilation + */ + bool vertexFailed = false, pixelFailed = false, linkFailed = false; + + const GLchar* vertexSourcePtr = config->vertexShader->code.c_str(); + const GLchar* pixelSourcePtr = config->pixelShader->code.c_str(); + + GLuint vertex, pixel; + GLint success; + GLuint program; + GLchar infoLog[512]; + + vertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex, 1, &vertexSourcePtr, NULL); + glCompileShader(vertex); + + glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(vertex, 512, NULL, infoLog); + LOG(ERROR) << "Vertex shader compilation failed: " << std::endl << infoLog; + vertexFailed = true; + }; + + pixel = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(pixel, 1, &pixelSourcePtr, NULL); + glCompileShader(pixel); + + glGetShaderiv(pixel, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(pixel, 512, NULL, infoLog); + LOG(ERROR) << "Fragment shader compilation failed: " << std::endl << infoLog; + pixelFailed = true; + }; + + if (vertexFailed || pixelFailed) + throw std::runtime_error("Shaders not compiled"); + + program = glCreateProgram(); + glAttachShader(program, vertex); + glAttachShader(program, pixel); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(program, 512, NULL, infoLog); + LOG(ERROR) << "Shader program not linked: " << std::endl << infoLog; + linkFailed = true; + } + + glDeleteShader(vertex); + glDeleteShader(pixel); + + if (linkFailed) + throw std::runtime_error("Shader not linked"); + + oglState.UseProgram(program); + pipeline->program = GlResource(program, GlResourceType::Program); + glCheckError(); + + + /* + * Shader parameters + */ + for (auto&& [name, type] : config->shaderParameters) { + GLint location = glGetUniformLocation(program, name.c_str()); + if (location < 0) { + LOG(ERROR) << "Uniform name \"" << name << "\" not found in shader"; + } + 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); + } + glCheckError(); + + + /* + * Vertex attributes + */ + size_t bufferId = 0; + for (const auto& buffer : config->vertexBuffers) { + size_t vertexSize = 0; + size_t cmdOffset = pipeline->vertexBindCmds.size(); + for (const auto& [name, type, count, instances] : buffer) { + if (name.empty()) { + vertexSize += GalTypeGetSize(type) * count; + continue; + } + + GLint location = glGetAttribLocation(program, name.c_str()); + if (location < 0) { + LOG(ERROR) << "Vertex attribute name \"" << name << "\" not found in shader"; + } + + size_t attribSize = GalTypeGetSize(type); + + for (size_t i = 0; i < count; i++) { + pipeline->vertexBindCmds.push_back({ + bufferId, + static_cast<size_t>(location + i), + GalTypeGetComponentGlType(type), + GalTypeGetComponents(type), + vertexSize, + 0, + instances, + }); + + vertexSize += attribSize; + } + } + + for (size_t i = cmdOffset; i < pipeline->vertexBindCmds.size(); i++) + pipeline->vertexBindCmds[i].offset = vertexSize; + + bufferId++; + } + glCheckError(); + + + return pipeline; + } + + virtual std::shared_ptr<FramebufferConfig> CreateFramebufferConfig() override { + auto config = std::make_shared<FramebufferConfigOgl>(); + return std::static_pointer_cast<FramebufferConfig, FramebufferConfigOgl>(config); + } + + virtual std::shared_ptr<Framebuffer> BuildFramebuffer(std::shared_ptr<FramebufferConfig> config) override { + auto conf = std::static_pointer_cast<FramebufferConfigOgl, FramebufferConfig>(config); + auto fb = std::make_shared<FramebufferOgl>(); + + GLuint newFbo; + glGenFramebuffers(1, &newFbo); + fb->fbo = GlResource(newFbo, GlResourceType::Fbo); + + oglState.BindFbo(fb->fbo); + + if (conf->depthStencil) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, conf->depthStencil->type, conf->depthStencil->texture, 0); + fb->depthStencil = std::move(conf->depthStencil); + } + + for (auto&& [location, texture] : conf->colors) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + location, texture->type, texture->texture, 0); + fb->colors.emplace_back(std::move(texture)); + } + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + LOG(ERROR) << "Framebuffer not completed: " << glCheckFramebufferStatus(GL_FRAMEBUFFER); + } + + oglState.BindFbo(0); + glCheckError(); + + return std::static_pointer_cast<Framebuffer, FramebufferOgl>(fb); + } + + virtual std::shared_ptr<Framebuffer> GetDefaultFramebuffer() override { + if (!fbDefault) + fbDefault = std::make_shared<FramebufferOgl>(); + fbDefault->fbo = GlResource(0, GlResourceType::None); + return std::static_pointer_cast<Framebuffer, FramebufferOgl>(fbDefault); + } + + + virtual std::shared_ptr<ShaderParameters> GetGlobalShaderParameters() override { + return nullptr; + } + + virtual std::shared_ptr<Shader> LoadVertexShader(std::string_view code) override { + auto shader = std::make_shared<ShaderOgl>(); + shader->code = code; + shader->isVertex = true; + return std::static_pointer_cast<Shader, ShaderOgl>(shader); + } + + virtual std::shared_ptr<Shader> LoadPixelShader(std::string_view code) override { + auto shader = std::make_shared<ShaderOgl>(); + shader->code = code; + shader->isVertex = false; + return std::static_pointer_cast<Shader, ShaderOgl>(shader); + } + +}; + +Impl* Gal::GetImplementation() +{ + if (!impl) + impl = std::make_unique<ImplOgl>(); + + return impl.get(); +} diff --git a/src/Render.cpp b/src/Render.cpp index b9b7ab0..6301ff5 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -6,7 +6,6 @@ #include <RmlUi/Lua.h> #include <RmlUi/Debugger.h> -#include "Shader.hpp" #include "AssetManager.hpp" #include "Event.hpp" #include "DebugInfo.hpp" @@ -15,9 +14,9 @@ #include "GameState.hpp" #include "RendererWorld.hpp" #include "Settings.hpp" -#include "Framebuffer.hpp" #include "Plugin.hpp" #include "Rml.hpp" +#include "Gal.hpp" const std::map<SDL_Keycode, Rml::Input::KeyIdentifier> keyMapping = { {SDLK_BACKSPACE, Rml::Input::KI_BACK}, @@ -92,11 +91,15 @@ void Render::InitSdl(unsigned int WinWidth, unsigned int WinHeight, std::string if (SDL_Init(SDL_INIT_VIDEO) < 0) throw std::runtime_error("SDL initalization failed: " + std::string(SDL_GetError())); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); +#ifndef NDEBUG + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); +#endif // !NDEBUG + window = SDL_CreateWindow( WinTitle.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, @@ -110,49 +113,90 @@ void Render::InitSdl(unsigned int WinWidth, unsigned int WinHeight, std::string throw std::runtime_error("OpenGl context creation failed: " + std::string(SDL_GetError())); SetMouseCapture(false); - renderState.WindowWidth = WinWidth; - renderState.WindowHeight = WinHeight; + + windowWidth = WinWidth; + windowHeight = WinHeight; SDL_GL_SetSwapInterval(0); } void Render::InitGlew() { - LOG(INFO) << "Initializing GLEW"; - glewExperimental = GL_TRUE; - GLenum glewStatus = glewInit(); - glCheckError(); - if (glewStatus != GLEW_OK) { - LOG(FATAL) << "Failed to initialize GLEW: " << glewGetErrorString(glewStatus); - } + auto gal = Gal::GetImplementation(); + gal->Init(); + + int width, height; + SDL_GL_GetDrawableSize(window, &width, &height); + gal->GetDefaultFramebuffer()->SetViewport(0, 0, width, height); + gal->GetDefaultFramebuffer()->Clear(); +} + +void Render::PrepareToRendering() { int width, height; SDL_GL_GetDrawableSize(window, &width, &height); - glViewport(0, 0, width, height); - glClearColor(0.0f,0.0f,0.0f, 1.0f); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - glFrontFace(GL_CCW); + float resolutionScale = Settings::ReadDouble("resolutionScale", 1.0f); + size_t scaledW = width * resolutionScale, scaledH = height * resolutionScale; - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glCheckError(); - if (glActiveTexture == nullptr) { - throw std::runtime_error("GLEW initialization failed with unknown reason"); + auto gal = Gal::GetImplementation(); + gal->GetDefaultFramebuffer()->SetViewport(0, 0, width, height); + + + auto dsTexConf = gal->CreateTexture2DConfig(scaledW, scaledH, Gal::Format::D24S8); + dsTexConf->SetMinFilter(Gal::Filtering::Nearest); + dsTexConf->SetMaxFilter(Gal::Filtering::Nearest); + fbDepthStencil = gal->BuildTexture(dsTexConf); + + auto texConf = gal->CreateTexture2DConfig(scaledW, scaledH, Gal::Format::R8G8B8A8); + texConf->SetMinFilter(Gal::Filtering::Nearest); + texConf->SetMaxFilter(Gal::Filtering::Nearest); + fbColor = gal->BuildTexture(texConf); + + auto fbConf = gal->CreateFramebufferConfig(); + fbConf->SetTexture(0, fbColor); + fbConf->SetDepthStencil(fbDepthStencil); + + framebuffer = gal->BuildFramebuffer(fbConf); + framebuffer->SetViewport(0, 0, scaledW, scaledH); + framebuffer->Clear(); + + std::string vertexSource, pixelSource; + { + auto vertAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/vert/fbo"); + vertexSource = std::string((char*)vertAsset->data.data(), (char*)vertAsset->data.data() + vertAsset->data.size()); + + auto pixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/fbo"); + pixelSource = std::string((char*)pixelAsset->data.data(), (char*)pixelAsset->data.data() + pixelAsset->data.size()); } -} -void Render::PrepareToRendering() { - //TextureAtlas texture - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D_ARRAY, AssetManager::GetTextureAtlasId()); - - int width, height; - SDL_GL_GetDrawableSize(window, &width, &height); - framebuffer = std::make_unique<Framebuffer>(width, height, true); - Framebuffer::GetDefault().Activate(); - Framebuffer::GetDefault().Resize(width, height); + constexpr float quadVertices[] = { + // positions // texCoords + -1.0f, 1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + + -1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f + }; + fbBuffer = gal->CreateBuffer(); + fbBuffer->SetData({ reinterpret_cast<const std::byte*>(quadVertices), reinterpret_cast<const std::byte*>(quadVertices) + sizeof(quadVertices) }); + auto fbPPC = gal->CreatePipelineConfig(); + fbPPC->SetTarget(gal->GetDefaultFramebuffer()); + fbPPC->SetVertexShader(gal->LoadVertexShader(vertexSource)); + fbPPC->SetPixelShader(gal->LoadPixelShader(pixelSource)); + fbPPC->AddStaticTexture("inputTexture", fbColor); + auto fbColorBB = fbPPC->BindVertexBuffer({ + {"Pos", Gal::Type::Vec2}, + {"TextureCoords", Gal::Type::Vec2} + }); + + fbPipeline = gal->BuildPipeline(fbPPC); + fbPipelineInstance = fbPipeline->CreateInstance({ + {fbColorBB, fbBuffer} + }); + + if (world) + world->PrepareRender(framebuffer); } void Render::UpdateKeyboard() { @@ -174,30 +218,30 @@ void Render::UpdateKeyboard() { } void Render::RenderFrame() { - OPTICK_EVENT(); - framebuffer->Clear(); - Framebuffer::GetDefault().Clear(); + OPTICK_EVENT(); - if (renderWorld) - framebuffer->Activate(); - if (isWireframe) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + Gal::GetImplementation()->GetDefaultFramebuffer()->Clear(); + framebuffer->Clear(); + + //if (isWireframe) + //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); if (renderWorld) - world->Render(renderState); - if (isWireframe) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - if (renderWorld) - framebuffer->RenderTo(Framebuffer::GetDefault()); + world->Render(static_cast<float>(windowWidth) / static_cast<float>(windowHeight)); + //if (isWireframe) + //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + fbPipeline->Activate(); + fbPipelineInstance->Activate(); + fbPipelineInstance->Render(0, 6); - RenderGui(); + RenderGui(); - if (world) { - world->Update(GetTime()->RemainTimeMs()); - } + if (world) { + world->Update(GetTime()->RemainTimeMs()); + } - - OPTICK_EVENT("VSYNC"); - SDL_GL_SwapWindow(window); + OPTICK_EVENT("VSYNC"); + SDL_GL_SwapWindow(window); } void Render::HandleEvents() { @@ -218,13 +262,11 @@ void Render::HandleEvents() { case SDL_WINDOWEVENT_RESIZED: { int width, height; SDL_GL_GetDrawableSize(window, &width, &height); - renderState.WindowWidth = width; - renderState.WindowHeight = height; + windowWidth = width; + windowHeight = height; rmlRender->Update(width, height); rmlContext->SetDimensions(Rml::Vector2i(width, height)); - double resolutionScale = Settings::ReadDouble("resolutionScale", 1.0f); - framebuffer->Resize(width * resolutionScale, height * resolutionScale); - Framebuffer::GetDefault().Resize(width, height); + PrepareToRendering(); break; } @@ -445,7 +487,7 @@ void Render::InitEvents() { listener.RegisterHandler("PlayerConnected", [this](const Event&) { stateString = "Loading terrain..."; - world = std::make_unique<RendererWorld>(); + world = std::make_unique<RendererWorld>(framebuffer); world->MaxRenderingDistance = Settings::ReadDouble("renderDistance", 2.0f); PUSH_EVENT("UpdateSectionsRender", 0); }); @@ -454,7 +496,6 @@ void Render::InitEvents() { stateString = "Playing"; renderWorld = true; SetState(State::Playing); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); GetGameState()->GetPlayer()->isFlying = Settings::ReadBool("flight", false); PUSH_EVENT("SetMinLightLevel", (float)Settings::ReadDouble("brightness", 0.2f)); }); @@ -464,7 +505,6 @@ void Render::InitEvents() { renderWorld = false; world.reset(); SetState(State::MainMenu); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); PluginSystem::CallOnDisconnected("Connection failed: " + eventData.get <std::string>()); }); @@ -473,7 +513,6 @@ void Render::InitEvents() { renderWorld = false; world.reset(); SetState(State::MainMenu); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); PluginSystem::CallOnDisconnected("Disconnected: " + eventData.get<std::string>()); }); @@ -555,10 +594,7 @@ void Render::InitEvents() { float brightness = Settings::ReadDouble("brightness", 0.2f); PUSH_EVENT("SetMinLightLevel", brightness); - float resolutionScale = Settings::ReadDouble("resolutionScale", 1.0f); - int width, height; - SDL_GL_GetDrawableSize(window, &width, &height); - framebuffer->Resize(width * resolutionScale, height * resolutionScale); + PrepareToRendering(); }); } @@ -568,9 +604,9 @@ void Render::InitRml() { rmlSystem = std::make_unique<RmlSystemInterface>(); Rml::SetSystemInterface(rmlSystem.get()); - rmlRender = std::make_unique<RmlRenderInterface>(renderState); + rmlRender = std::make_unique<RmlRenderInterface>(); Rml::SetRenderInterface(rmlRender.get()); - rmlRender->Update(renderState.WindowWidth, renderState.WindowHeight); + rmlRender->Update(windowWidth, windowHeight); rmlFile = std::make_unique<RmlFileInterface>(); Rml::SetFileInterface(rmlFile.get()); @@ -580,7 +616,7 @@ void Render::InitRml() { Rml::Lua::Initialise(PluginSystem::GetLuaState()); - rmlContext = Rml::CreateContext("default", Rml::Vector2i(renderState.WindowWidth, renderState.WindowHeight)); + rmlContext = Rml::CreateContext("default", Rml::Vector2i(windowWidth, windowHeight)); if (!Rml::Debugger::Initialise(rmlContext)) LOG(WARNING) << "Rml debugger not initialized"; diff --git a/src/Render.hpp b/src/Render.hpp index 9a9feee..87494fa 100644 --- a/src/Render.hpp +++ b/src/Render.hpp @@ -8,11 +8,10 @@ #include <SDL.h> #include "Utility.hpp" -#include "Renderer.hpp" #include "Event.hpp" +#include "Gal.hpp" class RendererWorld; -class Framebuffer; class RmlRenderInterface; class RmlSystemInterface; class RmlFileInterface; @@ -31,20 +30,25 @@ class Render { float mouseXDelta, mouseYDelta; std::unique_ptr<RendererWorld> world; bool renderWorld = false; - RenderState renderState; + size_t windowWidth, windowHeight; std::map<SDL_Scancode, bool> isKeyPressed; bool HasFocus=true; float sensetivity = 0.1f; - bool isWireframe = false; - std::unique_ptr<Framebuffer> framebuffer; - EventListener listener; + bool isWireframe = false; + std::shared_ptr<Gal::Framebuffer> framebuffer; + std::shared_ptr<Gal::Texture> fbDepthStencil; + std::shared_ptr<Gal::Texture> fbColor; + std::shared_ptr<Gal::Pipeline> fbPipeline; + std::shared_ptr<Gal::PipelineInstance> fbPipelineInstance; + std::shared_ptr<Gal::Buffer> fbBuffer; + EventListener listener; std::string stateString; - std::unique_ptr<RmlRenderInterface> rmlRender; - std::unique_ptr<RmlSystemInterface> rmlSystem; - std::unique_ptr<RmlFileInterface> rmlFile; - Rml::Context* rmlContext; - unsigned short sdlKeyMods = 0; - bool hideRml = false; + std::unique_ptr<RmlRenderInterface> rmlRender; + std::unique_ptr<RmlSystemInterface> rmlSystem; + std::unique_ptr<RmlFileInterface> rmlFile; + Rml::Context* rmlContext; + unsigned short sdlKeyMods = 0; + bool hideRml = false; void SetMouseCapture(bool IsCaptured); diff --git a/src/Renderer.cpp b/src/Renderer.cpp deleted file mode 100644 index 947fd6f..0000000 --- a/src/Renderer.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "Renderer.hpp" - -#include <optick.h> - -void RenderState::SetActiveVao(GLuint Vao) { - OPTICK_EVENT(); - glBindVertexArray(Vao); - ActiveVao = Vao; -} - -void RenderState::SetActiveShader(GLuint Shader) { - if (Shader != ActiveShader) { - glUseProgram(Shader); - ActiveShader = Shader; - } -}
\ No newline at end of file diff --git a/src/Renderer.hpp b/src/Renderer.hpp deleted file mode 100644 index ed3d1fa..0000000 --- a/src/Renderer.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <GL/glew.h> - -class RenderState { - GLuint ActiveVao = -1; - GLuint ActiveShader = -1; -public: - void SetActiveVao(GLuint Vao); - void SetActiveShader(GLuint Shader); - unsigned int WindowWidth, WindowHeight; - long long TimeOfDay; -};
\ No newline at end of file diff --git a/src/RendererEntity.cpp b/src/RendererEntity.cpp index fcbf79a..02a5f54 100644 --- a/src/RendererEntity.cpp +++ b/src/RendererEntity.cpp @@ -1,141 +1,22 @@ #include "RendererEntity.hpp" #include <glm/gtc/matrix_transform.hpp> -#include <glm/gtc/type_ptr.hpp> #include <optick.h> #include "Entity.hpp" -#include "GameState.hpp" -#include "Renderer.hpp" -#include "AssetManager.hpp" +#include "World.hpp" -const GLfloat vertices[] = { - -0.5f, 0.5f, 0.5f, - -0.5f, -0.5f, 0.5f, - -0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - -0.5f, 0.5f, 0.5f, - -0.5f, 0.5f, -0.5f, - -0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, 0.5f, -0.5f, - 0.5f, 0.5f, -0.5f, - -0.5f, 0.5f, -0.5f, - -0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, 0.5f, - -0.5f, 0.5f, 0.5f, - -0.5f, 0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, -0.5f -}; -const GLfloat uv_coords[] = { - //Z+ - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, +RendererEntity::RendererEntity(unsigned int id): entityId(id) {} - //Z- - 1.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 0.0f, - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - - //X+ - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - - //X- - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - - //Y+ - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - - //Y- - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, -}; - -const GLuint magic = 993214; -GLuint Vbo = magic,Vao = magic,Vbo2 = magic; - -GLuint RendererEntity::GetVao(){ - if (Vbo == magic) { - glGenBuffers(1, &Vbo); - glBindBuffer(GL_ARRAY_BUFFER, Vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glGenBuffers(1, &Vbo2); - glBindBuffer(GL_ARRAY_BUFFER, Vbo2); - glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW); - - glGenVertexArrays(1, &Vao); - glBindVertexArray(Vao); - { - glBindBuffer(GL_ARRAY_BUFFER, Vbo); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); - glEnableVertexAttribArray(0); - - glBindBuffer(GL_ARRAY_BUFFER, Vbo2); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0); - glEnableVertexAttribArray(1); - } - glBindVertexArray(0); - } - return Vao; -} - -RendererEntity::RendererEntity(unsigned int id) -{ - entityId = id; -} - -RendererEntity::~RendererEntity() { -} - -void RendererEntity::Render(RenderState& renderState, const World *world) { - OPTICK_EVENT(); +void RendererEntity::Render(std::shared_ptr<Gal::Pipeline> pipeline, const World *world) { + OPTICK_EVENT(); glm::mat4 model = glm::mat4(1.0); const Entity &entity = world->GetEntity(entityId); model = glm::translate(model, entity.pos.glm()); model = glm::translate(model, glm::vec3(0, entity.height / 2.0, 0)); model = glm::scale(model, glm::vec3(entity.width, entity.height, entity.width)); - Shader *entityShader = AssetManager::GetAsset<AssetShader>("/altcraft/shaders/entity")->shader.get(); - entityShader->SetUniform("model", model); - entityShader->SetUniform("color", entity.renderColor); - glCheckError(); - glDrawArrays(GL_LINES, 0, 24); - - glCheckError(); + pipeline->SetShaderParameter("model", model); + pipeline->SetShaderParameter("color", entity.renderColor); } diff --git a/src/RendererEntity.hpp b/src/RendererEntity.hpp index 346f9fb..b9097bd 100644 --- a/src/RendererEntity.hpp +++ b/src/RendererEntity.hpp @@ -1,17 +1,14 @@ #pragma once -#include <GL/glew.h> +#include "Gal.hpp" -class RenderState; class World; class RendererEntity { unsigned int entityId; + std::shared_ptr<Gal::Pipeline> pipeline; public: RendererEntity(unsigned int id); - ~RendererEntity(); - void Render(RenderState& renderState, const World *world); - - static GLuint GetVao(); + void Render(std::shared_ptr<Gal::Pipeline> pipeline, const World *world); }; diff --git a/src/RendererSection.cpp b/src/RendererSection.cpp index cc58676..429a8bd 100644 --- a/src/RendererSection.cpp +++ b/src/RendererSection.cpp @@ -6,84 +6,19 @@ #include <optick.h> #include "Utility.hpp" -#include "Renderer.hpp" #include "RendererSectionData.hpp" -RendererSection::RendererSection(const RendererSectionData &data) { + +RendererSection::RendererSection(const RendererSectionData& data, std::shared_ptr<Gal::Pipeline> pipeline, std::shared_ptr<Gal::BufferBinding> bufferBinding) { OPTICK_EVENT(); - glGenVertexArrays(1, &Vao); - - glGenBuffers(1, &Vbo); - glBindBuffer(GL_ARRAY_BUFFER, Vbo); - - glBindVertexArray(Vao); - { - //Cube vertices - GLuint VertAttribPos = 0; - glVertexAttribPointer(VertAttribPos, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, positions[0])); - glEnableVertexAttribArray(VertAttribPos); - glVertexAttribDivisor(VertAttribPos, 1); - - glVertexAttribPointer(VertAttribPos + 1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, positions[1])); - glEnableVertexAttribArray(VertAttribPos + 1); - glVertexAttribDivisor(VertAttribPos + 1, 1); - - glVertexAttribPointer(VertAttribPos + 2, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, positions[2])); - glEnableVertexAttribArray(VertAttribPos + 2); - glVertexAttribDivisor(VertAttribPos + 2, 1); - - glVertexAttribPointer(VertAttribPos + 3, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, positions[3])); - glEnableVertexAttribArray(VertAttribPos + 3); - glVertexAttribDivisor(VertAttribPos + 3, 1); - glCheckError(); - - //Cube uvs - GLuint UvAttribPos = 4; - glVertexAttribPointer(UvAttribPos, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uvs[0])); - glEnableVertexAttribArray(UvAttribPos); - glVertexAttribDivisor(UvAttribPos, 1); - - glVertexAttribPointer(UvAttribPos + 1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uvs[1])); - glEnableVertexAttribArray(UvAttribPos + 1); - glVertexAttribDivisor(UvAttribPos + 1, 1); - - glVertexAttribPointer(UvAttribPos + 2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uvs[2])); - glEnableVertexAttribArray(UvAttribPos + 2); - glVertexAttribDivisor(UvAttribPos + 2, 1); - - glVertexAttribPointer(UvAttribPos + 3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uvs[3])); - glEnableVertexAttribArray(UvAttribPos + 3); - glVertexAttribDivisor(UvAttribPos + 3, 1); - - //Uv Layer - GLuint uvLayerAttribPos = 8; - glVertexAttribPointer(uvLayerAttribPos, 1, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uvLayers)); - glEnableVertexAttribArray(uvLayerAttribPos); - glVertexAttribDivisor(uvLayerAttribPos, 1); - - //Animation - GLuint animationAttribPos = 9; - glVertexAttribPointer(animationAttribPos, 1, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, animations)); - glEnableVertexAttribArray(animationAttribPos); - glVertexAttribDivisor(animationAttribPos, 1); - - //Color - GLuint colorAttribPos = 10; - glVertexAttribPointer(colorAttribPos, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, colors)); - glEnableVertexAttribArray(colorAttribPos); - glVertexAttribDivisor(colorAttribPos, 1); - - //Light - GLuint lightAttribPos = 11; - glVertexAttribPointer(lightAttribPos, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, lights)); - glEnableVertexAttribArray(lightAttribPos); - glVertexAttribDivisor(lightAttribPos, 1); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - glBindVertexArray(0); - glCheckError(); + auto gal = Gal::GetImplementation(); + buffer = gal->CreateBuffer(); + + pipelineInstance = pipeline->CreateInstance({ + {bufferBinding, buffer} + }); + pipelineInstance->SetInstancesCount(4); UpdateData(data); } @@ -94,25 +29,21 @@ RendererSection::RendererSection(RendererSection && other) { } RendererSection::~RendererSection() { - if (Vao != 0) - glDeleteVertexArrays(1, &Vao); - glDeleteBuffers(1, &Vbo); } void swap(RendererSection & lhs, RendererSection & rhs) { - std::swap(lhs.Vbo, rhs.Vbo); - std::swap(lhs.Vao, rhs.Vao); + std::swap(lhs.pipelineInstance, rhs.pipelineInstance); + std::swap(lhs.buffer, rhs.buffer); std::swap(lhs.hash, rhs.hash); std::swap(lhs.numOfFaces, rhs.numOfFaces); std::swap(lhs.sectionPos, rhs.sectionPos); } -void RendererSection::Render(RenderState &renderState) { +void RendererSection::Render() { OPTICK_EVENT(); - renderState.SetActiveVao(Vao); - glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, numOfFaces); - glCheckError(); + pipelineInstance->Activate(); + pipelineInstance->Render(0, numOfFaces); } Vector RendererSection::GetPosition() { @@ -126,11 +57,7 @@ size_t RendererSection::GetHash() { void RendererSection::UpdateData(const RendererSectionData & data) { OPTICK_EVENT(); - glBindBuffer(GL_ARRAY_BUFFER, Vbo); - glBufferData(GL_ARRAY_BUFFER, data.vertices.size() * sizeof(VertexData), data.vertices.data(), GL_STATIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glCheckError(); + buffer->SetData({ reinterpret_cast<const std::byte*>(data.vertices.data()), reinterpret_cast<const std::byte*>(data.vertices.data() + data.vertices.size())}); numOfFaces = data.vertices.size(); sectionPos = data.sectionPos; diff --git a/src/RendererSection.hpp b/src/RendererSection.hpp index 3ea1fec..0a03f44 100644 --- a/src/RendererSection.hpp +++ b/src/RendererSection.hpp @@ -1,29 +1,26 @@ #pragma once -#include <glm/mat4x4.hpp> -#include <GL/glew.h> - #include "Vector.hpp" +#include "Gal.hpp" class RenderState; class RendererSectionData; class RendererSection { - GLuint Vao = { 0 }; - GLuint Vbo = { 0 }; - + std::shared_ptr<Gal::PipelineInstance> pipelineInstance; + std::shared_ptr<Gal::Buffer> buffer; size_t hash; Vector sectionPos; RendererSection(const RendererSection &other) = delete; public: - RendererSection(const RendererSectionData &data); + RendererSection(const RendererSectionData& data, std::shared_ptr<Gal::Pipeline> pipeline, std::shared_ptr<Gal::BufferBinding> bufferBinding); RendererSection(RendererSection &&other); ~RendererSection(); - void Render(RenderState &renderState); + void Render(); Vector GetPosition(); diff --git a/src/RendererSky.cpp b/src/RendererSky.cpp deleted file mode 100644 index 1eab369..0000000 --- a/src/RendererSky.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include "RendererSky.hpp" - -#include <optick.h> - -#include "Renderer.hpp" -#include "Utility.hpp" - -const GLfloat vertices[] = { - //Z+ edge - -0.5f, -0.5f, 0.5f, - -0.5f, 0.5f, 0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, 0.5f, - -0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - - //Z- edge - -0.5f, 0.5f, -0.5f, - -0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - -0.5f, 0.5f, -0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, 0.5f, -0.5f, - - //X+ edge - -0.5f, -0.5f, 0.5f, - -0.5f, -0.5f, -0.5f, - -0.5f, 0.5f, -0.5f, - -0.5f, -0.5f, 0.5f, - -0.5f, 0.5f, -0.5f, - -0.5f, 0.5f, 0.5f, - - //X- edge - 0.5f, 0.5f, -0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, 0.5f, 0.5f, - 0.5f, -0.5f, -0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, 0.5f, -0.5f, - - //Y+ edge - -0.5f, 0.5f, 0.5f, - 0.5f, 0.5f, -0.5f, - 0.5f, 0.5f, 0.5f, - -0.5f, 0.5f, -0.5f, - 0.5f, 0.5f, -0.5f, - -0.5f, 0.5f, 0.5f, - - //Y- edge - 0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, 0.5f, - 0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, 0.5f, -}; - -const GLfloat uv_coords[] = { - //Z+ - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - - //Z- - 1.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 0.0f, - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - - //X+ - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - - //X- - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - - //Y+ - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f, - 1.0f, 1.0f, - - //Y- - 1.0f, 0.0f, - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 1.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, -}; - -RendererSky::RendererSky() { - glGenBuffers(1, &VboVert); - glBindBuffer(GL_ARRAY_BUFFER, VboVert); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glGenBuffers(1, &VboUv); - glBindBuffer(GL_ARRAY_BUFFER, VboUv); - glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW); - glGenVertexArrays(1, &Vao); - - glBindVertexArray(Vao); - { - glBindBuffer(GL_ARRAY_BUFFER, VboVert); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); - glEnableVertexAttribArray(0); - - glBindBuffer(GL_ARRAY_BUFFER, VboUv); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0); - glEnableVertexAttribArray(1); - } - glBindVertexArray(0); - glCheckError(); -} - -RendererSky::~RendererSky() { - glDeleteBuffers(1, &VboVert); - glDeleteBuffers(1, &VboUv); - glDeleteVertexArrays(1, &Vao); - //glCheckError(); -} - -void RendererSky::Render(RenderState &renderState) { - OPTICK_EVENT(); - renderState.SetActiveVao(Vao); - glDrawArrays(GL_TRIANGLES, 0, 36); - glCheckError(); -} diff --git a/src/RendererSky.hpp b/src/RendererSky.hpp deleted file mode 100644 index 8c6a409..0000000 --- a/src/RendererSky.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <GL/glew.h> - -class RenderState; - -class RendererSky { - GLuint VboVert, VboUv, Vao; -public: - RendererSky(); - ~RendererSky(); - void Render(RenderState &renderState); -};
\ No newline at end of file diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index 6996762..cb4551f 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -8,8 +8,6 @@ #include "Frustum.hpp" #include "Event.hpp" #include "AssetManager.hpp" -#include "Renderer.hpp" -#include "Shader.hpp" #include "GameState.hpp" #include "Section.hpp" #include "RendererSectionData.hpp" @@ -153,7 +151,7 @@ void RendererWorld::UpdateAllSections(VectorF playerPos) { } } -RendererWorld::RendererWorld() { +RendererWorld::RendererWorld(std::shared_ptr<Gal::Framebuffer> target) { OPTICK_EVENT(); MaxRenderingDistance = 2; numOfWorkers = _max(1, (signed int) std::thread::hardware_concurrency() - 2); @@ -162,7 +160,7 @@ RendererWorld::RendererWorld() { globalTimeStart = std::chrono::high_resolution_clock::now(); - PrepareRender(); + PrepareRender(target); listener->RegisterHandler("DeleteSectionRender", [this](const Event& eventData) { OPTICK_EVENT("EV_DeleteSectionRender"); @@ -188,7 +186,7 @@ RendererWorld::RendererWorld() { } it->second.UpdateData(parsing[id].renderer); } else - sections.emplace(std::make_pair(parsing[id].renderer.sectionPos, RendererSection(parsing[id].renderer))); + sections.emplace(std::make_pair(parsing[id].renderer.sectionPos, RendererSection(parsing[id].renderer, sectionsPipeline, sectionsBufferBinding))); parsing[id] = RendererWorld::SectionParsing(); }); @@ -259,8 +257,7 @@ RendererWorld::RendererWorld() { listener->RegisterHandler("SetMinLightLevel", [this](const Event& eventData) { auto value = eventData.get<float>(); - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/face")->shader->Activate(); - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/face")->shader->SetUniform("MinLightLevel", value); + sectionsPipeline->SetShaderParameter("MinLightLevel", value); }); for (int i = 0; i < numOfWorkers; i++) @@ -282,175 +279,437 @@ RendererWorld::~RendererWorld() { DebugInfo::readyRenderer = 0; } -void RendererWorld::Render(RenderState & renderState) { +void RendererWorld::Render(float screenRatio) { OPTICK_EVENT(); //Common glm::mat4 projection = glm::perspective( - glm::radians(70.0f), (float) renderState.WindowWidth / (float) renderState.WindowHeight, + glm::radians(70.0f), screenRatio, 0.1f, 10000000.0f ); glm::mat4 view = GetGameState()->GetViewMatrix(); glm::mat4 projView = projection * view; //Render Entities -#ifndef __APPLE__ - glLineWidth(3.0); -#endif - Shader *entityShader = AssetManager::GetAsset<AssetShader>("/altcraft/shaders/entity")->shader.get(); - entityShader->Activate(); - entityShader->SetUniform("projection", projection); - entityShader->SetUniform("view", view); - glCheckError(); - - renderState.SetActiveVao(RendererEntity::GetVao()); + constexpr size_t entitiesVerticesCount = 240; + entitiesPipeline->Activate(); + entitiesPipeline->SetShaderParameter("projView", projView); + + entitiesPipelineInstance->Activate(); for (auto& it : entities) { - it.Render(renderState, &GetGameState()->GetWorld()); + it.Render(entitiesPipeline, &GetGameState()->GetWorld()); + entitiesPipelineInstance->Render(0, entitiesVerticesCount); } //Render selected block Vector selectedBlock = GetGameState()->GetSelectionStatus().selectedBlock; if (selectedBlock != Vector()) { -#ifndef __APPLE__ - glLineWidth(2.0f); -#endif { glm::mat4 model = glm::mat4(1.0); model = glm::translate(model, selectedBlock.glm()); model = glm::translate(model,glm::vec3(0.5f,0.5f,0.5f)); model = glm::scale(model,glm::vec3(1.01f,1.01f,1.01f)); - entityShader->SetUniform("model", model); - entityShader->SetUniform("color", glm::vec3(0, 0, 0)); - glCheckError(); - glDrawArrays(GL_LINES, 0, 24); + entitiesPipeline->SetShaderParameter("model", model); + entitiesPipeline->SetShaderParameter("color", glm::vec3(0, 0, 0)); + entitiesPipelineInstance->Render(0, entitiesVerticesCount); } } //Render raycast hit const bool renderHit = false; if (renderHit) { - VectorF hit = GetGameState()->GetSelectionStatus().raycastHit; -#ifndef __APPLE__ - glLineWidth(2.0f); -#endif + VectorF hit = GetGameState()->GetSelectionStatus().raycastHit; { glm::mat4 model; model = glm::translate(model, hit.glm()); - model = glm::scale(model,glm::vec3(0.3f,0.3f,0.3f)); - entityShader->SetUniform("model", model); + model = glm::scale(model, glm::vec3(0.3f, 0.3f, 0.3f)); + //entityShader->SetUniform("model", model); + entitiesPipeline->SetShaderParameter("model", model); if (selectedBlock == Vector()) - entityShader->SetUniform("color", glm::vec3(0.7f, 0, 0)); + entitiesPipeline->SetShaderParameter("color", glm::vec3(0.7f, 0.0f, 0.0f)); else - entityShader->SetUniform("color", glm::vec3(0, 0, 0.7f)); - glCheckError(); - glDrawArrays(GL_LINE_STRIP, 0, 36); + entitiesPipeline->SetShaderParameter("color", glm::vec3(0.0f, 0.0f, 0.7f)); + entitiesPipelineInstance->Render(0, entitiesVerticesCount); } } -#ifndef __APPLE__ - glLineWidth(1.0); -#endif - glCheckError(); //Render sky - renderState.TimeOfDay = GetGameState()->GetTimeStatus().timeOfDay; - Shader *skyShader = AssetManager::GetAsset<AssetShader>("/altcraft/shaders/sky")->shader.get(); - skyShader->Activate(); - skyShader->SetUniform("projection", projection); - skyShader->SetUniform("view", view); - glm::mat4 model = glm::mat4(1.0); - model = glm::translate(model, GetGameState()->GetPlayer()->pos.glm()); - const float scale = 1000000.0f; - model = glm::scale(model, glm::vec3(scale, scale, scale)); - float shift = GetGameState()->GetTimeStatus().interpolatedTimeOfDay / 24000.0f; - if (shift < 0) - shift *= -1.0f; - model = glm::rotate(model, glm::radians(90.0f), glm::vec3(0, 1.0f, 0.0f)); - model = glm::rotate(model, glm::radians(360.0f * shift), glm::vec3(-1.0f, 0.0f, 0.0f)); - skyShader->SetUniform("model", model); - - glCheckError(); - - const int sunriseMin = 22000; - const int sunriseMax = 23500; - const int moonriseMin = 12000; - const int moonriseMax = 13500; - const float sunriseLength = sunriseMax - sunriseMin; - const float moonriseLength = moonriseMax - moonriseMin; - - float mixLevel = 0; - float dayTime = GetGameState()->GetTimeStatus().interpolatedTimeOfDay; - if (dayTime < 0) - dayTime *= -1; - while (dayTime > 24000) - dayTime -= 24000; - if (dayTime > 0 && dayTime < moonriseMin || dayTime > sunriseMax) //day - mixLevel = 1.0; - if (dayTime > moonriseMax && dayTime < sunriseMin) //night - mixLevel = 0.0; - if (dayTime >= sunriseMin && dayTime <= sunriseMax) //sunrise - mixLevel = (dayTime - sunriseMin) / sunriseLength; - if (dayTime >= moonriseMin && dayTime <= moonriseMax) { //moonrise - float timePassed = (dayTime - moonriseMin); - mixLevel = 1.0 - (timePassed / moonriseLength); - } + glm::mat4 model = glm::mat4(1.0); + model = glm::translate(model, GetGameState()->GetPlayer()->pos.glm()); + const float scale = 1000000.0f; + model = glm::scale(model, glm::vec3(scale, scale, scale)); + float shift = GetGameState()->GetTimeStatus().interpolatedTimeOfDay / 24000.0f; + if (shift < 0) + shift *= -1.0f; + model = glm::rotate(model, glm::radians(90.0f), glm::vec3(0, 1.0f, 0.0f)); + model = glm::rotate(model, glm::radians(360.0f * shift), glm::vec3(-1.0f, 0.0f, 0.0f)); + + const int sunriseMin = 22000; + const int sunriseMax = 23500; + const int moonriseMin = 12000; + const int moonriseMax = 13500; + const float sunriseLength = sunriseMax - sunriseMin; + const float moonriseLength = moonriseMax - moonriseMin; + + float mixLevel = 0; + float dayTime = GetGameState()->GetTimeStatus().interpolatedTimeOfDay; + if (dayTime < 0) + dayTime *= -1; + while (dayTime > 24000) + dayTime -= 24000; + if (dayTime > 0 && dayTime < moonriseMin || dayTime > sunriseMax) //day + mixLevel = 1.0; + if (dayTime > moonriseMax && dayTime < sunriseMin) //night + mixLevel = 0.0; + if (dayTime >= sunriseMin && dayTime <= sunriseMax) //sunrise + mixLevel = (dayTime - sunriseMin) / sunriseLength; + if (dayTime >= moonriseMin && dayTime <= moonriseMax) { //moonrise + float timePassed = (dayTime - moonriseMin); + mixLevel = 1.0 - (timePassed / moonriseLength); + } - skyShader->SetUniform("DayTime", mixLevel); + skyPipeline->Activate(); + skyPipeline->SetShaderParameter("projView", projView); + skyPipeline->SetShaderParameter("model", model); + skyPipeline->SetShaderParameter("DayTime", mixLevel); + skyPipelineInstance->Activate(); + skyPipelineInstance->Render(0, 36); - rendererSky.Render(renderState); - glCheckError(); //Render sections - auto rawGlobalTime = (std::chrono::high_resolution_clock::now() - globalTimeStart); - float globalTime = rawGlobalTime.count() / 1000000000.0f; - Shader *blockShader = AssetManager::GetAsset<AssetShader>("/altcraft/shaders/face")->shader.get(); - blockShader->Activate(); - blockShader->SetUniform("DayTime", mixLevel); - blockShader->SetUniform("projView", projView); - blockShader->SetUniform("GlobalTime", globalTime); - glCheckError(); + auto rawGlobalTime = (std::chrono::high_resolution_clock::now() - globalTimeStart); + float globalTime = rawGlobalTime.count() / 1000000000.0f; + sectionsPipeline->Activate(); + sectionsPipeline->SetShaderParameter("DayTime", mixLevel); + sectionsPipeline->SetShaderParameter("projView", projView); - Frustum frustum(projView); + Frustum frustum(projView); size_t culledSections = sections.size(); - unsigned int renderedFaces = 0; + unsigned int renderedFaces = 0; for (auto& section : sections) { - glm::vec3 point{ - section.second.GetPosition().x * 16 + 8, - section.second.GetPosition().y * 16 + 8, - section.second.GetPosition().z * 16 + 8 - }; + glm::vec3 point{ + section.second.GetPosition().x * 16 + 8, + section.second.GetPosition().y * 16 + 8, + section.second.GetPosition().z * 16 + 8 + }; - bool isVisible = frustum.TestSphere(point, 16.0f); + bool isVisible = frustum.TestSphere(point, 16.0f); if (!isVisible) { culledSections--; continue; } - section.second.Render(renderState); - renderedFaces += section.second.numOfFaces; + section.second.Render(); + renderedFaces += section.second.numOfFaces; } DebugInfo::culledSections = culledSections; - DebugInfo::renderFaces = renderedFaces; - glCheckError(); + DebugInfo::renderFaces = renderedFaces; } -void RendererWorld::PrepareRender() { - Shader *blockShader = AssetManager::GetAsset<AssetShader>("/altcraft/shaders/face")->shader.get(); - blockShader->Activate(); - blockShader->SetUniform("textureAtlas", 0); - blockShader->SetUniform("MinLightLevel", 0.2f); - - TextureCoord sunTexture = AssetManager::GetTexture("/minecraft/textures/environment/sun"); - TextureCoord moonTexture = AssetManager::GetTexture("/minecraft/textures/environment/moon_phases"); - moonTexture.w /= 4.0f; //First phase will be fine for now - moonTexture.h /= 2.0f; - - Shader *sky = AssetManager::GetAsset<AssetShader>("/altcraft/shaders/sky")->shader.get(); - sky->Activate(); - sky->SetUniform("textureAtlas", 0); - sky->SetUniform("sunTexture", glm::vec4(sunTexture.x, sunTexture.y, sunTexture.w, sunTexture.h)); - sky->SetUniform("sunTextureLayer", (float)sunTexture.layer); - sky->SetUniform("moonTexture", glm::vec4(moonTexture.x, moonTexture.y, moonTexture.w, moonTexture.h)); - sky->SetUniform("moonTextureLayer", (float)moonTexture.layer); +void RendererWorld::PrepareRender(std::shared_ptr<Gal::Framebuffer> target) { + std::string sectionVertexSource, sectionPixelSource; + { + auto vertAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/vert/face"); + sectionVertexSource = std::string((char*)vertAsset->data.data(), (char*)vertAsset->data.data() + vertAsset->data.size()); + + auto pixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/face"); + sectionPixelSource = std::string((char*)pixelAsset->data.data(), (char*)pixelAsset->data.data() + pixelAsset->data.size()); + } + + std::string entitiesVertexSource, entitiesPixelSource; + { + auto vertAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/vert/entity"); + entitiesVertexSource = std::string((char*)vertAsset->data.data(), (char*)vertAsset->data.data() + vertAsset->data.size()); + + auto pixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/entity"); + entitiesPixelSource = std::string((char*)pixelAsset->data.data(), (char*)pixelAsset->data.data() + pixelAsset->data.size()); + } + + std::string skyVertexSource, skyPixelSource; + { + auto vertAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/vert/sky"); + skyVertexSource = std::string((char*)vertAsset->data.data(), (char*)vertAsset->data.data() + vertAsset->data.size()); + + auto pixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/sky"); + skyPixelSource = std::string((char*)pixelAsset->data.data(), (char*)pixelAsset->data.data() + pixelAsset->data.size()); + } + + auto gal = Gal::GetImplementation(); + { + auto sectionsPLC = gal->CreatePipelineConfig(); + sectionsPLC->SetTarget(target); + sectionsPLC->AddShaderParameter("projView", Gal::Type::Mat4); + sectionsPLC->AddShaderParameter("DayTime", Gal::Type::Float); + sectionsPLC->AddShaderParameter("GlobalTime", Gal::Type::Float); + sectionsPLC->AddShaderParameter("MinLightLevel", Gal::Type::Float); + sectionsPLC->AddStaticTexture("textureAtlas", AssetManager::GetTextureAtlas()); + sectionsPLC->SetVertexShader(gal->LoadVertexShader(sectionVertexSource)); + sectionsPLC->SetPixelShader(gal->LoadPixelShader(sectionPixelSource)); + sectionsPLC->SetPrimitive(Gal::Primitive::TriangleFan); + sectionsBufferBinding = sectionsPLC->BindVertexBuffer({ + {"position", Gal::Type::Vec3, 4, 1}, + {"uv", Gal::Type::Vec2, 4, 1}, + {"uvLayer", Gal::Type::Float, 1, 1}, + {"animation", Gal::Type::Float, 1, 1}, + {"color", Gal::Type::Vec3, 1, 1}, + {"light", Gal::Type::Vec2, 1, 1}, + {"", Gal::Type::Uint8, 20, 1} + }); + sectionsPipeline = gal->BuildPipeline(sectionsPLC); + sectionsPipeline->SetShaderParameter("MinLightLevel", 0.2f); + } + + { + auto entitiesPLC = gal->CreatePipelineConfig(); + entitiesPLC->SetTarget(target); + entitiesPLC->AddShaderParameter("projView", Gal::Type::Mat4); + entitiesPLC->AddShaderParameter("model", Gal::Type::Mat4); + entitiesPLC->AddShaderParameter("color", Gal::Type::Vec3); + entitiesPLC->SetVertexShader(gal->LoadVertexShader(entitiesVertexSource)); + entitiesPLC->SetPixelShader(gal->LoadPixelShader(entitiesPixelSource)); + entitiesPLC->SetPrimitive(Gal::Primitive::Triangle); + auto entitiesPosBB = entitiesPLC->BindVertexBuffer({ + {"position", Gal::Type::Vec3}, + }); + auto entitiesIndicesBB = entitiesPLC->BindIndexBuffer(); + + entitiesPipeline = gal->BuildPipeline(entitiesPLC); + + constexpr float lw = 0.485f; // line width + + constexpr float vertices[] = { + 0.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, + -0.5f, 0.5f, 0.5f, + -0.5f, -0.5f, 0.5f, + -0.5f, lw, 0.5f, + 0.5f, lw, -0.5f, + 0.5f, lw, 0.5f, + -0.5f, lw, -0.5f, + 0.5f, -lw, -0.5f, + 0.5f, -lw, 0.5f, + -0.5f, -lw, -0.5f, + -0.5f, -lw, 0.5f, + -0.5f, -0.5f, lw, + 0.5f, 0.5f, lw, + 0.5f, lw, lw, + 0.5f, -lw, lw, + -0.5f, 0.5f, lw, + 0.5f, -0.5f, lw, + -0.5f, lw, lw, + -0.5f, -lw, lw, + -0.5f, 0.5f, -lw, + 0.5f, -0.5f, -lw, + -0.5f, lw, -lw, + -0.5f, -lw, -lw, + -0.5f, -0.5f, -lw, + 0.5f, 0.5f, -lw, + 0.5f, lw, -lw, + 0.5f, -lw, -lw, + -lw, lw, 0.5f, + -lw, -lw, 0.5f, + -lw, lw, -0.5f, + -lw, -0.5f, lw, + -lw, -0.5f, -lw, + -lw, -lw, -0.5f, + -lw, 0.5f, lw, + -lw, 0.5f, -lw, + lw, lw, -0.5f, + lw, -lw, -0.5f, + lw, lw, 0.5f, + lw, 0.5f, lw, + lw, 0.5f, -lw, + lw, -lw, 0.5f, + lw, -0.5f, lw, + lw, -0.5f, -lw, + }; + + constexpr int indices[] = { + 47, 26, 22, + 7, 33, 43, + 18, 11, 19, + 12, 28, 27, + 31, 13, 10, + 43, 14, 11, + 25, 12, 27, + 20, 4, 22, + 1, 41, 35, + 3, 18, 44, + 9, 24, 16, + 28, 6, 29, + 45, 30, 1, + 11, 20, 19, + 35, 15, 12, + 39, 25, 21, + 2, 6, 38, + 45, 18, 30, + 37, 29, 6, + 8, 4, 46, + 10, 42, 41, + 8, 17, 36, + 9, 34, 33, + 37, 17, 29, + 47, 48, 26, + 11, 3, 43, + 3, 7, 43, + 7, 9, 33, + 1, 30, 10, + 30, 18, 31, + 10, 30, 31, + 18, 3, 11, + 19, 31, 18, + 12, 15, 28, + 31, 32, 13, + 43, 46, 14, + 7, 21, 9, + 21, 25, 23, + 9, 21, 23, + 25, 5, 12, + 27, 23, 25, + 13, 32, 2, + 32, 20, 26, + 2, 32, 26, + 20, 14, 4, + 22, 26, 20, + 12, 5, 35, + 5, 1, 35, + 1, 10, 41, + 44, 39, 3, + 39, 21, 7, + 3, 39, 7, + 9, 23, 24, + 16, 24, 8, + 24, 28, 17, + 8, 24, 17, + 28, 15, 6, + 29, 17, 28, + 1, 5, 40, + 5, 25, 40, + 40, 45, 1, + 11, 14, 20, + 35, 38, 15, + 39, 40, 25, + 15, 38, 6, + 38, 42, 2, + 42, 13, 2, + 45, 44, 18, + 6, 2, 48, + 2, 26, 48, + 48, 37, 6, + 14, 46, 4, + 46, 34, 8, + 34, 16, 8, + 10, 13, 42, + 36, 47, 8, + 47, 22, 4, + 8, 47, 4, + 9, 16, 34, + 37, 36, 17, + }; + + entitiesPosBuffer = gal->CreateBuffer(); + entitiesPosBuffer->SetData({ reinterpret_cast<const std::byte*>(vertices), reinterpret_cast<const std::byte*>(vertices) + sizeof(vertices) }); + entitiesIndexBuffer = gal->CreateBuffer(); + entitiesIndexBuffer->SetData({ reinterpret_cast<const std::byte*>(indices), reinterpret_cast<const std::byte*>(indices) + sizeof(indices) }); + + entitiesPipelineInstance = entitiesPipeline->CreateInstance({ + {entitiesPosBB, entitiesPosBuffer}, + {entitiesIndicesBB, entitiesIndexBuffer} + }); + } + + { + auto skyPPC = gal->CreatePipelineConfig(); + skyPPC->SetTarget(target); + skyPPC->AddShaderParameter("sunTexture", Gal::Type::Vec4); + skyPPC->AddShaderParameter("sunTextureLayer", Gal::Type::Float); + skyPPC->AddShaderParameter("moonTexture", Gal::Type::Vec4); + skyPPC->AddShaderParameter("moonTextureLayer", Gal::Type::Float); + 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({ + {"position", Gal::Type::Vec3}, + {"", Gal::Type::Vec2}, + }); + + constexpr float vertices[] = { + //Z+ Positions UVs + -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, + + //Z- + -0.5f, 0.5f, -0.5f, 1.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, + + //X+ + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, + -0.5f, 0.5f, -0.5f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, + + //X- + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, + + //Y+ + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, + + //Y- + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 1.0f, 0.0f, + }; + + TextureCoord sunTexture = AssetManager::GetTexture("/minecraft/textures/environment/sun"); + TextureCoord moonTexture = AssetManager::GetTexture("/minecraft/textures/environment/moon_phases"); + moonTexture.w /= 4.0f; // First phase will be fine for now + moonTexture.h /= 2.0f; + + skyPipeline = gal->BuildPipeline(skyPPC); + skyPipeline->Activate(); + 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)); + skyPipeline->SetShaderParameter("moonTextureLayer", static_cast<float>(moonTexture.layer)); + + skyBuffer = gal->CreateBuffer(); + skyBuffer->SetData({ reinterpret_cast<const std::byte*>(vertices), reinterpret_cast<const std::byte*>(vertices) + sizeof(vertices) }); + + skyPipelineInstance = skyPipeline->CreateInstance({ + {skyPosUvBB, skyBuffer} + }); + } } void RendererWorld::Update(double timeToUpdate) { diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index 85cb736..e645b30 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -9,7 +9,6 @@ #include "RendererSection.hpp" #include "RendererEntity.hpp" -#include "RendererSky.hpp" #include "RendererSectionData.hpp" class Frustum; @@ -20,11 +19,11 @@ class EventListener; class RenderState; class RendererWorld { - struct SectionParsing { - SectionsData data; - RendererSectionData renderer; - bool parsing = false; - }; + struct SectionParsing { + SectionsData data; + RendererSectionData renderer; + bool parsing = false; + }; //General std::unique_ptr<EventListener> listener; @@ -33,28 +32,34 @@ class RendererWorld { std::vector<std::thread> workers; void WorkerFunction(size_t WorkerId); bool isRunning = true; - const static size_t parsingBufferSize = 64; - SectionParsing parsing[parsingBufferSize]; - std::queue<Vector> parseQueue; - bool parseQueueNeedRemoveUnnecessary = false; - void ParseQueueUpdate(); - void ParseQeueueRemoveUnnecessary(); + const static size_t parsingBufferSize = 64; + SectionParsing parsing[parsingBufferSize]; + std::queue<Vector> parseQueue; + bool parseQueueNeedRemoveUnnecessary = false; + void ParseQueueUpdate(); + void ParseQeueueRemoveUnnecessary(); //Blocks std::vector<Vector> renderList; std::map<Vector, RendererSection> sections; void UpdateAllSections(VectorF playerPos); - std::chrono::time_point<std::chrono::high_resolution_clock> globalTimeStart; + std::chrono::time_point<std::chrono::high_resolution_clock> globalTimeStart; + std::shared_ptr<Gal::Pipeline> sectionsPipeline; + std::shared_ptr<Gal::BufferBinding> sectionsBufferBinding; //Entities std::vector<RendererEntity> entities; + std::shared_ptr<Gal::Pipeline> entitiesPipeline; + std::shared_ptr<Gal::PipelineInstance> entitiesPipelineInstance; + std::shared_ptr<Gal::Buffer> entitiesPosBuffer, entitiesIndexBuffer; //Sky - Texture *skyTexture; - RendererSky rendererSky; + std::shared_ptr<Gal::Pipeline> skyPipeline; + std::shared_ptr<Gal::PipelineInstance> skyPipelineInstance; + std::shared_ptr<Gal::Buffer> skyBuffer; public: - RendererWorld(); - ~RendererWorld(); + RendererWorld(std::shared_ptr<Gal::Framebuffer> target); + ~RendererWorld(); - void Render(RenderState& renderState); - void PrepareRender(); + void Render(float screenRatio); + void PrepareRender(std::shared_ptr<Gal::Framebuffer> target); double MaxRenderingDistance; diff --git a/src/Rml.cpp b/src/Rml.cpp index 179d4b9..fa2d4e7 100644 --- a/src/Rml.cpp +++ b/src/Rml.cpp @@ -3,7 +3,6 @@ #include <easylogging++.h> #include "AssetManager.hpp" -#include "Shader.hpp" #include "Utility.hpp" double RmlSystemInterface::GetElapsedTime() { @@ -45,87 +44,104 @@ void RmlSystemInterface::GetClipboardText(Rml::String& text) { text = clipboard; } -RmlRenderInterface::RmlRenderInterface(RenderState& renderState) : State(&renderState) { - glGenVertexArrays(1, &Vao); - glBindVertexArray(Vao); - glCheckError(); +RmlRenderInterface::RmlRenderInterface() { + std::string vertexSource, pixelSource, texPixelSource; + { + auto vertAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/vert/rml"); + vertexSource = std::string((char*)vertAsset->data.data(), (char*)vertAsset->data.data() + vertAsset->data.size()); + + auto pixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/rml"); + pixelSource = std::string((char*)pixelAsset->data.data(), (char*)pixelAsset->data.data() + pixelAsset->data.size()); + + auto texPixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/rmltex"); + texPixelSource = std::string((char*)texPixelAsset->data.data(), (char*)texPixelAsset->data.data() + texPixelAsset->data.size()); + } + + auto gal = Gal::GetImplementation(); - glGenBuffers(1, &Ebo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, nullptr, GL_STREAM_DRAW); - glCheckError(); + vertexBuffer = gal->CreateBuffer(); + indexBuffer = gal->CreateBuffer(); - glGenBuffers(1, &Vbo); - glBindBuffer(GL_ARRAY_BUFFER, Vbo); - glBufferData(GL_ARRAY_BUFFER, 0, nullptr, GL_STREAM_DRAW); - glCheckError(); + { + auto pipelineConfig = gal->CreatePipelineConfig(); + pipelineConfig->AddShaderParameter("viewportSize", Gal::Type::Vec2u32); + pipelineConfig->AddShaderParameter("translation", Gal::Type::Vec2); + pipelineConfig->SetTarget(gal->GetDefaultFramebuffer()); + pipelineConfig->SetVertexShader(gal->LoadVertexShader(vertexSource)); + pipelineConfig->SetPixelShader(gal->LoadPixelShader(pixelSource)); + + auto vertBuffBind = pipelineConfig->BindVertexBuffer({ + {"pos", Gal::Type::Vec2}, + {"color", Gal::Type::Vec4u8}, + {"", Gal::Type::Vec2}, //it's not used in shader, so driver optimizes it away + }); + + auto indexBuffBind = pipelineConfig->BindIndexBuffer(); + + pipeline = gal->BuildPipeline(pipelineConfig); + + pipelineInstance = pipeline->CreateInstance({ + {vertBuffBind, vertexBuffer}, + {indexBuffBind, indexBuffer}, + }); + } { - //Vertex position (2 float) - GLuint PosAttribPos = 0; - glVertexAttribPointer(PosAttribPos, 2, GL_FLOAT, GL_FALSE, 20, (void*)0); - glEnableVertexAttribArray(PosAttribPos); - - //Vertex colour (4 uint8 RGBA) - GLuint ColAttribPos = 1; - glVertexAttribIPointer(ColAttribPos, 4, GL_UNSIGNED_BYTE, 20, (void*)8); - glEnableVertexAttribArray(ColAttribPos); - - //Vertex tex_coord (2 float) - GLuint TexAttribPos = 2; - glVertexAttribPointer(TexAttribPos, 2, GL_FLOAT, GL_FALSE, 20, (void*)12); - glEnableVertexAttribArray(TexAttribPos); + auto texPipelineConfig = gal->CreatePipelineConfig(); + texPipelineConfig->AddShaderParameter("viewportSize", Gal::Type::Vec2u32); + texPipelineConfig->AddShaderParameter("translation", Gal::Type::Vec2); + texPipelineConfig->AddShaderParameter("fontTexture", Gal::Type::Int32); + texPipelineConfig->SetTarget(gal->GetDefaultFramebuffer()); + texPipelineConfig->SetVertexShader(gal->LoadVertexShader(vertexSource)); + texPipelineConfig->SetPixelShader(gal->LoadPixelShader(texPixelSource)); + + auto texVertBuffBind = texPipelineConfig->BindVertexBuffer({ + {"pos", Gal::Type::Vec2}, + {"color", Gal::Type::Vec4u8}, + {"tex_coord", Gal::Type::Vec2}, + }); + + auto texIndexBuffBind = texPipelineConfig->BindIndexBuffer(); + + texPipeline = gal->BuildPipeline(texPipelineConfig); + + texPipelineInstance = texPipeline->CreateInstance({ + {texVertBuffBind, vertexBuffer}, + {texIndexBuffBind, indexBuffer}, + }); } - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glCheckError(); + + } RmlRenderInterface::~RmlRenderInterface() { - glDeleteVertexArrays(1, &Vao); - glDeleteBuffers(1, &Vbo); - glDeleteBuffers(1, &Ebo); - glCheckError(); } void RmlRenderInterface::RenderGeometry(Rml::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rml::TextureHandle texture, const Rml::Vector2f& translation) { - if (texture) { - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/rmltex")->shader->Activate(); - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/rmltex")->shader->SetUniform("translation", glm::vec2(translation.x, translation.y)); - glBindTexture(GL_TEXTURE_2D, texture); + indexBuffer->SetData({ reinterpret_cast<std::byte*>(indices), reinterpret_cast<std::byte*>(indices + num_indices) }); + vertexBuffer->SetData({ reinterpret_cast<std::byte*>(vertices), reinterpret_cast<std::byte*>(vertices + num_vertices) }); + + auto tex = textures.find(texture); + if (tex != textures.end()) { + texPipeline->Activate(); + texPipeline->SetShaderParameter("translation", glm::vec2(translation.x, translation.y)); + texPipeline->SetDynamicTexture("fontTexture", tex->second); + texPipelineInstance->Activate(); + texPipelineInstance->Render(0, num_indices); } else { - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/rml")->shader->Activate(); - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/rml")->shader->SetUniform("translation", glm::vec2(translation.x, translation.y)); - } - glCheckError(); - - glBindVertexArray(Vao); - glCheckError(); - - glBindBuffer(GL_ARRAY_BUFFER, Vbo); - glBufferData(GL_ARRAY_BUFFER, num_vertices * sizeof(Rml::Vertex), vertices, GL_STREAM_DRAW); - glCheckError(); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_indices * sizeof(int), indices, GL_STREAM_DRAW); - glCheckError(); - - glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_INT, 0); - glCheckError(); - glBindVertexArray(0); + pipeline->Activate(); + pipeline->SetShaderParameter("translation", glm::vec2(translation.x, translation.y)); + pipelineInstance->Activate(); + pipelineInstance->Render(0, num_indices); + } } void RmlRenderInterface::EnableScissorRegion(bool enable) { - if (enable) - glEnable(GL_SCISSOR_TEST); - else - glDisable(GL_SCISSOR_TEST); + Gal::GetImplementation()->SetScissor(enable); } void RmlRenderInterface::SetScissorRegion(int x, int y, int width, int height) { - glScissor(x, vpHeight - (y + height), width, height); - glCheckError(); + Gal::GetImplementation()->SetScissor(x, y, width, height); } bool RmlRenderInterface::LoadTexture(Rml::TextureHandle& texture_handle, Rml::Vector2i& texture_dimensions, const Rml::String& source) { @@ -133,38 +149,25 @@ bool RmlRenderInterface::LoadTexture(Rml::TextureHandle& texture_handle, Rml::Ve } bool RmlRenderInterface::GenerateTexture(Rml::TextureHandle& texture_handle, const Rml::byte* source, const Rml::Vector2i& source_dimensions) { - int mipLevelCount = 1; - glActiveTexture(GL_TEXTURE0); - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glCheckError(); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, source_dimensions.x, source_dimensions.y, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, source); - glCheckError(); - - texture_handle = texture; + size_t textureId = textures.empty() ? 1 : textures.rbegin()->first + 1; + auto gal = Gal::GetImplementation(); + auto textureConfig = gal->CreateTexture2DConfig(source_dimensions.x, source_dimensions.y, Gal::Format::R8G8B8A8); + auto texture = gal->BuildTexture(textureConfig); + texture->SetData({ reinterpret_cast<const std::byte*>(source),reinterpret_cast<const std::byte*>(source + (source_dimensions.x * source_dimensions.y) * 4) }); + textures.insert({ textureId,texture }); + texture_handle = textureId; + return true; } void RmlRenderInterface::ReleaseTexture(Rml::TextureHandle texture) { - GLuint textures = texture; - glDeleteTextures(1, &textures); - glCheckError(); + textures.erase(textures.find(texture)); } void RmlRenderInterface::Update(unsigned int windowWidth, unsigned int windowHeight) { - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/rml")->shader->Activate(); - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/rml")->shader->SetUniform("viewportSize", windowWidth, windowHeight); - glCheckError(); - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/rmltex")->shader->Activate(); - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/rmltex")->shader->SetUniform("viewportSize", windowWidth, windowHeight); - AssetManager::GetAsset<AssetShader>("/altcraft/shaders/rmltex")->shader->SetUniform("fontTexture", 0); - glCheckError(); + pipeline->SetShaderParameter("viewportSize", glm::uvec2(windowWidth, windowHeight)); + texPipeline->SetShaderParameter("viewportSize", glm::uvec2(windowWidth, windowHeight)); + vpWidth = windowWidth; vpHeight = windowHeight; } diff --git a/src/Rml.hpp b/src/Rml.hpp index edcdc8b..2e3a672 100644 --- a/src/Rml.hpp +++ b/src/Rml.hpp @@ -6,7 +6,7 @@ #include <RmlUi/Core/RenderInterface.h> #include <RmlUi/Core/FileInterface.h> -#include "Renderer.hpp" +#include "Gal.hpp" class AssetTreeNode; @@ -30,14 +30,15 @@ public: }; class RmlRenderInterface : public Rml::RenderInterface { - RenderState* State; - - GLuint Vao, Vbo, Ebo; + std::shared_ptr<Gal::Pipeline> pipeline, texPipeline; + std::shared_ptr<Gal::PipelineInstance> pipelineInstance, texPipelineInstance; + std::shared_ptr<Gal::Buffer> vertexBuffer, indexBuffer; + std::map<size_t, std::shared_ptr<Gal::Texture>> textures; unsigned int vpWidth, vpHeight; public: - RmlRenderInterface(RenderState &renderState); + RmlRenderInterface(); RmlRenderInterface(const RmlRenderInterface&) = delete; diff --git a/src/Shader.cpp b/src/Shader.cpp deleted file mode 100644 index 08866e1..0000000 --- a/src/Shader.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "Shader.hpp" - -#include <fstream> -#include <sstream> - -#include <easylogging++.h> - - -GLuint Shader::GetUniformLocation(const std::string &name) { - auto it = uniforms.find(name); - if (it == uniforms.end()) { - LOG(ERROR) << "Accessed not existing uniform " << name; - return 0; - } - return it->second; -} - -Shader::Shader(const std::string &vertSource, const std::string &fragSource, const std::vector<std::string> &uniformsNames) -{ - bool vertFailed = false, fragFailed = false, linkFailed = false, uniformsFailed = false; - const GLchar *vertSourcePtr = vertSource.c_str(); - const GLchar *fragSourcePtr = fragSource.c_str(); - - GLuint vertex, fragment; - GLint success; - GLchar infoLog[512]; - - vertex = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertex, 1, &vertSourcePtr, NULL); - glCompileShader(vertex); - - glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(vertex, 512, NULL, infoLog); - LOG(ERROR) << "Vertex shader compilation failed: " << std::endl << infoLog; - vertFailed = true; - }; - - fragment = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment, 1, &fragSourcePtr, NULL); - glCompileShader(fragment); - - glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(fragment, 512, NULL, infoLog); - LOG(ERROR) << "Fragment shader compilation failed: " << std::endl << infoLog; - fragFailed = true; - }; - - if (vertFailed || fragFailed) - throw std::runtime_error("Shaders not compiled"); - - program = glCreateProgram(); - glAttachShader(program, vertex); - glAttachShader(program, fragment); - glLinkProgram(program); - glGetProgramiv(program, GL_LINK_STATUS, &success); - if (!success) { - glGetProgramInfoLog(program, 512, NULL, infoLog); - LOG(ERROR) << "Shader program not linked: " << std::endl << infoLog; - linkFailed = true; - } - - glDeleteShader(vertex); - glDeleteShader(fragment); - - if (linkFailed) - throw std::runtime_error("Shader not linked"); - - glUseProgram(program); - - for (auto &it : uniformsNames) { - GLuint location = glGetUniformLocation(program, it.c_str()); - if (location == -1) { - glDeleteProgram(program); - LOG(ERROR) << "Uniform name \"" << it << "\" not found in shader"; - throw std::runtime_error("Invalid uniform"); - } - - uniforms[it] = location; - } -} - -Shader::~Shader() -{ - if (program) - glDeleteProgram(program); -} - -void Shader::Activate() -{ - glUseProgram(program); -} diff --git a/src/Shader.hpp b/src/Shader.hpp deleted file mode 100644 index 6b3220d..0000000 --- a/src/Shader.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include <map> -#include <vector> -#include <string> - -#include <GL/glew.h> -#include <glm/glm.hpp> -#include <glm/gtc/type_ptr.hpp> - -class Shader { - std::map<std::string, GLuint> uniforms; - GLuint program = 0; - - GLuint GetUniformLocation(const std::string &name); - -public: - Shader(const Shader &) = delete; - Shader(Shader &&other) = delete; - Shader &operator=(const Shader &) = delete; - Shader &operator=(Shader &&other) = delete; - - Shader(const std::string &vertSource, const std::string &fragSource, const std::vector<std::string> &uniformsNames); - - ~Shader(); - - void Activate(); - - inline void SetUniform(const std::string& name, unsigned int val, unsigned int val2) { - glUniform2ui(GetUniformLocation(name), val, val2); - } - - inline void SetUniform(const std::string &name, int val) { - glUniform1i(GetUniformLocation(name), val); - } - - inline void SetUniform(const std::string& name, int val, int val2) { - glUniform2i(GetUniformLocation(name), val, val2); - } - - inline void SetUniform(const std::string &name, float val) { - glUniform1f(GetUniformLocation(name), val); - } - - inline void SetUniform(const std::string &name, glm::vec2 val) { - glUniform2f(GetUniformLocation(name), val.x, val.y); - } - - inline void SetUniform(const std::string &name, glm::vec3 val) { - glUniform3f(GetUniformLocation(name), val.x, val.y, val.z); - } - - inline void SetUniform(const std::string &name, glm::vec4 val) { - glUniform4f(GetUniformLocation(name), val.x, val.y, val.z, val.w); - } - - inline void SetUniform(const std::string &name, glm::mat4 val) { - glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, glm::value_ptr(val)); - } -};
\ No newline at end of file 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 ; |