aboutsummaryrefslogtreecommitdiff
path: root/source/Renderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Renderer.cpp')
-rw-r--r--source/Renderer.cpp130
1 files changed, 116 insertions, 14 deletions
diff --git a/source/Renderer.cpp b/source/Renderer.cpp
index dec24ea..f96c3a0 100644
--- a/source/Renderer.cpp
+++ b/source/Renderer.cpp
@@ -1,19 +1,43 @@
#include "Renderer.hpp"
-RenderObject::RenderObject(GpuMesh* mesh, Material* material) {
+#include <cassert>
+
+RenderObject::RenderObject()
+ : mVao{ GL_NONE } {
+}
+
+RenderObject::~RenderObject() {
+ DeleteGLObjects();
+}
+
+GLuint RenderObject::GetGLVao() const {
+ return mVao;
+}
+
+void RenderObject::RebuildIfNecessary() {
+ if (mVao != GL_NONE) {
+ return;
+ }
+
+ assert(mIndexBuf != nullptr);
+ assert(mVertexFormat != nullptr);
+
glGenVertexArrays(1, &mVao);
glBindVertexArray(mVao);
- auto& vf = mesh->vertFormat;
- auto& vBindings = mesh->vertBufBindings.bindings;
- auto& shaderInfo = material->GetShader()->GetInfo();
+ auto& vBindings = mVertexBufBinding.bindings;
+ auto& shaderInfo = mMaterial->GetShader()->GetInfo();
// Setup vertex buffers
- for (auto& elm : vf->elements) {
+ for (auto& elm : mVertexFormat->elements) {
assert(elm.bindingIndex < vBindings.size());
auto& buffer = vBindings[elm.bindingIndex];
- int index = material->GetShader()->GetInfo().FindInputLocation(elm.semantic);
+ int index = shaderInfo.FindInputLocation(elm.semantic);
+ if (index == -1) {
+ continue;
+ }
+
glBindBuffer(GL_ARRAY_BUFFER, buffer->handle);
glEnableVertexAttribArray(index);
glVertexAttribPointer(
@@ -21,23 +45,101 @@ RenderObject::RenderObject(GpuMesh* mesh, Material* material) {
Tags::VectorLenOf(elm.type),
Tags::FindGLType(elm.type),
Tags::IsNormalized(elm.type),
- vf->vertexSize,
+ mVertexFormat->vertexSize,
(void*)(uintptr_t)elm.offset);
}
// Setup index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->indexBuf->handle);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuf->handle);
glBindVertexArray(GL_NONE);
}
-RenderObject::~RenderObject() {
- glDeleteVertexArrays(1, &mVao);
+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 != GL_NONE) {
+ glDeleteVertexArrays(1, &mVao);
+ mVao = GL_NONE;
+ }
+}
+
+void Renderer::BeginFrame(Camera& camera, float currentTime, float deltaTime) {
+ assert(mInsideFrame == false);
+ mInsideFrame = true;
+ mFrame_Cam = &camera;
+ mFrame_Transform = camera.CalcProjectionMatrix() * camera.CalcViewMatrix();
+ mFrame_Time = currentTime;
+ mFrame_DeltaTime = deltaTime;
+}
+
+void Renderer::EndFrame() {
+ assert(mInsideFrame == true);
+ mInsideFrame = false;
}
-void Renderer::Draw(RenderObject& object) {
- auto indexType = object.GetMesh()->indexBuf->indexType;
+void Renderer::Draw(const RenderObject* objects, size_t count) {
+ using namespace Tags;
+
+ assert(mInsideFrame);
+
+ // 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();
- glBindVertexArray(object.GetGLVao());
- glDrawElements(GL_TRIANGLES, 0, Tags::FindGLType(indexType), 0);
+ glUseProgram(shader->GetProgram());
+
+ // Autofill uniforms
+ if (shader->autofillLoc_Transform != kInvalidLocation) {
+ glUniformMatrix4fv(shader->autofillLoc_Transform, 1, GL_FALSE, &mFrame_Transform[0][0]);
+ }
+ if (shader->autofillLoc_Time != kInvalidLocation) {
+ glUniform1f(shader->autofillLoc_Time, mFrame_Time);
+ }
+ if (shader->autofillLoc_DeltaTime != kInvalidLocation) {
+ glUniform1f(shader->autofillLoc_DeltaTime, mFrame_DeltaTime);
+ }
+
+ // Material uniforms
+ mat->UseUniforms();
+
+ glBindVertexArray(object.GetGLVao());
+ glDrawElements(GL_TRIANGLES, indexBuffer->count, indexBuffer->GetIndexTypeGL(), 0);
+ }
}