Create a renderer that handles model rendering
This commit is contained in:
parent
0a3d80d17c
commit
3a49373d75
|
@ -1,6 +1,7 @@
|
||||||
#include "simpleengine/camera.h"
|
#include "simpleengine/camera.h"
|
||||||
#include "simpleengine/gfx/light.h"
|
#include "simpleengine/gfx/light.h"
|
||||||
#include "simpleengine/gfx/model.h"
|
#include "simpleengine/gfx/model.h"
|
||||||
|
#include "simpleengine/gfx/renderer.h"
|
||||||
#include "simpleengine/gfx/texture.h"
|
#include "simpleengine/gfx/texture.h"
|
||||||
#include "simpleengine/objects/3d/terrain.h"
|
#include "simpleengine/objects/3d/terrain.h"
|
||||||
#include "simpleengine/vector.h"
|
#include "simpleengine/vector.h"
|
||||||
|
@ -32,6 +33,22 @@ CMRC_DECLARE(resource_shaders);
|
||||||
|
|
||||||
namespace se = simpleengine;
|
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) {
|
std::string read_resource_shader(const std::string& path) {
|
||||||
auto fs = cmrc::resource_shaders::get_filesystem();
|
auto fs = cmrc::resource_shaders::get_filesystem();
|
||||||
cmrc::file vertex_file = fs.open(path);
|
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);
|
auto cube = std::make_shared<se::gfx::Model>(game.get_window(), core_shader, cube_vertices, cube_indicies);
|
||||||
cube->calculate_normals();
|
cube->calculate_normals();
|
||||||
cube->translate(3.5f, 0.f, 0.f);
|
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));
|
auto camera = std::make_shared<se::Camera>(game.get_window(), core_shader, 70, glm::vec3(0, 0, 0));
|
||||||
game.add_event(camera);
|
game.add_event(camera);
|
||||||
|
|
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <iostream>
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
|
@ -15,12 +17,30 @@ namespace simpleengine::gfx {
|
||||||
public:
|
public:
|
||||||
GLuint handle;
|
GLuint handle;
|
||||||
|
|
||||||
VAO() {
|
VAO(GLuint handle) : handle(handle) {
|
||||||
glCreateVertexArrays(1, &handle);
|
//glCreateVertexArrays(1, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
~VAO() {
|
~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() {
|
void destroy() {
|
||||||
|
@ -29,6 +49,12 @@ namespace simpleengine::gfx {
|
||||||
|
|
||||||
void bind() const {
|
void bind() const {
|
||||||
glBindVertexArray(handle);
|
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.
|
// TODO: Fix this.
|
||||||
|
|
|
@ -15,16 +15,23 @@ namespace simpleengine::gfx {
|
||||||
GLint type;
|
GLint type;
|
||||||
bool dynamic;
|
bool dynamic;
|
||||||
|
|
||||||
VBO() = default;
|
//VBO() = default;
|
||||||
|
|
||||||
VBO(GLint type, bool dynamic) : type(type), dynamic(dynamic) {
|
VBO(GLuint handle, GLint type, bool dynamic) : type(type), dynamic(dynamic), handle(handle) {
|
||||||
glGenBuffers(1, &handle);
|
//glGenBuffers(1, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
~VBO() {
|
~VBO() {
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VBO init(GLint type, bool dynamic) {
|
||||||
|
GLuint handle;
|
||||||
|
glGenBuffers(1, &handle);
|
||||||
|
|
||||||
|
return VBO(handle, type, dynamic);
|
||||||
|
}
|
||||||
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
glDeleteBuffers(1, &handle);
|
glDeleteBuffers(1, &handle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
namespace simpleengine::gfx {
|
namespace simpleengine::gfx {
|
||||||
Model::Model(GLFWwindow* window, gfx::Shader shader, std::vector<LitVertex> vertices, std::vector<GLuint> indicies) :
|
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)),
|
simpleengine::Renderable(window), shader(shader), vertices(vertices), indicies(indicies), vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)),
|
||||||
ebo(gfx::VBO(GL_ELEMENT_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) :
|
Model::Model(GLFWwindow* window, GLuint shader_program, std::vector<LitVertex> vertices, std::vector<GLuint> indicies) :
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue