From ce116b8ba834363921cc31ce2ef0781d6f6b2627 Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Sun, 14 Nov 2021 07:27:39 +0500 Subject: Added basic Graphics Abstraction Layer --- src/Gal.hpp | 255 ++++++++++++++++++ src/GalOgl.cpp | 836 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Render.cpp | 37 +-- src/Rml.cpp | 143 ++++++---- src/Rml.hpp | 5 +- 5 files changed, 1189 insertions(+), 87 deletions(-) create mode 100644 src/Gal.hpp create mode 100644 src/GalOgl.cpp 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 +#include +#include +#include + +#include + +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 CreateBuffer() = 0; + + + virtual std::shared_ptr CreateTexture2DConfig(size_t width, size_t height, Format format) = 0; + + virtual std::shared_ptr CreateTexture3DConfig(size_t width, size_t height, size_t depth, bool interpolateLayers, Format format) = 0; + + virtual std::shared_ptr BuildTexture(std::shared_ptr config) = 0; + + + virtual std::shared_ptr CreatePipelineConfig() = 0; + + virtual std::shared_ptr BuildPipeline(std::shared_ptr config) = 0; + + + virtual std::shared_ptr CreateFramebufferConfig() = 0; + + virtual std::shared_ptr BuildFramebuffer(std::shared_ptr config) = 0; + + virtual std::shared_ptr GetDefaultFramebuffer() = 0; + + + virtual std::shared_ptr GetGlobalShaderParameters() = 0; + + virtual std::shared_ptr LoadVertexShader(std::string_view code) = 0; + + virtual std::shared_ptr LoadPixelShader(std::string_view code) = 0; + + }; + + struct Buffer { + virtual ~Buffer() = default; + + virtual void SetData(std::vector&& 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&& data, size_t mipLevel = 0) = 0; + }; + + struct PipelineConfig { + virtual ~PipelineConfig() = default; + + virtual void SetVertexShader(std::shared_ptr shader) = 0; + + virtual void SetPixelShader(std::shared_ptr shader) = 0; + + virtual void AddShaderParameter(std::string_view name, Type type) = 0; + + virtual void SetTarget(std::shared_ptr target) = 0; + + virtual std::shared_ptr BindVertexBuffer(std::vector &&bufferLayout) = 0; + + virtual std::shared_ptr BindIndexBuffer() = 0; + }; + + struct Pipeline { + virtual ~Pipeline() = default; + + virtual void Activate() = 0; + + virtual std::shared_ptr CreateInstance(std::vector, std::shared_ptr>> &&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 +#include + +#include "Utility.hpp" + +using namespace Gal; + +class ImplOgl; +class FramebufferDefaultOgl; +class ShaderOgl; + +std::unique_ptr impl; +std::shared_ptr 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::max)(); //parenthess for windows' max macro +}; + +class BufferOgl : public Buffer { +public: + GLuint vbo; + + virtual void SetData(std::vector&& 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&& 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 vertexShader, pixelShader; + std::map shaderParameters; + std::shared_ptr targetFb; + std::vector> vertexBuffers; + +public: + virtual void SetVertexShader(std::shared_ptr shader) override { + vertexShader = std::static_pointer_cast(shader); + } + + virtual void SetPixelShader(std::shared_ptr shader) override { + pixelShader = std::static_pointer_cast(shader); + } + + virtual void AddShaderParameter(std::string_view name, Type type) override { + shaderParameters.emplace(std::string(name), type); + } + + virtual void SetTarget(std::shared_ptr target) override { + targetFb = target; + } + + virtual std::shared_ptr BindVertexBuffer(std::vector &&bufferLayout) override { + auto binding = std::make_shared(vertexBuffers.size()); + vertexBuffers.push_back(bufferLayout); + return std::static_pointer_cast(binding); + } + + virtual std::shared_ptr BindIndexBuffer() override { + auto binding = std::make_shared(BufferBindingOgl::indexValue); + return std::static_pointer_cast(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 shaderParameters; + GLuint program; + struct VertexBindingCommand { + size_t bufferId; + size_t location; + GLenum type; + size_t count; + size_t stride; + size_t offset; + }; + std::vector vertexBindCmds; + + virtual void Activate() override { + glUseProgram(program); + glCheckError(); + } + + virtual std::shared_ptr CreateInstance(std::vector, std::shared_ptr>>&& buffers) override { + auto instance = std::make_shared(); + + size_t indexBuffer = BufferBindingOgl::indexValue; + std::map bufferBindingId; + + for (auto&& [binding, buffer] : buffers) { + auto bind = std::static_pointer_cast(binding); + auto buff = std::static_pointer_cast(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(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(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 CreateBuffer() override { + auto buff = std::make_shared(); + glGenBuffers(1, &buff->vbo); + buff->SetData({}); + glCheckError(); + return std::static_pointer_cast(buff); + } + + + virtual std::shared_ptr CreateTexture2DConfig(size_t width, size_t height, Format format) override { + auto config = std::make_shared(); + + config->width = width; + config->height = height; + config->format = format; + + return std::static_pointer_cast(config); + } + + virtual std::shared_ptr CreateTexture3DConfig(size_t width, size_t height, size_t depth, bool interpolateLayers, Format format) override { + auto config = std::make_shared(); + + config->width = width; + config->height = height; + config->depth = depth; + config->interpolateLayers = interpolateLayers; + config->format = format; + + return std::static_pointer_cast(config); + } + + virtual std::shared_ptr BuildTexture(std::shared_ptr config) override { + auto texConfig = std::static_pointer_cast(config); + auto texture = std::make_shared(); + + 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(texture->width * texture->height * texture->depth * GalFormatGetSize(texture->format))); + glCheckError(); + + return std::static_pointer_cast(texture); + } + + + virtual std::shared_ptr CreatePipelineConfig() override { + auto pipelineConfig = std::make_shared(); + return std::static_pointer_cast(pipelineConfig); + } + + virtual std::shared_ptr BuildPipeline(std::shared_ptr pipelineConfig) override { + auto pipeline = std::make_shared(); + auto config = std::static_pointer_cast(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(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 CreateFramebufferConfig() override { + return nullptr; + } + + virtual std::shared_ptr BuildFramebuffer(std::shared_ptr config) override { + return nullptr; + } + + virtual std::shared_ptr GetDefaultFramebuffer() override { + if (!fbDefault) + fbDefault = std::make_shared(); + return std::static_pointer_cast(fbDefault); + } + + + virtual std::shared_ptr GetGlobalShaderParameters() override { + return nullptr; + } + + virtual std::shared_ptr LoadVertexShader(std::string_view code) override { + auto shader = std::make_shared(); + shader->code = code; + shader->isVertex = true; + return std::static_pointer_cast(shader); + } + + virtual std::shared_ptr LoadPixelShader(std::string_view code) override { + auto shader = std::make_shared(); + shader->code = code; + shader->isVertex = false; + return std::static_pointer_cast(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(); + + 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 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(indices), reinterpret_cast(indices + num_indices) }); + vertexBuffer->SetData({ reinterpret_cast(vertices), reinterpret_cast(vertices + num_vertices) }); + glCheckError(); + + if (texture) { - AssetManager::GetAsset("/altcraft/shaders/rmltex")->shader->Activate(); - AssetManager::GetAsset("/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("/altcraft/shaders/rml")->shader->Activate(); - AssetManager::GetAsset("/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("/altcraft/shaders/rml")->shader->Activate(); - AssetManager::GetAsset("/altcraft/shaders/rml")->shader->SetUniform("viewportSize", windowWidth, windowHeight); - glCheckError(); - AssetManager::GetAsset("/altcraft/shaders/rmltex")->shader->Activate(); - AssetManager::GetAsset("/altcraft/shaders/rmltex")->shader->SetUniform("viewportSize", windowWidth, windowHeight); - AssetManager::GetAsset("/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 #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 pipeline, texPipeline; + std::shared_ptr pipelineInstance, texPipelineInstance; + std::shared_ptr vertexBuffer, indexBuffer; unsigned int vpWidth, vpHeight; public: -- cgit v1.2.3 From 5651b71788487e986ea945d76cbaf647d4554813 Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Sun, 14 Nov 2021 16:23:15 +0500 Subject: Added dynamic textures for Gal --- src/Gal.hpp | 2 ++ src/GalOgl.cpp | 27 +++++++++++++++++++-------- src/Rml.cpp | 32 ++++++++++++++------------------ src/Rml.hpp | 3 +-- 4 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/Gal.hpp b/src/Gal.hpp index 0f2d162..ec00442 100644 --- a/src/Gal.hpp +++ b/src/Gal.hpp @@ -172,6 +172,8 @@ namespace Gal { virtual std::shared_ptr CreateInstance(std::vector, std::shared_ptr>> &&buffers) = 0; + virtual void SetDynamicTexture(std::string_view name, std::shared_ptr texture) = 0; + virtual void SetShaderParameter(std::string_view name, float value) = 0; virtual void SetShaderParameter(std::string_view name, double value) = 0; diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index 4fb2794..e39f5f0 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -265,7 +265,7 @@ class TextureConfigOgl : public TextureConfig { public: Format format; - size_t width = 0, height = 0, depth = 0; + size_t width = 1, height = 1, depth = 1; bool interpolateLayers = false; Filtering min = Filtering::Nearest, max = Filtering::Nearest; @@ -292,10 +292,11 @@ public: GLenum type; GLuint texture; Format format; - size_t width = 0, height = 0, depth = 0; + size_t width, height, depth; virtual void SetData(std::vector&& data, size_t mipLevel = 0) override { - if (data.size() != width * height * depth * GalFormatGetSize(format)) + size_t expectedSize = width * height * depth * GalFormatGetSize(format); + if (data.size() != expectedSize) throw std::logic_error("Size of data is not valid for this texture"); glBindTexture(type, texture); @@ -405,6 +406,14 @@ public: glCheckError(); } + virtual void SetDynamicTexture(std::string_view name, std::shared_ptr texture) override { + Activate(); + glActiveTexture(GL_TEXTURE0); + auto tex = std::static_pointer_cast(texture); + glBindTexture(tex->type, tex->texture); + SetShaderParameter(name, 0); + } + virtual std::shared_ptr CreateInstance(std::vector, std::shared_ptr>>&& buffers) override { auto instance = std::make_shared(); @@ -590,6 +599,7 @@ public: config->width = width; config->height = height; + config->depth = 1; config->format = format; return std::static_pointer_cast(config); @@ -619,14 +629,15 @@ public: glGenTextures(1, &texture->texture); glCheckError(); + glBindTexture(texture->type, texture->texture); - 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); - + 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)); glCheckError(); + glBindTexture(texture->type, 0); texture->SetData(std::vector(texture->width * texture->height * texture->depth * GalFormatGetSize(texture->format))); glCheckError(); diff --git a/src/Rml.cpp b/src/Rml.cpp index 4e28529..4f5c0b9 100644 --- a/src/Rml.cpp +++ b/src/Rml.cpp @@ -45,7 +45,7 @@ void RmlSystemInterface::GetClipboardText(Rml::String& text) { text = clipboard; } -RmlRenderInterface::RmlRenderInterface(RenderState& renderState) : State(&renderState) { +RmlRenderInterface::RmlRenderInterface(RenderState& renderState) { auto gal = Gal::GetImplementation(); auto pipelineConfig = gal->CreatePipelineConfig(); pipelineConfig->AddShaderParameter("viewportSize", Gal::Type::Vec2u32); @@ -117,15 +117,15 @@ void RmlRenderInterface::RenderGeometry(Rml::Vertex* vertices, int num_vertices, vertexBuffer->SetData({ reinterpret_cast(vertices), reinterpret_cast(vertices + num_vertices) }); glCheckError(); - - if (texture) { + auto tex = textures.find(texture); + if (tex != textures.end()) { texPipeline->Activate(); glCheckError(); texPipeline->SetShaderParameter("translation", glm::vec2(translation.x, translation.y)); glCheckError(); - texPipelineInstance->Activate(); + texPipeline->SetDynamicTexture("fontTexture", tex->second); glCheckError(); - glBindTexture(GL_TEXTURE_2D, texture); + texPipelineInstance->Activate(); glCheckError(); texPipelineInstance->Render(0, num_indices); } else { @@ -157,21 +157,16 @@ 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); + 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(source),reinterpret_cast(source + (source_dimensions.x * source_dimensions.y) * 4) }); + textures.insert({ textureId,texture }); + texture_handle = textureId; glCheckError(); - texture_handle = texture; return true; } @@ -185,11 +180,12 @@ void RmlRenderInterface::Update(unsigned int windowWidth, unsigned int windowHei glCheckError(); - pipeline->SetShaderParameter("viewportSize", glm::uvec2(windowWidth, windowHeight)); texPipeline->SetShaderParameter("viewportSize", glm::uvec2(windowWidth, windowHeight)); texPipeline->SetShaderParameter("fontTexture", 0); + glCheckError(); + vpWidth = windowWidth; vpHeight = windowHeight; } diff --git a/src/Rml.hpp b/src/Rml.hpp index 42203d4..9aa6be0 100644 --- a/src/Rml.hpp +++ b/src/Rml.hpp @@ -31,11 +31,10 @@ public: }; class RmlRenderInterface : public Rml::RenderInterface { - RenderState* State; - std::shared_ptr pipeline, texPipeline; std::shared_ptr pipelineInstance, texPipelineInstance; std::shared_ptr vertexBuffer, indexBuffer; + std::map> textures; unsigned int vpWidth, vpHeight; public: -- cgit v1.2.3 From 1e40c0b0e6928558c5ea02612d52860ba80d9f05 Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Sun, 14 Nov 2021 17:24:30 +0500 Subject: Added ScissorTest to Gal --- src/Gal.hpp | 5 +++ src/GalOgl.cpp | 12 ++++++ src/Rml.cpp | 134 +++++++++++++++++++++++++-------------------------------- 3 files changed, 75 insertions(+), 76 deletions(-) diff --git a/src/Gal.hpp b/src/Gal.hpp index ec00442..06850ea 100644 --- a/src/Gal.hpp +++ b/src/Gal.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -91,6 +92,10 @@ namespace Gal { 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 CreateBuffer() = 0; diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index e39f5f0..7a662e8 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -584,6 +584,18 @@ public: } + 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); + } + + virtual void SetScissor(bool enabled) override { + if (enabled) + glEnable(GL_SCISSOR_TEST); + else + glDisable(GL_SCISSOR_TEST); + } + virtual std::shared_ptr CreateBuffer() override { auto buff = std::make_shared(); diff --git a/src/Rml.cpp b/src/Rml.cpp index 4f5c0b9..d886377 100644 --- a/src/Rml.cpp +++ b/src/Rml.cpp @@ -3,7 +3,6 @@ #include #include "AssetManager.hpp" -#include "Shader.hpp" #include "Utility.hpp" double RmlSystemInterface::GetElapsedTime() { @@ -46,110 +45,103 @@ void RmlSystemInterface::GetClipboardText(Rml::String& text) { } RmlRenderInterface::RmlRenderInterface(RenderState& renderState) { - auto gal = Gal::GetImplementation(); - auto pipelineConfig = gal->CreatePipelineConfig(); - pipelineConfig->AddShaderParameter("viewportSize", Gal::Type::Vec2u32); - pipelineConfig->AddShaderParameter("translation", Gal::Type::Vec2); - pipelineConfig->SetTarget(gal->GetDefaultFramebuffer()); - - 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)); + 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 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 pixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/rml"); + pixelSource = std::string((char*)pixelAsset->data.data(), (char*)pixelAsset->data.data() + pixelAsset->data.size()); - auto indexBuffBind = pipelineConfig->BindIndexBuffer(); + auto texPixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/rmltex"); + texPixelSource = std::string((char*)texPixelAsset->data.data(), (char*)texPixelAsset->data.data() + texPixelAsset->data.size()); + } - pipeline = gal->BuildPipeline(pipelineConfig); + auto gal = Gal::GetImplementation(); vertexBuffer = gal->CreateBuffer(); - indexBuffer = gal->CreateBuffer(); - pipelineInstance = pipeline->CreateInstance({ - {vertBuffBind, vertexBuffer}, - {indexBuffBind, indexBuffer}, - }); - - 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 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 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 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 indexBuffBind = pipelineConfig->BindIndexBuffer(); - auto texVertBuffBind = texturePipelineConfig->BindVertexBuffer({ - {"pos", Gal::Type::Vec2}, - {"color", Gal::Type::Vec4u8}, - {"tex_coord", Gal::Type::Vec2}, - }); + pipeline = gal->BuildPipeline(pipelineConfig); - auto texIndexBuffBind = texturePipelineConfig->BindIndexBuffer(); - - texPipeline = gal->BuildPipeline(texturePipelineConfig); + pipelineInstance = pipeline->CreateInstance({ + {vertBuffBind, vertexBuffer}, + {indexBuffBind, indexBuffer}, + }); + } + + { + 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}, + }); + } - texPipelineInstance = texPipeline->CreateInstance({ - {texVertBuffBind, vertexBuffer}, - {texIndexBuffBind, indexBuffer}, - }); - glCheckError(); + } RmlRenderInterface::~RmlRenderInterface() { - 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(indices), reinterpret_cast(indices + num_indices) }); vertexBuffer->SetData({ reinterpret_cast(vertices), reinterpret_cast(vertices + num_vertices) }); - glCheckError(); auto tex = textures.find(texture); if (tex != textures.end()) { texPipeline->Activate(); - glCheckError(); texPipeline->SetShaderParameter("translation", glm::vec2(translation.x, translation.y)); - glCheckError(); texPipeline->SetDynamicTexture("fontTexture", tex->second); - glCheckError(); texPipelineInstance->Activate(); - glCheckError(); texPipelineInstance->Render(0, num_indices); } else { pipeline->Activate(); - glCheckError(); pipeline->SetShaderParameter("translation", glm::vec2(translation.x, translation.y)); - glCheckError(); pipelineInstance->Activate(); - glCheckError(); pipelineInstance->Render(0, num_indices); } - glCheckError(); } 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) { @@ -157,7 +149,6 @@ 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) { - glCheckError(); 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); @@ -165,26 +156,17 @@ bool RmlRenderInterface::GenerateTexture(Rml::TextureHandle& texture_handle, con texture->SetData({ reinterpret_cast(source),reinterpret_cast(source + (source_dimensions.x * source_dimensions.y) * 4) }); textures.insert({ textureId,texture }); texture_handle = textureId; - glCheckError(); 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) { - - glCheckError(); - pipeline->SetShaderParameter("viewportSize", glm::uvec2(windowWidth, windowHeight)); texPipeline->SetShaderParameter("viewportSize", glm::uvec2(windowWidth, windowHeight)); - texPipeline->SetShaderParameter("fontTexture", 0); - - glCheckError(); vpWidth = windowWidth; vpHeight = windowHeight; -- cgit v1.2.3 From 663821b00ca8440509e0bc6d5022c809c7fe1cff Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Mon, 15 Nov 2021 12:55:20 +0500 Subject: Changed section rendering to Gal --- src/Gal.hpp | 12 ++++++ src/GalOgl.cpp | 86 +++++++++++++++++++++++++++++++++------- src/RendererSection.cpp | 103 +++++++----------------------------------------- src/RendererSection.hpp | 13 +++--- src/RendererWorld.cpp | 49 +++++++++++++++++++---- src/RendererWorld.hpp | 2 + 6 files changed, 148 insertions(+), 117 deletions(-) diff --git a/src/Gal.hpp b/src/Gal.hpp index 06850ea..8089fd3 100644 --- a/src/Gal.hpp +++ b/src/Gal.hpp @@ -77,9 +77,17 @@ namespace Gal { Clamp, }; + enum class Primitive { + Triangle, + TriangleStrip, + TriangleFan, + }; + struct VertexAttribute { std::string name; Type type; + size_t count = 1; + size_t instances = 0; }; Impl* GetImplementation(); @@ -165,6 +173,8 @@ namespace Gal { virtual void SetTarget(std::shared_ptr target) = 0; + virtual void SetPrimitive(Primitive primitive) = 0; + virtual std::shared_ptr BindVertexBuffer(std::vector &&bufferLayout) = 0; virtual std::shared_ptr BindIndexBuffer() = 0; @@ -212,6 +222,8 @@ namespace Gal { 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 { diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index 7a662e8..0452cab 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "Utility.hpp" @@ -341,7 +342,7 @@ public: std::map shaderParameters; std::shared_ptr targetFb; std::vector> vertexBuffers; - + Primitive vertexPrimitive = Primitive::Triangle; public: virtual void SetVertexShader(std::shared_ptr shader) override { vertexShader = std::static_pointer_cast(shader); @@ -359,6 +360,10 @@ public: targetFb = target; } + virtual void SetPrimitive(Primitive primitive) override { + vertexPrimitive = primitive; + } + virtual std::shared_ptr BindVertexBuffer(std::vector &&bufferLayout) override { auto binding = std::make_shared(vertexBuffers.size()); vertexBuffers.push_back(bufferLayout); @@ -375,6 +380,9 @@ public: class PipelineInstanceOgl : public PipelineInstance { public: GLuint vao; + bool useIndex = false; + Primitive primitive; + size_t instances = 0; virtual void Activate() override { glBindVertexArray(vao); @@ -382,9 +390,44 @@ public: } virtual void Render(size_t offset = 0, size_t count = -1) override { - glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0); + GLenum vertexMode; + switch (primitive) { + 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); + } + } + glCheckError(); } + + virtual void SetInstancesCount(size_t count) override { + instances = count; + } }; class PipelineOgl : public Pipeline { @@ -398,8 +441,10 @@ public: size_t count; size_t stride; size_t offset; + size_t instances; }; std::vector vertexBindCmds; + Primitive primitive; virtual void Activate() override { glUseProgram(program); @@ -417,6 +462,8 @@ public: virtual std::shared_ptr CreateInstance(std::vector, std::shared_ptr>>&& buffers) override { auto instance = std::make_shared(); + instance->primitive = primitive; + size_t indexBuffer = BufferBindingOgl::indexValue; std::map bufferBindingId; @@ -455,10 +502,15 @@ public: glCheckError(); glEnableVertexAttribArray(cmd.location); glCheckError(); + if (cmd.instances) { + glVertexAttribDivisor(cmd.location, cmd.instances); + glCheckError(); + } } if (indexBuffer != BufferBindingOgl::indexValue) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); + instance->useIndex = true; } glBindVertexArray(0); @@ -543,6 +595,7 @@ public: 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)); glCheckError(); } }; @@ -666,6 +719,8 @@ public: auto pipeline = std::make_shared(); auto config = std::static_pointer_cast(pipelineConfig); + pipeline->primitive = config->vertexPrimitive; + //Shader compilation bool vertexFailed = false, pixelFailed = false, linkFailed = false; @@ -757,9 +812,9 @@ public: for (const auto& buffer : config->vertexBuffers) { size_t vertexSize = 0; size_t cmdOffset = pipeline->vertexBindCmds.size(); - for (const auto& [name, type] : buffer) { + for (const auto& [name, type, count, instances] : buffer) { if (name.empty()) { - vertexSize += GalTypeGetSize(type); + vertexSize += GalTypeGetSize(type) * count; continue; } @@ -772,16 +827,19 @@ public: size_t attribSize = GalTypeGetSize(type); - pipeline->vertexBindCmds.push_back({ - bufferId, - static_cast(location), - GalTypeGetComponentGlType(type), - GalTypeGetComponents(type), - vertexSize, - 0 - }); - - vertexSize += attribSize; + for (size_t i = 0; i < count; i++) { + pipeline->vertexBindCmds.push_back({ + bufferId, + static_cast(location + i), + GalTypeGetComponentGlType(type), + GalTypeGetComponents(type), + vertexSize, + 0, + instances, + }); + + vertexSize += attribSize; + } } for (size_t i = cmdOffset; i < pipeline->vertexBindCmds.size(); i++) 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 #include "Utility.hpp" -#include "Renderer.hpp" #include "RendererSectionData.hpp" -RendererSection::RendererSection(const RendererSectionData &data) { + +RendererSection::RendererSection(const RendererSectionData& data, std::shared_ptr pipeline, std::shared_ptr 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(data.vertices.data()), reinterpret_cast(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 -#include - #include "Vector.hpp" +#include "Gal.hpp" class RenderState; class RendererSectionData; class RendererSection { - GLuint Vao = { 0 }; - GLuint Vbo = { 0 }; - + std::shared_ptr pipelineInstance; + std::shared_ptr buffer; size_t hash; Vector sectionPos; RendererSection(const RendererSection &other) = delete; public: - RendererSection(const RendererSectionData &data); + RendererSection(const RendererSectionData& data, std::shared_ptr pipeline, std::shared_ptr bufferBinding); RendererSection(RendererSection &&other); ~RendererSection(); - void Render(RenderState &renderState); + void Render(); Vector GetPosition(); diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index 6996762..2764405 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -188,7 +188,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(); }); @@ -401,12 +401,16 @@ void RendererWorld::Render(RenderState & renderState) { //Render sections auto rawGlobalTime = (std::chrono::high_resolution_clock::now() - globalTimeStart); float globalTime = rawGlobalTime.count() / 1000000000.0f; - Shader *blockShader = AssetManager::GetAsset("/altcraft/shaders/face")->shader.get(); + /*Shader* blockShader = AssetManager::GetAsset("/altcraft/shaders/face")->shader.get(); blockShader->Activate(); blockShader->SetUniform("DayTime", mixLevel); blockShader->SetUniform("projView", projView); blockShader->SetUniform("GlobalTime", globalTime); glCheckError(); + */ + sectionsPipeline->Activate(); + sectionsPipeline->SetShaderParameter("DayTime", mixLevel); + sectionsPipeline->SetShaderParameter("projView", projView); Frustum frustum(projView); @@ -425,7 +429,7 @@ void RendererWorld::Render(RenderState & renderState) { culledSections--; continue; } - section.second.Render(renderState); + section.second.Render(); renderedFaces += section.second.numOfFaces; } DebugInfo::culledSections = culledSections; @@ -434,10 +438,41 @@ void RendererWorld::Render(RenderState & renderState) { } void RendererWorld::PrepareRender() { - Shader *blockShader = AssetManager::GetAsset("/altcraft/shaders/face")->shader.get(); - blockShader->Activate(); - blockShader->SetUniform("textureAtlas", 0); - blockShader->SetUniform("MinLightLevel", 0.2f); + 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()); + } + + auto gal = Gal::GetImplementation(); + { + auto sectionsPLC = gal->CreatePipelineConfig(); + sectionsPLC->SetTarget(gal->GetDefaultFramebuffer()); + 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->AddShaderParameter("textureAtlas", Gal::Type::Int32); + 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); + sectionsPipeline->SetShaderParameter("textureAtlas", 0); + } + TextureCoord sunTexture = AssetManager::GetTexture("/minecraft/textures/environment/sun"); TextureCoord moonTexture = AssetManager::GetTexture("/minecraft/textures/environment/moon_phases"); diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index 85cb736..c0af0dc 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -44,6 +44,8 @@ class RendererWorld { std::map sections; void UpdateAllSections(VectorF playerPos); std::chrono::time_point globalTimeStart; + std::shared_ptr sectionsPipeline; + std::shared_ptr sectionsBufferBinding; //Entities std::vector entities; //Sky -- cgit v1.2.3 From 513fe5ebe3f59aa8d85d9517db9fe0bfa531d3dc Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Wed, 17 Nov 2021 10:59:16 +0500 Subject: Changed entities rendering to Gal --- src/Gal.hpp | 1 + src/GalOgl.cpp | 5 +- src/RendererEntity.cpp | 131 ++---------------------- src/RendererEntity.hpp | 9 +- src/RendererWorld.cpp | 270 +++++++++++++++++++++++++++++++++---------------- src/RendererWorld.hpp | 3 + 6 files changed, 197 insertions(+), 222 deletions(-) diff --git a/src/Gal.hpp b/src/Gal.hpp index 8089fd3..51d3bd6 100644 --- a/src/Gal.hpp +++ b/src/Gal.hpp @@ -78,6 +78,7 @@ namespace Gal { }; enum class Primitive { + Line, Triangle, TriangleStrip, TriangleFan, diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index 0452cab..5643b4d 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -392,6 +392,9 @@ public: 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; @@ -820,9 +823,7 @@ public: 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); 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 -#include #include #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 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("/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 +#include "Gal.hpp" -class RenderState; class World; class RendererEntity { unsigned int entityId; + std::shared_ptr pipeline; public: RendererEntity(unsigned int id); - ~RendererEntity(); - void Render(RenderState& renderState, const World *world); - - static GLuint GetVao(); + void Render(std::shared_ptr pipeline, const World *world); }; diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index 2764405..03d575b 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -293,62 +293,47 @@ void RendererWorld::Render(RenderState & renderState) { glm::mat4 projView = projection * view; //Render Entities -#ifndef __APPLE__ - glLineWidth(3.0); -#endif - Shader *entityShader = AssetManager::GetAsset("/altcraft/shaders/entity")->shader.get(); - entityShader->Activate(); - entityShader->SetUniform("projection", projection); - entityShader->SetUniform("view", view); - glCheckError(); - - renderState.SetActiveVao(RendererEntity::GetVao()); + entitiesPipeline->Activate(); + entitiesPipeline->SetShaderParameter("projection", projection); + entitiesPipeline->SetShaderParameter("view", view); + + entitiesPipelineInstance->Activate(); for (auto& it : entities) { - it.Render(renderState, &GetGameState()->GetWorld()); + it.Render(entitiesPipeline, &GetGameState()->GetWorld()); + entitiesPipelineInstance->Render(0, 24); } //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, 24); } } //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, 24); } } -#ifndef __APPLE__ - glLineWidth(1.0); -#endif - glCheckError(); //Render sky renderState.TimeOfDay = GetGameState()->GetTimeStatus().timeOfDay; @@ -399,80 +384,187 @@ void RendererWorld::Render(RenderState & renderState) { glCheckError(); //Render sections - auto rawGlobalTime = (std::chrono::high_resolution_clock::now() - globalTimeStart); - float globalTime = rawGlobalTime.count() / 1000000000.0f; - /*Shader* blockShader = AssetManager::GetAsset("/altcraft/shaders/face")->shader.get(); - blockShader->Activate(); - blockShader->SetUniform("DayTime", mixLevel); - blockShader->SetUniform("projView", projView); - blockShader->SetUniform("GlobalTime", globalTime); - glCheckError(); - */ - sectionsPipeline->Activate(); - sectionsPipeline->SetShaderParameter("DayTime", mixLevel); - sectionsPipeline->SetShaderParameter("projView", projView); - - Frustum frustum(projView); + 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); 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(); - renderedFaces += section.second.numOfFaces; + renderedFaces += section.second.numOfFaces; } DebugInfo::culledSections = culledSections; - DebugInfo::renderFaces = renderedFaces; - glCheckError(); + DebugInfo::renderFaces = renderedFaces; } void RendererWorld::PrepareRender() { - 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()); + 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()); - } + auto pixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/face"); + sectionPixelSource = std::string((char*)pixelAsset->data.data(), (char*)pixelAsset->data.data() + pixelAsset->data.size()); + } - auto gal = Gal::GetImplementation(); - { - auto sectionsPLC = gal->CreatePipelineConfig(); - sectionsPLC->SetTarget(gal->GetDefaultFramebuffer()); - 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->AddShaderParameter("textureAtlas", Gal::Type::Int32); - 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); - sectionsPipeline->SetShaderParameter("textureAtlas", 0); - } - + 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()); + } + + auto gal = Gal::GetImplementation(); + { + auto sectionsPLC = gal->CreatePipelineConfig(); + sectionsPLC->SetTarget(gal->GetDefaultFramebuffer()); + 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->AddShaderParameter("textureAtlas", Gal::Type::Int32); + 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); + sectionsPipeline->SetShaderParameter("textureAtlas", 0); + } + + { + auto entitiesPLC = gal->CreatePipelineConfig(); + entitiesPLC->SetTarget(gal->GetDefaultFramebuffer()); + entitiesPLC->AddShaderParameter("view", Gal::Type::Mat4); + entitiesPLC->AddShaderParameter("projection", 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::Line); + auto entitiesPosBB = entitiesPLC->BindVertexBuffer({ + {"position", Gal::Type::Vec3}, + }); + auto entitiesUvBB = entitiesPLC->BindVertexBuffer({ + {"uvPosition", Gal::Type::Vec2}, + }); + + entitiesPipeline = gal->BuildPipeline(entitiesPLC); + + constexpr float 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 + }; + + constexpr float uvs[] = { + //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, + }; + + entitiesPosBuffer = gal->CreateBuffer(); + entitiesPosBuffer->SetData({ reinterpret_cast(vertices), reinterpret_cast(vertices + sizeof(vertices)) }); + entitiesUvBuffer = gal->CreateBuffer(); + entitiesUvBuffer->SetData({ reinterpret_cast(uvs), reinterpret_cast(uvs + sizeof(uvs)) }); + + entitiesPipelineInstance = entitiesPipeline->CreateInstance({ + {entitiesPosBB, entitiesPosBuffer}, + {entitiesUvBB, entitiesUvBuffer}, + }); + } TextureCoord sunTexture = AssetManager::GetTexture("/minecraft/textures/environment/sun"); TextureCoord moonTexture = AssetManager::GetTexture("/minecraft/textures/environment/moon_phases"); diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index c0af0dc..80eadb3 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -48,6 +48,9 @@ class RendererWorld { std::shared_ptr sectionsBufferBinding; //Entities std::vector entities; + std::shared_ptr entitiesPipeline; + std::shared_ptr entitiesPipelineInstance; + std::shared_ptr entitiesPosBuffer, entitiesUvBuffer; //Sky Texture *skyTexture; RendererSky rendererSky; -- cgit v1.2.3 From da9cff10a320b2ee144cb34a281a116f1d2f49cf Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Wed, 17 Nov 2021 13:11:36 +0500 Subject: Optimized entities rendering --- cwd/assets/altcraft/shaders/entity.json | 3 +- cwd/assets/altcraft/shaders/frag/entity.fs | 11 +- cwd/assets/altcraft/shaders/vert/entity.vs | 17 +-- src/RendererWorld.cpp | 223 ++++++++++++++++++----------- src/RendererWorld.hpp | 2 +- 5 files changed, 154 insertions(+), 102 deletions(-) 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/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/src/RendererWorld.cpp b/src/RendererWorld.cpp index 03d575b..4bec197 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -293,14 +293,14 @@ void RendererWorld::Render(RenderState & renderState) { glm::mat4 projView = projection * view; //Render Entities + constexpr size_t entitiesVerticesCount = 240; entitiesPipeline->Activate(); - entitiesPipeline->SetShaderParameter("projection", projection); - entitiesPipeline->SetShaderParameter("view", view); + entitiesPipeline->SetShaderParameter("projView", projView); entitiesPipelineInstance->Activate(); for (auto& it : entities) { it.Render(entitiesPipeline, &GetGameState()->GetWorld()); - entitiesPipelineInstance->Render(0, 24); + entitiesPipelineInstance->Render(0, entitiesVerticesCount); } //Render selected block @@ -313,7 +313,7 @@ void RendererWorld::Render(RenderState & renderState) { model = glm::scale(model,glm::vec3(1.01f,1.01f,1.01f)); entitiesPipeline->SetShaderParameter("model", model); entitiesPipeline->SetShaderParameter("color", glm::vec3(0, 0, 0)); - entitiesPipelineInstance->Render(0, 24); + entitiesPipelineInstance->Render(0, entitiesVerticesCount); } } @@ -331,7 +331,7 @@ void RendererWorld::Render(RenderState & renderState) { entitiesPipeline->SetShaderParameter("color", glm::vec3(0.7f, 0.0f, 0.0f)); else entitiesPipeline->SetShaderParameter("color", glm::vec3(0.0f, 0.0f, 0.7f)); - entitiesPipelineInstance->Render(0, 24); + entitiesPipelineInstance->Render(0, entitiesVerticesCount); } } @@ -462,107 +462,164 @@ void RendererWorld::PrepareRender() { { auto entitiesPLC = gal->CreatePipelineConfig(); entitiesPLC->SetTarget(gal->GetDefaultFramebuffer()); - entitiesPLC->AddShaderParameter("view", Gal::Type::Mat4); - entitiesPLC->AddShaderParameter("projection", Gal::Type::Mat4); + 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::Line); + entitiesPLC->SetPrimitive(Gal::Primitive::Triangle); auto entitiesPosBB = entitiesPLC->BindVertexBuffer({ {"position", Gal::Type::Vec3}, }); - auto entitiesUvBB = entitiesPLC->BindVertexBuffer({ - {"uvPosition", Gal::Type::Vec2}, - }); + auto entitiesIndicesBB = entitiesPLC->BindIndexBuffer(); entitiesPipeline = gal->BuildPipeline(entitiesPLC); + constexpr float lw = 0.485f; // line width + constexpr float 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.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, 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 float uvs[] = { - //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, + 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(vertices), reinterpret_cast(vertices + sizeof(vertices)) }); - entitiesUvBuffer = gal->CreateBuffer(); - entitiesUvBuffer->SetData({ reinterpret_cast(uvs), reinterpret_cast(uvs + sizeof(uvs)) }); + entitiesPosBuffer->SetData({ reinterpret_cast(vertices), reinterpret_cast(vertices) + sizeof(vertices) }); + entitiesIndexBuffer = gal->CreateBuffer(); + entitiesIndexBuffer->SetData({ reinterpret_cast(indices), reinterpret_cast(indices) + sizeof(indices) }); entitiesPipelineInstance = entitiesPipeline->CreateInstance({ {entitiesPosBB, entitiesPosBuffer}, - {entitiesUvBB, entitiesUvBuffer}, + {entitiesIndicesBB, entitiesIndexBuffer} }); } diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index 80eadb3..f26abda 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -50,7 +50,7 @@ class RendererWorld { std::vector entities; std::shared_ptr entitiesPipeline; std::shared_ptr entitiesPipelineInstance; - std::shared_ptr entitiesPosBuffer, entitiesUvBuffer; + std::shared_ptr entitiesPosBuffer, entitiesIndexBuffer; //Sky Texture *skyTexture; RendererSky rendererSky; -- cgit v1.2.3 From 8ab6abaae252050bf0ee03cd2a988c0e4e502718 Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Fri, 19 Nov 2021 11:48:37 +0500 Subject: Changed sky rendering to Gal --- cwd/assets/altcraft/shaders/frag/sky.fs | 23 ++-- cwd/assets/altcraft/shaders/sky.json | 3 +- cwd/assets/altcraft/shaders/vert/sky.vs | 18 ++- src/RendererSky.cpp | 144 ------------------------ src/RendererSky.hpp | 13 --- src/RendererWorld.cpp | 192 +++++++++++++++++++++++--------- src/RendererWorld.hpp | 34 +++--- 7 files changed, 173 insertions(+), 254 deletions(-) delete mode 100644 src/RendererSky.cpp delete mode 100644 src/RendererSky.hpp 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/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/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 - -#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 - -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 4bec197..cadad3f 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -337,51 +337,48 @@ void RendererWorld::Render(RenderState & renderState) { //Render sky renderState.TimeOfDay = GetGameState()->GetTimeStatus().timeOfDay; - Shader *skyShader = AssetManager::GetAsset("/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); - } - skyShader->SetUniform("DayTime", mixLevel); + 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); + } + + 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); @@ -433,6 +430,15 @@ void RendererWorld::PrepareRender() { 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(); @@ -623,18 +629,94 @@ void RendererWorld::PrepareRender() { }); } - 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("/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); + { + auto skyPPC = gal->CreatePipelineConfig(); + skyPPC->SetTarget(gal->GetDefaultFramebuffer()); + skyPPC->AddShaderParameter("textureAtlas", Gal::Type::Int32); + skyPPC->AddShaderParameter("sunTexture", Gal::Type::Vec4); + skyPPC->AddShaderParameter("sunTextureLayer", Gal::Type::Float); + skyPPC->AddShaderParameter("moonTexture", Gal::Type::Vec4); + 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->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("textureAtlas", 0); + skyPipeline->SetShaderParameter("sunTexture", glm::vec4(sunTexture.x, sunTexture.y, sunTexture.w, sunTexture.h)); + skyPipeline->SetShaderParameter("sunTextureLayer", static_cast(sunTexture.layer)); + skyPipeline->SetShaderParameter("moonTexture", glm::vec4(moonTexture.x, moonTexture.y, moonTexture.w, moonTexture.h)); + skyPipeline->SetShaderParameter("moonTextureLayer", static_cast(moonTexture.layer)); + + skyBuffer = gal->CreateBuffer(); + skyBuffer->SetData({ reinterpret_cast(vertices), reinterpret_cast(vertices) + sizeof(vertices) }); + + skyPipelineInstance = skyPipeline->CreateInstance({ + {skyPosUvBB, skyBuffer} + }); + } } void RendererWorld::Update(double timeToUpdate) { diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index f26abda..706af68 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 listener; @@ -33,17 +32,17 @@ class RendererWorld { std::vector workers; void WorkerFunction(size_t WorkerId); bool isRunning = true; - const static size_t parsingBufferSize = 64; - SectionParsing parsing[parsingBufferSize]; - std::queue parseQueue; - bool parseQueueNeedRemoveUnnecessary = false; - void ParseQueueUpdate(); - void ParseQeueueRemoveUnnecessary(); + const static size_t parsingBufferSize = 64; + SectionParsing parsing[parsingBufferSize]; + std::queue parseQueue; + bool parseQueueNeedRemoveUnnecessary = false; + void ParseQueueUpdate(); + void ParseQeueueRemoveUnnecessary(); //Blocks std::vector renderList; std::map sections; void UpdateAllSections(VectorF playerPos); - std::chrono::time_point globalTimeStart; + std::chrono::time_point globalTimeStart; std::shared_ptr sectionsPipeline; std::shared_ptr sectionsBufferBinding; //Entities @@ -52,11 +51,12 @@ class RendererWorld { std::shared_ptr entitiesPipelineInstance; std::shared_ptr entitiesPosBuffer, entitiesIndexBuffer; //Sky - Texture *skyTexture; - RendererSky rendererSky; + std::shared_ptr skyPipeline; + std::shared_ptr skyPipelineInstance; + std::shared_ptr skyBuffer; public: - RendererWorld(); - ~RendererWorld(); + RendererWorld(); + ~RendererWorld(); void Render(RenderState& renderState); void PrepareRender(); -- cgit v1.2.3 From b99f058de08063cb1632a9ef35e4edb10097f31b Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Fri, 19 Nov 2021 15:02:11 +0500 Subject: Changed TextureAtlas to Gal --- src/AssetManager.cpp | 4 +- src/AssetManager.hpp | 4 +- src/Gal.hpp | 4 ++ src/GalOgl.cpp | 127 +++++++++++++++++++++++++++++++++++++++++++------- src/Render.cpp | 6 +-- src/RendererWorld.cpp | 6 +-- src/TextureAtlas.cpp | 34 +++++++------- src/TextureAtlas.hpp | 10 ++-- src/Utility.cpp | 34 -------------- src/Utility.hpp | 6 +-- 10 files changed, 141 insertions(+), 94 deletions(-) diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 9cbb6df..1a7e523 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -690,9 +690,9 @@ AssetTreeNode *AssetManager::GetAssetByAssetName(const std::string & assetName) return node; } -GLuint AssetManager::GetTextureAtlasId() +std::shared_ptr AssetManager::GetTextureAtlas() { - return atlas->GetRawTextureId(); + return atlas->GetGalTexture(); } TextureCoord AssetManager::GetTexture(const std::string assetName) { diff --git a/src/AssetManager.hpp b/src/AssetManager.hpp index 7f6c4fb..6fe2eab 100644 --- a/src/AssetManager.hpp +++ b/src/AssetManager.hpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -15,6 +14,7 @@ #include "Block.hpp" #include "TextureAtlas.hpp" #include "Shader.hpp" +#include "Gal.hpp" enum FaceDirection { down, @@ -189,7 +189,7 @@ namespace AssetManager { AssetTreeNode *GetAssetByAssetName(const std::string &assetName); - GLuint GetTextureAtlasId(); + std::shared_ptr GetTextureAtlas(); TextureCoord GetTexture(const std::string assetName); }; diff --git a/src/Gal.hpp b/src/Gal.hpp index 51d3bd6..82ede78 100644 --- a/src/Gal.hpp +++ b/src/Gal.hpp @@ -161,6 +161,8 @@ namespace Gal { virtual ~Texture() = default; virtual void SetData(std::vector&& 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 &&data, size_t mipLevel = 0) = 0; }; struct PipelineConfig { @@ -172,6 +174,8 @@ namespace Gal { virtual void AddShaderParameter(std::string_view name, Type type) = 0; + virtual void AddStaticTexture(std::string_view name, std::shared_ptr texture) = 0; + virtual void SetTarget(std::shared_ptr target) = 0; virtual void SetPrimitive(Primitive primitive) = 0; diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index 5643b4d..7ee6cf3 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "Utility.hpp" @@ -234,6 +235,41 @@ GLenum GalWrappingGetGlType(Wrapping wrapping) { return 0; } +GLenum glCheckError_(const char* file, int line) { + OPTICK_EVENT(); + GLenum errorCode; + while ((errorCode = glGetError()) != GL_NO_ERROR) { + std::string error; + switch (errorCode) { + case GL_INVALID_ENUM: + error = "INVALID_ENUM"; + break; + case GL_INVALID_VALUE: + error = "INVALID_VALUE"; + break; + case GL_INVALID_OPERATION: + error = "INVALID_OPERATION"; + break; + case GL_STACK_OVERFLOW: + error = "STACK_OVERFLOW"; + break; + case GL_STACK_UNDERFLOW: + error = "STACK_UNDERFLOW"; + break; + case GL_OUT_OF_MEMORY: + error = "OUT_OF_MEMORY"; + break; + case GL_INVALID_FRAMEBUFFER_OPERATION: + error = "INVALID_FRAMEBUFFER_OPERATION"; + break; + } + static int t = 0; + LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line; + } + return errorCode; +} +#define glCheckError() glCheckError_(__FILE__, __LINE__) + class ShaderOgl : public Shader { public: @@ -268,6 +304,7 @@ public: Format format; size_t width = 1, height = 1, depth = 1; bool interpolateLayers = false; + GLenum type; Filtering min = Filtering::Nearest, max = Filtering::Nearest; Wrapping wrap = Wrapping::Clamp; @@ -334,11 +371,51 @@ public: glBindTexture(type, 0); } + virtual void SetSubData(size_t x, size_t y, size_t z, size_t width, size_t height, size_t depth, std::vector&& data, size_t mipLevel = 0) override { + size_t expectedSize = width * height * depth * GalFormatGetSize(format); + if (data.size() != expectedSize) + throw std::logic_error("Size of data is not valid for this texture"); + + glBindTexture(type, texture); + glCheckError(); + + switch (type) { + case GL_TEXTURE_2D: + case GL_PROXY_TEXTURE_2D: + case GL_TEXTURE_1D_ARRAY: + case GL_PROXY_TEXTURE_1D_ARRAY: + case GL_TEXTURE_RECTANGLE: + case GL_PROXY_TEXTURE_RECTANGLE: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + case GL_PROXY_TEXTURE_CUBE_MAP: + glTexSubImage2D(type, mipLevel, x, y, width, height, GalFormatGetGlFormat(format), GalFormatGetGlType(format), data.data()); + break; + case GL_TEXTURE_3D: + case GL_PROXY_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + case GL_PROXY_TEXTURE_2D_ARRAY: + glTexSubImage3D(type, mipLevel, x, y, z, width, height, depth, GalFormatGetGlFormat(format), GalFormatGetGlType(format), data.data()); + break; + default: + throw std::runtime_error("Unknown texture type"); + } + + glCheckError(); + + glBindTexture(type, 0); + } + }; class PipelineConfigOgl : public PipelineConfig { public: std::shared_ptr vertexShader, pixelShader; + std::map> textures; std::map shaderParameters; std::shared_ptr targetFb; std::vector> vertexBuffers; @@ -356,6 +433,11 @@ public: shaderParameters.emplace(std::string(name), type); } + virtual void AddStaticTexture(std::string_view name, std::shared_ptr texture) override { + auto tex = std::static_pointer_cast(texture); + textures.emplace(std::string(name), tex); + } + virtual void SetTarget(std::shared_ptr target) override { targetFb = target; } @@ -436,6 +518,7 @@ public: class PipelineOgl : public Pipeline { public: std::map shaderParameters; + std::vector> staticTextures; GLuint program; struct VertexBindingCommand { size_t bufferId; @@ -451,15 +534,21 @@ public: virtual void Activate() override { glUseProgram(program); + + for (size_t i = 0; i < staticTextures.size(); i++) { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(staticTextures[i]->type, staticTextures[i]->texture); + } + glCheckError(); } virtual void SetDynamicTexture(std::string_view name, std::shared_ptr texture) override { Activate(); - glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0 + staticTextures.size()); auto tex = std::static_pointer_cast(texture); glBindTexture(tex->type, tex->texture); - SetShaderParameter(name, 0); + SetShaderParameter(name, static_cast(staticTextures.size())); } virtual std::shared_ptr CreateInstance(std::vector, std::shared_ptr>>&& buffers) override { @@ -665,6 +754,7 @@ public: virtual std::shared_ptr CreateTexture2DConfig(size_t width, size_t height, Format format) override { auto config = std::make_shared(); + config->type = GL_TEXTURE_2D; config->width = width; config->height = height; config->depth = 1; @@ -676,6 +766,7 @@ public: virtual std::shared_ptr CreateTexture3DConfig(size_t width, size_t height, size_t depth, bool interpolateLayers, Format format) override { auto config = std::make_shared(); + config->type = interpolateLayers ? GL_TEXTURE_3D : GL_TEXTURE_2D_ARRAY; config->width = width; config->height = height; config->depth = depth; @@ -689,7 +780,7 @@ public: auto texConfig = std::static_pointer_cast(config); auto texture = std::make_shared(); - texture->type = GL_TEXTURE_2D; + texture->type = texConfig->type; texture->format = texConfig->format; texture->width = texConfig->width; texture->height = texConfig->height; @@ -789,26 +880,26 @@ public: for (auto&& [name, type] : config->shaderParameters) { GLint location = glGetUniformLocation(program, name.c_str()); if (location < 0) { - glDeleteProgram(program); LOG(ERROR) << "Uniform name \"" << name << "\" not found in shader"; - throw std::runtime_error("Invalid uniform"); - } - switch (type) { - case Type::Vec2: - glUniform2f(location, 0.0f, 0.0f); - break; - case Type::Vec2u8: - case Type::Vec2u16: - case Type::Vec2u32: - glUniform2ui(location, 0, 0); - break; - case Type::Vec4u8: - glUniform4ui(location, 0, 0, 0, 0); - break; } pipeline->shaderParameters.insert({ name,location }); } + glCheckError(); + + //Static textures + + size_t usedTextureBlocks = 0; + for (auto&& [name, texture] : config->textures) { + GLint location = glGetUniformLocation(program, name.c_str()); + if (location < 0) { + LOG(ERROR) << "Texture uniform name \"" << name << "\" not found in shader"; + } + + glUniform1i(location, usedTextureBlocks); + pipeline->staticTextures.push_back(texture); + } + //Vertex attributes size_t bufferId = 0; diff --git a/src/Render.cpp b/src/Render.cpp index 8b78efb..74582a1 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -127,11 +127,7 @@ void Render::InitGlew() { } void Render::PrepareToRendering() { - //TextureAtlas texture - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D_ARRAY, AssetManager::GetTextureAtlasId()); - - int width, height; + int width, height; SDL_GL_GetDrawableSize(window, &width, &height); framebuffer = std::make_unique(width, height, true); Framebuffer::GetDefault().Activate(); diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index cadad3f..5970160 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -447,7 +447,7 @@ void RendererWorld::PrepareRender() { sectionsPLC->AddShaderParameter("DayTime", Gal::Type::Float); sectionsPLC->AddShaderParameter("GlobalTime", Gal::Type::Float); sectionsPLC->AddShaderParameter("MinLightLevel", Gal::Type::Float); - sectionsPLC->AddShaderParameter("textureAtlas", Gal::Type::Int32); + sectionsPLC->AddStaticTexture("textureAtlas", AssetManager::GetTextureAtlas()); sectionsPLC->SetVertexShader(gal->LoadVertexShader(sectionVertexSource)); sectionsPLC->SetPixelShader(gal->LoadPixelShader(sectionPixelSource)); sectionsPLC->SetPrimitive(Gal::Primitive::TriangleFan); @@ -462,7 +462,6 @@ void RendererWorld::PrepareRender() { }); sectionsPipeline = gal->BuildPipeline(sectionsPLC); sectionsPipeline->SetShaderParameter("MinLightLevel", 0.2f); - sectionsPipeline->SetShaderParameter("textureAtlas", 0); } { @@ -632,7 +631,6 @@ void RendererWorld::PrepareRender() { { auto skyPPC = gal->CreatePipelineConfig(); skyPPC->SetTarget(gal->GetDefaultFramebuffer()); - skyPPC->AddShaderParameter("textureAtlas", Gal::Type::Int32); skyPPC->AddShaderParameter("sunTexture", Gal::Type::Vec4); skyPPC->AddShaderParameter("sunTextureLayer", Gal::Type::Float); skyPPC->AddShaderParameter("moonTexture", Gal::Type::Vec4); @@ -640,6 +638,7 @@ void RendererWorld::PrepareRender() { skyPPC->AddShaderParameter("DayTime", Gal::Type::Float); skyPPC->AddShaderParameter("projView", Gal::Type::Mat4); skyPPC->AddShaderParameter("model", Gal::Type::Mat4); + skyPPC->AddStaticTexture("textureAtlas", AssetManager::GetTextureAtlas()); skyPPC->SetVertexShader(gal->LoadVertexShader(skyVertexSource)); skyPPC->SetPixelShader(gal->LoadPixelShader(skyPixelSource)); auto skyPosUvBB = skyPPC->BindVertexBuffer({ @@ -704,7 +703,6 @@ void RendererWorld::PrepareRender() { skyPipeline = gal->BuildPipeline(skyPPC); skyPipeline->Activate(); - skyPipeline->SetShaderParameter("textureAtlas", 0); skyPipeline->SetShaderParameter("sunTexture", glm::vec4(sunTexture.x, sunTexture.y, sunTexture.w, sunTexture.h)); skyPipeline->SetShaderParameter("sunTextureLayer", static_cast(sunTexture.layer)); skyPipeline->SetShaderParameter("moonTexture", glm::vec4(moonTexture.x, moonTexture.y, moonTexture.w, moonTexture.h)); diff --git a/src/TextureAtlas.cpp b/src/TextureAtlas.cpp index 406418f..7e44a86 100644 --- a/src/TextureAtlas.cpp +++ b/src/TextureAtlas.cpp @@ -35,7 +35,7 @@ TextureAtlas::TextureAtlas(std::vector &textures) { textureCoords.resize(textures.size()); - int layer = 0; + size_t layer = 0; for (;;layer++) { stbrp_context context; std::vector nodes; @@ -81,18 +81,16 @@ TextureAtlas::TextureAtlas(std::vector &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 &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(textures[i].data.data()), reinterpret_cast(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 -#include +#include "Gal.hpp" struct TextureData { std::vector data; //expected format RGBA8888 @@ -16,16 +16,12 @@ struct TextureCoord { }; class TextureAtlas { - GLuint texture; + std::shared_ptr texture; std::vector textureCoords; public: TextureAtlas(std::vector &textures); - TextureAtlas(const TextureAtlas &) = delete; - - ~TextureAtlas(); - - inline GLuint GetRawTextureId() { + std::shared_ptr 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 #include -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 #include -#include - using Uuid = std::vector; template @@ -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 ; -- cgit v1.2.3 From b837000b88e34cf297380c99ea608a1517fdf26d Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Sat, 20 Nov 2021 00:09:45 +0500 Subject: Added framebuffer to Gal --- src/Gal.hpp | 5 ++ src/GalOgl.cpp | 128 +++++++++++++++++++++++++++++++++++++------------- src/Render.cpp | 121 ++++++++++++++++++++++++++++++++++------------- src/Render.hpp | 25 ++++++---- src/RendererWorld.cpp | 12 ++--- src/RendererWorld.hpp | 4 +- 6 files changed, 212 insertions(+), 83 deletions(-) diff --git a/src/Gal.hpp b/src/Gal.hpp index 82ede78..f448c89 100644 --- a/src/Gal.hpp +++ b/src/Gal.hpp @@ -60,6 +60,7 @@ namespace Gal { }; enum class Format { + D24S8, R8G8B8, R8G8B8A8, }; @@ -241,6 +242,10 @@ namespace Gal { struct FramebufferConfig { virtual ~FramebufferConfig() = default; + + virtual void SetDepthStencil(std::shared_ptr texture) = 0; + + virtual void SetTexture(size_t location, std::shared_ptr texture) = 0; }; struct ShaderParameters { diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index 7ee6cf3..74e1f33 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -10,11 +10,11 @@ using namespace Gal; class ImplOgl; -class FramebufferDefaultOgl; class ShaderOgl; +class FramebufferOgl; std::unique_ptr impl; -std::shared_ptr fbDefault; +std::shared_ptr fbDefault; size_t GalTypeGetComponents(Gal::Type type) { switch (type) { @@ -171,6 +171,8 @@ size_t GalFormatGetSize(Format format) { GLenum GalFormatGetGlInternalFormat(Format format) { switch (format) { + case Format::D24S8: + return GL_DEPTH24_STENCIL8; case Format::R8G8B8: return GL_RGB8; case Format::R8G8B8A8: @@ -183,6 +185,8 @@ GLenum GalFormatGetGlInternalFormat(Format format) { GLenum GalFormatGetGlFormat(Format format) { switch (format) { + case Format::D24S8: + return GL_DEPTH_STENCIL; case Format::R8G8B8: return GL_RGB; case Format::R8G8B8A8: @@ -195,6 +199,8 @@ GLenum GalFormatGetGlFormat(Format format) { 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: @@ -334,7 +340,7 @@ public: virtual void SetData(std::vector&& data, size_t mipLevel = 0) override { size_t expectedSize = width * height * depth * GalFormatGetSize(format); - if (data.size() != expectedSize) + if (data.size() != expectedSize && !data.empty()) throw std::logic_error("Size of data is not valid for this texture"); glBindTexture(type, texture); @@ -354,13 +360,13 @@ public: 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()); + 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.data()); + 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"); @@ -412,12 +418,53 @@ public: }; +class FramebufferOgl : public Framebuffer { +public: + size_t vpX = 0, vpY = 0, vpW = 1, vpH = 1; + std::shared_ptr depthStencil; + std::vector> colors; + + GLuint fbo = 0; + + virtual void Clear() override { + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + 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; + } +}; + +class FramebufferConfigOgl : public FramebufferConfig { +public: + std::shared_ptr depthStencil; + std::map> colors; + + virtual void SetDepthStencil(std::shared_ptr texture) override { + auto tex = std::static_pointer_cast(texture); + depthStencil = tex; + } + + virtual void SetTexture(size_t location, std::shared_ptr texture) override { + auto tex = std::static_pointer_cast(texture); + colors.emplace(location, tex); + } +}; + class PipelineConfigOgl : public PipelineConfig { public: std::shared_ptr vertexShader, pixelShader; std::map> textures; std::map shaderParameters; - std::shared_ptr targetFb; + std::shared_ptr targetFb; std::vector> vertexBuffers; Primitive vertexPrimitive = Primitive::Triangle; public: @@ -439,7 +486,8 @@ public: } virtual void SetTarget(std::shared_ptr target) override { - targetFb = target; + auto fb = std::static_pointer_cast(target); + targetFb = fb; } virtual void SetPrimitive(Primitive primitive) override { @@ -531,10 +579,14 @@ public: }; std::vector vertexBindCmds; Primitive primitive; + std::shared_ptr target; virtual void Activate() override { glUseProgram(program); + glBindFramebuffer(GL_FRAMEBUFFER, target->fbo); + glViewport(target->vpX, target->vpY, target->vpW, target->vpH); + for (size_t i = 0; i < staticTextures.size(); i++) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(staticTextures[i]->type, staticTextures[i]->texture); @@ -815,6 +867,10 @@ public: pipeline->primitive = config->vertexPrimitive; + pipeline->target = config->targetFb; + if (!pipeline->target) + pipeline->target = std::static_pointer_cast(GetDefaultFramebuffer()); + //Shader compilation bool vertexFailed = false, pixelFailed = false, linkFailed = false; @@ -900,6 +956,8 @@ public: pipeline->staticTextures.push_back(texture); } + glCheckError(); + //Vertex attributes size_t bufferId = 0; @@ -946,17 +1004,44 @@ public: } virtual std::shared_ptr CreateFramebufferConfig() override { - return nullptr; + auto config = std::make_shared(); + return std::static_pointer_cast(config); } virtual std::shared_ptr BuildFramebuffer(std::shared_ptr config) override { - return nullptr; + auto conf = std::static_pointer_cast(config); + auto fb = std::make_shared(); + + glGenFramebuffers(1, &fb->fbo); + + glBindFramebuffer(GL_FRAMEBUFFER, 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); + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glCheckError(); + + return std::static_pointer_cast(fb); } virtual std::shared_ptr GetDefaultFramebuffer() override { if (!fbDefault) - fbDefault = std::make_shared(); - return std::static_pointer_cast(fbDefault); + fbDefault = std::make_shared(); + fbDefault->fbo = 0; + return std::static_pointer_cast(fbDefault); } @@ -979,27 +1064,6 @@ public: } }; -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) diff --git a/src/Render.cpp b/src/Render.cpp index 74582a1..e6eb673 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -6,7 +6,6 @@ #include #include -#include "Shader.hpp" #include "AssetManager.hpp" #include "Event.hpp" #include "DebugInfo.hpp" @@ -15,7 +14,6 @@ #include "GameState.hpp" #include "RendererWorld.hpp" #include "Settings.hpp" -#include "Framebuffer.hpp" #include "Plugin.hpp" #include "Rml.hpp" #include "Gal.hpp" @@ -93,7 +91,7 @@ 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); @@ -124,14 +122,76 @@ void Render::InitGlew() { 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); - framebuffer = std::make_unique(width, height, true); - Framebuffer::GetDefault().Activate(); - Framebuffer::GetDefault().Resize(width, height); + SDL_GL_GetDrawableSize(window, &width, &height); + + float resolutionScale = Settings::ReadDouble("resolutionScale", 1.0f); + size_t scaledW = width * resolutionScale, scaledH = height * resolutionScale; + + 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()); + } + + 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(quadVertices), reinterpret_cast(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() { @@ -153,30 +213,30 @@ void Render::UpdateKeyboard() { } void Render::RenderFrame() { - OPTICK_EVENT(); - //framebuffer->Clear(); - Framebuffer::GetDefault().Clear(); + OPTICK_EVENT(); + + Gal::GetImplementation()->GetDefaultFramebuffer()->Clear(); + framebuffer->Clear(); - //if (renderWorld) - // framebuffer->Activate(); - if (isWireframe) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + //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 (isWireframe) + //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - RenderGui(); + fbPipeline->Activate(); + fbPipelineInstance->Activate(); + fbPipelineInstance->Render(0, 6); - if (world) { - world->Update(GetTime()->RemainTimeMs()); - } + RenderGui(); + + if (world) { + world->Update(GetTime()->RemainTimeMs()); + } - - OPTICK_EVENT("VSYNC"); - SDL_GL_SwapWindow(window); + OPTICK_EVENT("VSYNC"); + SDL_GL_SwapWindow(window); } void Render::HandleEvents() { @@ -201,9 +261,7 @@ void Render::HandleEvents() { renderState.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; } @@ -424,7 +482,7 @@ void Render::InitEvents() { listener.RegisterHandler("PlayerConnected", [this](const Event&) { stateString = "Loading terrain..."; - world = std::make_unique(); + world = std::make_unique(framebuffer); world->MaxRenderingDistance = Settings::ReadDouble("renderDistance", 2.0f); PUSH_EVENT("UpdateSectionsRender", 0); }); @@ -534,10 +592,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(); }); } diff --git a/src/Render.hpp b/src/Render.hpp index 9a9feee..cf9b9f9 100644 --- a/src/Render.hpp +++ b/src/Render.hpp @@ -10,9 +10,9 @@ #include "Utility.hpp" #include "Renderer.hpp" #include "Event.hpp" +#include "Gal.hpp" class RendererWorld; -class Framebuffer; class RmlRenderInterface; class RmlSystemInterface; class RmlFileInterface; @@ -35,16 +35,21 @@ class Render { std::map isKeyPressed; bool HasFocus=true; float sensetivity = 0.1f; - bool isWireframe = false; - std::unique_ptr framebuffer; - EventListener listener; + bool isWireframe = false; + std::shared_ptr framebuffer; + std::shared_ptr fbDepthStencil; + std::shared_ptr fbColor; + std::shared_ptr fbPipeline; + std::shared_ptr fbPipelineInstance; + std::shared_ptr fbBuffer; + EventListener listener; std::string stateString; - std::unique_ptr rmlRender; - std::unique_ptr rmlSystem; - std::unique_ptr rmlFile; - Rml::Context* rmlContext; - unsigned short sdlKeyMods = 0; - bool hideRml = false; + std::unique_ptr rmlRender; + std::unique_ptr rmlSystem; + std::unique_ptr rmlFile; + Rml::Context* rmlContext; + unsigned short sdlKeyMods = 0; + bool hideRml = false; void SetMouseCapture(bool IsCaptured); diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp index 5970160..e4a1589 100644 --- a/src/RendererWorld.cpp +++ b/src/RendererWorld.cpp @@ -153,7 +153,7 @@ void RendererWorld::UpdateAllSections(VectorF playerPos) { } } -RendererWorld::RendererWorld() { +RendererWorld::RendererWorld(std::shared_ptr target) { OPTICK_EVENT(); MaxRenderingDistance = 2; numOfWorkers = _max(1, (signed int) std::thread::hardware_concurrency() - 2); @@ -162,7 +162,7 @@ RendererWorld::RendererWorld() { globalTimeStart = std::chrono::high_resolution_clock::now(); - PrepareRender(); + PrepareRender(target); listener->RegisterHandler("DeleteSectionRender", [this](const Event& eventData) { OPTICK_EVENT("EV_DeleteSectionRender"); @@ -411,7 +411,7 @@ void RendererWorld::Render(RenderState & renderState) { DebugInfo::renderFaces = renderedFaces; } -void RendererWorld::PrepareRender() { +void RendererWorld::PrepareRender(std::shared_ptr target) { std::string sectionVertexSource, sectionPixelSource; { auto vertAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/vert/face"); @@ -442,7 +442,7 @@ void RendererWorld::PrepareRender() { auto gal = Gal::GetImplementation(); { auto sectionsPLC = gal->CreatePipelineConfig(); - sectionsPLC->SetTarget(gal->GetDefaultFramebuffer()); + sectionsPLC->SetTarget(target); sectionsPLC->AddShaderParameter("projView", Gal::Type::Mat4); sectionsPLC->AddShaderParameter("DayTime", Gal::Type::Float); sectionsPLC->AddShaderParameter("GlobalTime", Gal::Type::Float); @@ -466,7 +466,7 @@ void RendererWorld::PrepareRender() { { auto entitiesPLC = gal->CreatePipelineConfig(); - entitiesPLC->SetTarget(gal->GetDefaultFramebuffer()); + entitiesPLC->SetTarget(target); entitiesPLC->AddShaderParameter("projView", Gal::Type::Mat4); entitiesPLC->AddShaderParameter("model", Gal::Type::Mat4); entitiesPLC->AddShaderParameter("color", Gal::Type::Vec3); @@ -630,7 +630,7 @@ void RendererWorld::PrepareRender() { { auto skyPPC = gal->CreatePipelineConfig(); - skyPPC->SetTarget(gal->GetDefaultFramebuffer()); + skyPPC->SetTarget(target); skyPPC->AddShaderParameter("sunTexture", Gal::Type::Vec4); skyPPC->AddShaderParameter("sunTextureLayer", Gal::Type::Float); skyPPC->AddShaderParameter("moonTexture", Gal::Type::Vec4); diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index 706af68..91910a0 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -55,11 +55,11 @@ class RendererWorld { std::shared_ptr skyPipelineInstance; std::shared_ptr skyBuffer; public: - RendererWorld(); + RendererWorld(std::shared_ptr target); ~RendererWorld(); void Render(RenderState& renderState); - void PrepareRender(); + void PrepareRender(std::shared_ptr target); double MaxRenderingDistance; -- cgit v1.2.3 From 83c61036966c4c358a094cabe27c8de60082200d Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Sat, 20 Nov 2021 00:29:28 +0500 Subject: Removed every reference to OpenGL except GalOgl.cpp --- src/AssetManager.cpp | 27 ----------- src/AssetManager.hpp | 3 +- src/Framebuffer.cpp | 129 -------------------------------------------------- src/Framebuffer.hpp | 29 ------------ src/Render.cpp | 20 ++++---- src/Render.hpp | 3 +- src/Renderer.cpp | 16 ------- src/Renderer.hpp | 13 ----- src/RendererWorld.cpp | 11 ++--- src/RendererWorld.hpp | 2 +- src/Rml.cpp | 2 +- src/Rml.hpp | 3 +- src/Shader.cpp | 93 ------------------------------------ src/Shader.hpp | 60 ----------------------- 14 files changed, 17 insertions(+), 394 deletions(-) delete mode 100644 src/Framebuffer.cpp delete mode 100644 src/Framebuffer.hpp delete mode 100644 src/Renderer.cpp delete mode 100644 src/Renderer.hpp delete mode 100644 src/Shader.cpp delete mode 100644 src/Shader.hpp diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 1a7e523..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 fragPath = j["frag"].get(); - - 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 uniforms; - - for (auto& it : j["uniforms"]) { - uniforms.push_back(it.get()); - } - - node.asset = std::make_unique(); - AssetShader* asset = dynamic_cast(node.asset.get()); - asset->shader = std::make_unique(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) { diff --git a/src/AssetManager.hpp b/src/AssetManager.hpp index 6fe2eab..2bee47c 100644 --- a/src/AssetManager.hpp +++ b/src/AssetManager.hpp @@ -13,7 +13,6 @@ #include "Vector.hpp" #include "Block.hpp" #include "TextureAtlas.hpp" -#include "Shader.hpp" #include "Gal.hpp" enum FaceDirection { @@ -164,7 +163,7 @@ struct AssetTexture : Asset { }; struct AssetShader : Asset { - std::unique_ptr shader; + }; struct AssetScript : Asset { 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 -#include "Utility.hpp" -#include "AssetManager.hpp" -#include - -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("/altcraft/shaders/fbo")->shader->Activate(); - AssetManager::GetAsset("/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("/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(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 - -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/Render.cpp b/src/Render.cpp index e6eb673..b1277b2 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -109,8 +109,9 @@ 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); } @@ -221,7 +222,7 @@ void Render::RenderFrame() { //if (isWireframe) //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); if (renderWorld) - world->Render(renderState); + world->Render(static_cast(windowWidth) / static_cast(windowHeight)); //if (isWireframe) //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -257,8 +258,8 @@ 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)); PrepareToRendering(); @@ -491,7 +492,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)); }); @@ -501,7 +501,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 ()); }); @@ -510,7 +509,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()); }); @@ -602,9 +600,9 @@ void Render::InitRml() { rmlSystem = std::make_unique(); Rml::SetSystemInterface(rmlSystem.get()); - rmlRender = std::make_unique(renderState); + rmlRender = std::make_unique(); Rml::SetRenderInterface(rmlRender.get()); - rmlRender->Update(renderState.WindowWidth, renderState.WindowHeight); + rmlRender->Update(windowWidth, windowHeight); rmlFile = std::make_unique(); Rml::SetFileInterface(rmlFile.get()); @@ -614,7 +612,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 cf9b9f9..87494fa 100644 --- a/src/Render.hpp +++ b/src/Render.hpp @@ -8,7 +8,6 @@ #include #include "Utility.hpp" -#include "Renderer.hpp" #include "Event.hpp" #include "Gal.hpp" @@ -31,7 +30,7 @@ class Render { float mouseXDelta, mouseYDelta; std::unique_ptr world; bool renderWorld = false; - RenderState renderState; + size_t windowWidth, windowHeight; std::map isKeyPressed; bool HasFocus=true; float sensetivity = 0.1f; 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 - -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 - -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/RendererWorld.cpp b/src/RendererWorld.cpp index e4a1589..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" @@ -259,8 +257,7 @@ RendererWorld::RendererWorld(std::shared_ptr target) { listener->RegisterHandler("SetMinLightLevel", [this](const Event& eventData) { auto value = eventData.get(); - AssetManager::GetAsset("/altcraft/shaders/face")->shader->Activate(); - AssetManager::GetAsset("/altcraft/shaders/face")->shader->SetUniform("MinLightLevel", value); + sectionsPipeline->SetShaderParameter("MinLightLevel", value); }); for (int i = 0; i < numOfWorkers; i++) @@ -282,11 +279,11 @@ 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(); @@ -336,8 +333,6 @@ void RendererWorld::Render(RenderState & renderState) { } //Render sky - renderState.TimeOfDay = GetGameState()->GetTimeStatus().timeOfDay; - glm::mat4 model = glm::mat4(1.0); model = glm::translate(model, GetGameState()->GetPlayer()->pos.glm()); const float scale = 1000000.0f; diff --git a/src/RendererWorld.hpp b/src/RendererWorld.hpp index 91910a0..e645b30 100644 --- a/src/RendererWorld.hpp +++ b/src/RendererWorld.hpp @@ -58,7 +58,7 @@ public: RendererWorld(std::shared_ptr target); ~RendererWorld(); - void Render(RenderState& renderState); + void Render(float screenRatio); void PrepareRender(std::shared_ptr target); double MaxRenderingDistance; diff --git a/src/Rml.cpp b/src/Rml.cpp index d886377..fa2d4e7 100644 --- a/src/Rml.cpp +++ b/src/Rml.cpp @@ -44,7 +44,7 @@ void RmlSystemInterface::GetClipboardText(Rml::String& text) { text = clipboard; } -RmlRenderInterface::RmlRenderInterface(RenderState& renderState) { +RmlRenderInterface::RmlRenderInterface() { std::string vertexSource, pixelSource, texPixelSource; { auto vertAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/vert/rml"); diff --git a/src/Rml.hpp b/src/Rml.hpp index 9aa6be0..2e3a672 100644 --- a/src/Rml.hpp +++ b/src/Rml.hpp @@ -6,7 +6,6 @@ #include #include -#include "Renderer.hpp" #include "Gal.hpp" class AssetTreeNode; @@ -39,7 +38,7 @@ class RmlRenderInterface : public Rml::RenderInterface { 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 -#include - -#include - - -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 &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 -#include -#include - -#include -#include -#include - -class Shader { - std::map 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 &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 -- cgit v1.2.3 From 993b5d90f05d61552d7fb1cf9b9e9944314af1bc Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Sat, 20 Nov 2021 02:00:09 +0500 Subject: Fixed GalOgl resource leaking --- src/GalOgl.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 114 insertions(+), 39 deletions(-) diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index 74e1f33..68ad96e 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -7,6 +7,72 @@ #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() { + return; + 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; @@ -269,7 +335,6 @@ GLenum glCheckError_(const char* file, int line) { error = "INVALID_FRAMEBUFFER_OPERATION"; break; } - static int t = 0; LOG(ERROR) << "OpenGL error: " << error << " at " << file << ":" << line; } return errorCode; @@ -277,24 +342,26 @@ GLenum glCheckError_(const char* file, int line) { #define glCheckError() glCheckError_(__FILE__, __LINE__) -class ShaderOgl : public Shader { -public: +struct ShaderOgl : public Shader { + bool isVertex = true; std::string code; + }; -class BufferBindingOgl : public BufferBinding { -public: +struct BufferBindingOgl : public BufferBinding { + BufferBindingOgl(size_t id) : bufferId(id) {} const size_t bufferId; static constexpr size_t indexValue = (std::numeric_limits::max)(); //parenthess for windows' max macro + }; -class BufferOgl : public Buffer { -public: - GLuint vbo; +struct BufferOgl : public Buffer { + + GlResource vbo; virtual void SetData(std::vector&& data) override { glBindBuffer(GL_ARRAY_BUFFER, vbo); @@ -302,10 +369,10 @@ public: glBindBuffer(GL_ARRAY_BUFFER, 0); glCheckError(); } + }; -class TextureConfigOgl : public TextureConfig { -public: +struct TextureConfigOgl : public TextureConfig { Format format; size_t width = 1, height = 1, depth = 1; @@ -314,7 +381,6 @@ public: Filtering min = Filtering::Nearest, max = Filtering::Nearest; Wrapping wrap = Wrapping::Clamp; - virtual void SetMinFilter(Filtering filter) override { min = filter; @@ -330,11 +396,10 @@ public: }; -class TextureOgl : public Texture { -public: +struct TextureOgl : public Texture { GLenum type; - GLuint texture; + GlResource texture; Format format; size_t width, height, depth; @@ -418,16 +483,16 @@ public: }; -class FramebufferOgl : public Framebuffer { -public: +struct FramebufferOgl : public Framebuffer { + size_t vpX = 0, vpY = 0, vpW = 1, vpH = 1; std::shared_ptr depthStencil; std::vector> colors; - GLuint fbo = 0; + GlResource fbo; virtual void Clear() override { - glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo ? fbo : 0); GLbitfield clearBits = 0; clearBits |= GL_COLOR_BUFFER_BIT; clearBits |= GL_DEPTH_BUFFER_BIT; @@ -441,10 +506,11 @@ public: vpW = w; vpH = h; } + }; -class FramebufferConfigOgl : public FramebufferConfig { -public: +struct FramebufferConfigOgl : public FramebufferConfig { + std::shared_ptr depthStencil; std::map> colors; @@ -459,15 +525,15 @@ public: } }; -class PipelineConfigOgl : public PipelineConfig { -public: +struct PipelineConfigOgl : public PipelineConfig { + std::shared_ptr vertexShader, pixelShader; std::map> textures; std::map shaderParameters; std::shared_ptr targetFb; std::vector> vertexBuffers; Primitive vertexPrimitive = Primitive::Triangle; -public: + virtual void SetVertexShader(std::shared_ptr shader) override { vertexShader = std::static_pointer_cast(shader); } @@ -504,12 +570,12 @@ public: auto binding = std::make_shared(BufferBindingOgl::indexValue); return std::static_pointer_cast(binding); } - + }; -class PipelineInstanceOgl : public PipelineInstance { -public: - GLuint vao; +struct PipelineInstanceOgl : public PipelineInstance { + + GlResource vao; bool useIndex = false; Primitive primitive; size_t instances = 0; @@ -561,13 +627,14 @@ public: virtual void SetInstancesCount(size_t count) override { instances = count; } + }; -class PipelineOgl : public Pipeline { -public: +struct PipelineOgl : public Pipeline { + std::map shaderParameters; std::vector> staticTextures; - GLuint program; + GlResource program; struct VertexBindingCommand { size_t bufferId; size_t location; @@ -621,7 +688,9 @@ public: bufferBindingId.insert({ bind->bufferId,buff->vbo }); } - glGenVertexArrays(1, &instance->vao); + GLuint newVao; + glGenVertexArrays(1, &newVao); + instance->vao = GlResource(newVao, GlResourceType::Vao); glBindVertexArray(instance->vao); glCheckError(); @@ -742,11 +811,10 @@ public: glUniformMatrix4fv(shaderParameters.at(std::string(name)), 1, GL_FALSE, glm::value_ptr(value)); glCheckError(); } -}; -class ImplOgl : public Impl { +}; -public: +struct ImplOgl : public Impl { virtual void Init() override { LOG(INFO) << "Initalizing Gal:OpenGL..."; @@ -796,7 +864,9 @@ public: virtual std::shared_ptr CreateBuffer() override { auto buff = std::make_shared(); - glGenBuffers(1, &buff->vbo); + GLuint newVbo; + glGenBuffers(1, &newVbo); + buff->vbo = GlResource(newVbo, GlResourceType::Vbo); buff->SetData({}); glCheckError(); return std::static_pointer_cast(buff); @@ -838,7 +908,9 @@ public: texture->height = texConfig->height; texture->depth = texConfig->depth; - glGenTextures(1, &texture->texture); + GLuint newTex; + glGenTextures(1, &newTex); + texture->texture = GlResource(newTex, GlResourceType::Texture); glCheckError(); glBindTexture(texture->type, texture->texture); @@ -929,7 +1001,7 @@ public: glCheckError(); - pipeline->program = program; + pipeline->program = GlResource(program, GlResourceType::Program); //Shader parameters @@ -1012,7 +1084,9 @@ public: auto conf = std::static_pointer_cast(config); auto fb = std::make_shared(); - glGenFramebuffers(1, &fb->fbo); + GLuint newFbo; + glGenFramebuffers(1, &newFbo); + fb->fbo = GlResource(newFbo, GlResourceType::Fbo); glBindFramebuffer(GL_FRAMEBUFFER, fb->fbo); @@ -1040,7 +1114,7 @@ public: virtual std::shared_ptr GetDefaultFramebuffer() override { if (!fbDefault) fbDefault = std::make_shared(); - fbDefault->fbo = 0; + fbDefault->fbo = GlResource(0, GlResourceType::None); return std::static_pointer_cast(fbDefault); } @@ -1062,6 +1136,7 @@ public: shader->isVertex = false; return std::static_pointer_cast(shader); } + }; Impl* Gal::GetImplementation() -- cgit v1.2.3 From 90eb59b998f8062720023e1c92383c396b4029d9 Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Sat, 20 Nov 2021 12:06:25 +0500 Subject: Optimized state access in GalOgl --- src/GalOgl.cpp | 204 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 136 insertions(+), 68 deletions(-) diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index 68ad96e..b7d4add 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -79,6 +79,90 @@ 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 impl; std::shared_ptr fbDefault; @@ -364,9 +448,9 @@ struct BufferOgl : public Buffer { GlResource vbo; virtual void SetData(std::vector&& data) override { - glBindBuffer(GL_ARRAY_BUFFER, vbo); + oglState.BindVbo(vbo); glBufferData(GL_ARRAY_BUFFER, data.size(), data.data(), GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + oglState.BindVbo(0); glCheckError(); } @@ -408,10 +492,12 @@ struct TextureOgl : public Texture { if (data.size() != expectedSize && !data.empty()) throw std::logic_error("Size of data is not valid for this texture"); - glBindTexture(type, texture); - glCheckError(); + 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: @@ -438,8 +524,7 @@ struct TextureOgl : public Texture { } glCheckError(); - - glBindTexture(type, 0); + 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&& data, size_t mipLevel = 0) override { @@ -447,10 +532,12 @@ struct TextureOgl : public Texture { if (data.size() != expectedSize) throw std::logic_error("Size of data is not valid for this texture"); - glBindTexture(type, texture); - glCheckError(); + 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: @@ -477,8 +564,7 @@ struct TextureOgl : public Texture { } glCheckError(); - - glBindTexture(type, 0); + oglState.BindTexture(type, 0); } }; @@ -492,12 +578,13 @@ struct FramebufferOgl : public Framebuffer { GlResource fbo; virtual void Clear() override { - glBindFramebuffer(GL_FRAMEBUFFER, fbo ? fbo : 0); + oglState.BindFbo(fbo ? fbo : 0); GLbitfield clearBits = 0; clearBits |= GL_COLOR_BUFFER_BIT; clearBits |= GL_DEPTH_BUFFER_BIT; clearBits |= GL_STENCIL_BUFFER_BIT; glClear(clearBits); + glCheckError(); } virtual void SetViewport(size_t x, size_t y, size_t w, size_t h) override { @@ -581,8 +668,7 @@ struct PipelineInstanceOgl : public PipelineInstance { size_t instances = 0; virtual void Activate() override { - glBindVertexArray(vao); - glCheckError(); + oglState.BindVao(vao); } virtual void Render(size_t offset = 0, size_t count = -1) override { @@ -620,8 +706,6 @@ struct PipelineInstanceOgl : public PipelineInstance { glDrawArrays(vertexMode, offset, count); } } - - glCheckError(); } virtual void SetInstancesCount(size_t count) override { @@ -649,25 +733,21 @@ struct PipelineOgl : public Pipeline { std::shared_ptr target; virtual void Activate() override { - glUseProgram(program); - - glBindFramebuffer(GL_FRAMEBUFFER, target->fbo); - glViewport(target->vpX, target->vpY, target->vpW, target->vpH); + 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++) { - glActiveTexture(GL_TEXTURE0 + i); - glBindTexture(staticTextures[i]->type, staticTextures[i]->texture); + oglState.BindTexture(staticTextures[i]->type, staticTextures[i]->texture, i); } - - glCheckError(); } virtual void SetDynamicTexture(std::string_view name, std::shared_ptr texture) override { Activate(); - glActiveTexture(GL_TEXTURE0 + staticTextures.size()); auto tex = std::static_pointer_cast(texture); - glBindTexture(tex->type, tex->texture); + oglState.BindTexture(tex->type, tex->texture, staticTextures.size()); SetShaderParameter(name, static_cast(staticTextures.size())); + glCheckError(); } virtual std::shared_ptr CreateInstance(std::vector, std::shared_ptr>>&& buffers) override { @@ -691,12 +771,10 @@ struct PipelineOgl : public Pipeline { GLuint newVao; glGenVertexArrays(1, &newVao); instance->vao = GlResource(newVao, GlResourceType::Vao); - glBindVertexArray(instance->vao); - glCheckError(); + oglState.BindVao(instance->vao); for (const auto& cmd : vertexBindCmds) { - glBindBuffer(GL_ARRAY_BUFFER, bufferBindingId.find(cmd.bufferId)->second); - glCheckError(); + oglState.BindVbo(bufferBindingId.find(cmd.bufferId)->second); switch (cmd.type) { case GL_FLOAT: case GL_DOUBLE: @@ -712,104 +790,89 @@ struct PipelineOgl : public Pipeline { break; } - glCheckError(); glEnableVertexAttribArray(cmd.location); - glCheckError(); if (cmd.instances) { glVertexAttribDivisor(cmd.location, cmd.instances); - glCheckError(); } } if (indexBuffer != BufferBindingOgl::indexValue) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); + oglState.BindEbo(indexBuffer); instance->useIndex = true; } - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 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); - 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(); glUniformMatrix4fv(shaderParameters.at(std::string(name)), 1, GL_FALSE, glm::value_ptr(value)); - glCheckError(); } }; @@ -821,10 +884,10 @@ struct ImplOgl : public Impl { 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); @@ -843,6 +906,7 @@ struct ImplOgl : public Impl { virtual void DeInit() override { LOG(INFO) << "Destroying Gal:OpenGL..."; + glCheckError(); } virtual void Cleanup() override { @@ -852,6 +916,7 @@ struct ImplOgl : public Impl { 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 { @@ -859,6 +924,7 @@ struct ImplOgl : public Impl { glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); + glCheckError(); } @@ -911,16 +977,15 @@ struct ImplOgl : public Impl { GLuint newTex; glGenTextures(1, &newTex); texture->texture = GlResource(newTex, GlResourceType::Texture); - glCheckError(); - glBindTexture(texture->type, texture->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)); - glCheckError(); - glBindTexture(texture->type, 0); + oglState.BindTexture(texture->type, 0); texture->SetData(std::vector(texture->width * texture->height * texture->depth * GalFormatGetSize(texture->format))); glCheckError(); @@ -943,8 +1008,10 @@ struct ImplOgl : public Impl { if (!pipeline->target) pipeline->target = std::static_pointer_cast(GetDefaultFramebuffer()); - //Shader compilation + /* + * Shader compilation + */ bool vertexFailed = false, pixelFailed = false, linkFailed = false; const GLchar* vertexSourcePtr = config->vertexShader->code.c_str(); @@ -997,14 +1064,14 @@ struct ImplOgl : public Impl { if (linkFailed) throw std::runtime_error("Shader not linked"); - glUseProgram(program); - - glCheckError(); - + oglState.UseProgram(program); pipeline->program = GlResource(program, GlResourceType::Program); + glCheckError(); - //Shader parameters + /* + * Shader parameters + */ for (auto&& [name, type] : config->shaderParameters) { GLint location = glGetUniformLocation(program, name.c_str()); if (location < 0) { @@ -1012,11 +1079,12 @@ struct ImplOgl : public Impl { } pipeline->shaderParameters.insert({ name,location }); } - glCheckError(); - //Static textures + /* + * Static textures + */ size_t usedTextureBlocks = 0; for (auto&& [name, texture] : config->textures) { GLint location = glGetUniformLocation(program, name.c_str()); @@ -1027,11 +1095,12 @@ struct ImplOgl : public Impl { glUniform1i(location, usedTextureBlocks); pipeline->staticTextures.push_back(texture); } - glCheckError(); - //Vertex attributes + /* + * Vertex attributes + */ size_t bufferId = 0; for (const auto& buffer : config->vertexBuffers) { size_t vertexSize = 0; @@ -1069,9 +1138,9 @@ struct ImplOgl : public Impl { bufferId++; } - glCheckError(); + return pipeline; } @@ -1088,7 +1157,7 @@ struct ImplOgl : public Impl { glGenFramebuffers(1, &newFbo); fb->fbo = GlResource(newFbo, GlResourceType::Fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fb->fbo); + oglState.BindFbo(fb->fbo); if (conf->depthStencil) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, conf->depthStencil->type, conf->depthStencil->texture, 0); @@ -1104,8 +1173,7 @@ struct ImplOgl : public Impl { LOG(ERROR) << "Framebuffer not completed: " << glCheckFramebufferStatus(GL_FRAMEBUFFER); } - glBindFramebuffer(GL_FRAMEBUFFER, 0); - + oglState.BindFbo(0); glCheckError(); return std::static_pointer_cast(fb); -- cgit v1.2.3 From 7090f1008205b6527c76cc5bbf32f4f3b6a661f5 Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Sat, 20 Nov 2021 13:45:51 +0500 Subject: Improved errors logging for OGL --- src/GalOgl.cpp | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/Render.cpp | 4 ++ 2 files changed, 134 insertions(+), 2 deletions(-) diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index b7d4add..9bfa6f7 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -40,7 +40,6 @@ public: } ~GlResource() { - return; switch (type) { case GlResourceType::Vbo: glDeleteBuffers(1, &res); @@ -423,7 +422,124 @@ GLenum glCheckError_(const char* file, int line) { } return errorCode; } + +#ifndef NDEBUG #define glCheckError() glCheckError_(__FILE__, __LINE__) +#else +#define glCheckError() +#endif // !NDEBUG + + +void APIENTRY 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 { @@ -582,7 +698,8 @@ struct FramebufferOgl : public Framebuffer { GLbitfield clearBits = 0; clearBits |= GL_COLOR_BUFFER_BIT; clearBits |= GL_DEPTH_BUFFER_BIT; - clearBits |= GL_STENCIL_BUFFER_BIT; + if (depthStencil) + clearBits |= GL_STENCIL_BUFFER_BIT; glClear(clearBits); glCheckError(); } @@ -902,6 +1019,17 @@ struct ImplOgl : public Impl { 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 { diff --git a/src/Render.cpp b/src/Render.cpp index b1277b2..6301ff5 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -96,6 +96,10 @@ void Render::InitSdl(unsigned int WinWidth, unsigned int WinHeight, std::string 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, -- cgit v1.2.3 From b481a989899b7adf92de20ce40e5a92cff056140 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Sat, 20 Nov 2021 11:54:16 +0300 Subject: Update ci.yml --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 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 + -- cgit v1.2.3 From 0575cdc65bfa11bda766ab6b89e44e7c90e865c7 Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Sat, 20 Nov 2021 13:59:43 +0500 Subject: Fixed missing APIENTRY linux build --- src/GalOgl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GalOgl.cpp b/src/GalOgl.cpp index 9bfa6f7..052c68a 100644 --- a/src/GalOgl.cpp +++ b/src/GalOgl.cpp @@ -430,7 +430,7 @@ GLenum glCheckError_(const char* file, int line) { #endif // !NDEBUG -void APIENTRY glDebugOutput(GLenum source, +void GLAPIENTRY glDebugOutput(GLenum source, GLenum type, unsigned int id, GLenum severity, -- cgit v1.2.3