summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Gal.hpp255
-rw-r--r--src/GalOgl.cpp836
-rw-r--r--src/Render.cpp37
-rw-r--r--src/Rml.cpp143
-rw-r--r--src/Rml.hpp5
5 files changed, 1189 insertions, 87 deletions
diff --git a/src/Gal.hpp b/src/Gal.hpp
new file mode 100644
index 0000000..0f2d162
--- /dev/null
+++ b/src/Gal.hpp
@@ -0,0 +1,255 @@
+#pragma once
+
+#include <cstdint>
+#include <memory>
+#include <vector>
+#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 {
+ R8G8B8,
+ R8G8B8A8,
+ };
+
+ enum class Filtering {
+ Nearest,
+ Bilinear,
+ Trilinear,
+ Anisotropy,
+ };
+
+ enum class Wrapping {
+ Repeat,
+ Mirror,
+ Clamp,
+ };
+
+ struct VertexAttribute {
+ std::string name;
+ Type type;
+ };
+
+ Impl* GetImplementation();
+
+ struct Impl {
+
+ virtual void Init() = 0;
+
+ virtual void DeInit() = 0;
+
+ virtual void Cleanup() = 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;
+ };
+
+ 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 SetTarget(std::shared_ptr<Framebuffer> target) = 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 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;
+ };
+
+ 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;
+ };
+
+ 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..4fb2794
--- /dev/null
+++ b/src/GalOgl.cpp
@@ -0,0 +1,836 @@
+#include "Gal.hpp"
+
+#include <easylogging++.h>
+#include <GL/glew.h>
+
+#include "Utility.hpp"
+
+using namespace Gal;
+
+class ImplOgl;
+class FramebufferDefaultOgl;
+class ShaderOgl;
+
+std::unique_ptr<ImplOgl> impl;
+std::shared_ptr<FramebufferDefaultOgl> 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::R8G8B8:
+ return GL_RGB8;
+ case Format::R8G8B8A8:
+ return GL_RGBA8;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+GLenum GalFormatGetGlFormat(Format format) {
+ switch (format) {
+ 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::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;
+}
+
+
+class ShaderOgl : public Shader {
+public:
+ bool isVertex = true;
+ std::string code;
+};
+
+class BufferBindingOgl : public BufferBinding {
+public:
+ 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
+};
+
+class BufferOgl : public Buffer {
+public:
+ GLuint vbo;
+
+ virtual void SetData(std::vector<std::byte>&& data) override {
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, data.size(), data.data(), GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glCheckError();
+ }
+};
+
+class TextureConfigOgl : public TextureConfig {
+public:
+
+ Format format;
+ size_t width = 0, height = 0, depth = 0;
+ bool interpolateLayers = false;
+
+ 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;
+ }
+
+};
+
+class TextureOgl : public Texture {
+public:
+
+ GLenum type;
+ GLuint texture;
+ Format format;
+ size_t width = 0, height = 0, depth = 0;
+
+ virtual void SetData(std::vector<std::byte>&& data, size_t mipLevel = 0) override {
+ if (data.size() != width * height * depth * GalFormatGetSize(format))
+ throw std::logic_error("Size of data is not valid for this texture");
+
+ glBindTexture(type, texture);
+ glCheckError();
+
+ switch (type) {
+ case GL_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_2D:
+ case GL_TEXTURE_1D_ARRAY:
+ case GL_PROXY_TEXTURE_1D_ARRAY:
+ case GL_TEXTURE_RECTANGLE:
+ case GL_PROXY_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ case GL_PROXY_TEXTURE_CUBE_MAP:
+ glTexImage2D(type, mipLevel, GalFormatGetGlInternalFormat(format), width, height, 0, 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:
+ glTexImage3D(type, mipLevel, GalFormatGetGlInternalFormat(format), width, height, depth, 0, GalFormatGetGlFormat(format), GalFormatGetGlType(format), data.data());
+ break;
+ default:
+ throw std::runtime_error("Unknown texture type");
+ }
+
+ glCheckError();
+
+ glBindTexture(type, 0);
+ }
+
+};
+
+class PipelineConfigOgl : public PipelineConfig {
+public:
+ std::shared_ptr<ShaderOgl> vertexShader, pixelShader;
+ std::map<std::string, Type> shaderParameters;
+ std::shared_ptr<Framebuffer> targetFb;
+ std::vector<std::vector<VertexAttribute>> vertexBuffers;
+
+public:
+ 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 SetTarget(std::shared_ptr<Framebuffer> target) override {
+ targetFb = target;
+ }
+
+ 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);
+ }
+
+};
+
+class PipelineInstanceOgl : public PipelineInstance {
+public:
+ GLuint vao;
+
+ virtual void Activate() override {
+ glBindVertexArray(vao);
+ glCheckError();
+ }
+
+ virtual void Render(size_t offset = 0, size_t count = -1) override {
+ glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0);
+ glCheckError();
+ }
+};
+
+class PipelineOgl : public Pipeline {
+public:
+ std::map<std::string, size_t> shaderParameters;
+ GLuint program;
+ struct VertexBindingCommand {
+ size_t bufferId;
+ size_t location;
+ GLenum type;
+ size_t count;
+ size_t stride;
+ size_t offset;
+ };
+ std::vector<VertexBindingCommand> vertexBindCmds;
+
+ virtual void Activate() override {
+ glUseProgram(program);
+ 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>();
+
+ 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 });
+ }
+
+ glGenVertexArrays(1, &instance->vao);
+ glBindVertexArray(instance->vao);
+ glCheckError();
+
+ for (const auto& cmd : vertexBindCmds) {
+ glBindBuffer(GL_ARRAY_BUFFER, bufferBindingId.find(cmd.bufferId)->second);
+ glCheckError();
+ 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;
+ }
+
+ glCheckError();
+ glEnableVertexAttribArray(cmd.location);
+ glCheckError();
+ }
+
+ if (indexBuffer != BufferBindingOgl::indexValue) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
+ }
+
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glCheckError();
+
+ return instance;
+ }
+
+ virtual void SetShaderParameter(std::string_view name, float value) override {
+ Activate();
+ glUniform1f(shaderParameters.at(std::string(name)), value);
+ glCheckError();
+ }
+
+ virtual void SetShaderParameter(std::string_view name, double value) override {
+ Activate();
+ glUniform1d(shaderParameters.at(std::string(name)), value);
+ glCheckError();
+ }
+
+ virtual void SetShaderParameter(std::string_view name, int8_t value) override {
+ Activate();
+ glUniform1i(shaderParameters.at(std::string(name)), value);
+ glCheckError();
+ }
+
+ virtual void SetShaderParameter(std::string_view name, int16_t value) override {
+ Activate();
+ glUniform1i(shaderParameters.at(std::string(name)), value);
+ glCheckError();
+ }
+
+ virtual void SetShaderParameter(std::string_view name, int32_t value) override {
+ Activate();
+ glUniform1i(shaderParameters.at(std::string(name)), value);
+ glCheckError();
+ }
+
+ virtual void SetShaderParameter(std::string_view name, uint8_t value) override {
+ Activate();
+ glUniform1ui(shaderParameters.at(std::string(name)), value);
+ glCheckError();
+ }
+
+ virtual void SetShaderParameter(std::string_view name, uint16_t value) override {
+ Activate();
+ glUniform1ui(shaderParameters.at(std::string(name)), value);
+ glCheckError();
+ }
+
+ virtual void SetShaderParameter(std::string_view name, uint32_t value) override {
+ Activate();
+ glUniform1ui(shaderParameters.at(std::string(name)), value);
+ glCheckError();
+ }
+
+ virtual void SetShaderParameter(std::string_view name, glm::vec2 value) override {
+ Activate();
+ glUniform2f(shaderParameters.at(std::string(name)), value.x, value.y);
+ glCheckError();
+ }
+
+ virtual void SetShaderParameter(std::string_view name, glm::uvec2 value) override {
+ Activate();
+ glUniform2ui(shaderParameters.at(std::string(name)), value.x, value.y);
+ glCheckError();
+ }
+
+ virtual void SetShaderParameter(std::string_view name, glm::vec3 value) override {
+ Activate();
+ glUniform3f(shaderParameters.at(std::string(name)), value.x, value.y, value.z);
+ glCheckError();
+ }
+
+ 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);
+ glCheckError();
+ }
+
+ virtual void SetShaderParameter(std::string_view name, glm::mat4 value) override {
+ Activate();
+ glCheckError();
+ }
+};
+
+class ImplOgl : public Impl {
+
+public:
+
+ virtual void Init() override {
+ LOG(INFO) << "Initalizing Gal:OpenGL...";
+ LOG(INFO) << "Initializing GLEW";
+ glewExperimental = GL_TRUE;
+ GLenum glewStatus = glewInit();
+ glCheckError();
+ 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");
+ }
+ }
+
+ virtual void DeInit() override {
+ LOG(INFO) << "Destroying Gal:OpenGL...";
+ }
+
+ virtual void Cleanup() override {
+
+ }
+
+
+ virtual std::shared_ptr<Buffer> CreateBuffer() override {
+ auto buff = std::make_shared<BufferOgl>();
+ glGenBuffers(1, &buff->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->width = width;
+ config->height = height;
+ 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->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 = GL_TEXTURE_2D;
+ texture->format = texConfig->format;
+ texture->width = texConfig->width;
+ texture->height = texConfig->height;
+ texture->depth = texConfig->depth;
+
+ glGenTextures(1, &texture->texture);
+ glCheckError();
+
+ glTexParameteri(texture->type, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(texture->type, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(texture->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(texture->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glCheckError();
+
+ 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);
+
+ //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");
+
+ glUseProgram(program);
+
+ glCheckError();
+
+ pipeline->program = program;
+
+ //Shader parameters
+
+ for (auto&& [name, type] : config->shaderParameters) {
+ GLint location = glGetUniformLocation(program, name.c_str());
+ if (location < 0) {
+ glDeleteProgram(program);
+ LOG(ERROR) << "Uniform name \"" << name << "\" not found in shader";
+ throw std::runtime_error("Invalid uniform");
+ }
+ switch (type) {
+ case Type::Vec2:
+ glUniform2f(location, 0.0f, 0.0f);
+ break;
+ case Type::Vec2u8:
+ case Type::Vec2u16:
+ case Type::Vec2u32:
+ glUniform2ui(location, 0, 0);
+ break;
+ case Type::Vec4u8:
+ glUniform4ui(location, 0, 0, 0, 0);
+ break;
+ }
+ pipeline->shaderParameters.insert({ name,location });
+ }
+
+ //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] : buffer) {
+ if (name.empty()) {
+ vertexSize += GalTypeGetSize(type);
+ continue;
+ }
+
+ GLint location = glGetAttribLocation(program, name.c_str());
+ if (location < 0) {
+ glDeleteProgram(program);
+ LOG(ERROR) << "Vertex attribute name \"" << name << "\" not found in shader";
+ throw std::runtime_error("Invalid attribute");
+ }
+
+ size_t attribSize = GalTypeGetSize(type);
+
+ pipeline->vertexBindCmds.push_back({
+ bufferId,
+ static_cast<size_t>(location),
+ GalTypeGetComponentGlType(type),
+ GalTypeGetComponents(type),
+ vertexSize,
+ 0
+ });
+
+ 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 {
+ return nullptr;
+ }
+
+ virtual std::shared_ptr<Framebuffer> BuildFramebuffer(std::shared_ptr<FramebufferConfig> config) override {
+ return nullptr;
+ }
+
+ virtual std::shared_ptr<Framebuffer> GetDefaultFramebuffer() override {
+ if (!fbDefault)
+ fbDefault = std::make_shared<FramebufferDefaultOgl>();
+ return std::static_pointer_cast<Framebuffer, FramebufferDefaultOgl>(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);
+ }
+};
+
+class FramebufferDefaultOgl : public Framebuffer {
+ size_t vpX, vpY, vpW, vpH;
+public:
+
+ virtual void Clear() override {
+ GLbitfield clearBits = 0;
+ clearBits |= GL_COLOR_BUFFER_BIT;
+ clearBits |= GL_DEPTH_BUFFER_BIT;
+ clearBits |= GL_STENCIL_BUFFER_BIT;
+ glClear(clearBits);
+ }
+
+ virtual void SetViewport(size_t x, size_t y, size_t w, size_t h) override {
+ vpX = x;
+ vpY = y;
+ vpW = w;
+ vpH = h;
+ glViewport(x, y, w, h);
+ }
+};
+
+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..8b78efb 100644
--- a/src/Render.cpp
+++ b/src/Render.cpp
@@ -18,6 +18,7 @@
#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},
@@ -117,30 +118,12 @@ void Render::InitSdl(unsigned int WinWidth, unsigned int WinHeight, std::string
}
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);
- 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);
-
- 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");
- }
+ gal->GetDefaultFramebuffer()->SetViewport(0, 0, width, height);
}
void Render::PrepareToRendering() {
@@ -175,19 +158,19 @@ void Render::UpdateKeyboard() {
void Render::RenderFrame() {
OPTICK_EVENT();
- framebuffer->Clear();
+ //framebuffer->Clear();
Framebuffer::GetDefault().Clear();
- if (renderWorld)
- framebuffer->Activate();
+ //if (renderWorld)
+ // framebuffer->Activate();
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());
+ //if (renderWorld)
+ // framebuffer->RenderTo(Framebuffer::GetDefault());
RenderGui();
diff --git a/src/Rml.cpp b/src/Rml.cpp
index 179d4b9..4e28529 100644
--- a/src/Rml.cpp
+++ b/src/Rml.cpp
@@ -46,74 +46,98 @@ void RmlSystemInterface::GetClipboardText(Rml::String& text) {
}
RmlRenderInterface::RmlRenderInterface(RenderState& renderState) : State(&renderState) {
- glGenVertexArrays(1, &Vao);
- glBindVertexArray(Vao);
- glCheckError();
+ auto gal = Gal::GetImplementation();
+ auto pipelineConfig = gal->CreatePipelineConfig();
+ pipelineConfig->AddShaderParameter("viewportSize", Gal::Type::Vec2u32);
+ pipelineConfig->AddShaderParameter("translation", Gal::Type::Vec2);
+ pipelineConfig->SetTarget(gal->GetDefaultFramebuffer());
- glGenBuffers(1, &Ebo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ebo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, nullptr, GL_STREAM_DRAW);
- glCheckError();
+ auto vertAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/vert/rml");
+ std::string vertSource((char*)vertAsset->data.data(), (char*)vertAsset->data.data() + vertAsset->data.size());
+ auto pixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/rml");
+ std::string pixelSource((char*)pixelAsset->data.data(), (char*)pixelAsset->data.data() + pixelAsset->data.size());
+ pipelineConfig->SetVertexShader(gal->LoadVertexShader(vertSource));
+ 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);
+
+ vertexBuffer = gal->CreateBuffer();
+
+ indexBuffer = gal->CreateBuffer();
+
+ pipelineInstance = pipeline->CreateInstance({
+ {vertBuffBind, vertexBuffer},
+ {indexBuffBind, indexBuffer},
+ });
- glGenBuffers(1, &Vbo);
- glBindBuffer(GL_ARRAY_BUFFER, Vbo);
- glBufferData(GL_ARRAY_BUFFER, 0, nullptr, GL_STREAM_DRAW);
glCheckError();
-
- {
- //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);
- }
- glBindVertexArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ auto texturePipelineConfig = gal->CreatePipelineConfig();
+ texturePipelineConfig->AddShaderParameter("viewportSize", Gal::Type::Vec2u32);
+ texturePipelineConfig->AddShaderParameter("translation", Gal::Type::Vec2);
+ texturePipelineConfig->AddShaderParameter("fontTexture", Gal::Type::Int32);
+ texturePipelineConfig->SetTarget(gal->GetDefaultFramebuffer());
+
+ auto texturePixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/rmltex");
+ std::string texturePixelSource((char*)texturePixelAsset->data.data(), (char*)texturePixelAsset->data.data() + texturePixelAsset->data.size());
+ texturePipelineConfig->SetVertexShader(gal->LoadVertexShader(vertSource));
+ texturePipelineConfig->SetPixelShader(gal->LoadPixelShader(texturePixelSource));
+
+ auto texVertBuffBind = texturePipelineConfig->BindVertexBuffer({
+ {"pos", Gal::Type::Vec2},
+ {"color", Gal::Type::Vec4u8},
+ {"tex_coord", Gal::Type::Vec2},
+ });
+
+ auto texIndexBuffBind = texturePipelineConfig->BindIndexBuffer();
+
+ texPipeline = gal->BuildPipeline(texturePipelineConfig);
+
+ texPipelineInstance = texPipeline->CreateInstance({
+ {texVertBuffBind, vertexBuffer},
+ {texIndexBuffBind, indexBuffer},
+ });
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) {
+ 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) });
+ glCheckError();
+
+
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));
+ texPipeline->Activate();
+ glCheckError();
+ texPipeline->SetShaderParameter("translation", glm::vec2(translation.x, translation.y));
+ glCheckError();
+ texPipelineInstance->Activate();
+ glCheckError();
glBindTexture(GL_TEXTURE_2D, texture);
+ glCheckError();
+ 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);
+ pipeline->Activate();
+ glCheckError();
+ pipeline->SetShaderParameter("translation", glm::vec2(translation.x, translation.y));
+ glCheckError();
+ pipelineInstance->Activate();
+ glCheckError();
+ pipelineInstance->Render(0, num_indices);
+ }
glCheckError();
- glBindVertexArray(0);
}
void RmlRenderInterface::EnableScissorRegion(bool enable) {
@@ -158,13 +182,14 @@ void RmlRenderInterface::ReleaseTexture(Rml::TextureHandle 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));
+ texPipeline->SetShaderParameter("fontTexture", 0);
+
vpWidth = windowWidth;
vpHeight = windowHeight;
}
diff --git a/src/Rml.hpp b/src/Rml.hpp
index edcdc8b..42203d4 100644
--- a/src/Rml.hpp
+++ b/src/Rml.hpp
@@ -7,6 +7,7 @@
#include <RmlUi/Core/FileInterface.h>
#include "Renderer.hpp"
+#include "Gal.hpp"
class AssetTreeNode;
@@ -32,7 +33,9 @@ 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;
unsigned int vpWidth, vpHeight;
public: