aboutsummaryrefslogtreecommitdiff
path: root/source/30-game/Renderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/30-game/Renderer.cpp')
-rw-r--r--source/30-game/Renderer.cpp158
1 files changed, 122 insertions, 36 deletions
diff --git a/source/30-game/Renderer.cpp b/source/30-game/Renderer.cpp
index 3497449..ad8bf35 100644
--- a/source/30-game/Renderer.cpp
+++ b/source/30-game/Renderer.cpp
@@ -2,10 +2,16 @@
#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 +107,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 +149,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;
+}