diff options
Diffstat (limited to 'source/Renderer.cpp')
-rw-r--r-- | source/Renderer.cpp | 157 |
1 files changed, 121 insertions, 36 deletions
diff --git a/source/Renderer.cpp b/source/Renderer.cpp index 3497449..e30b64d 100644 --- a/source/Renderer.cpp +++ b/source/Renderer.cpp @@ -1,11 +1,16 @@ #include "Renderer.hpp" #include "GameObject.hpp" +#include "RapidJsonHelper.hpp" +#include <rapidjson/document.h> #include <cassert> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/quaternion.hpp> #include <glm/gtx/quaternion.hpp> +#include <string_view> + +using namespace std::literals; RenderObject::RenderObject() : mVao{ GL_NONE } { @@ -101,6 +106,28 @@ void RenderObject::DeleteGLObjects() { } } +Renderer::Renderer() + : binding_WireframeMaterial{ gDefaultMaterial } // +{ + mRenderOptions[RO_Shading] = true; + mRenderOptions[RO_Wireframe] = false; +} + +void Renderer::LoadBindings(const rapidjson::Value& bindings) { + if (auto rvWireframe = rapidjson::GetProperty(bindings, "WireframeMaterial"sv)) { + Uid uidWireframe; + uidWireframe.Read(*rvWireframe); + // TODO don't assume + binding_WireframeMaterial.Attach(((IresMaterial*)IresManager::instance->FindIres(uidWireframe))->GetInstance()); + } +} + +void Renderer::SaveBindings(rapidjson::Value& into, rapidjson::Document& root) const { + if (auto ires = binding_WireframeMaterial->GetIres()) { + into.AddMember("WireframeMaterial", ires->GetUid().Write(root), root.GetAllocator()); + } +} + void Renderer::BeginFrame(Camera& camera, float currentTime, float deltaTime) { assert(mInsideFrame == false); mInsideFrame = true; @@ -121,50 +148,108 @@ void Renderer::Draw(const RenderObject* objects, const GameObject* gameObject, s assert(mInsideFrame); - auto vpMatrix = mFrame.matrixProj * mFrame.matrixView; + // Desired order: proj * view * (translate * rotate * scale) * vec + // <----- order of application <----- ^^^ input + glm::mat4 objectMatrix(1.0f); + objectMatrix = glm::translate(objectMatrix, gameObject->GetPos()); + objectMatrix *= glm::toMat4(gameObject->GetRotation()); + objectMatrix = glm::scale(objectMatrix, gameObject->GetScale()); + auto mvpMatrix = mFrame.matrixProj * mFrame.matrixView * objectMatrix; - // TODO shader grouping - // TODO material grouping - for (size_t i = 0; i < count; ++i) { - auto& object = objects[i]; - auto indexBuffer = object.GetIndexBuffer(); - auto mat = object.GetMaterial(); - auto shader = mat->GetShader(); + if (GetRenderOption(RO_Shading)) { + // TODO shader grouping + // TODO material grouping + for (size_t i = 0; i < count; ++i) { + auto& object = objects[i]; + auto indexBuffer = object.GetIndexBuffer(); + auto mat = object.GetMaterial(); + auto shader = mat->GetShader(); - glUseProgram(shader->GetProgram()); + glUseProgram(shader->GetProgram()); - // Material uniforms - mat->UseUniforms(); + // Material uniforms + mat->UseUniforms(); - // Next available texture unit ID after all material textures - int texIdx = mat->GetTextures().size(); + // Next available texture unit ID after all material textures + int texIdx = mat->GetTextures().size(); - // Autofill uniforms - if (shader->autofill_Transform != kInvalidLocation) { - glm::mat4 objectMatrix(1.0f); - objectMatrix = glm::translate(objectMatrix, gameObject->GetPos()); - objectMatrix *= glm::toMat4(gameObject->GetRotation()); - objectMatrix = glm::scale(objectMatrix, gameObject->GetScale()); - glm::mat4 transform = vpMatrix * objectMatrix; + // Autofill uniforms + if (shader->autofill_Transform != kInvalidLocation) { + glUniformMatrix4fv(shader->autofill_Transform, 1, GL_FALSE, &mvpMatrix[0][0]); + } + if (shader->autofill_Time != kInvalidLocation) { + glUniform1f(shader->autofill_Time, mFrame.time); + } + if (shader->autofill_DeltaTime != kInvalidLocation) { + glUniform1f(shader->autofill_DeltaTime, mFrame.deltaTime); + } + if (shader->autofill_TextureAtlas != kInvalidLocation && + object.autofill_TextureAtlas != nullptr) + { + glActiveTexture(GL_TEXTURE0 + texIdx); + glBindTexture(GL_TEXTURE_2D, object.autofill_TextureAtlas->GetHandle()); + glUniform1i(shader->autofill_TextureAtlas, texIdx); + ++texIdx; + } - glUniformMatrix4fv(shader->autofill_Transform, 1, GL_FALSE, &transform[0][0]); - } - if (shader->autofill_Time != kInvalidLocation) { - glUniform1f(shader->autofill_Time, mFrame.time); + glBindVertexArray(object.GetGLVao()); + glDrawElements(GL_TRIANGLES, indexBuffer->count, indexBuffer->GetIndexTypeGL(), 0); } - if (shader->autofill_DeltaTime != kInvalidLocation) { - glUniform1f(shader->autofill_DeltaTime, mFrame.deltaTime); - } - if (shader->autofill_TextureAtlas != kInvalidLocation && - object.autofill_TextureAtlas != nullptr) - { - glActiveTexture(GL_TEXTURE0 + texIdx); - glBindTexture(GL_TEXTURE_2D, object.autofill_TextureAtlas->GetHandle()); - glUniform1i(shader->autofill_TextureAtlas, texIdx); - ++texIdx; + } + + if (GetRenderOption(RO_Wireframe)) { + auto& mat = *binding_WireframeMaterial; + auto& shader = *mat.GetShader(); + auto& shaderInfo = shader.GetInfo(); + + glUseProgram(shader.GetProgram()); + mat.UseUniforms(); + + // TODO reduce calls with consecutive wireframe setting + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + for (size_t i = 0; i < count; ++i) { + auto& object = objects[i]; + + auto& vBindings = object.GetVertexBufferBindings().bindings; + auto vf = object.GetVertexFormat(); + + // Setup vertex buffers + for (auto& elm : vf->elements) { + assert(elm.bindingIndex < vBindings.size()); + auto& buffer = vBindings[elm.bindingIndex]; + + int index = shaderInfo.FindInputLocation(elm.semantic); + if (index == -1) { + continue; + } + + glBindBuffer(GL_ARRAY_BUFFER, buffer->handle); + glEnableVertexAttribArray(index); + glVertexAttribPointer( + index, + Tags::VectorLenOf(elm.type), + Tags::FindGLType(elm.type), + Tags::IsNormalized(elm.type), + vf->vertexSize, + (void*)(uintptr_t)elm.offset); + } + + // Setup index buffer + auto indexBuffer = object.GetIndexBuffer(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer->handle); + + glDrawElements(GL_TRIANGLES, indexBuffer->count, indexBuffer->GetIndexTypeGL(), 0); } + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glBindVertexArray(object.GetGLVao()); - glDrawElements(GL_TRIANGLES, indexBuffer->count, indexBuffer->GetIndexTypeGL(), 0); + return; } } + +bool Renderer::GetRenderOption(RenderOption option) const { + return mRenderOptions[option]; +} + +void Renderer::SetRenderOption(RenderOption option, bool flag) { + mRenderOptions[option] = flag; +} |