Implement batched rendering with multiple textures

This commit is contained in:
SeanOMik 2022-08-18 11:34:05 -04:00
parent db94d85168
commit 0226819a46
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
26 changed files with 557 additions and 143 deletions

28
CMake/Findsoil2.cmake Normal file
View File

@ -0,0 +1,28 @@
# Find SOIL2
# Find the SOIL2 includes and library
#
# SOIL2_INCLUDE_DIRS - where to find SOIL2.h, etc.
# SOIL2_LIBRARIES - List of libraries when using SOIL2.
# SOIL2_FOUND - True if SOIL2 found.
#
# Based on the FindZLIB.cmake module.
IF (SOIL2_INCLUDE_DIR)
# Already in cache, be silent
SET(SOIL2_FIND_QUIETLY TRUE)
ENDIF (SOIL2_INCLUDE_DIR)
FIND_PATH(SOIL2_INCLUDE_DIR SOIL2.h PATH_SUFFIXES include/SOIL2 include)
SET(SOIL2_NAMES SOIL2 SOIL2 soil2)
FIND_LIBRARY(SOIL2_LIBRARY NAMES ${SOIL2_NAMES} )
MARK_AS_ADVANCED( SOIL2_LIBRARY SOIL2_INCLUDE_DIR )
# Per-recommendation
SET(SOIL2_INCLUDE_DIRS "${SOIL2_INCLUDE_DIR}")
SET(SOIL2_LIBRARIES "${SOIL2_LIBRARY}")
# handle the QUIETLY and REQUIRED arguments and set SOIL2_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(soil2 DEFAULT_MSG SOIL2_LIBRARIES SOIL2_INCLUDE_DIRS)

View File

@ -3,14 +3,24 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
project(SimpleEngine) project(SimpleEngine)
include(cmrc/CMakeRC.cmake) include(cmrc/CMakeRC.cmake)
include(CMake/Findsoil2.cmake)
# Add some CMake options: # Add some CMake options:
option(SIMPLE_ENGINE_BUILD_EXAMPLES "Build example projects" ON) option(SIMPLE_ENGINE_BUILD_EXAMPLES "Build example projects" ON)
# By default use OpenGL GLVND
option(SIMPLE_ENGINE_USE_GL_LEGACY "Use OpenGL legacy, or use BLVND" OFF)
if (SIMPLE_ENGINE_USE_GL_LEGACY)
set(OpenGL_GL_PREFERENCE "LEGACY")
else()
set(OpenGL_GL_PREFERENCE "GLVND")
endif()
find_package(GLEW REQUIRED) find_package(GLEW REQUIRED)
find_package(glfw3 CONFIG REQUIRED) find_package(glfw3 CONFIG REQUIRED)
find_package(glm CONFIG REQUIRED) find_package(glm CONFIG REQUIRED)
find_package(soil2 CONFIG REQUIRED) find_package(soil2 REQUIRED)
find_package(OpenGL REQUIRED)
# Link sources # Link sources
file(GLOB_RECURSE source_list src/*.cpp) file(GLOB_RECURSE source_list src/*.cpp)
@ -32,10 +42,13 @@ cmrc_add_resource_library(
# Link dependencies # Link dependencies
target_link_libraries(simpleengine PUBLIC GLEW::GLEW) target_link_libraries(simpleengine PUBLIC GLEW::GLEW)
target_link_libraries(simpleengine PUBLIC glfw) target_link_libraries(simpleengine PUBLIC glfw)
target_link_libraries(simpleengine PUBLIC glm::glm) target_link_libraries(simpleengine PUBLIC glm)
target_link_libraries(simpleengine PUBLIC soil2) target_link_libraries(simpleengine PUBLIC soil2)
target_link_libraries(simpleengine PUBLIC ${OPENGL_LIBRARIES})
target_link_libraries(simpleengine PRIVATE simpleengine_resources) target_link_libraries(simpleengine PRIVATE simpleengine_resources)
# Include some dependencies' include directories
include_directories(${OPENGL_INCLUDE_DIR})
include_directories(${GLM_INCLUDE_DIRS}) include_directories(${GLM_INCLUDE_DIRS})
# Add examples as a target if the user has them enabled # Add examples as a target if the user has them enabled

2
cmrc

@ -1 +1 @@
Subproject commit a64bea50c05594c8e7cf1f08e441bb9507742e2e Subproject commit e386a629eb537d384811e598a3c96b9ca928f65e

View File

@ -0,0 +1,3 @@
*.blend
*.obj
*.png

View File

@ -2,16 +2,18 @@
#include "simpleengine/gfx/light.h" #include "simpleengine/gfx/light.h"
#include "simpleengine/gfx/model.h" #include "simpleengine/gfx/model.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/ext/matrix_clip_space.hpp>
#include <glm/fwd.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/obj_model.h> #include <simpleengine/objects/3d/mesh.h>
#include <simpleengine/gfx/shaders/core_3d_shader.h> #include <simpleengine/gfx/shaders/core_3d_shader.h>
#include <chrono> #include <chrono>
@ -22,7 +24,11 @@
#include <cmrc/cmrc.hpp> #include <cmrc/cmrc.hpp>
CMRC_DECLARE(resource_shaders); CMRC_DECLARE(resource_shaders);
#ifdef __linux__
#include <SOIL2.h>
#else
#include <SOIL2/SOIL2.h> #include <SOIL2/SOIL2.h>
#endif
namespace se = simpleengine; namespace se = simpleengine;
@ -39,23 +45,33 @@ int main(int argc, char *argv[]) {
/* se::gfx::Texture wall_texture("resources/wall.jpg"); /* se::gfx::Texture wall_texture("resources/wall.jpg");
se::gfx::Texture crate_texture("resources/container.jpg", true, true); */ se::gfx::Texture crate_texture("resources/container.jpg", true, true); */
// Load core shaders from simpleengine resources // Load core shaders from SimpleEngine resources
se::gfx::shaders::Core3dShader core_shader; se::gfx::shaders::Core3dShader core_shader;
auto light = std::make_shared<se::gfx::Light>(core_shader, glm::vec3(0.f, 0.f, -20.f), glm::vec3(1.f, 1.f, 1.f)); auto light = std::make_shared<se::gfx::Light>(core_shader, glm::vec3(0.f, 1.f, -10.f), glm::vec3(1.f, 1.f, 1.f));
game.add_event(light); game.add_event(light);
se::gfx::Texture white_texture("examples/dev_testing/resources/white_texture.png"); se::gfx::Texture white_texture("examples/dev_testing/resources/white_texture.png");
/* white_texture.shine_damper = 10; // white_texture.shine_damper = 10;
white_texture.reflectivity = 1; */ //white_texture.reflectivity = 1;
auto dragon = std::make_shared<se::objects_3d::ObjModel>(game.get_window(), core_shader, white_texture, "examples/dev_testing/resources/dragon.obj"); /* auto dragon = std::make_shared<se::objects_3d::Mesh>(game.get_window(), core_shader, white_texture, "examples/dev_testing/resources/dragon.obj");
dragon->translate(0.f, -5.f, -25.f); dragon->translate(0.f, -5.f, -15.f);
game.add_event(dragon); game.add_event(dragon); */
/* se::gfx::Texture stall_texture("resources/stallTexture.png"); /* auto cube = std::make_shared<se::objects_3d::Mesh>(game.get_window(), core_shader, white_texture, "examples/dev_testing/resources/cube.obj");
auto stall = std::make_shared<se::objects_3d::ObjModel>(game.get_window(), core_shader, stall_texture, "resources/stall.obj"); cube->translate(0.f, -5.f, -15.f);
stall->translate(0.f, -4.f, -25.f); game.add_event(cube);
game.add_event(stall); */
se::gfx::Texture grass("examples/dev_testing/resources/grass.png");
auto terrain = std::make_shared<se::objects_3d::Terrain>(game.get_window(), core_shader, grass, 0, 0);
terrain->translate(0.f, -5.f, -15.f);
game.add_event(terrain); */
se::gfx::Texture stall_texture("examples/dev_testing/resources/stallTextureb.png");
auto stall = std::make_shared<se::objects_3d::Mesh>(game.get_window(), core_shader, stall_texture, "examples/dev_testing/resources/stall.obj");
stall->translate(10.f, -5.f, 0.f);
stall->rotate_y(90.f);
game.add_event(stall);
/* std::vector<se::Vertex> square_vertices = { /* std::vector<se::Vertex> square_vertices = {
{ se::Vectorf(0.5f, 0.5f, -1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 0.f) }, // top right { se::Vectorf(0.5f, 0.5f, -1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 0.f) }, // top right
@ -71,10 +87,16 @@ int main(int argc, char *argv[]) {
auto square = std::make_shared<se::gfx::Model>(game.get_window(), core_shader, square_vertices, indicies); auto square = std::make_shared<se::gfx::Model>(game.get_window(), core_shader, square_vertices, indicies);
square->translate(1.25f, 0.f, -1.f); square->translate(1.25f, 0.f, -1.f);
square->scale(.75f); //square->rotate_y(90.f);
game.add_event(square); //square->scale(.75f);
game.add_event(square); */
std::vector<se::Vertex> tri_vertices = { /* se::gfx::Texture white_texture("examples/dev_testing/resources/white_texture.png");
auto cube = std::make_shared<se::objects_3d::Mesh>(game.get_window(), core_shader, white_texture, "examples/dev_testing/resources/cube.obj");
cube->translate(-1.25f, 0.f, -1.f);
game.add_event(cube); */
/* std::vector<se::Vertex> tri_vertices = {
{ se::Vectorf(-0.5f, -0.5f, -1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 0.f) }, // top right { se::Vectorf(-0.5f, -0.5f, -1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 0.f) }, // top right
{ se::Vectorf(0.5f, -0.5f, -1.f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) }, // bottom right { se::Vectorf(0.5f, -0.5f, -1.f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) }, // bottom right
{ se::Vectorf(0.f, 0.5f, -1.f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(0.5f, 1.0f) }, // bottom left { se::Vectorf(0.f, 0.5f, -1.f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(0.5f, 1.0f) }, // bottom left
@ -86,56 +108,39 @@ int main(int argc, char *argv[]) {
game.add_event(tri); */ game.add_event(tri); */
/* std::vector<se::Vertex> cube_vertices = { /* std::vector<se::Vertex> cube_vertices = {
{ se::Vectorf(-0.5f,0.5f,-0.5f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(1.f, 1.f) }, { se::Vectorf(-1.f, -1.f, -1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 0.f) },
{ se::Vectorf(-0.5f,-0.5f,-0.5f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) }, { se::Vectorf(1.f, -1.f, -1.f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) },
{ se::Vectorf(0.5f,-0.5f,-0.5f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(0.f, 0.f) }, { se::Vectorf(1.f, 1.f, -1.f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(2.f, 0.f) },
{ se::Vectorf(0.5f,0.5f,-0.5f), glm::vec3(1.f, 1.f, 0.f), glm::vec2(0.f, 1.f) }, { se::Vectorf(-1.f, 1.f, -1.f), glm::vec3(1.f, 1.f, 0.f), glm::vec2(3.f, 0.f) },
{ se::Vectorf(-1, -1, -1), glm::vec3(1.f, 1.f, 0.f), glm::vec2(4.f, 0.f) },
{ se::Vectorf(-0.5f,0.5f,0.5f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(1.f, 1.f) }, { se::Vectorf(-1, -1, 1), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 1.f) },
{ se::Vectorf(-0.5f,-0.5f,0.5f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) }, { se::Vectorf(1, -1, 1), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 1.f) },
{ se::Vectorf(0.5f,-0.5f,0.5f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(0.f, 0.f) }, { se::Vectorf(1, 1, 1), glm::vec3(0.f, 0.f, 1.f), glm::vec2(2.f, 1.f) },
{ se::Vectorf(0.5f,0.5f,0.5f), glm::vec3(1.f, 1.f, 0.f), glm::vec2(0.f, 1.f) }, { se::Vectorf(-1, 1, 1), glm::vec3(1.f, 1.f, 0.f), glm::vec2(3.f, 1.f) },
{ se::Vectorf(-1, -1, 1), glm::vec3(1.f, 1.f, 0.f), glm::vec2(4.f, 1.f) },
{ se::Vectorf(0.5f,0.5f,-0.5f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(1.f, 1.f) }, { se::Vectorf(-1, 1, -1), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, -1.f) },
{ se::Vectorf(0.5f,-0.5f,-0.5f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) }, { se::Vectorf(1, 1, -1), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, -1.f) },
{ se::Vectorf(0.5f,-0.5f,0.5f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(0.f, 0.f) },
{ se::Vectorf(0.5f,0.5f,0.5f), glm::vec3(1.f, 1.f, 0.f), glm::vec2(0.f, 1.f) },
{ se::Vectorf(-0.5f,0.5f,-0.5f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(1.f, 1.f) }, { se::Vectorf(-1, 1, 1), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 2.f) },
{ se::Vectorf(-0.5f,-0.5f,-0.5f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) }, { se::Vectorf(1, 1, 1), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 2.f) },
{ se::Vectorf(-0.5f,-0.5f,0.5f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(0.f, 0.f) },
{ se::Vectorf(-0.5f,0.5f,0.5f), glm::vec3(1.f, 1.f, 0.f), glm::vec2(0.f, 1.f) },
{ se::Vectorf(-0.5f,0.5f,0.5f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(1.f, 1.f) },
{ se::Vectorf(-0.5f,0.5f,-0.5f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) },
{ se::Vectorf(0.5f,0.5f,-0.5f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(0.f, 0.f) },
{ se::Vectorf(0.5f,0.5f,0.5f), glm::vec3(1.f, 1.f, 0.f), glm::vec2(0.f, 1.f) },
{ se::Vectorf(-0.5f,-0.5f,0.5f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(1.f, 1.f) },
{ se::Vectorf(-0.5f,-0.5f,-0.5f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) },
{ se::Vectorf(0.5f,-0.5f,-0.5f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(0.f, 0.f) },
{ se::Vectorf(0.5f,-0.5f,0.5f), glm::vec3(1.f, 1.f, 0.f), glm::vec2(0.f, 1.f) },
}; };
std::vector<GLuint> cube_indicies = { std::vector<GLuint> cube_indicies = {
0,1,3, 0, 1, 5, 5, 1, 6,
3,1,2, 1, 2, 6, 6, 2, 7,
4,5,7, 2, 3, 7, 7, 3, 8,
7,5,6, 3, 4, 8, 8, 4, 9,
8,9,11, 10, 11, 0, 0, 11, 1,
11,9,10, 5, 6, 12, 12, 6, 13
12,13,15,
15,13,14,
16,17,19,
19,17,18,
20,21,23,
23,21,22
}; };
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->translate(3.f, 0.f, 0.f);
game.add_event(cube); */ game.add_event(cube); */
auto camera = std::make_shared<se::Camera>(game.get_window(), core_shader, 70, glm::vec3(0, 0, -10)); 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);
return game.run(); return game.run();

View File

@ -12,7 +12,7 @@
namespace simpleengine { namespace simpleengine {
class Camera : public simpleengine::Event { class Camera : public simpleengine::Event {
private: private:
//glm::vec3 camera_forward;
public: public:
glm::vec3 position; glm::vec3 position;
glm::vec3 rotation; glm::vec3 rotation;
@ -20,12 +20,16 @@ namespace simpleengine {
glm::mat4 projection_matrix; glm::mat4 projection_matrix;
glm::mat4 view_matrix; glm::mat4 view_matrix;
glm::vec3 world_up = glm::vec3(0.f, 1.f, 0.f); //glm::vec3 camera_rotation;
glm::vec3 cam_front = glm::vec3(0.f, 0.f, -1.f); /* 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_up = glm::vec3(0.0f, 1.0f, 0.0f);
float fov; float fov;
float near_plane; float near_plane;
float far_plane; float far_plane;
float movement_speed = 2.5f;
Camera(GLFWwindow* window, gfx::Shader shader, float fov = 70, glm::vec3 position = glm::vec3(0.f), glm::vec3 rotation = glm::vec3(0.f), Camera(GLFWwindow* window, gfx::Shader shader, float fov = 70, glm::vec3 position = glm::vec3(0.f), glm::vec3 rotation = glm::vec3(0.f),
float near_plane = 0.1f, float far_plane = 1000.f, glm::vec3 world_up = glm::vec3(0.f, 1.f, 0.f), float near_plane = 0.1f, float far_plane = 1000.f, glm::vec3 world_up = glm::vec3(0.f, 1.f, 0.f),

View File

@ -35,10 +35,10 @@ namespace simpleengine {
void add_event(std::shared_ptr<simpleengine::Event> event); void add_event(std::shared_ptr<simpleengine::Event> event);
void update(); void update(const float& delta_time);
void handle_input(); void handle_input(const float& delta_time);
void render_window(); void render_window(const float& delta_time);
void render_items(); void render_items(const float& delta_time);
void exit(); void exit();
int run(); int run();
@ -53,5 +53,11 @@ namespace simpleengine {
GLFWwindow* window; GLFWwindow* window;
std::vector<std::shared_ptr<simpleengine::Event>> events; std::vector<std::shared_ptr<simpleengine::Event>> events;
const bool& window_resizeable; const bool& window_resizeable;
float get_delta_time();
float last_frame_time;
/* float currentFrameTime;
float deltaTime; */
}; };
} }

View File

@ -24,7 +24,7 @@ namespace simpleengine::gfx {
Model(GLFWwindow* window, GLuint shader_program, std::vector<Vertex> vertices, Model(GLFWwindow* window, GLuint shader_program, std::vector<Vertex> vertices,
std::vector<GLuint> indicies = std::vector<GLuint>()); std::vector<GLuint> indicies = std::vector<GLuint>());
protected: protected:
void setup_vertexes(); virtual void setup_vertices();
public: public:
virtual void update(const float& delta_time) override; virtual void update(const float& delta_time) override;

View File

@ -184,6 +184,9 @@ namespace simpleengine::gfx {
void set_uniform_float(GLint location, GLfloat fl, bool bind_shader = true); void set_uniform_float(GLint location, GLfloat fl, bool bind_shader = true);
void set_uniform_float(const char* uniform_name, GLfloat fl, bool bind_shader = true); void set_uniform_float(const char* uniform_name, GLfloat fl, bool bind_shader = true);
void set_uniform_float_array(GLint location, int count, GLfloat* arr, bool bind_shader = true);
void set_uniform_float_array(const char* uniform_name, int count, GLfloat* arr, bool bind_shader = true);
void set_uniform_float_vec2(GLint location, glm::vec2 vec, bool bind_shader = true); void set_uniform_float_vec2(GLint location, glm::vec2 vec, bool bind_shader = true);
void set_uniform_float_vec2(const char* uniform_name, glm::vec2 vec, bool bind_shader = true); void set_uniform_float_vec2(const char* uniform_name, glm::vec2 vec, bool bind_shader = true);
@ -196,6 +199,9 @@ namespace simpleengine::gfx {
void set_uniform_int(GLint location, GLint i, bool bind_shader = true); void set_uniform_int(GLint location, GLint i, bool bind_shader = true);
void set_uniform_int(const char* uniform_name, GLint i, bool bind_shader = true); void set_uniform_int(const char* uniform_name, GLint i, bool bind_shader = true);
void set_uniform_int_array(GLint location, int count, GLint* arr, bool bind_shader = true);
void set_uniform_int_array(const char* uniform_name, int count, GLint* arr, bool bind_shader = true);
void set_uniform_int_vec2(GLint location, glm::ivec2 vec, bool bind_shader = true); void set_uniform_int_vec2(GLint location, glm::ivec2 vec, bool bind_shader = true);
void set_uniform_int_vec2(const char* uniform_name, glm::ivec2 vec, bool bind_shader = true); void set_uniform_int_vec2(const char* uniform_name, glm::ivec2 vec, bool bind_shader = true);

View File

@ -14,13 +14,13 @@ namespace simpleengine::gfx::shaders {
this->program = glCreateProgram(); this->program = glCreateProgram();
auto vertex_fs = cmrc::simpleengine_resources::get_filesystem(); auto vertex_fs = cmrc::simpleengine_resources::get_filesystem();
cmrc::file vertex_file = vertex_fs.open("resources/shaders/vertex_core.glsl"); cmrc::file vertex_file = vertex_fs.open("resources/shaders/core/3d/vertex_core.glsl");
std::string vertex_source(vertex_file.begin()); std::string vertex_source(vertex_file.begin());
Shader vertex = gfx::Shader::from_source(program, ShaderType::ST_Vertex, vertex_source); Shader vertex = gfx::Shader::from_source(program, ShaderType::ST_Vertex, vertex_source);
this->shader = vertex.shader; this->shader = vertex.shader;
auto fragment_fs = cmrc::simpleengine_resources::get_filesystem(); auto fragment_fs = cmrc::simpleengine_resources::get_filesystem();
cmrc::file fragment_file = fragment_fs.open("resources/shaders/fragment_core.glsl"); cmrc::file fragment_file = fragment_fs.open("resources/shaders/core/3d/fragment_core.glsl");
std::string fragment_source(fragment_file.begin()); std::string fragment_source(fragment_file.begin());
fragment_shader = gfx::Shader::from_source(program, ShaderType::ST_Fragment, fragment_source); fragment_shader = gfx::Shader::from_source(program, ShaderType::ST_Fragment, fragment_source);

View File

@ -0,0 +1,60 @@
#pragma once
#ifdef __linux__
#include <GL/glew.h>
#include <GL/gl.h>
#else
#include <gl/glew.h>
#include <gl/gl.h>
#endif
#include "shader.h"
#include <string>
namespace simpleengine::gfx {
/**
* @brief Shader Storage buffer Object
*
* https://www.khronos.org/opengl/wiki/Shader_Storage_Buffer_Object
*/
class SSBO {
private:
GLuint bind_index;
void gen_buffer() {
glGenBuffers(1, &handle);
}
public:
GLuint handle;
gfx::Shader& shader;
SSBO(gfx::Shader& shader, GLuint bind_index) : bind_index(bind_index), shader(shader) {
gen_buffer();
}
SSBO(gfx::Shader& shader, const std::string& ssbo_name) : shader(shader) {
bind_index = glGetProgramResourceIndex(shader.program, GL_SHADER_STORAGE_BLOCK, ssbo_name.c_str());
gen_buffer();
}
void bind_buffer() {
glBindBuffer(GL_SHADER_STORAGE_BUFFER, handle);
}
void bind_ssbo() {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, bind_index, handle);
}
void buffer(void* data, size_t offset, size_t size) {
bind_buffer();
glBufferData(GL_SHADER_STORAGE_BUFFER, size - offset, data, GL_DYNAMIC_COPY);
}
void unbind() {
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
}
};
}

View File

@ -12,7 +12,11 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#ifdef __linux__
#include <SOIL2.h>
#else
#include <SOIL2/SOIL2.h> #include <SOIL2/SOIL2.h>
#endif
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
@ -26,11 +30,21 @@ namespace simpleengine::gfx {
unsigned int image_type; unsigned int image_type;
public: public:
/**
* @brief The type of the texture
*
*/
enum Type {
TexT_DIFFUSE,
TexT_SPECULAR
};
int height; int height;
int width; int width;
int channels; int channels;
float shine_damper = 1.f; float shine_damper = 1.f;
float reflectivity = 0.f; float reflectivity = 0.f;
Type type;
/** /**
* @brief Construct a new Texture object from a path. * @brief Construct a new Texture object from a path.
@ -61,5 +75,7 @@ namespace simpleengine::gfx {
Texture(std::vector<unsigned char> buffer, bool img_2d = true, bool mipmap = true); Texture(std::vector<unsigned char> buffer, bool img_2d = true, bool mipmap = true);
void bind() const; void bind() const;
unsigned int get_texture_id() const;
}; };
} }

View File

@ -7,6 +7,7 @@
#include "../renderable.h" #include "../renderable.h"
#include "../transformable.h" */ #include "../transformable.h" */
#include "ssbo.h"
#include "shader.h" #include "shader.h"
#include "model.h" #include "model.h"
#include "texture.h" #include "texture.h"
@ -18,13 +19,18 @@
namespace simpleengine::gfx { namespace simpleengine::gfx {
class TexturedModel : public simpleengine::gfx::Model { class TexturedModel : public simpleengine::gfx::Model {
public: public:
gfx::Texture texture; std::vector<gfx::Texture> textures;
TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector<Vertex> vertices, TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector<Vertex> vertices,
std::vector<GLuint> indicies = std::vector<GLuint>()); std::vector<GLuint> indicies = std::vector<GLuint>());
TexturedModel(GLFWwindow* window, GLuint shader_program, gfx::Texture texture, std::vector<Vertex> vertices, TexturedModel(GLFWwindow* window, GLuint shader_program, gfx::Texture texture, std::vector<Vertex> vertices,
std::vector<GLuint> indicies = std::vector<GLuint>()); std::vector<GLuint> indicies = std::vector<GLuint>());
TexturedModel(GLFWwindow* window, gfx::Shader shader, std::vector<gfx::Texture> textures, std::vector<Vertex> vertices,
std::vector<GLuint> indicies = std::vector<GLuint>());
TexturedModel(GLFWwindow* window, GLuint shader_program, std::vector<gfx::Texture> textures, std::vector<Vertex> vertices,
std::vector<GLuint> indicies = std::vector<GLuint>());
virtual void update(const float& delta_time) override; virtual void update(const float& delta_time) override;
virtual void render(GLFWwindow* target) override; virtual void render(GLFWwindow* target) override;
}; };

View File

@ -17,7 +17,7 @@
#include "../../gfx/textured_model.h" #include "../../gfx/textured_model.h"
namespace simpleengine::objects_3d { namespace simpleengine::objects_3d {
class ObjModel : public simpleengine::gfx::TexturedModel { class Mesh : public simpleengine::gfx::TexturedModel {
private: private:
/** /**
* @brief Split a string multiple times (if possible) with a character delimiter. * @brief Split a string multiple times (if possible) with a character delimiter.
@ -49,8 +49,8 @@ namespace simpleengine::objects_3d {
public: public:
std::vector<LitVertex> lit_vertices; std::vector<LitVertex> lit_vertices;
ObjModel(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::string filename); Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::string filename);
ObjModel(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::ifstream file_stream); Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::ifstream file_stream);
virtual void update(const float& delta_time) override; virtual void update(const float& delta_time) override;
}; };

View File

@ -0,0 +1,104 @@
#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<Vertex>()), 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 {
} */
};
}

View File

@ -52,9 +52,9 @@ namespace simpleengine {
transform_matrix = glm::translate(transform_matrix, glm::vec3(x, y, z)); transform_matrix = glm::translate(transform_matrix, glm::vec3(x, y, z));
} }
virtual void translate(const glm::vec3& vec) { /* virtual void translate(const glm::vec3& vec) {
transform_matrix = glm::translate(transform_matrix, vec); transform_matrix = glm::translate(transform_matrix, vec);
} } */
virtual glm::mat4 rotation_matrix(float degrees, glm::vec3 rotation_axis) const { virtual glm::mat4 rotation_matrix(float degrees, glm::vec3 rotation_axis) const {
return glm::rotate(transform_matrix, glm::radians(degrees), rotation_axis); return glm::rotate(transform_matrix, glm::radians(degrees), rotation_axis);

View File

@ -19,10 +19,12 @@ namespace simpleengine {
simpleengine::Vectorf position; simpleengine::Vectorf position;
glm::vec3 color; glm::vec3 color;
glm::vec2 tex_coord; glm::vec2 tex_coord;
float texture_id = 0.f;
Vertex() = default; Vertex() = default;
Vertex(simpleengine::Vectorf position, glm::vec3 color, glm::vec2 tex_coord) : position(position), color(color), tex_coord(tex_coord) { Vertex(simpleengine::Vectorf position, glm::vec3 color, glm::vec2 tex_coord, int texture_id = 0) :
position(position), color(color), tex_coord(tex_coord), texture_id((float) texture_id) {
} }
}; };
@ -37,11 +39,17 @@ namespace simpleengine {
glm::vec3 color; glm::vec3 color;
glm::vec2 tex_coord; glm::vec2 tex_coord;
glm::vec3 normal; glm::vec3 normal;
float texture_id = 0.f;
LitVertex() = default; LitVertex() = default;
LitVertex(simpleengine::Vectorf position, glm::vec3 color, glm::vec2 tex_coord, glm::vec3 normal) : LitVertex(simpleengine::Vectorf position, glm::vec3 color, glm::vec2 tex_coord, glm::vec3 normal, int texture_id = 0) :
position(position), color(color), tex_coord(tex_coord), normal(normal) { position(position), color(color), tex_coord(tex_coord), normal(normal), texture_id((float) texture_id) {
}
LitVertex(simpleengine::Vectorf position, glm::vec2 tex_coord, glm::vec3 normal, int texture_id = 0) :
position(position), color(glm::vec3(1.f)), tex_coord(tex_coord), normal(normal), texture_id((float) texture_id) {
} }
}; };

View File

@ -1,20 +1,25 @@
#version 440 #version 440
in vec3 vs_position; in vec3 vs_position;
in mat4 vs_transform; in vec3 vs_color;
in vec2 vs_texcoord;
in vec3 vs_normal; in vec3 vs_normal;
in vec2 vs_texcoord;
flat in float vs_tex_id; // < 0 is reserved for solid colored objects.
in mat4 vs_transform;
in vec3 vs_to_light; in vec3 vs_to_light;
in vec3 vs_to_camera; in vec3 vs_to_camera;
uniform bool texture_is_set; uniform sampler2D u_textures[16];
uniform sampler2D vs_texture; uniform float u_texture_shine[16];
uniform float u_texture_reflectivity[16];
uniform vec3 light_color; uniform vec3 light_color;
uniform float shine_damper;
uniform float reflectivity;
out vec4 fs_color; out vec4 fs_color;
vec3 calculate_specular(vec3 unit_normal, float shine_damper, float reflectivity);
void main() { void main() {
// Lighting // Lighting
vec3 unit_normal = normalize(vs_normal); vec3 unit_normal = normalize(vs_normal);
@ -24,8 +29,21 @@ void main() {
float brightness = max(dot_prod, 0.f); float brightness = max(dot_prod, 0.f);
vec3 diffuse = brightness * light_color; vec3 diffuse = brightness * light_color;
// Specular lighting if (vs_tex_id > -1) {
// only do all this math is reflectivity is > 0 int id = int(vs_tex_id);
float shine_damper = u_texture_shine[id];
float reflectivity = u_texture_reflectivity[id];
vec3 final_specular = calculate_specular(unit_normal, shine_damper, reflectivity);
fs_color = vec4(diffuse, 1.f) * texture(u_textures[1], vs_texcoord) + vec4(final_specular, 1.f);
//fs_color = texture(u_textures[1], vs_texcoord);
} else {
fs_color = vec4(diffuse, 1.f) * vec4(vs_color, 1.f); // We don't add any reflectivity to solid colored vectors.
}
}
vec3 calculate_specular(vec3 unit_normal, float shine_damper, float reflectivity) {
vec3 final_specular = vec3(0.f); vec3 final_specular = vec3(0.f);
if (reflectivity > 0) { if (reflectivity > 0) {
vec3 unit_vector_to_camera = normalize(vs_to_camera); vec3 unit_vector_to_camera = normalize(vs_to_camera);
@ -37,10 +55,5 @@ void main() {
final_specular = damped_specular * reflectivity * light_color; final_specular = damped_specular * reflectivity * light_color;
} }
if (texture_is_set) { return final_specular;
//fs_color = vec4(0.5 * unit_normal + vec3(0.5), 1.f); // Visualize normals
fs_color = vec4(diffuse, 1.f) * texture(vs_texture, vs_texcoord) + vec4(final_specular, 1.f);
} else {
fs_color = vec4(diffuse, 1.f) + vec4(final_specular, 1.f);
}
} }

View File

@ -1,13 +1,18 @@
#version 440 #version 440
layout (location = 0) in vec3 vertex_position; layout (location = 0) in vec3 vertex_position;
layout (location = 1) in vec2 vertex_texcoord; layout (location = 1) in vec3 vertex_color;
layout (location = 2) in vec3 vertex_normal; layout (location = 2) in vec3 vertex_normal;
layout (location = 3) in vec2 vertex_texcoord;
layout (location = 4) in float vertex_tex_id;
out vec3 vs_position; out vec3 vs_position;
out vec2 vs_texcoord; out vec3 vs_color;
out mat4 vs_transform;
out vec3 vs_normal; out vec3 vs_normal;
out vec2 vs_texcoord;
flat out float vs_tex_id;
out mat4 vs_transform;
out vec3 vs_to_light; out vec3 vs_to_light;
out vec3 vs_to_camera; out vec3 vs_to_camera;
@ -19,9 +24,14 @@ uniform vec3 light_position;
void main() { void main() {
vec4 world_pos = (transform_matrix * vec4(vertex_position, 1.f)); vec4 world_pos = (transform_matrix * vec4(vertex_position, 1.f));
// Directly pass things to the fragment shader.
vs_position = world_pos.xyz; vs_position = world_pos.xyz;
vs_transform = transform_matrix; vs_transform = transform_matrix;
vs_texcoord = vertex_texcoord; vs_texcoord = vertex_texcoord;
vs_color = vertex_color;
vs_tex_id = vertex_tex_id;
gl_Position = projection_matrix * view_matrix * world_pos; gl_Position = projection_matrix * view_matrix * world_pos;

View File

@ -1,16 +1,20 @@
#include "camera.h" #include "camera.h"
#include <GLFW/glfw3.h>
#include <glm/ext/quaternion_geometric.hpp>
#include <glm/trigonometric.hpp>
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) : simpleengine::Event(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) {
world_up(world_up), cam_front(cam_front) {
// TODO: Update width and height on window resize. // TODO: Update width and height on window resize.
int width, height; int width, height;
glfwGetFramebufferSize(window, &width, &height); glfwGetFramebufferSize(window, &width, &height);
projection_matrix = glm::perspective(glm::radians(fov), ((float) width) / height, near_plane, far_plane); projection_matrix = glm::perspective(glm::radians(fov), ((float) width) / height, near_plane, far_plane);
//rotation = glm::vec3(0.f, 0.f, -1.f);
} }
Camera::Camera(GLFWwindow* window, GLuint shader_prog, float fov, glm::vec3 position, glm::vec3 rotation, Camera::Camera(GLFWwindow* window, GLuint shader_prog, float fov, glm::vec3 position, glm::vec3 rotation,
@ -20,23 +24,76 @@ namespace simpleengine {
} }
void Camera::update(const float& delta_time) { void Camera::update(const float& delta_time) {
if (glfwGetKey(window, GLFW_KEY_MINUS) == GLFW_PRESS) {
movement_speed -= abs(movement_speed - .2f);
}
if (glfwGetKey(window, GLFW_KEY_EQUAL) == GLFW_PRESS) {
movement_speed += .2f;
}
if (glfwGetKey(window, GLFW_KEY_0) == GLFW_PRESS) {
movement_speed = 2.5f;
}
float camera_speed = movement_speed * delta_time;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
position.z -= 0.02f; position += camera_speed * camera_front;
} }
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
position.z += 0.02f; position -= camera_speed * camera_front;
} }
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
position.x += 0.02f; position += glm::normalize(glm::cross(camera_front, camera_up)) * camera_speed;
} }
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
position.x -= 0.02f; position -= glm::normalize(glm::cross(camera_front, camera_up)) * camera_speed;
} }
view_matrix = glm::lookAt(position, position + cam_front, world_up); if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) {
position.y += camera_speed;
}
if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) {
position.y -= camera_speed;
}
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
rotation.z += camera_speed;
}
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) {
rotation.z -= camera_speed;
}
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {
rotation.y -= camera_speed;
}
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
rotation.y += camera_speed;
}
// Limit the pitch of the camera.
if (rotation.z >= glm::radians(89.f)) {
rotation.z = glm::radians(89.f);
}
if (rotation.z <= -glm::radians(89.f)) {
rotation.z = -glm::radians(89.f);
}
glm::vec3 direction;
direction.x = cos(rotation.y) * cos(rotation.z);
direction.y = sin(rotation.z);
direction.z = sin(rotation.y) * cos(rotation.z);
camera_front = glm::normalize(direction);
view_matrix = glm::lookAt(position, position + camera_front, camera_up);
shader.use(); shader.use();
shader.set_uniform_matrix_4f("view_matrix", view_matrix, false); shader.set_uniform_matrix_4f("view_matrix", view_matrix, false);

