Start working on scene based rendering
The renderer will render a scene object which has entities and "stray" models to render
This commit is contained in:
parent
3a49373d75
commit
61ff63bef0
|
@ -1,22 +1,24 @@
|
||||||
#include "simpleengine/camera.h"
|
#include "simpleengine/camera.h"
|
||||||
#include "simpleengine/gfx/light.h"
|
#include "simpleengine/gfx/light.h"
|
||||||
|
#include "simpleengine/gfx/material.h"
|
||||||
#include "simpleengine/gfx/model.h"
|
#include "simpleengine/gfx/model.h"
|
||||||
#include "simpleengine/gfx/renderer.h"
|
#include "simpleengine/gfx/renderer.h"
|
||||||
#include "simpleengine/gfx/texture.h"
|
#include "simpleengine/gfx/texture.h"
|
||||||
#include "simpleengine/objects/3d/terrain.h"
|
|
||||||
#include "simpleengine/vector.h"
|
#include "simpleengine/vector.h"
|
||||||
#include <glm/ext/matrix_clip_space.hpp>
|
|
||||||
#include <glm/fwd.hpp>
|
|
||||||
#include <memory>
|
|
||||||
#include <simpleengine/gfx/shader.h>
|
#include <simpleengine/gfx/shader.h>
|
||||||
#include <simpleengine/renderable.h>
|
#include <simpleengine/renderable.h>
|
||||||
#include <simpleengine/event/event.h>
|
#include <simpleengine/event/event.h>
|
||||||
#include <simpleengine/shader_program.h>
|
#include <simpleengine/shader_program.h>
|
||||||
#include <simpleengine/game.h>
|
#include <simpleengine/game.h>
|
||||||
#include <simpleengine/vertex.h>
|
#include <simpleengine/vertex.h>
|
||||||
#include <simpleengine/objects/3d/mesh.h>
|
|
||||||
#include <simpleengine/gfx/shaders/core_3d_shader.h>
|
#include <simpleengine/gfx/shaders/core_3d_shader.h>
|
||||||
|
|
||||||
|
#include <simpleengine/scene.h>
|
||||||
|
|
||||||
|
#include <glm/ext/matrix_clip_space.hpp>
|
||||||
|
#include <glm/fwd.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -33,22 +35,6 @@ 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);
|
||||||
|
@ -153,14 +139,17 @@ int main(int argc, char *argv[]) {
|
||||||
5, 6, 12, 12, 6, 13
|
5, 6, 12, 12, 6, 13
|
||||||
};
|
};
|
||||||
|
|
||||||
auto cube = std::make_shared<se::gfx::Model>(game.get_window(), core_shader, cube_vertices, cube_indicies);
|
se::gfx::Material material(white_texture, 1.f, 0.f, 0.f, 0.f, 0.f);
|
||||||
|
|
||||||
|
auto cube = std::make_shared<se::gfx::Model>(cube_vertices, cube_indicies,
|
||||||
|
std::optional<se::gfx::Material>(material));
|
||||||
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);
|
/* auto renderer = std::make_shared<se::gfx::Renderer>(game.get_window(), core_shader);
|
||||||
renderer->add_model(white_texture, cube);
|
renderer->add_model(white_texture, cube);
|
||||||
game.add_event(renderer);
|
game.add_event(renderer); */
|
||||||
|
|
||||||
/* auto r_event = std::make_shared<RendererEvent>(renderer);
|
/* auto r_event = std::make_shared<RendererEvent>(renderer);
|
||||||
game.add_event(r_event); */
|
game.add_event(r_event); */
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
namespace simpleengine {
|
namespace simpleengine {
|
||||||
class Camera : public simpleengine::Event {
|
class Camera : public simpleengine::Event {
|
||||||
private:
|
private:
|
||||||
//glm::vec3 camera_forward;
|
GLFWwindow* window;
|
||||||
public:
|
public:
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
glm::vec3 rotation;
|
glm::vec3 rotation;
|
||||||
|
@ -20,9 +20,6 @@ namespace simpleengine {
|
||||||
|
|
||||||
glm::mat4 projection_matrix;
|
glm::mat4 projection_matrix;
|
||||||
glm::mat4 view_matrix;
|
glm::mat4 view_matrix;
|
||||||
//glm::vec3 camera_rotation;
|
|
||||||
/* glm::vec3 world_up = glm::vec3(0.f, 1.f, 0.f);
|
|
||||||
glm::vec3 cam_front = glm::vec3(0.f, 0.f, -1.f); */
|
|
||||||
glm::vec3 camera_front = glm::vec3(0.0f, 0.0f, -1.0f);
|
glm::vec3 camera_front = glm::vec3(0.0f, 0.0f, -1.0f);
|
||||||
glm::vec3 camera_up = glm::vec3(0.0f, 1.0f, 0.0f);
|
glm::vec3 camera_up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
|
@ -40,6 +37,5 @@ namespace simpleengine {
|
||||||
glm::vec3 cam_front = glm::vec3(0.f, 0.f, -1.f));
|
glm::vec3 cam_front = glm::vec3(0.f, 0.f, -1.f));
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override;
|
virtual void update(const float& delta_time) override;
|
||||||
virtual void render(GLFWwindow* target) override;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "gfx/model.h"
|
||||||
|
#include "event/event.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace simpleengine {
|
||||||
|
/**
|
||||||
|
* @brief A Model is a object that will be shown on the screen by a renderer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Component : public simpleengine::Event {
|
||||||
|
public:
|
||||||
|
Component() = default;
|
||||||
|
|
||||||
|
virtual void update(const float& delta_time) override {
|
||||||
|
std::cout << "Component update" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::vector<std::shared_ptr<gfx::Model>> get_renderable_models() {
|
||||||
|
std::cout << "Got renderables" << std::endl;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "component.h"
|
||||||
|
#include "transformable.h"
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace simpleengine {
|
||||||
|
/**
|
||||||
|
* @brief A Model is a object that will be shown on the screen by a renderer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Entity : public simpleengine::Event, public simpleengine::Transformable {
|
||||||
|
public:
|
||||||
|
std::vector<Component> components;
|
||||||
|
|
||||||
|
Entity(std::vector<Component> components = {}) : components(components) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void update(const float& delta_time) override {
|
||||||
|
std::cout << "Update entity" << std::endl;
|
||||||
|
|
||||||
|
for (auto& component : components) {
|
||||||
|
component.update(delta_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::vector<std::shared_ptr<gfx::Model>> get_renderable_models() {
|
||||||
|
std::cout << "Got renderables from entity" << std::endl;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<gfx::Model>> models;
|
||||||
|
for (auto& component : components) {
|
||||||
|
std::vector<std::shared_ptr<gfx::Model>> comp_models = component.get_renderable_models();
|
||||||
|
|
||||||
|
// Move comp_models into models
|
||||||
|
models.insert(models.end(), std::make_move_iterator(comp_models.begin()),
|
||||||
|
std::make_move_iterator(comp_models.end()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return models;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -9,12 +9,9 @@
|
||||||
namespace simpleengine {
|
namespace simpleengine {
|
||||||
class Event : public simpleengine::Destructable {
|
class Event : public simpleengine::Destructable {
|
||||||
public:
|
public:
|
||||||
explicit Event(GLFWwindow* window = nullptr) : window(window) {}
|
Event() = default;
|
||||||
virtual ~Event() = default;
|
virtual ~Event() = default;
|
||||||
|
|
||||||
virtual void update(const float& delta_time) = 0;
|
virtual void update(const float& delta_time) = 0;
|
||||||
virtual void render(GLFWwindow* target) = 0;
|
|
||||||
protected:
|
|
||||||
GLFWwindow* window;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "texture.h"
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
namespace simpleengine::gfx {
|
||||||
|
class Material {
|
||||||
|
public:
|
||||||
|
Texture texture;
|
||||||
|
|
||||||
|
float ambient_scalar;
|
||||||
|
float diffuse_scalar;
|
||||||
|
float specular_scalar;
|
||||||
|
float shine;
|
||||||
|
float reflectivity;
|
||||||
|
|
||||||
|
Material(Texture texture, float shine, float reflectivity, float specular_scalar, float ambient_scalar, float diffuse_scalar) :
|
||||||
|
texture(texture), ambient_scalar(ambient_scalar), diffuse_scalar(diffuse_scalar), specular_scalar(specular_scalar),
|
||||||
|
shine(shine), reflectivity(reflectivity) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,38 +1,34 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
|
#include "../event/event.h"
|
||||||
#include "vao.h"
|
#include "vao.h"
|
||||||
#include "vbo.h"
|
#include "vbo.h"
|
||||||
#include "../vertex.h"
|
#include "../vertex.h"
|
||||||
#include "../renderable.h"
|
#include "../renderable.h"
|
||||||
#include "../transformable.h"
|
#include "../transformable.h"
|
||||||
|
#include "material.h"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace simpleengine::gfx {
|
namespace simpleengine::gfx {
|
||||||
class Model : public simpleengine::Renderable, public simpleengine::Transformable {
|
/**
|
||||||
|
* @brief A Model is a object that will be shown on the screen by a renderer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Model : public simpleengine::Event, public simpleengine::Transformable {
|
||||||
public:
|
public:
|
||||||
|
std::optional<Material> material;
|
||||||
std::vector<LitVertex> vertices;
|
std::vector<LitVertex> vertices;
|
||||||
std::vector<GLuint> indicies;
|
std::vector<GLuint> indicies;
|
||||||
gfx::VBO ebo;
|
|
||||||
gfx::VBO vbo;
|
|
||||||
gfx::VAO vao;
|
|
||||||
|
|
||||||
gfx::Shader shader;
|
Model(std::vector<LitVertex> vertices, std::vector<GLuint> indicies = std::vector<GLuint>(), std::optional<Material> material = std::nullopt);
|
||||||
|
|
||||||
Model(GLFWwindow* window, gfx::Shader shader, std::vector<LitVertex> vertices, std::vector<GLuint> indicies = std::vector<GLuint>());
|
|
||||||
Model(GLFWwindow* window, GLuint shader_program, std::vector<LitVertex> vertices,
|
|
||||||
std::vector<GLuint> indicies = std::vector<GLuint>());
|
|
||||||
protected:
|
|
||||||
virtual void setup_vertices();
|
|
||||||
public:
|
|
||||||
virtual void update(const float& delta_time) override;
|
virtual void update(const float& delta_time) override;
|
||||||
virtual void render(GLFWwindow* target) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
glm::vec3 compute_face_normal(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& p3);
|
glm::vec3 compute_face_normal(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& p3);
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
/**
|
||||||
* @brief Calculate the normals of the model.
|
* @brief Calculate the normals of the model.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/* #include "shader.h"
|
|
||||||
#include "vao.h"
|
|
||||||
#include "vbo.h"
|
|
||||||
#include "../vertex.h"
|
|
||||||
#include "../renderable.h"
|
|
||||||
#include "../transformable.h" */
|
|
||||||
|
|
||||||
#include "ssbo.h"
|
|
||||||
#include "shader.h"
|
|
||||||
#include "model.h"
|
|
||||||
#include "texture.h"
|
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace simpleengine::gfx {
|
|
||||||
class TexturedModel : public simpleengine::gfx::Model {
|
|
||||||
public:
|
|
||||||
std::vector<gfx::Texture> textures;
|
|
||||||
|
|
||||||
TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector<LitVertex> vertices,
|
|
||||||
std::vector<GLuint> indicies = std::vector<GLuint>());
|
|
||||||
TexturedModel(GLFWwindow* window, GLuint shader_program, gfx::Texture texture, std::vector<LitVertex> vertices,
|
|
||||||
std::vector<GLuint> indicies = std::vector<GLuint>());
|
|
||||||
|
|
||||||
TexturedModel(GLFWwindow* window, gfx::Shader shader, std::vector<gfx::Texture> textures, std::vector<LitVertex> vertices,
|
|
||||||
std::vector<GLuint> indicies = std::vector<GLuint>());
|
|
||||||
TexturedModel(GLFWwindow* window, GLuint shader_program, std::vector<gfx::Texture> textures, std::vector<LitVertex> vertices,
|
|
||||||
std::vector<GLuint> indicies = std::vector<GLuint>());
|
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override;
|
|
||||||
virtual void render(GLFWwindow* target) override;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -50,9 +50,10 @@ namespace simpleengine::gfx {
|
||||||
void bind() const {
|
void bind() const {
|
||||||
glBindVertexArray(handle);
|
glBindVertexArray(handle);
|
||||||
|
|
||||||
|
// TODO: Handle opengl errors EVERYWHERE
|
||||||
GLenum err = glGetError();
|
GLenum err = glGetError();
|
||||||
if (err != GL_NO_ERROR) {
|
if (err != GL_NO_ERROR) {
|
||||||
//fprintf(stderr, "Ran into opengl error: 0x%x\n", err);
|
fprintf(stderr, "Ran into opengl error: 0x%x\n", err);
|
||||||
//std::cerr << "Ran into enum error: "
|
//std::cerr << "Ran into enum error: "
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "../../optional.h"
|
|
||||||
#include "../../vector.h"
|
|
||||||
#include "../../vertex.h"
|
|
||||||
#include "../../renderable.h"
|
|
||||||
#include "../../transformable.h"
|
|
||||||
#include "../../gfx/vao.h"
|
|
||||||
#include "../../gfx/vbo.h"
|
|
||||||
#include "../../gfx/shader.h"
|
|
||||||
#include "../../gfx/texture.h"
|
|
||||||
#include "../../gfx/textured_model.h"
|
|
||||||
|
|
||||||
namespace simpleengine::objects_3d {
|
|
||||||
class Mesh : public simpleengine::gfx::TexturedModel {
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @brief Split a string multiple times (if possible) with a character delimiter.
|
|
||||||
*
|
|
||||||
* @param str The string to split.
|
|
||||||
* @param delim The character to split by.
|
|
||||||
* @return std::vector<std::string> The tokens that were split out of str.
|
|
||||||
*/
|
|
||||||
std::vector<std::string> split_string(std::string str, const char delim);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Process a vertex from tokens read from the .obj file.
|
|
||||||
*
|
|
||||||
* @param vertex_data The vertex string tokens to process the vertex from.
|
|
||||||
* @param in_textures The texture coords that are unsorted, just read from the .obj file.
|
|
||||||
* @param in_normals The normals that are unsorted, just read from the .obj file.
|
|
||||||
* @param out_indicies (out) The vector to insert the indicies that were extracted from `vertex_data` into.
|
|
||||||
* @param out_textures (out) The vector to insert the texture coords that were extracted from `vertex_data` into.
|
|
||||||
* @param out_normals (out) The vector to insert the normals that were extracted from `vertex_data` into.
|
|
||||||
*/
|
|
||||||
static void process_vertex(const std::vector<std::string>& vertex_data, const std::vector<glm::vec2>& in_textures,
|
|
||||||
const std::vector<glm::vec3>& in_normals, std::vector<GLuint>& out_indicies, std::vector<glm::vec2>& out_textures, std::vector<glm::vec3>& out_normals);
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @brief This is replaced with `lit_vertices`!!!!
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
using simpleengine::gfx::Model::vertices;
|
|
||||||
public:
|
|
||||||
std::vector<LitVertex> lit_vertices;
|
|
||||||
|
|
||||||
Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::string filename);
|
|
||||||
Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::ifstream file_stream);
|
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../../gfx/model.h"
|
|
||||||
#include "../../gfx/texture.h"
|
|
||||||
#include "../../gfx/textured_model.h"
|
|
||||||
#include "../../renderable.h"
|
|
||||||
#include "../../vertex.h"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace simpleengine::objects_3d {
|
|
||||||
class Terrain : public simpleengine::gfx::TexturedModel {
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @brief DO NOT USE!!! Replaced with lit_vertices
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
using gfx::Model::vertices;
|
|
||||||
public:
|
|
||||||
std::vector<LitVertex> lit_vertices;
|
|
||||||
const float size;
|
|
||||||
const int vertex_count;
|
|
||||||
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
|
|
||||||
gfx::Texture texture;
|
|
||||||
|
|
||||||
Terrain(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, int grid_x, int grid_y, float size = 800.f, int vertex_count = 128) :
|
|
||||||
simpleengine::gfx::TexturedModel(window, shader, { texture }, std::vector<LitVertex>()), x(grid_x * size), y(grid_y * size),
|
|
||||||
texture(texture), size(size), vertex_count(vertex_count) {
|
|
||||||
|
|
||||||
generate_terrain();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void setup_vertices() override {
|
|
||||||
vao.bind();
|
|
||||||
vbo.buffer(lit_vertices.data(), 0, sizeof(LitVertex) * lit_vertices.size());
|
|
||||||
ebo.buffer(indicies.data(), 0, 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, 1, 2, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, tex_coord));
|
|
||||||
vao.enable_attrib(vbo, 2, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, normal));
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
void generate_terrain() {
|
|
||||||
lit_vertices.clear();
|
|
||||||
indicies.clear();
|
|
||||||
|
|
||||||
// Reserve space for vertices and indicies before hand.
|
|
||||||
int count = pow(vertex_count, 2);
|
|
||||||
lit_vertices.reserve(count);
|
|
||||||
indicies.reserve(6 * pow(vertex_count - 1, 2));
|
|
||||||
|
|
||||||
int vertex_index = 0;
|
|
||||||
for (int i = 0; i < vertex_count; i++) {
|
|
||||||
for (int j = 0; j < vertex_count; j++) {
|
|
||||||
Vectorf pos( (float) j / ((float) vertex_count - 1) * size, 0, (float) i / ((float) vertex_count - 1) * size);
|
|
||||||
glm::vec2 tex( (float) j / (float) vertex_count - 1, (float) i / (float) vertex_count - 1);
|
|
||||||
glm::vec3 normals(0, 1, 0);
|
|
||||||
lit_vertices.emplace_back(pos, tex, normals);
|
|
||||||
|
|
||||||
vertex_index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int indicies_index = 0;
|
|
||||||
for (int i = 0; i < vertex_count; i++) {
|
|
||||||
for (int j = 0; j < vertex_count; j++) {
|
|
||||||
int top_left = (i * vertex_count) + j;
|
|
||||||
int top_right = top_left + 1;
|
|
||||||
int bottom_left = ((i + 1) * vertex_count) + j;
|
|
||||||
int bottom_right = bottom_left + 1;
|
|
||||||
|
|
||||||
indicies.push_back(top_left);
|
|
||||||
indicies.push_back(bottom_left);
|
|
||||||
indicies.push_back(top_right);
|
|
||||||
indicies.push_back(top_right);
|
|
||||||
indicies.push_back(bottom_left);
|
|
||||||
indicies.push_back(bottom_right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "========= New terrain generated =========" << std::endl;
|
|
||||||
std::cout << " Lit vertices count: " << lit_vertices.size() << std::endl;
|
|
||||||
std::cout << " Indicies count: " << indicies.size() << std::endl;
|
|
||||||
|
|
||||||
setup_vertices();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual void render(GLFWwindow* target) override {
|
|
||||||
|
|
||||||
} */
|
|
||||||
};
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,9 +9,11 @@
|
||||||
namespace simpleengine {
|
namespace simpleengine {
|
||||||
class Renderable : public simpleengine::Event {
|
class Renderable : public simpleengine::Event {
|
||||||
private:
|
private:
|
||||||
using super = simpleengine::Event;
|
using Super = simpleengine::Event;
|
||||||
public:
|
public:
|
||||||
explicit Renderable(GLFWwindow* window = nullptr) : super(window) {}
|
Renderable() = default;
|
||||||
virtual ~Renderable() = default;
|
virtual ~Renderable() = default;
|
||||||
|
|
||||||
|
virtual void render(GLFWwindow* target) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "gfx/model.h"
|
||||||
|
#include "entity.h"
|
||||||
|
#include "event/event.h"
|
||||||
|
#include "renderable.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace simpleengine {
|
||||||
|
class Scene : public simpleengine::Event {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief A list of entities in this scene.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
std::vector<std::shared_ptr<Entity>> entities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Models that don't belong to an entity.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
std::vector<std::shared_ptr<gfx::Model>> stray_models;
|
||||||
|
|
||||||
|
Scene() = default;
|
||||||
|
|
||||||
|
void add_entity(std::shared_ptr<Entity> entity) {
|
||||||
|
entities.push_back(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_stray_model(std::shared_ptr<gfx::Model> stray) {
|
||||||
|
stray_models.push_back(stray);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void update(const float& delta_time) override {
|
||||||
|
for (auto& entity : entities) {
|
||||||
|
entity->update(delta_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
namespace simpleengine {
|
namespace simpleengine {
|
||||||
Camera::Camera(GLFWwindow* window, gfx::Shader shader, float fov, glm::vec3 position, glm::vec3 rotation,
|
Camera::Camera(GLFWwindow* window, gfx::Shader shader, float fov, glm::vec3 position, glm::vec3 rotation,
|
||||||
float near_plane, float far_plane, glm::vec3 world_up, glm::vec3 cam_front) : simpleengine::Event(window), shader(shader),
|
float near_plane, float far_plane, glm::vec3 world_up, glm::vec3 cam_front) : window(window), shader(shader),
|
||||||
projection_matrix(1.f), view_matrix(1.f), fov(fov), position(position), rotation(rotation), near_plane(near_plane), far_plane(far_plane) {
|
projection_matrix(1.f), view_matrix(1.f), fov(fov), position(position), rotation(rotation), near_plane(near_plane), far_plane(far_plane) {
|
||||||
|
|
||||||
// TODO: Update width and height on window resize.
|
// TODO: Update width and height on window resize.
|
||||||
|
@ -100,8 +100,4 @@ namespace simpleengine {
|
||||||
shader.set_uniform_matrix_4f("projection_matrix", projection_matrix, false);
|
shader.set_uniform_matrix_4f("projection_matrix", projection_matrix, false);
|
||||||
shader.unuse();
|
shader.unuse();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::render(GLFWwindow* target) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -94,7 +94,7 @@ void simpleengine::Game::render_window(const float& delta_time) {
|
||||||
|
|
||||||
void simpleengine::Game::render_items(const float& delta_time) {
|
void simpleengine::Game::render_items(const float& delta_time) {
|
||||||
for (const std::shared_ptr<Event>& event : events) {
|
for (const std::shared_ptr<Event>& event : events) {
|
||||||
event->render(window);
|
//event->render(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,60 +1,15 @@
|
||||||
#include "gfx/model.h"
|
#include "gfx/model.h"
|
||||||
|
|
||||||
namespace simpleengine::gfx {
|
namespace simpleengine::gfx {
|
||||||
Model::Model(GLFWwindow* window, gfx::Shader shader, std::vector<LitVertex> vertices, std::vector<GLuint> indicies) :
|
Model::Model(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, std::optional<Material> material) :
|
||||||
simpleengine::Renderable(window), shader(shader), vertices(vertices), indicies(indicies), vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)),
|
material(material), vertices(vertices), indicies(indicies) {
|
||||||
ebo(gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false)), vao(gfx::VAO::init()) {
|
|
||||||
|
|
||||||
//setup_vertices();
|
|
||||||
}
|
|
||||||
|
|
||||||
Model::Model(GLFWwindow* window, GLuint shader_program, std::vector<LitVertex> vertices, std::vector<GLuint> indicies) :
|
|
||||||
Model(window, gfx::Shader(shader_program), vertices, indicies) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Model::setup_vertices() {
|
|
||||||
vao.bind();
|
|
||||||
vbo.buffer(vertices.data(), 0, sizeof(LitVertex) * vertices.size());
|
|
||||||
if (!indicies.empty()) {
|
|
||||||
ebo.buffer(indicies.data(), 0, 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));
|
|
||||||
// Attribute 2 is used for normals
|
|
||||||
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));
|
|
||||||
|
|
||||||
/* vao.disable_attrib(vbo, 2);
|
|
||||||
vao.disable_attrib(vbo, 4);
|
|
||||||
vao.set_attrib_value(vbo, 4, -1.f); */
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::update(const float& delta_time) {
|
void Model::update(const float& delta_time) {
|
||||||
this->rotate_y(1.f);
|
this->rotate_y(1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::render(GLFWwindow* target) {
|
|
||||||
shader.use();
|
|
||||||
shader.set_uniform_matrix_4f("transform_matrix", transform_matrix, false);
|
|
||||||
|
|
||||||
// When binding to the texture, also tell the shader if the texture is set or not.
|
|
||||||
//shader.set_uniform_int("texture_is_set", (GLint) false, false);
|
|
||||||
|
|
||||||
vao.bind();
|
|
||||||
if (indicies.empty()) {
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
|
|
||||||
} else {
|
|
||||||
glDrawElements(GL_TRIANGLES, indicies.size(), GL_UNSIGNED_INT, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 Model::compute_face_normal(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& p3) {
|
glm::vec3 Model::compute_face_normal(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& p3) {
|
||||||
// Uses p2 as a new origin for p1,p3
|
// Uses p2 as a new origin for p1,p3
|
||||||
auto a = p3 - p2;
|
auto a = p3 - p2;
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
#include "gfx/textured_model.h"
|
|
||||||
#include "gfx/ssbo.h"
|
|
||||||
|
|
||||||
namespace simpleengine::gfx {
|
|
||||||
TexturedModel::TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector<LitVertex> vertices,
|
|
||||||
std::vector<GLuint> indicies) : simpleengine::gfx::Model(window, shader, vertices, indicies),
|
|
||||||
textures(std::vector<gfx::Texture>{texture}) {
|
|
||||||
}
|
|
||||||
|
|
||||||
TexturedModel::TexturedModel(GLFWwindow* window, GLuint shader_program, gfx::Texture texture,
|
|
||||||
std::vector<LitVertex> vertices, std::vector<GLuint> indicies) : TexturedModel(window, gfx::Shader(shader_program),
|
|
||||||
std::vector<gfx::Texture>{texture}, vertices, indicies) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TexturedModel::TexturedModel(GLFWwindow* window, gfx::Shader shader, std::vector<gfx::Texture> textures, std::vector<LitVertex> vertices,
|
|
||||||
std::vector<GLuint> indicies) : simpleengine::gfx::Model(window, shader, vertices, indicies),
|
|
||||||
textures(textures) {
|
|
||||||
}
|
|
||||||
|
|
||||||
TexturedModel::TexturedModel(GLFWwindow* window, GLuint shader_program, std::vector<gfx::Texture> textures,
|
|
||||||
std::vector<LitVertex> vertices, std::vector<GLuint> indicies) : TexturedModel(window, gfx::Shader(shader_program),
|
|
||||||
textures, vertices, indicies) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void TexturedModel::update(const float& delta_time) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void TexturedModel::render(GLFWwindow* target) {
|
|
||||||
shader.use();
|
|
||||||
shader.set_uniform_matrix_4f("transform_matrix", 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);
|
|
||||||
|
|
||||||
/* int samples[2] = { 0, 1 };
|
|
||||||
float shine[2] = { 1.f, 1.f};
|
|
||||||
float reflectivity[2] = { 0.f, 0.f};
|
|
||||||
|
|
||||||
shader.set_uniform_int_array("u_textures", 2, samples, false);
|
|
||||||
shader.set_uniform_float_array("u_texture_shine", 2, shine, false);
|
|
||||||
shader.set_uniform_float_array("u_texture_reflectivity", 2, reflectivity, false); */
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + tex_id);
|
|
||||||
glBindTextureUnit(tex_id, textures.front().get_texture_id());
|
|
||||||
const auto& texture = textures.front();
|
|
||||||
texture.bind();
|
|
||||||
|
|
||||||
vao.bind();
|
|
||||||
if (indicies.empty()) {
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
|
|
||||||
} else {
|
|
||||||
glDrawElements(GL_TRIANGLES, indicies.size(), GL_UNSIGNED_INT, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,126 +0,0 @@
|
||||||
#include "objects/3d/mesh.h"
|
|
||||||
|
|
||||||
namespace simpleengine::objects_3d {
|
|
||||||
std::vector<std::string> Mesh::split_string(std::string str, const char delim) {
|
|
||||||
std::istringstream ss(str);
|
|
||||||
|
|
||||||
std::vector<std::string> tokens;
|
|
||||||
size_t pos = 0;
|
|
||||||
std::string token;
|
|
||||||
while ((pos = str.find(delim)) != std::string::npos) {
|
|
||||||
token = str.substr(0, pos);
|
|
||||||
tokens.push_back(token);
|
|
||||||
str.erase(0, pos + 1);
|
|
||||||
}
|
|
||||||
tokens.push_back(str);
|
|
||||||
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mesh::process_vertex(const std::vector<std::string>& vertex_data, const std::vector<glm::vec2>& in_textures,
|
|
||||||
const std::vector<glm::vec3>& in_normals, std::vector<GLuint>& out_indicies,
|
|
||||||
std::vector<glm::vec2>& out_textures, std::vector<glm::vec3>& out_normals) {
|
|
||||||
|
|
||||||
// Get the index the current vertex and put it in indicies
|
|
||||||
int currentVertexIndex = stoi(vertex_data[0]) - 1;
|
|
||||||
out_indicies.push_back(currentVertexIndex);
|
|
||||||
|
|
||||||
// Read texture coords
|
|
||||||
glm::vec2 current_tex = in_textures.at(stoi(vertex_data[1]) - 1);
|
|
||||||
current_tex.y = 1 - current_tex.y;
|
|
||||||
out_textures.at(currentVertexIndex) = current_tex;
|
|
||||||
|
|
||||||
// Read normals
|
|
||||||
glm::vec3 current_norm = in_normals.at(stoi(vertex_data[2]) - 1);
|
|
||||||
out_normals.at(currentVertexIndex) = current_norm;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mesh::Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::string filename) :
|
|
||||||
Mesh(window, shader, texture, std::ifstream(filename, std::ios::in | std::ios::binary)) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Mesh::Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::ifstream file_stream) :
|
|
||||||
simpleengine::gfx::TexturedModel(window, shader, std::vector<gfx::Texture>{texture}, std::vector<LitVertex>()) {
|
|
||||||
|
|
||||||
if (!file_stream.is_open()) {
|
|
||||||
std::cerr << "File stream that was given to ObjModel::ObjModel is not open!" << std::endl;
|
|
||||||
throw std::runtime_error("Failed to open ObjModel model file");
|
|
||||||
}
|
|
||||||
|
|
||||||
// The vertices, texture coords, and normals that were read from the obj file
|
|
||||||
// these are not in a particular order.
|
|
||||||
std::vector<glm::vec3> obj_vertices;
|
|
||||||
std::vector<glm::vec2> obj_textures;
|
|
||||||
std::vector<glm::vec3> obj_normals;
|
|
||||||
|
|
||||||
// The texture coords and normals that have been sorted.
|
|
||||||
std::vector<glm::vec2> textures;
|
|
||||||
std::vector<glm::vec3> normals;
|
|
||||||
|
|
||||||
// Read the vertices, texture coords, and normals. Break when run into indices
|
|
||||||
std::string line;
|
|
||||||
while (std::getline(file_stream, line)) {
|
|
||||||
std::vector<std::string> line_tokens = split_string(line, ' ');
|
|
||||||
|
|
||||||
if (line_tokens.front() == "v") {
|
|
||||||
//glm::vec3 vertex(stof(line_tokens[1]), stof(line_tokens[2]), stof(line_tokens[3]));
|
|
||||||
obj_vertices.emplace_back(stof(line_tokens[1]), stof(line_tokens[2]), stof(line_tokens[3]));
|
|
||||||
} else if (line_tokens.front() == "vt") {
|
|
||||||
obj_textures.emplace_back(stof(line_tokens[1]), stof(line_tokens[2]));
|
|
||||||
} else if (line_tokens.front() == "vn") {
|
|
||||||
obj_normals.emplace_back(stof(line_tokens[1]), stof(line_tokens[2]), stof(line_tokens[3]));
|
|
||||||
} else if (line_tokens.front() == "f") {
|
|
||||||
auto size = obj_vertices.size();
|
|
||||||
textures.resize(size);
|
|
||||||
normals.resize(size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process the indicies. This will sort everything for storing inside of the Vertex list.
|
|
||||||
do {
|
|
||||||
if (!line.starts_with("f")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::vector<std::string> line_tokens = split_string(line, ' ');
|
|
||||||
std::vector<std::string> vertex1 = split_string(line_tokens[1], '/');
|
|
||||||
std::vector<std::string> vertex2 = split_string(line_tokens[2], '/');
|
|
||||||
std::vector<std::string> vertex3 = split_string(line_tokens[3], '/');
|
|
||||||
|
|
||||||
process_vertex(vertex1, obj_textures, obj_normals, indicies, textures, normals);
|
|
||||||
process_vertex(vertex2, obj_textures, obj_normals, indicies, textures, normals);
|
|
||||||
process_vertex(vertex3, obj_textures, obj_normals, indicies, textures, normals);
|
|
||||||
} while (std::getline(file_stream, line));
|
|
||||||
|
|
||||||
file_stream.close();
|
|
||||||
|
|
||||||
const int texture_id = 0;
|
|
||||||
|
|
||||||
std::cout << "Texture ID: " << texture_id << std::endl;
|
|
||||||
|
|
||||||
// Insert everything into lit_vertices.
|
|
||||||
for (int i = 0; i < obj_vertices.size(); i++) {
|
|
||||||
lit_vertices.emplace_back(simpleengine::Vectorf(obj_vertices.at(i)), glm::vec3(1.f), textures.at(i), normals.at(i), texture_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create VAO and EBO and assign buffers
|
|
||||||
vao.bind();
|
|
||||||
vbo.buffer(lit_vertices.data(), 0, sizeof(LitVertex) * lit_vertices.size());
|
|
||||||
ebo.buffer(indicies.data(), 0, 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mesh::update(const float& delta_time) {
|
|
||||||
this->rotate_y(0.0005f); // Slowly rotate (for debugging)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue