diff --git a/OpenGLEngine/Application.cpp b/OpenGLEngine/Application.cpp index cfd594b..1ca66da 100644 --- a/OpenGLEngine/Application.cpp +++ b/OpenGLEngine/Application.cpp @@ -1,14 +1,11 @@ #include "Application.h" -#include -#include -#include - -#pragma comment(lib, "opengl32.lib") +#include "Exception.h" Application::Application(const char* class_name, HINSTANCE h_instance) : m_window(class_name, h_instance), m_input_manager(&m_window.get_input_manager()), m_client_size(1280, 720) { + base_init(); } @@ -25,8 +22,7 @@ Application::~Application() int Application::run() { - if (!base_init()) return 1; - + init(); MessageResponse resp(UNSET); while (resp != QUIT_MESSAGE) { // Handle all messages @@ -45,10 +41,10 @@ void Application::close() { } -bool Application::base_init() +void Application::base_init() { - if (!m_window.register_class()) return false; - if (!m_window.create_window("OpenGLEngine", -1, -1, m_client_size.x, m_client_size.y)) return false; + if (!m_window.register_class()) throw EXCEPTION("Unable to register window class."); + if (!m_window.create_window("OpenGLEngine", -1, -1, m_client_size.x, m_client_size.y)) throw EXCEPTION("Unable to create window"); // Initialize window with OpenGL (May want to move this into MyApplication to allow application customization) // https://www.khronos.org/opengl/wiki/Creating_an_OpenGL_Context_(WGL) @@ -70,12 +66,23 @@ bool Application::base_init() SetPixelFormat(device_context, pixel_format, &pfd); - m_window.set_h_glrc(wglCreateContext(m_window.get_h_dc())); + HGLRC glrc = wglCreateContext(m_window.get_h_dc()); + + wglMakeCurrent(device_context, glrc); + + m_window.set_h_glrc(glrc); + + GLenum glewErr = glewInit(); + if (glewErr != GLEW_OK) + { + OutputDebugString("Glew Init Failed: "); + OutputDebugString((char*)glewGetErrorString(glewErr)); + OutputDebugString("\n"); + throw EXCEPTION("GLEW Init Failure"); + } m_window.show(SW_NORMAL); m_fps.prepare(); - - return init(); } void Application::base_close() diff --git a/OpenGLEngine/Application.h b/OpenGLEngine/Application.h index 257420e..ccdd3be 100644 --- a/OpenGLEngine/Application.h +++ b/OpenGLEngine/Application.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "stdafx.h" #include "vec2.h" @@ -19,7 +19,7 @@ public: protected: // Called on initialization of the application (called by base_init) - virtual bool init() = 0; + virtual void init() = 0; virtual void update(float delta_time, clock_t clock) = 0; @@ -40,7 +40,7 @@ protected: // The FPS counter of this application FPS m_fps; private: - bool base_init(); + void base_init(); void base_close(); }; diff --git a/OpenGLEngine/Batch.h b/OpenGLEngine/Batch.h new file mode 100644 index 0000000..3777be8 --- /dev/null +++ b/OpenGLEngine/Batch.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +#include "ShaderProgram.h" +#include "Renderable.h" + +template +class Batch +{ +public: + Batch(ShaderProgram* p_shader_program, const std::vector*>& p_renderables); + + virtual void init() = 0; // Maybe make this automatic? Or in the constructor? + virtual void render() = 0; + +private: + ShaderProgram* m_p_shader_program; + std::vector*> m_p_renderables; +}; \ No newline at end of file diff --git a/OpenGLEngine/Exception.cpp b/OpenGLEngine/Exception.cpp new file mode 100644 index 0000000..2c3ef9e --- /dev/null +++ b/OpenGLEngine/Exception.cpp @@ -0,0 +1,16 @@ +#include "Exception.h" + +Exception::Exception(const std::string& message, const std::string& class_name) + : m_message(message), m_class_name(class_name) +{ +} + +const std::string& Exception::get_message() +{ + return m_message; +} + +const std::string& Exception::get_class_name() +{ + return m_class_name; +} \ No newline at end of file diff --git a/OpenGLEngine/Exception.h b/OpenGLEngine/Exception.h new file mode 100644 index 0000000..7635dd6 --- /dev/null +++ b/OpenGLEngine/Exception.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +// TODO: This MUST be changed to something less generic +#define EXCEPTION(message) Exception(message, typeid(*this).name()) + +class Exception +{ +public: + Exception(const std::string& message, const std::string& class_name); + + const std::string& get_message(); + const std::string& get_class_name(); + +private: + std::string m_message; + std::string m_class_name; +}; \ No newline at end of file diff --git a/OpenGLEngine/Mesh.h b/OpenGLEngine/Mesh.h new file mode 100644 index 0000000..dfce78e --- /dev/null +++ b/OpenGLEngine/Mesh.h @@ -0,0 +1,10 @@ +#pragma once + +template +struct Mesh +{ + VertexType* vertices = nullptr; + unsigned int vertex_count = 0; + IndexType* indices = nullptr; + unsigned int index_count = 0; +}; \ No newline at end of file diff --git a/OpenGLEngine/MyApplication.cpp b/OpenGLEngine/MyApplication.cpp index 825f224..e483665 100644 --- a/OpenGLEngine/MyApplication.cpp +++ b/OpenGLEngine/MyApplication.cpp @@ -10,10 +10,10 @@ MyApplication::~MyApplication() { } -bool MyApplication::init() +void MyApplication::init() { + m_scene.init(); m_scene.use(); - return true; } void MyApplication::update(float delta_time, clock_t clock) diff --git a/OpenGLEngine/MyApplication.h b/OpenGLEngine/MyApplication.h index ee52e66..97c58e8 100644 --- a/OpenGLEngine/MyApplication.h +++ b/OpenGLEngine/MyApplication.h @@ -10,7 +10,7 @@ public: MyApplication(const char* class_name, HINSTANCE h_instance); ~MyApplication(); - bool init() override; + void init() override; void update(float delta_time, clock_t clock) override; diff --git a/OpenGLEngine/MyBatch.cpp b/OpenGLEngine/MyBatch.cpp new file mode 100644 index 0000000..1b2e88c --- /dev/null +++ b/OpenGLEngine/MyBatch.cpp @@ -0,0 +1,11 @@ +#include "MyBatch.h" + +void MyBatch::init() +{ + // TODO +} + +void MyBatch::render() +{ + // TODO +} \ No newline at end of file diff --git a/OpenGLEngine/MyBatch.h b/OpenGLEngine/MyBatch.h new file mode 100644 index 0000000..a208d7e --- /dev/null +++ b/OpenGLEngine/MyBatch.h @@ -0,0 +1,9 @@ +#pragma once + +#include "Batch.h" + +class MyBatch : public Batch +{ + void init() override; + void render() override; +}; \ No newline at end of file diff --git a/OpenGLEngine/MyShaderProgram.cpp b/OpenGLEngine/MyShaderProgram.cpp index 7e513db..bbd597a 100644 --- a/OpenGLEngine/MyShaderProgram.cpp +++ b/OpenGLEngine/MyShaderProgram.cpp @@ -4,8 +4,8 @@ MyShaderProgram::MyShaderProgram() // TEMP Hardcode in the path - : m_vertex_shader(Util::load_file("D:\\Development\\C++\\OpenGLEngine\\OpenGLEngine\\MyVertexShader.glsl").data(), VERTEX_SHADER), - m_fragment_shader(Util::load_file("D:\\Development\\C++\\OpenGLEngine\\OpenGLEngine\\MyFragmentShader.glsl").data(), FRAGMENT_SHADER) + : m_vertex_shader(Util::load_file("D:\\Development\\C++\\OpenGLEngine\\OpenGLEngine\\MyVertexShader.glsl"), VERTEX_SHADER), + m_fragment_shader(Util::load_file("D:\\Development\\C++\\OpenGLEngine\\OpenGLEngine\\MyFragmentShader.glsl"), FRAGMENT_SHADER) { attach_shader(m_vertex_shader); attach_shader(m_fragment_shader); diff --git a/OpenGLEngine/MyShaderProgram.h b/OpenGLEngine/MyShaderProgram.h index 5ee329d..ab6cd38 100644 --- a/OpenGLEngine/MyShaderProgram.h +++ b/OpenGLEngine/MyShaderProgram.h @@ -13,6 +13,8 @@ public: float z; }; + typedef unsigned int Index; + MyShaderProgram(); protected: diff --git a/OpenGLEngine/MySimpleScene.cpp b/OpenGLEngine/MySimpleScene.cpp index 2ae60f6..187405e 100644 --- a/OpenGLEngine/MySimpleScene.cpp +++ b/OpenGLEngine/MySimpleScene.cpp @@ -9,6 +9,12 @@ MySimpleScene::~MySimpleScene() { } +void MySimpleScene::init() +{ + m_shader_program.init(); + m_triangle.init(); +} + void MySimpleScene::use() { } @@ -25,5 +31,5 @@ void MySimpleScene::render() { m_shader_program.use(); glBindBuffer(GL_ARRAY_BUFFER, m_triangle.get_vbo()); - glDrawArrays(GL_TRIANGLES, 0, m_triangle.get_vertex_count()); + glDrawArrays(GL_TRIANGLES, 0, 3); } diff --git a/OpenGLEngine/MySimpleScene.h b/OpenGLEngine/MySimpleScene.h index 4aed9a6..85c8188 100644 --- a/OpenGLEngine/MySimpleScene.h +++ b/OpenGLEngine/MySimpleScene.h @@ -15,6 +15,8 @@ public: MySimpleScene(); ~MySimpleScene(); + void init() override; + void use() override; void unuse() override; diff --git a/OpenGLEngine/MyTriangle.cpp b/OpenGLEngine/MyTriangle.cpp index 5c98d06..5dc9922 100644 --- a/OpenGLEngine/MyTriangle.cpp +++ b/OpenGLEngine/MyTriangle.cpp @@ -1,31 +1,37 @@ #include "MyTriangle.h" +#include "Mesh.h" + MyTriangle::MyTriangle() { + MeshType* mesh = new MeshType(); + mesh->vertices = new VertexType[3] + { + { 0.0, 0.5, 1.0 }, + { 0.5, -0.5, 1.0 }, + { -0.5, -0.5, 1.0 }, + }; + mesh->vertex_count = 3; + mesh->indices = new unsigned int[3] { 0, 1, 2, }; + mesh->index_count = 3; + m_p_mesh = mesh; } MyTriangle::~MyTriangle() { -} - -const MyTriangle::VertexType* MyTriangle::get_vertices() const -{ - return m_vertices; -} - -const unsigned int MyTriangle::get_vertex_count() const -{ - return m_vertex_count; -} - -const MyTriangle::IndexType* MyTriangle::get_indices() const -{ - return m_indices; -} - -const unsigned int MyTriangle::get_index_count() const -{ - return m_index_count; + if (m_p_mesh != nullptr) + { + if (m_p_mesh->vertices != nullptr) + { + delete[] m_p_mesh->vertices; + } + if (m_p_mesh->indices != nullptr) + { + delete[] m_p_mesh->indices; + } + delete m_p_mesh; + m_p_mesh = nullptr; + } } GLuint MyTriangle::gen_vbo() const @@ -33,7 +39,7 @@ GLuint MyTriangle::gen_vbo() const GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, m_vertex_count * sizeof(VertexType), m_vertices, GL_STATIC_DRAW); // TODO: Optimise Usage + glBufferData(GL_ARRAY_BUFFER, m_p_mesh->vertex_count * sizeof(VertexType), m_p_mesh->vertices, GL_STATIC_DRAW); // TODO: Optimise Usage return vbo; } diff --git a/OpenGLEngine/MyTriangle.h b/OpenGLEngine/MyTriangle.h index 45a0588..91d5389 100644 --- a/OpenGLEngine/MyTriangle.h +++ b/OpenGLEngine/MyTriangle.h @@ -4,33 +4,16 @@ #include "MyShaderProgram.h" -class MyTriangle : public Renderable +class MyTriangle : public Renderable { public: MyTriangle(); ~MyTriangle(); - const VertexType* get_vertices() const override; - const unsigned int get_vertex_count() const override; - const IndexType* get_indices() const override; - const unsigned int get_index_count() const override; - protected: GLuint gen_vbo() const override; private: - const unsigned int m_vertex_count = 3; - const VertexType m_vertices[3] = - { - { 0.0f, 0.5f, 0.0f }, - { 0.5f, -0.5f, 0.0f }, - { -0.5f, -0.5f, 0.0f }, - }; - - const unsigned int m_index_count = 3; - const IndexType m_indices[3] = - { - 0, 1, 2, - }; + }; diff --git a/OpenGLEngine/OpenGLEngine.vcxproj b/OpenGLEngine/OpenGLEngine.vcxproj index df1d1f4..5503e84 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj +++ b/OpenGLEngine/OpenGLEngine.vcxproj @@ -69,7 +69,12 @@ - + + D:\Development\C++\OpenGLEngine\lib;$(LibraryPath) + + + D:\Development\C++\OpenGLEngine\lib;$(LibraryPath) + Level3 @@ -85,10 +90,9 @@ true true $(ProjectDir)..\include;%(AdditionalIncludeDirectories) + NotUsing - - opengl32.lib;%(AdditionalDependencies) - + @@ -112,7 +116,8 @@ true true true - C:\Users\peterm8\source\repos\OpenGLEngine\include;%(AdditionalIncludeDirectories) + $(ProjectDir)..\include;%(AdditionalIncludeDirectories) + NotUsing true @@ -121,6 +126,7 @@ + @@ -130,14 +136,20 @@ + + Create + Create + + + @@ -146,6 +158,7 @@ + diff --git a/OpenGLEngine/OpenGLEngine.vcxproj.filters b/OpenGLEngine/OpenGLEngine.vcxproj.filters index 0e49ed3..54b93ae 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj.filters +++ b/OpenGLEngine/OpenGLEngine.vcxproj.filters @@ -63,6 +63,12 @@ Source Files\Example + + Source Files + + + Source Files + @@ -116,6 +122,15 @@ Header Files\Example + + Header Files + + + Header Files + + + Header Files + diff --git a/OpenGLEngine/Renderable.h b/OpenGLEngine/Renderable.h index 27a59c8..1877718 100644 --- a/OpenGLEngine/Renderable.h +++ b/OpenGLEngine/Renderable.h @@ -1,31 +1,30 @@ #pragma once +#include "stdafx.h" + #include -#include -#include -#include +#include "Mesh.h" -#pragma comment(lib, "opengl32.lib") - -template +template class Renderable { public: typedef VertexType VertexType; - typedef unsigned int IndexType; + typedef IndexType IndexType; + typedef Mesh MeshType; - Renderable() + virtual ~Renderable() { }; + + void init() { m_vbo = gen_vbo(); } - virtual ~Renderable() { }; - - virtual const VertexType* get_vertices() const = 0; - virtual const unsigned int get_vertex_count() const = 0; - virtual const IndexType* get_indices() const = 0; - virtual const unsigned int get_index_count() const = 0; + const MeshType* get_mesh() const + { + return m_p_mesh; + } GLuint get_vbo() const { @@ -35,5 +34,6 @@ public: protected: virtual GLuint gen_vbo() const = 0;// TODO: A VBO for every object? - GLuint m_vbo; + const MeshType* m_p_mesh = nullptr; + GLuint m_vbo = 0; }; \ No newline at end of file diff --git a/OpenGLEngine/Scene.h b/OpenGLEngine/Scene.h index e4e54d4..97d6f88 100644 --- a/OpenGLEngine/Scene.h +++ b/OpenGLEngine/Scene.h @@ -1,5 +1,7 @@ #pragma once +#include "stdafx.h" + #include class Scene @@ -7,6 +9,9 @@ class Scene public: virtual ~Scene() { }; + // Called when the scene is ready to be initialized + virtual void init() = 0; + // Called when the scene is going to be used // Should allocate all graphics memory. virtual void use() = 0; diff --git a/OpenGLEngine/Shader.cpp b/OpenGLEngine/Shader.cpp index 6c3c75d..df143a6 100644 --- a/OpenGLEngine/Shader.cpp +++ b/OpenGLEngine/Shader.cpp @@ -1,7 +1,10 @@ #include "Shader.h" -Shader::Shader(const char* source, ShaderType type) - : m_type(type) +#include + +#include "Exception.h" + +Shader::Shader(const std::string& source, ShaderType type) { GLenum gl_shader_type; switch (type) @@ -18,7 +21,9 @@ Shader::Shader(const char* source, ShaderType type) m_shader = glCreateShader(gl_shader_type); - glShaderSource(m_shader, 1, &source, NULL); + const char* c_str = source.c_str(); + + glShaderSource(m_shader, 1, &c_str, NULL); glCompileShader(m_shader); // Make sure that the shader has been compiled successfully @@ -32,8 +37,11 @@ Shader::Shader(const char* source, ShaderType type) buffer[log_length] = '\0'; // Add null terminator OutputDebugString("Error Compiling Shader:\n"); OutputDebugString(buffer); + OutputDebugString("\nSource:\n"); + OutputDebugString(source.c_str()); + OutputDebugString("\n"); m_shader = 0; - throw "Error compiling shader."; + throw EXCEPTION("Error compiling shader."); } } diff --git a/OpenGLEngine/Shader.h b/OpenGLEngine/Shader.h index 3428fe6..142ac3b 100644 --- a/OpenGLEngine/Shader.h +++ b/OpenGLEngine/Shader.h @@ -1,10 +1,6 @@ #pragma once -#include -#include -#include - -#pragma comment(lib, "opengl32.lib") +#include "stdafx.h" #include @@ -17,13 +13,12 @@ enum ShaderType class Shader { public: - Shader(const char* source, ShaderType type); + Shader(const std::string& source, ShaderType type); ~Shader(); GLuint get_shader() const; private: GLuint m_shader; - ShaderType m_type; }; diff --git a/OpenGLEngine/ShaderProgram.cpp b/OpenGLEngine/ShaderProgram.cpp index 6f758dc..0cb5316 100644 --- a/OpenGLEngine/ShaderProgram.cpp +++ b/OpenGLEngine/ShaderProgram.cpp @@ -3,7 +3,6 @@ ShaderProgram::ShaderProgram() { m_program = glCreateProgram(); - m_vao = gen_vao(); } ShaderProgram::~ShaderProgram() @@ -11,6 +10,11 @@ ShaderProgram::~ShaderProgram() glDeleteProgram(m_program); } +void ShaderProgram::init() +{ + m_vao = gen_vao(); +} + void ShaderProgram::attach_shader(const Shader& shader) { glAttachShader(m_program, shader.get_shader()); diff --git a/OpenGLEngine/ShaderProgram.h b/OpenGLEngine/ShaderProgram.h index 2d559d5..acd1243 100644 --- a/OpenGLEngine/ShaderProgram.h +++ b/OpenGLEngine/ShaderProgram.h @@ -1,10 +1,8 @@ #pragma once -#include -#include -#include +#include "stdafx.h" -#pragma comment(lib, "opengl32.lib") +#include "Exception.h" #include "Shader.h" @@ -14,6 +12,7 @@ public: ShaderProgram(); virtual ~ShaderProgram(); + void init(); void use(); GLuint get_program() const; @@ -27,6 +26,6 @@ protected: virtual GLuint gen_vao() const = 0; private: - GLuint m_program; - GLuint m_vao; + GLuint m_program = 0; + GLuint m_vao = 0; }; \ No newline at end of file diff --git a/OpenGLEngine/Util.cpp b/OpenGLEngine/Util.cpp index e01e386..4a2d436 100644 --- a/OpenGLEngine/Util.cpp +++ b/OpenGLEngine/Util.cpp @@ -1,17 +1,32 @@ #include "Util.h" #include +#include -std::vector Util::load_file(const std::string& path) +#include "Exception.h" + +std::string Util::load_file(const std::string& path) { - std::ifstream input_stream(path, std::ios::binary | std::ios::in | std::ios::ate); - if (input_stream) + std::ifstream input_stream; + try { - std::streampos size = input_stream.tellg(); - input_stream.seekg(std::ios::beg); - std::vector buffer(size); - input_stream.read(buffer.data(), size); - input_stream.close(); + input_stream.open(path); + } + catch (std::ios::failure& e) + { + throw Exception(std::string("Error Opening File: ") + e.what(), "class Util"); + } + if (input_stream.is_open()) + { + input_stream.seekg(0, std::ios::end); + size_t size = input_stream.tellg(); + std::string buffer(size, ' '); + input_stream.seekg(std::ios::beg); + input_stream.read(&buffer[0], size); + return buffer; + } + else + { + throw Exception("Unable to access file: " + path, "class Util"); } - throw "Unable to access file."; } \ No newline at end of file diff --git a/OpenGLEngine/Util.h b/OpenGLEngine/Util.h index d356f1c..e6c9ecc 100644 --- a/OpenGLEngine/Util.h +++ b/OpenGLEngine/Util.h @@ -6,5 +6,5 @@ class Util { public: - static std::vector load_file(const std::string& path); + static std::string load_file(const std::string& path); }; \ No newline at end of file diff --git a/OpenGLEngine/Window.h b/OpenGLEngine/Window.h index f4d5b9a..b023d6a 100644 --- a/OpenGLEngine/Window.h +++ b/OpenGLEngine/Window.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "stdafx.h" #include "InputManager.h" diff --git a/OpenGLEngine/main.cpp b/OpenGLEngine/main.cpp index 297e3e3..f82cfbf 100644 --- a/OpenGLEngine/main.cpp +++ b/OpenGLEngine/main.cpp @@ -1,7 +1,27 @@ +#include "stdafx.h" + +#include + +#include + +#include "Exception.h" + #include "MyApplication.h" int WINAPI WinMain(HINSTANCE h_instance, HINSTANCE h_prev_instance, LPSTR cmd_line, int n_cmd_show) { - MyApplication my_app("my_app", h_instance); - return my_app.run(); + try + { + MyApplication my_app("my_app", h_instance); + return my_app.run(); + } + catch (Exception& e) + { + OutputDebugString("Caught Exception: ["); + OutputDebugString(e.get_class_name().c_str()); + OutputDebugString("]: "); + OutputDebugString(e.get_message().c_str()); + OutputDebugString("\n"); + return 1; + } } \ No newline at end of file diff --git a/OpenGLEngine/stdafx.cpp b/OpenGLEngine/stdafx.cpp new file mode 100644 index 0000000..46cd188 --- /dev/null +++ b/OpenGLEngine/stdafx.cpp @@ -0,0 +1,2 @@ + +#include "stdafx.h" diff --git a/OpenGLEngine/stdafx.h b/OpenGLEngine/stdafx.h new file mode 100644 index 0000000..a3d2e39 --- /dev/null +++ b/OpenGLEngine/stdafx.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +#pragma comment(lib, "glew32.lib") +#pragma comment(lib, "opengl32.lib") \ No newline at end of file diff --git a/lib/glew32.lib b/lib/glew32.lib new file mode 100644 index 0000000..25f707c Binary files /dev/null and b/lib/glew32.lib differ