diff --git a/OpenGLEngine/MeshFactory.h b/OpenGLEngine/MeshFactory.h index 4caa461..93f7470 100644 --- a/OpenGLEngine/MeshFactory.h +++ b/OpenGLEngine/MeshFactory.h @@ -6,14 +6,16 @@ #include "Exception.h" +#include "Mesh.h" + template class MeshFactory { public: typedef Mesh MeshType; -protected: - MeshFactory() {} // Prevent Instantiation +private: + MeshFactory() {} // Prevent instanciation of this static class public: typedef unsigned int SizeType; @@ -23,8 +25,11 @@ public: for (SizeType i = 0; i < m_meshes.size(); ++i) { delete[] m_meshes[i]->vertices; + m_meshes[i]->vertices = nullptr; delete[] m_meshes[i]->indices; + m_meshes[i]->indices = nullptr; delete m_meshes[i]; + m_meshes[i] = nullptr; } } @@ -54,7 +59,7 @@ public: } } - static MeshType* gen(const DrawMode& draw_mode, const VertexType& a, const VertexType& b) + static MeshType* gen(const DrawMode& draw_mode, const VertexType& a, const VertexType& b) { MeshType* mesh; switch (draw_mode) @@ -90,7 +95,6 @@ public: case DrawMode::DRAW_POINTS: case DrawMode::DRAW_LINE_STRIP: case DrawMode::DRAW_LINE_LOOP: - case DrawMode::DRAW_LINES: case DrawMode::DRAW_TRIANGLE_STRIP: case DrawMode::DRAW_TRIANGLE_FAN: case DrawMode::DRAW_TRIANGLES: @@ -102,6 +106,18 @@ public: mesh->indices[1] = 1; mesh->indices[2] = 2; return mesh; + case DrawMode::DRAW_LINES: + mesh = create_mesh(3, 6); + mesh->vertices[0] = a; + mesh->vertices[1] = b; + mesh->vertices[2] = c; + mesh->indices[0] = 0; + mesh->indices[1] = 1; + mesh->indices[2] = 1; + mesh->indices[3] = 2; + mesh->indices[4] = 2; + mesh->indices[5] = 0; + return mesh; case DrawMode::DRAW_LINE_STRIP_ADJACENCY: case DrawMode::DRAW_LINES_ADJACENCY: case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY: @@ -120,7 +136,6 @@ public: case DrawMode::DRAW_POINTS: case DrawMode::DRAW_LINE_STRIP: case DrawMode::DRAW_LINE_LOOP: - case DrawMode::DRAW_LINES: case DrawMode::DRAW_TRIANGLE_STRIP: case DrawMode::DRAW_TRIANGLE_FAN: mesh = create_mesh(4, 4); @@ -133,6 +148,21 @@ public: mesh->indices[2] = 2; mesh->indices[3] = 3; return mesh; + case DrawMode::DRAW_LINES: // Implementation similar to LINE_LOOP + mesh = create_mesh(4, 8); + mesh->vertices[0] = a; + mesh->vertices[1] = b; + mesh->vertices[2] = c; + mesh->vertices[3] = d; + mesh->indices[0] = 0; + mesh->indices[1] = 1; + mesh->indices[2] = 1; + mesh->indices[3] = 2; + mesh->indices[4] = 2; + mesh->indices[5] = 3; + mesh->indices[6] = 3; + mesh->indices[7] = 0; + return mesh; case DrawMode::DRAW_TRIANGLES: mesh = create_mesh(4, 6); mesh->vertices[0] = a; @@ -186,17 +216,160 @@ public: } } + // Generates a "cube" (8-vert shape) with 8 vertices. This function should probably not be used + // if the vertices are expected to have normals. + static MeshType* gen_cube( + const DrawMode& draw_mode, + const VertexType& top_left_front, + const VertexType& bottom_left_front, + const VertexType& top_right_front, + const VertexType& bottom_right_front, + const VertexType& top_left_back, + const VertexType& bottom_left_back, + const VertexType& top_right_back, + const VertexType& bottom_right_back + ) + { + MeshType* mesh; + switch (draw_mode) + { + case DrawMode::DRAW_POINTS: + mesh = create_mesh(8, 8); + mesh->vertices[0] = top_left_front; + mesh->vertices[1] = bottom_left_front; + mesh->vertices[2] = top_right_front; + mesh->vertices[3] = bottom_right_front; + mesh->vertices[4] = top_left_back; + mesh->vertices[5] = bottom_left_back; + mesh->vertices[6] = top_right_back; + mesh->vertices[7] = bottom_right_back; + mesh->indices[0] = 0; + mesh->indices[1] = 1; + mesh->indices[2] = 3; + mesh->indices[3] = 3; + mesh->indices[4] = 4; + mesh->indices[5] = 5; + mesh->indices[6] = 6; + mesh->indices[7] = 7; + return mesh; + case DrawMode::DRAW_LINES: + mesh = create_mesh(8, 24); + mesh->vertices[0] = top_left_front; + mesh->vertices[1] = bottom_left_front; + mesh->vertices[2] = top_right_front; + mesh->vertices[3] = bottom_right_front; + mesh->vertices[4] = top_left_back; + mesh->vertices[5] = bottom_left_back; + mesh->vertices[6] = top_right_back; + mesh->vertices[7] = bottom_right_back; + // Front + mesh->indices[0] = 0; + mesh->indices[1] = 1; + mesh->indices[2] = 1; + mesh->indices[3] = 2; + mesh->indices[4] = 2; + mesh->indices[5] = 3; + mesh->indices[6] = 3; + mesh->indices[7] = 0; + // Back + mesh->indices[8] = 4; + mesh->indices[9] = 5; + mesh->indices[10] = 5; + mesh->indices[11] = 6; + mesh->indices[12] = 6; + mesh->indices[13] = 7; + mesh->indices[14] = 7; + mesh->indices[15] = 4; + // Connecting + mesh->indices[16] = 0; + mesh->indices[17] = 4; + mesh->indices[18] = 1; + mesh->indices[19] = 5; + mesh->indices[20] = 2; + mesh->indices[21] = 6; + mesh->indices[22] = 3; + mesh->indices[23] = 7; + return mesh; + case DrawMode::DRAW_TRIANGLES: + mesh = create_mesh(8, 36); + mesh->vertices[0] = top_left_front; + mesh->vertices[1] = bottom_left_front; + mesh->vertices[2] = top_right_front; + mesh->vertices[3] = bottom_right_front; + mesh->vertices[4] = top_left_back; + mesh->vertices[5] = bottom_left_back; + mesh->vertices[6] = top_right_back; + mesh->vertices[7] = bottom_right_back; + // Counter Clockwise + // Front + mesh->indices[0] = 1; + mesh->indices[1] = 3; + mesh->indices[2] = 0; + mesh->indices[3] = 0; + mesh->indices[4] = 3; + mesh->indices[5] = 2; + // Right + mesh->indices[6] = 3; + mesh->indices[7] = 7; + mesh->indices[8] = 2; + mesh->indices[9] = 2; + mesh->indices[10] = 7; + mesh->indices[11] = 6; + // Back + mesh->indices[12] = 7; + mesh->indices[13] = 5; + mesh->indices[14] = 6; + mesh->indices[15] = 6; + mesh->indices[16] = 5; + mesh->indices[17] = 4; + // Left + mesh->indices[18] = 5; + mesh->indices[19] = 1; + mesh->indices[20] = 4; + mesh->indices[21] = 4; + mesh->indices[22] = 1; + mesh->indices[23] = 0; + // Top + mesh->indices[24] = 0; + mesh->indices[25] = 2; + mesh->indices[26] = 4; + mesh->indices[27] = 4; + mesh->indices[28] = 2; + mesh->indices[29] = 6; + // Bottom + mesh->indices[30] = 5; + mesh->indices[31] = 7; + mesh->indices[32] = 1; + mesh->indices[33] = 1; + mesh->indices[34] = 7; + mesh->indices[35] = 3; + return mesh; + case DrawMode::DRAW_LINE_STRIP: + case DrawMode::DRAW_LINE_LOOP: + case DrawMode::DRAW_TRIANGLE_STRIP: // Could probably implement this one in some way in the future + case DrawMode::DRAW_TRIANGLE_FAN: + case DrawMode::DRAW_LINE_STRIP_ADJACENCY: + case DrawMode::DRAW_LINES_ADJACENCY: + case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY: + case DrawMode::DRAW_TRIANGLES_ADJACENCY: + case DrawMode::DRAW_PATCHES: + default: + throw EXCEPTION("Unable to gen_cube for current draw mode: " + std::to_string(draw_mode)); + } + } + protected: static MeshType* create_mesh(unsigned int vertex_count, unsigned int index_count) { MeshType* mesh = new MeshType(); mesh->vertices = new VertexType[vertex_count]; mesh->vertex_count = vertex_count; - mesh->indices = new IndexType[vertex_count]; + mesh->indices = new IndexType[index_count]; mesh->index_count = index_count; m_meshes.push_back(mesh); return mesh; } + private: static std::vector m_meshes; }; diff --git a/OpenGLEngine/MyApplication.cpp b/OpenGLEngine/MyApplication.cpp index caf7536..e31e541 100644 --- a/OpenGLEngine/MyApplication.cpp +++ b/OpenGLEngine/MyApplication.cpp @@ -1,15 +1,15 @@ #include "MyApplication.h" MyApplication::MyApplication(int width, int height) - : Application(width, height), m_basic_scene(*this), m_simple_2d_scene(*this), m_simple_3d_scene(*this) -{ -} + : Application(width, height), m_basic_scene(*this), m_simple_2d_scene(*this), m_simple_3d_scene(*this), m_simple_cube_scene(*this) +{} void MyApplication::init() { m_basic_scene.init(); m_simple_2d_scene.init(); m_simple_3d_scene.init(); + m_simple_cube_scene.init(); m_p_current_scene = &m_basic_scene; m_p_current_scene->use(); @@ -29,6 +29,10 @@ void MyApplication::update(float delta_time, clock_t clock) { swap_scene(&m_simple_3d_scene); } + else if (m_glfw_input_manager.is_key_pressed(GLFW_KEY_4)) + { + swap_scene(&m_simple_cube_scene); + } m_p_current_scene->update(delta_time, clock); } diff --git a/OpenGLEngine/MyApplication.h b/OpenGLEngine/MyApplication.h index 6bd3934..cbcb605 100644 --- a/OpenGLEngine/MyApplication.h +++ b/OpenGLEngine/MyApplication.h @@ -4,6 +4,7 @@ #include "MyBasicScene.h" #include "MySimple2DScene.h" #include "MySimple3DScene.h" +#include "MySimpleCubeScene.h" class MyApplication : public Application @@ -27,5 +28,6 @@ private: MyBasicScene m_basic_scene; MySimple2DScene m_simple_2d_scene; MySimple3DScene m_simple_3d_scene; + MySimpleCubeScene m_simple_cube_scene; }; diff --git a/OpenGLEngine/MyBasicShaderProgram.cpp b/OpenGLEngine/MyBasicShaderProgram.cpp index 4b59e5f..b133d14 100644 --- a/OpenGLEngine/MyBasicShaderProgram.cpp +++ b/OpenGLEngine/MyBasicShaderProgram.cpp @@ -3,8 +3,8 @@ #include "Util.h" MyBasicShaderProgram::MyBasicShaderProgram() - // TEMP Hardcode in the path. (Should Use Relative Path to General Shader Dir) - : m_vertex_shader(Util::load_file(SHADER_PATH "MyBasicVS.glsl"), VERTEX_SHADER), + : ShaderProgram(), + m_vertex_shader(Util::load_file(SHADER_PATH "MyBasicVS.glsl"), VERTEX_SHADER), m_fragment_shader(Util::load_file(SHADER_PATH "MyBasicFS.glsl"), FRAGMENT_SHADER) { attach_shader(m_vertex_shader); diff --git a/OpenGLEngine/MySimple2DScene.h b/OpenGLEngine/MySimple2DScene.h index beffb46..099910e 100644 --- a/OpenGLEngine/MySimple2DScene.h +++ b/OpenGLEngine/MySimple2DScene.h @@ -24,8 +24,8 @@ public: void render() override; private: - MyBatch m_batch; - MySimpleShaderProgram::Renderable m_shape; MySimpleShaderProgram m_shader_program; + MySimpleShaderProgram::Renderable m_shape; + MyBatch m_batch; Camera2D m_camera; }; \ No newline at end of file diff --git a/OpenGLEngine/MySimple3DScene.h b/OpenGLEngine/MySimple3DScene.h index b8c0797..9e7a19e 100644 --- a/OpenGLEngine/MySimple3DScene.h +++ b/OpenGLEngine/MySimple3DScene.h @@ -24,9 +24,9 @@ public: void render() override; private: - MyBatch m_batch; - MySimpleShaderProgram::Renderable m_shape; MySimpleShaderProgram m_shader_program; + MySimpleShaderProgram::Renderable m_shape; + MyBatch m_batch; Camera3D m_camera; }; diff --git a/OpenGLEngine/MySimpleCubeScene.cpp b/OpenGLEngine/MySimpleCubeScene.cpp new file mode 100644 index 0000000..4896789 --- /dev/null +++ b/OpenGLEngine/MySimpleCubeScene.cpp @@ -0,0 +1,92 @@ +#include "MySimpleCubeScene.h" + +#include "constants.h" + +#include "MeshFactory.h" +#include "DrawMode.h" + +MySimpleCubeScene::MySimpleCubeScene(Application& application) + : Scene(application), + m_shape(MeshFactory::gen_cube( + DrawMode::DRAW_TRIANGLES, + MySimpleShaderProgram::Vertex(-1.0f, 1.0f, -1.0f), + MySimpleShaderProgram::Vertex(-1.0f, -1.0f, -1.0f), + MySimpleShaderProgram::Vertex( 1.0f, 1.0f, -1.0f), + MySimpleShaderProgram::Vertex( 1.0f, -1.0f, -1.0f), + MySimpleShaderProgram::Vertex(-1.0f, 1.0f, 1.0f), + MySimpleShaderProgram::Vertex(-1.0f, -1.0f, 1.0f), + MySimpleShaderProgram::Vertex( 1.0f, 1.0f, 1.0f), + MySimpleShaderProgram::Vertex( 1.0f, -1.0f, 1.0f) + ), DrawMode::DRAW_TRIANGLES), + m_batch(&m_shape, 1), + m_camera((float)egm::TAU_1_4, (float)m_screen_size.x / m_screen_size.y, 1.0f, 10.0f, vec3(0.0f, 0.0f, -5.0f)) +{} + +MySimpleCubeScene::~MySimpleCubeScene() +{} + +void MySimpleCubeScene::init() +{ + m_batch.init(); +} + +void MySimpleCubeScene::use() +{ + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); +} + +void MySimpleCubeScene::unuse() +{ + +} + +void MySimpleCubeScene::update(float delta_time, clock_t clock) +{ + float brightness; + float radians; + + clock_t c; + const clock_t intervals = 512 * CLOCKS_PER_SEC / 100; + const clock_t half_interval = 256 * CLOCKS_PER_SEC / 100; + c = clock % intervals; + if (c < half_interval) + brightness = (float)c / half_interval; + else + brightness = (float)(intervals - c) / half_interval; + + radians = (float)egm::TAU * c / intervals; + + { + MySimpleShaderProgram::Color& color = m_batch.get_color(0); + color.r = brightness; + color.g = brightness; + color.b = brightness; + color.a = 1.0f; + + Poseable& pose = m_batch.get_pose(0); + pose.update_position(vec3(3 * (float)cos(radians), 0.0f, 0.0f)); + } + + vec3 camera_translation(0.0f, 0.0f, 0.0f); + + if (m_input_manager.is_key_down(GLFW_KEY_W)) camera_translation.y += 1; + if (m_input_manager.is_key_down(GLFW_KEY_S)) camera_translation.y -= 1; + if (m_input_manager.is_key_down(GLFW_KEY_A)) camera_translation.x -= 1; + if (m_input_manager.is_key_down(GLFW_KEY_D)) camera_translation.x += 1; + if (m_input_manager.is_key_down(GLFW_KEY_Q)) camera_translation.z -= 1; + if (m_input_manager.is_key_down(GLFW_KEY_E)) camera_translation.z += 1; + + m_camera.translate(camera_translation * delta_time); + + // TODO: Make a prerender function or move this to render + m_batch.prerender(); +} + +void MySimpleCubeScene::render() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_shader_program.use(); + glUniformMatrix4fv(0, 1, GL_FALSE, &m_camera.get_world_to_view_matrix()[0][0]); + m_batch.render(); +} \ No newline at end of file diff --git a/OpenGLEngine/MySimpleCubeScene.h b/OpenGLEngine/MySimpleCubeScene.h new file mode 100644 index 0000000..6e00d2b --- /dev/null +++ b/OpenGLEngine/MySimpleCubeScene.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Scene.h" + +#include "Camera3D.h" + +#include "MyBatch.h" +#include "MySimpleShaderProgram.h" + +class MySimpleCubeScene : public Scene +{ +public: + MySimpleCubeScene(Application& application); + ~MySimpleCubeScene(); + + void init() override; + + void use() override; + + void unuse() override; + + void update(float delta_time, clock_t clock) override; + + void render() override; + +private: + MySimpleShaderProgram m_shader_program; + MySimpleShaderProgram::Renderable m_shape; + MyBatch m_batch; + Camera3D m_camera; +}; + diff --git a/OpenGLEngine/MySimpleShaderProgram.cpp b/OpenGLEngine/MySimpleShaderProgram.cpp index 7ed61c4..53bf15b 100644 --- a/OpenGLEngine/MySimpleShaderProgram.cpp +++ b/OpenGLEngine/MySimpleShaderProgram.cpp @@ -3,8 +3,8 @@ #include "Util.h" MySimpleShaderProgram::MySimpleShaderProgram() - // TEMP Hardcode in the path. (Should Use Relative Path to General Shader Dir) - : m_vertex_shader(Util::load_file(SHADER_PATH "MySimpleVS.glsl"), VERTEX_SHADER), + : ShaderProgram(), + m_vertex_shader(Util::load_file(SHADER_PATH "MySimpleVS.glsl"), VERTEX_SHADER), m_fragment_shader(Util::load_file(SHADER_PATH "MySimpleFS.glsl"), FRAGMENT_SHADER) { attach_shader(m_vertex_shader); diff --git a/OpenGLEngine/OpenGLEngine.vcxproj b/OpenGLEngine/OpenGLEngine.vcxproj index accd101..6430b64 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj +++ b/OpenGLEngine/OpenGLEngine.vcxproj @@ -158,6 +158,7 @@ + @@ -188,6 +189,7 @@ + diff --git a/OpenGLEngine/OpenGLEngine.vcxproj.filters b/OpenGLEngine/OpenGLEngine.vcxproj.filters index 094b08c..d62d086 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj.filters +++ b/OpenGLEngine/OpenGLEngine.vcxproj.filters @@ -111,6 +111,9 @@ Source Files\Example\Rendering + + Source Files\Example\Application + @@ -194,6 +197,9 @@ Header Files\Example\Rendering + + Header Files\Example\Application + diff --git a/OpenGLEngine/ShaderProgram.cpp b/OpenGLEngine/ShaderProgram.cpp index e2aa88c..9d75b96 100644 --- a/OpenGLEngine/ShaderProgram.cpp +++ b/OpenGLEngine/ShaderProgram.cpp @@ -1,9 +1,8 @@ #include "ShaderProgram.h" ShaderProgram::ShaderProgram() -{ - m_program = glCreateProgram(); -} + : m_program(glCreateProgram()) +{} ShaderProgram::~ShaderProgram() { diff --git a/OpenGLEngine/main.cpp b/OpenGLEngine/main.cpp index 65714b9..5369de8 100644 --- a/OpenGLEngine/main.cpp +++ b/OpenGLEngine/main.cpp @@ -24,4 +24,6 @@ int main(int argc, char** argv) OutputDebugString("\n"); return 1; } + + } \ No newline at end of file