View File

@ -46,6 +46,7 @@ void simpleengine::Game::enable_default_gl_options() const {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
//glFrontFace(GL_CW);
} }
void simpleengine::Game::enable_gl_option(GLenum option) const { void simpleengine::Game::enable_gl_option(GLenum option) const {
@ -72,39 +73,50 @@ void simpleengine::Game::add_event(std::shared_ptr<simpleengine::Event> event) {
events.push_back(event); events.push_back(event);
} }
void simpleengine::Game::update() { void simpleengine::Game::update(const float& delta_time) {
handle_input(); handle_input(delta_time);
// Update items // Update items
for (const std::shared_ptr<Event>& event : events) { for (const std::shared_ptr<Event>& event : events) {
event->update(0.f); event->update(delta_time);
} }
} }
void simpleengine::Game::handle_input() { void simpleengine::Game::handle_input(const float& delta_time) {
} }
void simpleengine::Game::render_window() { void simpleengine::Game::render_window(const float& delta_time) {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
render_items(); render_items(delta_time);
} }
void simpleengine::Game::render_items() { 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);
} }
} }
float simpleengine::Game::get_delta_time() {
float current_frame_time = glfwGetTime();
float delta_time = current_frame_time - last_frame_time;
last_frame_time = current_frame_time;
return delta_time;
}
int simpleengine::Game::run() { int simpleengine::Game::run() {
while (!glfwWindowShouldClose(window)) { while (!glfwWindowShouldClose(window)) {
// Get delta time first thing
float delta_time = get_delta_time();
// Update input // Update input
glfwPollEvents(); glfwPollEvents();
update(); update(delta_time);
render_window(); render_window(delta_time);
// End draw // End draw
glfwSwapBuffers(window); glfwSwapBuffers(window);

View File

@ -5,7 +5,7 @@ namespace simpleengine::gfx {
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(GL_ARRAY_BUFFER, false)),
ebo(gfx::VBO(GL_ELEMENT_ARRAY_BUFFER, false)) { ebo(gfx::VBO(GL_ELEMENT_ARRAY_BUFFER, false)) {
setup_vertexes(); setup_vertices();
} }
Model::Model(GLFWwindow* window, GLuint shader_program, std::vector<Vertex> vertices, std::vector<GLuint> indicies) : Model::Model(GLFWwindow* window, GLuint shader_program, std::vector<Vertex> vertices, std::vector<GLuint> indicies) :
@ -13,28 +13,26 @@ namespace simpleengine::gfx {
} }
void Model::setup_vertexes() { void Model::setup_vertices() {
vao.bind(); vao.bind();
vbo.buffer(vertices.data(), 0, sizeof(Vertex) * vertices.size()); vbo.buffer(vertices.data(), 0, sizeof(Vertex) * vertices.size());
if (!indicies.empty()) { if (!indicies.empty()) {
ebo.buffer(indicies.data(), 0, indicies.size() * sizeof(GLuint)); ebo.buffer(indicies.data(), 0, indicies.size() * sizeof(GLuint));
} }
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, position)); // Enable VAO attributes
glEnableVertexAttribArray(0); vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, position));
vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, color));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, color)); // Attribute 2 is used for normals
glEnableVertexAttribArray(1); vao.enable_attrib(vbo, 3, 2, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, tex_coord));
vao.enable_attrib(vbo, 4, 1, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, texture_id));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, tex_coord));
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(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) { void Model::render(GLFWwindow* target) {
@ -42,7 +40,7 @@ namespace simpleengine::gfx {
shader.set_uniform_matrix_4f("transform_matrix", transform_matrix, false); 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. // 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); //shader.set_uniform_int("texture_is_set", (GLint) false, false);
vao.bind(); vao.bind();
if (indicies.empty()) { if (indicies.empty()) {

View File

@ -189,6 +189,22 @@ namespace simpleengine::gfx {
set_uniform_float(location, fl, bind_shader); set_uniform_float(location, fl, bind_shader);
} }
void Shader::set_uniform_float_array(GLint location, int count, GLfloat* arr, bool bind_shader) {
if (bind_shader) {
use();
}
glUniform1fv(location, count, arr);
if (bind_shader) {
unuse();
}
}
void Shader::set_uniform_float_array(const char* uniform_name, int count, GLfloat* arr, bool bind_shader) {
int location = get_uniform_location(uniform_name);
set_uniform_float_array(location, count, arr, bind_shader);
}
void Shader::set_uniform_float_vec2(GLint location, glm::vec2 vec, bool bind_shader) { void Shader::set_uniform_float_vec2(GLint location, glm::vec2 vec, bool bind_shader) {
if (bind_shader) { if (bind_shader) {
use(); use();
@ -249,6 +265,19 @@ namespace simpleengine::gfx {
set_uniform_int(location, i, bind_shader); set_uniform_int(location, i, bind_shader);
} }
void Shader::set_uniform_int_array(GLint location, int count, GLint* arr, bool bind_shader) {
if (bind_shader) {
use();
}
glUniform1iv(location, count, arr);
}
void Shader::set_uniform_int_array(const char* uniform_name, int count, GLint* arr, bool bind_shader) {
int location = get_uniform_location(uniform_name);
set_uniform_int_array(location, count, arr, bind_shader);
}
void Shader::set_uniform_int_vec2(GLint location, glm::ivec2 vec, bool bind_shader) { void Shader::set_uniform_int_vec2(GLint location, glm::ivec2 vec, bool bind_shader) {
if (bind_shader) { if (bind_shader) {
use(); use();

View File

@ -90,4 +90,8 @@ namespace simpleengine::gfx {
void Texture::bind() const { void Texture::bind() const {
glBindTexture(image_type, texture_id); glBindTexture(image_type, texture_id);
} }
unsigned int Texture::get_texture_id() const {
return texture_id;
}
} }

View File

@ -1,14 +1,26 @@
#include "gfx/textured_model.h" #include "gfx/textured_model.h"
#include "gfx/ssbo.h"
namespace simpleengine::gfx { namespace simpleengine::gfx {
TexturedModel::TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector<Vertex> vertices, TexturedModel::TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector<Vertex> vertices,
std::vector<GLuint> indicies) : simpleengine::gfx::Model(window, shader, vertices, indicies), texture(texture) { 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, TexturedModel::TexturedModel(GLFWwindow* window, GLuint shader_program, gfx::Texture texture,
std::vector<Vertex> vertices, std::vector<GLuint> indicies) : TexturedModel(window, gfx::Shader(shader_program), std::vector<Vertex> vertices, std::vector<GLuint> indicies) : TexturedModel(window, gfx::Shader(shader_program),
texture, vertices, indicies) { std::vector<gfx::Texture>{texture}, vertices, indicies) {
}
TexturedModel::TexturedModel(GLFWwindow* window, gfx::Shader shader, std::vector<gfx::Texture> textures, std::vector<Vertex> 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<Vertex> vertices, std::vector<GLuint> indicies) : TexturedModel(window, gfx::Shader(shader_program),
textures, vertices, indicies) {
} }
@ -19,11 +31,25 @@ namespace simpleengine::gfx {
void TexturedModel::render(GLFWwindow* target) { void TexturedModel::render(GLFWwindow* target) {
shader.use(); shader.use();
shader.set_uniform_matrix_4f("transform_matrix", transform_matrix, false); shader.set_uniform_matrix_4f("transform_matrix", transform_matrix, false);
shader.set_uniform_float("shine_damper", texture.shine_damper, false);
shader.set_uniform_float("reflectivity", texture.reflectivity, false);
// When binding to the texture, tell the shader if the texture is set or not. const int tex_id = 0;
shader.set_uniform_int("texture_is_set", (GLint) true, false);
// 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(); texture.bind();
vao.bind(); vao.bind();

View File

@ -1,7 +1,7 @@
#include "objects/3d/obj_model.h" #include "objects/3d/mesh.h"
namespace simpleengine::objects_3d { namespace simpleengine::objects_3d {
std::vector<std::string> ObjModel::split_string(std::string str, const char delim) { std::vector<std::string> Mesh::split_string(std::string str, const char delim) {
std::istringstream ss(str); std::istringstream ss(str);
std::vector<std::string> tokens; std::vector<std::string> tokens;
@ -17,8 +17,9 @@ namespace simpleengine::objects_3d {
return tokens; return tokens;
} }
void ObjModel::process_vertex(const std::vector<std::string>& vertex_data, const std::vector<glm::vec2>& in_textures, 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) { 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 // Get the index the current vertex and put it in indicies
int currentVertexIndex = stoi(vertex_data[0]) - 1; int currentVertexIndex = stoi(vertex_data[0]) - 1;
@ -34,13 +35,13 @@ namespace simpleengine::objects_3d {
out_normals.at(currentVertexIndex) = current_norm; out_normals.at(currentVertexIndex) = current_norm;
} }
ObjModel::ObjModel(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::string filename) : Mesh::Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::string filename) :
ObjModel(window, shader, texture, std::ifstream(filename, std::ios::in | std::ios::binary)) { Mesh(window, shader, texture, std::ifstream(filename, std::ios::in | std::ios::binary)) {
} }
ObjModel::ObjModel(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::ifstream file_stream) : Mesh::Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::ifstream file_stream) :
simpleengine::gfx::TexturedModel(window, shader, texture, std::vector<Vertex>()) { simpleengine::gfx::TexturedModel(window, shader, std::vector<gfx::Texture>{texture}, std::vector<Vertex>()) {
if (!file_stream.is_open()) { if (!file_stream.is_open()) {
std::cerr << "File stream that was given to ObjModel::ObjModel is not open!" << std::endl; std::cerr << "File stream that was given to ObjModel::ObjModel is not open!" << std::endl;
@ -94,9 +95,13 @@ namespace simpleengine::objects_3d {
file_stream.close(); file_stream.close();
const int texture_id = 0;
std::cout << "Texture ID: " << texture_id << std::endl;
// Insert everything into lit_vertices. // Insert everything into lit_vertices.
for (int i = 0; i < obj_vertices.size(); i++) { 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)); 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 // Create VAO and EBO and assign buffers
@ -106,15 +111,16 @@ namespace simpleengine::objects_3d {
// Enable VAO attributes // Enable VAO attributes
vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, position)); 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, 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)); 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); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
} }
void ObjModel::update(const float& delta_time) { void Mesh::update(const float& delta_time) {
this->rotate_y(0.05f); // Slowly rotate (for debugging) this->rotate_y(0.0005f); // Slowly rotate (for debugging)
} }
} }