diff options
Diffstat (limited to 'source/30-game/Renderer.cpp')
-rw-r--r-- | source/30-game/Renderer.cpp | 256 |
1 files changed, 0 insertions, 256 deletions
diff --git a/source/30-game/Renderer.cpp b/source/30-game/Renderer.cpp deleted file mode 100644 index 0454efe..0000000 --- a/source/30-game/Renderer.cpp +++ /dev/null @@ -1,256 +0,0 @@ -#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{ 0 } { -} - -RenderObject::~RenderObject() { - DeleteGLObjects(); -} - -GLuint RenderObject::GetGLVao() const { - return mVao; -} - -void RenderObject::RebuildIfNecessary() { - if (mVao != 0) { - return; - } - - assert(mIndexBuf != nullptr); - assert(mVertexFormat != nullptr); - - glGenVertexArrays(1, &mVao); - glBindVertexArray(mVao); - - auto& vBindings = mVertexBufBinding.bindings; - auto& shaderInfo = mMaterial->GetShader()->GetInfo(); - - // Setup vertex buffers - for (auto& elm : mVertexFormat->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), - mVertexFormat->vertexSize, - (void*)(uintptr_t)elm.offset); - } - - // Setup index buffer - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuf->handle); - - glBindVertexArray(0); -} - -void RenderObject::SetMaterial(Material* material) { - mMaterial.Attach(material); - DeleteGLObjects(); -} - -void RenderObject::UpdateIndexBuffer(GpuIndexBuffer* indexBuffer) { - mIndexBuf.Attach(indexBuffer); - DeleteGLObjects(); -} - -void RenderObject::UpdateVertexFormat(VertexFormat* vertexFormat) { - mVertexFormat.Attach(vertexFormat); - DeleteGLObjects(); -} - -void RenderObject::UpdateVertexBufferBindings(BufferBindings** bindingsOut) { - *bindingsOut = &mVertexBufBinding; - DeleteGLObjects(); -} - -void RenderObject::SetFormat(VertexFormat* vertexFormat, Tags::IndexType indexFormat) { - mIndexBuf.Attach(new GpuIndexBuffer()); - mIndexBuf->indexType = indexFormat; - mIndexBuf->count = 0; - - mVertexFormat.Attach(vertexFormat); - mVertexBufBinding.Clear(); - for (auto& element : vertexFormat->elements) { - if (mVertexBufBinding.GetBinding(element.bindingIndex) == nullptr) { - mVertexBufBinding.SetBinding(element.bindingIndex, new GpuVertexBuffer()); - } - } -} - -void RenderObject::DeleteGLObjects() { - if (mVao != 0) { - glDeleteVertexArrays(1, &mVao); - mVao = 0; - } -} - -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; - mFrame.camera = &camera; - mFrame.matrixView = camera.CalcViewMatrix(); - mFrame.matrixProj = camera.CalcProjectionMatrix(); - mFrame.time = currentTime; - mFrame.deltaTime = deltaTime; -} - -void Renderer::EndFrame() { - assert(mInsideFrame == true); - mInsideFrame = false; -} - -void Renderer::Draw(const RenderObject* objects, const GameObject* gameObject, size_t count) { - using namespace Tags; - - assert(mInsideFrame); - - // 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; - - 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()); - - // Material uniforms - mat->UseUniforms(); - - // Next available texture unit ID after all material textures - int texIdx = mat->GetTextures().size(); - - // 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; - } - - glBindVertexArray(object.GetGLVao()); - glDrawElements(GL_TRIANGLES, indexBuffer->count, indexBuffer->GetIndexTypeGL(), 0); - } - } - - 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); - - return; - } -} - -bool Renderer::GetRenderOption(RenderOption option) const { - return mRenderOptions[option]; -} - -void Renderer::SetRenderOption(RenderOption option, bool flag) { - mRenderOptions[option] = flag; -} |