Rework RenderComponent to be more flexible

This commit is contained in:
Ben Visness
2018-05-28 13:21:43 -05:00
parent ba5982b2a9
commit ba02e1a9c4
4 changed files with 84 additions and 64 deletions

View File

@@ -1,6 +1,7 @@
#include <HandmadeMath.h> #include <HandmadeMath.h>
#include "Entity.h" #include "Entity.h"
#include "RenderComponent.h"
#ifndef HMME_CUBE_H #ifndef HMME_CUBE_H
#define HMME_CUBE_H #define HMME_CUBE_H
@@ -86,24 +87,67 @@ static const GLfloat cubeColors[] = {
0.982f, 0.099f, 0.879f 0.982f, 0.099f, 0.879f
}; };
class CubeRenderComponent : public RenderComponent {
public:
GLuint vaoID;
GLuint vertexBufferID;
GLuint colorBufferID;
CubeRenderComponent() {
glGenVertexArrays(1, &vaoID);
glGenBuffers(1, &vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);
glGenBuffers(1, &colorBufferID);
glBindBuffer(GL_ARRAY_BUFFER, colorBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeColors), cubeColors, GL_STATIC_DRAW);
}
void Draw() override {
glBindVertexArray(vaoID);
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 2nd attribute buffer : colors
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorBufferID);
glVertexAttribPointer(
1, // attribute. No particular reason for 1, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Shader??
// Draw the triangle!
glDrawArrays(GL_TRIANGLES, 0, 36); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
};
class Cube : public Entity { class Cube : public Entity {
public: public:
float x = 0; float x = 0;
CubeRenderComponent rc = CubeRenderComponent();
Cube() { Cube() {
Entity::RenderComponent c; renderComponent = &rc;
glGenVertexArrays(1, &c.vaoID);
glGenBuffers(1, &c.vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, c.vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);
glGenBuffers(1, &c.colorBufferID);
glBindBuffer(GL_ARRAY_BUFFER, c.colorBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeColors), cubeColors, GL_STATIC_DRAW);
renderComponent = c;
} }
void Tick(float deltaSeconds) override { void Tick(float deltaSeconds) override {

View File

@@ -5,6 +5,8 @@
#ifndef HMME_ENTITY_H #ifndef HMME_ENTITY_H
#define HMME_ENTITY_H #define HMME_ENTITY_H
#include "RenderComponent.h"
class Entity { class Entity {
public: public:
hmm_vec3 position = HMM_Vec3(0.0f, 0.0f, 0.0f); hmm_vec3 position = HMM_Vec3(0.0f, 0.0f, 0.0f);
@@ -19,12 +21,7 @@ public:
virtual void Tick(float deltaSeconds) {} virtual void Tick(float deltaSeconds) {}
struct RenderComponent { RenderComponent *renderComponent = NULL;
GLuint vaoID;
GLuint vertexBufferID;
GLuint colorBufferID;
};
RenderComponent renderComponent;
// Context for rendering and stuff // Context for rendering and stuff
hmm_mat4 modelMatrix; hmm_mat4 modelMatrix;

View File

@@ -0,0 +1,13 @@
#include <HandmadeMath.h>
#ifndef HMME_RENDER_COMPONENT_H
#define HMME_RENDER_COMPONENT_H
#include "Entity.h"
class RenderComponent {
public:
virtual void Draw() = 0;
};
#endif

View File

@@ -85,6 +85,7 @@ int main()
hmm_mat4 view = HMM_LookAt(HMM_Vec3(3.0f, 3.0f, 4.0f), HMM_Vec3(0.0f, 0.0f, 0.0f), HMM_Vec3(0.0f, 1.0f, 0.0f)); hmm_mat4 view = HMM_LookAt(HMM_Vec3(3.0f, 3.0f, 4.0f), HMM_Vec3(0.0f, 0.0f, 0.0f), HMM_Vec3(0.0f, 1.0f, 0.0f));
hmm_mat4 vp = projection * view; hmm_mat4 vp = projection * view;
// Tick
auto now = high_resolution_clock::now(); auto now = high_resolution_clock::now();
if (hasTicked) { if (hasTicked) {
auto elapsedNanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(now - lastTickTime).count(); auto elapsedNanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(now - lastTickTime).count();
@@ -94,58 +95,23 @@ int main()
lastTickTime = now; lastTickTime = now;
hasTicked = true; hasTicked = true;
// Compute model positions for rendering
ComputeModelMatrices(&root, HMM_Mat4d(1.0f)); ComputeModelMatrices(&root, HMM_Mat4d(1.0f));
// Render!
auto it = EntityIterator(&root); auto it = EntityIterator(&root);
while (it.HasNext()) { while (it.HasNext()) {
Entity *e = it.Next(); Entity *e = it.Next();
if (!e->renderComponent.vaoID) { if (e->renderComponent) {
continue; // Use our shader
glUseProgram(programID);
hmm_mat4 mvp = vp * e->modelMatrix;
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp.Elements[0][0]);
e->renderComponent->Draw();
} }
Entity::RenderComponent rc = e->renderComponent;
glBindVertexArray(rc.vaoID);
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, rc.vertexBufferID);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 2nd attribute buffer : colors
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, rc.colorBufferID);
glVertexAttribPointer(
1, // attribute. No particular reason for 1, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Use our shader
glUseProgram(programID);
hmm_mat4 mvp = vp * e->modelMatrix;
// Send our transformation to the currently bound shader, in the "MVP" uniform
// This is done in the main loop since each model will have a different MVP matrix (At least for the M part)
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp.Elements[0][0]);
// Draw the triangle!
glDrawArrays(GL_TRIANGLES, 0, 36); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
} }
// Swap buffers // Swap buffers