Create a renderer that handles model rendering

This commit is contained in:
SeanOMik 2022-08-18 22:40:34 -04:00
parent 0a3d80d17c
commit 3a49373d75
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
6 changed files with 203 additions and 10 deletions

View File

@ -1,6 +1,7 @@
#include "simpleengine/camera.h"
#include "simpleengine/gfx/light.h"
#include "simpleengine/gfx/model.h"
#include "simpleengine/gfx/renderer.h"
#include "simpleengine/gfx/texture.h"
#include "simpleengine/objects/3d/terrain.h"
#include "simpleengine/vector.h"
@ -32,6 +33,22 @@ CMRC_DECLARE(resource_shaders);
namespace se = simpleengine;
class RendererEvent : public se::Event {
public:
RendererEvent(se::gfx::Renderer renderer) : se::Event(), renderer(renderer) {}
~RendererEvent() = default;
se::gfx::Renderer renderer;
virtual void update(const float& delta_time) override {
}
virtual void render(GLFWwindow* target) override {
this->renderer.render(nullptr);
}
};
std::string read_resource_shader(const std::string& path) {
auto fs = cmrc::resource_shaders::get_filesystem();
cmrc::file vertex_file = fs.open(path);
@ -139,7 +156,14 @@ int main(int argc, char *argv[]) {
auto cube = std::make_shared<se::gfx::Model>(game.get_window(), core_shader, cube_vertices, cube_indicies);
cube->calculate_normals();
cube->translate(3.5f, 0.f, 0.f);
game.add_event(cube);
//game.add_event(cube);
auto renderer = std::make_shared<se::gfx::Renderer>(game.get_window(), core_shader);
renderer->add_model(white_texture, cube);
game.add_event(renderer);
/* auto r_event = std::make_shared<RendererEvent>(renderer);
game.add_event(r_event); */
auto camera = std::make_shared<se::Camera>(game.get_window(), core_shader, 70, glm::vec3(0, 0, 0));
game.add_event(camera);

View File

@ -0,0 +1,47 @@
#pragma once
#include "texture.h"
#include "shader.h"
//#include "renderable.h"
#include "model.h"
#include <vector>
namespace simpleengine::gfx {
class Renderer : public simpleengine::Renderable {
private:
GLFWwindow* window;
public:
class RenderingModel {
public:
RenderingModel(std::shared_ptr<simpleengine::gfx::Model> model, simpleengine::gfx::Texture texture, gfx::VBO ebo,
gfx::VBO vbo, gfx::VAO vao) : model(model), texture(texture), ebo(ebo), vbo(vbo), vao(vao) {
}
std::shared_ptr<simpleengine::gfx::Model> model;
simpleengine::gfx::Texture texture;
gfx::VBO ebo;
gfx::VBO vbo;
gfx::VAO vao;
};
gfx::Shader shader;
std::vector<RenderingModel> rendering_models;
Renderer(GLFWwindow* window, gfx::Shader shader);
Renderer(GLFWwindow* window, GLuint shader_program);
virtual void add_model(simpleengine::gfx::Texture texture, std::shared_ptr<simpleengine::gfx::Model> model);
virtual void remove_model(std::shared_ptr<simpleengine::gfx::Model> model);
virtual void initialize();
virtual void update(const float& delta_time) override {
}
virtual void render(GLFWwindow* target) override;
};
}

View File

@ -1,5 +1,7 @@
#pragma once
#include <cstdio>
#include <iostream>
#ifdef __linux__
#include <GL/glew.h>
#include <GL/gl.h>
@ -15,12 +17,30 @@ namespace simpleengine::gfx {
public:
GLuint handle;
VAO() {
glCreateVertexArrays(1, &handle);
VAO(GLuint handle) : handle(handle) {
//glCreateVertexArrays(1, &handle);
}
~VAO() {
destroy();
std::cout << "TODO, drop VAO (" << handle << ")" << std::endl;
}
VAO& operator=(const VAO& other) {
if (this != &other) {
handle = other.handle;
}
std::cout << "Copied " << handle << std::endl;
return *this;
}
static VAO init() {
GLuint handle;
glCreateVertexArrays(1, &handle);
return VAO(handle);
}
void destroy() {
@ -29,6 +49,12 @@ namespace simpleengine::gfx {
void bind() const {
glBindVertexArray(handle);
GLenum err = glGetError();
if (err != GL_NO_ERROR) {
//fprintf(stderr, "Ran into opengl error: 0x%x\n", err);
//std::cerr << "Ran into enum error: "
}
}
// TODO: Fix this.

View File

@ -15,16 +15,23 @@ namespace simpleengine::gfx {
GLint type;
bool dynamic;
VBO() = default;
//VBO() = default;
VBO(GLint type, bool dynamic) : type(type), dynamic(dynamic) {
glGenBuffers(1, &handle);
VBO(GLuint handle, GLint type, bool dynamic) : type(type), dynamic(dynamic), handle(handle) {
//glGenBuffers(1, &handle);
}
~VBO() {
destroy();
}
static VBO init(GLint type, bool dynamic) {
GLuint handle;
glGenBuffers(1, &handle);
return VBO(handle, type, dynamic);
}
void destroy() {
glDeleteBuffers(1, &handle);
}

View File

@ -2,10 +2,10 @@
namespace simpleengine::gfx {
Model::Model(GLFWwindow* window, gfx::Shader shader, std::vector<LitVertex> vertices, std::vector<GLuint> indicies) :
simpleengine::Renderable(window), shader(shader), vertices(vertices), indicies(indicies), vbo(gfx::VBO(GL_ARRAY_BUFFER, false)),
ebo(gfx::VBO(GL_ELEMENT_ARRAY_BUFFER, false)) {
simpleengine::Renderable(window), shader(shader), vertices(vertices), indicies(indicies), vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)),
ebo(gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false)), vao(gfx::VAO::init()) {
setup_vertices();
//setup_vertices();
}
Model::Model(GLFWwindow* window, GLuint shader_program, std::vector<LitVertex> vertices, std::vector<GLuint> indicies) :

89
src/gfx/renderer.cpp Normal file
View File

@ -0,0 +1,89 @@
#include "gfx/renderer.h"
namespace simpleengine::gfx {
Renderer::Renderer(GLFWwindow* window, gfx::Shader shader): window(window), shader(shader) {
}
Renderer::Renderer(GLFWwindow* window, GLuint shader_program): Renderer(window,
gfx::Shader(shader_program)) {
}
void Renderer::add_model(simpleengine::gfx::Texture texture, std::shared_ptr<simpleengine::gfx::Model> model) {
auto ebo = gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false);
auto vbo = gfx::VBO::init(GL_ARRAY_BUFFER, false);
auto vao = gfx::VAO::init();
// Create and setup the EBO, VAO, and VBOs.
vao.bind();
vbo.buffer(model->vertices.data(), 0, sizeof(LitVertex) * model->vertices.size());
if (!model->indicies.empty()) {
ebo.buffer(model->indicies.data(), 0, model->indicies.size() * sizeof(GLuint));
}
// Enable VAO attributes
vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, position));
vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, color));
vao.enable_attrib(vbo, 2, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, normal));
vao.enable_attrib(vbo, 3, 2, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, tex_coord));
vao.enable_attrib(vbo, 4, 1, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, texture_id));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// Create the RenderingModel struct and store it in the vector for later.
RenderingModel rendering_model( model, texture, ebo, vbo, vao);
rendering_models.push_back(rendering_model);
}
void Renderer::remove_model(std::shared_ptr<simpleengine::gfx::Model> model) {
std::cerr << "Removing model is unimplemented!" << std::endl;
}
void Renderer::initialize() {
std::cout << "Base Renderer initialized" << std::endl;
}
void Renderer::render(GLFWwindow* target) {
shader.use();
for (RenderingModel& rendering : rendering_models) {
std::shared_ptr<Model>& model = rendering.model;
shader.use();
shader.set_uniform_matrix_4f("transform_matrix", model->transform_matrix, false);
rendering.vao.bind();
if (model->indicies.empty()) {
glDrawArrays(GL_TRIANGLES, 0, model->vertices.size());
} else {
glDrawElements(GL_TRIANGLES, model->indicies.size(), GL_UNSIGNED_INT, 0);
}
/* const Texture& texture = rendering.texture;
shader.set_uniform_matrix_4f("transform_matrix", model->transform_matrix, false);
const int tex_id = 0;
// On a batch renderer, you would set an array.
shader.set_uniform_int("u_textures", tex_id, false);
shader.set_uniform_float("u_texture_shine", 1.f, false);
shader.set_uniform_float("u_texture_reflectivity", 0.f, false);
glActiveTexture(GL_TEXTURE0 + tex_id);
glBindTextureUnit(tex_id, texture.get_texture_id());
texture.bind();
rendering.vao.bind();
if (model->indicies.empty()) {
glDrawArrays(GL_TRIANGLES, 0, model->vertices.size());
} else {
glDrawElements(GL_TRIANGLES, model->indicies.size(), GL_UNSIGNED_INT, 0);
} */
}
shader.unuse();
}
}