diff options
-rw-r--r-- | src/Gal.hpp | 12 | ||||
-rw-r--r-- | src/GalOgl.cpp | 86 | ||||
-rw-r--r-- | src/RendererSection.cpp | 103 | ||||
-rw-r--r-- | src/RendererSection.hpp | 13 | ||||
-rw-r--r-- | src/RendererWorld.cpp | 49 | ||||
-rw-r--r-- | 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<Framebuffer> target) = 0; + virtual void SetPrimitive(Primitive primitive) = 0; + virtual std::shared_ptr<BufferBinding> BindVertexBuffer(std::vector<VertexAttribute> &&bufferLayout) = 0; virtual std::shared_ptr<BufferBinding> BindIndexBuffer() = 0; @@ -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 <easylogging++.h> #include <GL/glew.h> +#include <glm/gtc/type_ptr.hpp> #include "Utility.hpp" @@ -341,7 +342,7 @@ public: std::map<std::string, Type> shaderParameters; std::shared_ptr<Framebuffer> targetFb; std::vector<std::vector<VertexAttribute>> vertexBuffers; - + Primitive vertexPrimitive = Primitive::Triangle; public: virtual void SetVertexShader(std::shared_ptr<Shader> shader) override { vertexShader = std::static_pointer_cast<ShaderOgl,Shader>(shader); @@ -359,6 +360,10 @@ public: targetFb = target; } + virtual void SetPrimitive(Primitive primitive) override { + vertexPrimitive = primitive; + } + virtual std::shared_ptr<BufferBinding> BindVertexBuffer(std::vector<VertexAttribute> &&bufferLayout) override { auto binding = std::make_shared<BufferBindingOgl>(vertexBuffers.size()); vertexBuffers.push_back(bufferLayout); @@ -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<VertexBindingCommand> vertexBindCmds; + Primitive primitive; virtual void Activate() override { glUseProgram(program); @@ -417,6 +462,8 @@ public: virtual std::shared_ptr<PipelineInstance> CreateInstance(std::vector<std::pair<std::shared_ptr<BufferBinding>, std::shared_ptr<Buffer>>>&& buffers) override { auto instance = std::make_shared<PipelineInstanceOgl>(); + instance->primitive = primitive; + size_t indexBuffer = BufferBindingOgl::indexValue; std::map<size_t, size_t> bufferBindingId; @@ -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<PipelineOgl>(); auto config = std::static_pointer_cast<PipelineConfigOgl, PipelineConfig>(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<size_t>(location), - GalTypeGetComponentGlType(type), - GalTypeGetComponents(type), - vertexSize, - 0 - }); - - vertexSize += attribSize; + for (size_t i = 0; i < count; i++) { + pipeline->vertexBindCmds.push_back({ + bufferId, + static_cast<size_t>(location + i), + GalTypeGetComponentGlType(type), + GalTypeGetComponents(type), + vertexSize, + 0, + instances, + }); + + vertexSize += attribSize; + } } for (size_t i = cmdOffset; i < pipeline->vertexBindCmds.size(); i++) diff --git a/src/RendererSection.cpp b/src/RendererSection.cpp index cc58676..429a8bd 100644 --- a/src/RendererSection.cpp +++ b/src/RendererSection.cpp @@ -6,84 +6,19 @@ #include <optick.h> #include "Utility.hpp" -#include "Renderer.hpp" #include "RendererSectionData.hpp" -RendererSection::RendererSection(const RendererSectionData &data) { + +RendererSection::RendererSection(const RendererSectionData& data, std::shared_ptr<Gal::Pipeline> pipeline, std::shared_ptr<Gal::BufferBinding> bufferBinding) { OPTICK_EVENT(); - glGenVertexArrays(1, &Vao); - - glGenBuffers(1, &Vbo); - glBindBuffer(GL_ARRAY_BUFFER, Vbo); - - glBindVertexArray(Vao); - { - //Cube vertices - GLuint VertAttribPos = 0; - glVertexAttribPointer(VertAttribPos, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, positions[0])); - glEnableVertexAttribArray(VertAttribPos); - glVertexAttribDivisor(VertAttribPos, 1); - - glVertexAttribPointer(VertAttribPos + 1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, positions[1])); - glEnableVertexAttribArray(VertAttribPos + 1); - glVertexAttribDivisor(VertAttribPos + 1, 1); - - glVertexAttribPointer(VertAttribPos + 2, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, positions[2])); - glEnableVertexAttribArray(VertAttribPos + 2); - glVertexAttribDivisor(VertAttribPos + 2, 1); - - glVertexAttribPointer(VertAttribPos + 3, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, positions[3])); - glEnableVertexAttribArray(VertAttribPos + 3); - glVertexAttribDivisor(VertAttribPos + 3, 1); - glCheckError(); - - //Cube uvs - GLuint UvAttribPos = 4; - glVertexAttribPointer(UvAttribPos, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uvs[0])); - glEnableVertexAttribArray(UvAttribPos); - glVertexAttribDivisor(UvAttribPos, 1); - - glVertexAttribPointer(UvAttribPos + 1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uvs[1])); - glEnableVertexAttribArray(UvAttribPos + 1); - glVertexAttribDivisor(UvAttribPos + 1, 1); - - glVertexAttribPointer(UvAttribPos + 2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uvs[2])); - glEnableVertexAttribArray(UvAttribPos + 2); - glVertexAttribDivisor(UvAttribPos + 2, 1); - - glVertexAttribPointer(UvAttribPos + 3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uvs[3])); - glEnableVertexAttribArray(UvAttribPos + 3); - glVertexAttribDivisor(UvAttribPos + 3, 1); - - //Uv Layer - GLuint uvLayerAttribPos = 8; - glVertexAttribPointer(uvLayerAttribPos, 1, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uvLayers)); - glEnableVertexAttribArray(uvLayerAttribPos); - glVertexAttribDivisor(uvLayerAttribPos, 1); - - //Animation - GLuint animationAttribPos = 9; - glVertexAttribPointer(animationAttribPos, 1, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, animations)); - glEnableVertexAttribArray(animationAttribPos); - glVertexAttribDivisor(animationAttribPos, 1); - - //Color - GLuint colorAttribPos = 10; - glVertexAttribPointer(colorAttribPos, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, colors)); - glEnableVertexAttribArray(colorAttribPos); - glVertexAttribDivisor(colorAttribPos, 1); - - //Light - GLuint lightAttribPos = 11; - glVertexAttribPointer(lightAttribPos, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, lights)); - glEnableVertexAttribArray(lightAttribPos); - glVertexAttribDivisor(lightAttribPos, 1); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - glBindVertexArray(0); - glCheckError(); + auto gal = Gal::GetImplementation(); + buffer = gal->CreateBuffer(); + + pipelineInstance = pipeline->CreateInstance({ + {bufferBinding, buffer} + }); + pipelineInstance->SetInstancesCount(4); UpdateData(data); } @@ -94,25 +29,21 @@ RendererSection::RendererSection(RendererSection && other) { } RendererSection::~RendererSection() { - if (Vao != 0) - glDeleteVertexArrays(1, &Vao); - glDeleteBuffers(1, &Vbo); } void swap(RendererSection & lhs, RendererSection & rhs) { - std::swap(lhs.Vbo, rhs.Vbo); - std::swap(lhs.Vao, rhs.Vao); + std::swap(lhs.pipelineInstance, rhs.pipelineInstance); + std::swap(lhs.buffer, rhs.buffer); std::swap(lhs.hash, rhs.hash); std::swap(lhs.numOfFaces, rhs.numOfFaces); std::swap(lhs.sectionPos, rhs.sectionPos); } -void RendererSection::Render(RenderState &renderState) { +void RendererSection::Render() { OPTICK_EVENT(); - renderState.SetActiveVao(Vao); - glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, numOfFaces); - glCheckError(); + pipelineInstance->Activate(); + pipelineInstance->Render(0, numOfFaces); } Vector RendererSection::GetPosition() { @@ -126,11 +57,7 @@ size_t RendererSection::GetHash() { void RendererSection::UpdateData(const RendererSectionData & data) { OPTICK_EVENT(); - glBindBuffer(GL_ARRAY_BUFFER, Vbo); - glBufferData(GL_ARRAY_BUFFER, data.vertices.size() * sizeof(VertexData), data.vertices.data(), GL_STATIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glCheckError(); + buffer->SetData({ reinterpret_cast<const std::byte*>(data.vertices.data()), reinterpret_cast<const std::byte*>(data.vertices.data() + data.vertices.size())}); numOfFaces = data.vertices.size(); sectionPos = data.sectionPos; diff --git a/src/RendererSection.hpp b/src/RendererSection.hpp index 3ea1fec..0a03f44 100644 --- a/src/RendererSection.hpp +++ b/src/RendererSection.hpp @@ -1,29 +1,26 @@ #pragma once -#include <glm/mat4x4.hpp> -#include <GL/glew.h> - #include "Vector.hpp" +#include "Gal.hpp" class RenderState; class RendererSectionData; class RendererSection { - GLuint Vao = { 0 }; - GLuint Vbo = { 0 }; - + std::shared_ptr<Gal::PipelineInstance> pipelineInstance; + std::shared_ptr<Gal::Buffer> buffer; size_t hash; Vector sectionPos; RendererSection(const RendererSection &other) = delete; public: - RendererSection(const RendererSectionData &data); + RendererSection(const RendererSectionData& data, std::shared_ptr<Gal::Pipeline> pipeline, std::shared_ptr<Gal::BufferBinding> bufferBinding); RendererSection(RendererSection &&other); ~RendererSection(); - void Render(RenderState &renderState); + void Render(); Vector GetPosition(); diff --git a/src/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<AssetShader>("/altcraft/shaders/face")->shader.get(); + /*Shader* blockShader = AssetManager::GetAsset<AssetShader>("/altcraft/shaders/face")->shader.get(); blockShader->Activate(); blockShader->SetUniform("DayTime", mixLevel); blockShader->SetUniform("projView", projView); blockShader->SetUniform("GlobalTime", globalTime); glCheckError(); + */ + 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<AssetShader>("/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<Vector, RendererSection> sections; void UpdateAllSections(VectorF playerPos); std::chrono::time_point<std::chrono::high_resolution_clock> globalTimeStart; + std::shared_ptr<Gal::Pipeline> sectionsPipeline; + std::shared_ptr<Gal::BufferBinding> sectionsBufferBinding; //Entities std::vector<RendererEntity> entities; //Sky |