summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaG1924 <12997935+LaG1924@users.noreply.github.com>2021-12-25 07:42:52 +0100
committerGitHub <noreply@github.com>2021-12-25 07:42:52 +0100
commit40421159568518bb7573903d14a2c69c64dead95 (patch)
tree15c830dce151bf0b427123efd214173742887e8e
parentMerge pull request #70 from LaG1924/ftr/build-3 (diff)
parentFixed missing APIENTRY linux build (diff)
downloadAltCraft-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
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--cwd/assets/altcraft/shaders/entity.json3
-rw-r--r--cwd/assets/altcraft/shaders/frag/entity.fs11
-rw-r--r--cwd/assets/altcraft/shaders/frag/sky.fs23
-rw-r--r--cwd/assets/altcraft/shaders/sky.json3
-rw-r--r--cwd/assets/altcraft/shaders/vert/entity.vs17
-rw-r--r--cwd/assets/altcraft/shaders/vert/sky.vs18
-rw-r--r--src/AssetManager.cpp31
-rw-r--r--src/AssetManager.hpp7
-rw-r--r--src/Framebuffer.cpp129
-rw-r--r--src/Framebuffer.hpp29
-rw-r--r--src/Gal.hpp284
-rw-r--r--src/GalOgl.cpp1344
-rw-r--r--src/Render.cpp176
-rw-r--r--src/Render.hpp28
-rw-r--r--src/Renderer.cpp16
-rw-r--r--src/Renderer.hpp13
-rw-r--r--src/RendererEntity.cpp131
-rw-r--r--src/RendererEntity.hpp9
-rw-r--r--src/RendererSection.cpp103
-rw-r--r--src/RendererSection.hpp13
-rw-r--r--src/RendererSky.cpp144
-rw-r--r--src/RendererSky.hpp13
-rw-r--r--src/RendererWorld.cpp505
-rw-r--r--src/RendererWorld.hpp43
-rw-r--r--src/Rml.cpp181
-rw-r--r--src/Rml.hpp11
-rw-r--r--src/Shader.cpp93
-rw-r--r--src/Shader.hpp60
-rw-r--r--src/TextureAtlas.cpp34
-rw-r--r--src/TextureAtlas.hpp10
-rw-r--r--src/Utility.cpp34
-rw-r--r--src/Utility.hpp6
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 ;