From a8c4b05d2fba6c02aa39b3f839f46b3d90d98f5f Mon Sep 17 00:00:00 2001 From: elipzer Date: Wed, 5 Sep 2018 19:10:38 -0400 Subject: [PATCH] It Works! A triangle renders on the screen. This commit gets creates the ObjectOriented scene and gets it working. The current test program swaps a triangle from small to large with the 1 and 2 keys on the keyboard. (1 for small and 2 for large). The small triangle is rendered by the simple scene and the large one is rendered by the object oriented one. --- OpenGLEngine/Application.cpp | 11 ++++-- OpenGLEngine/Application.h | 10 +++--- OpenGLEngine/GLFWInputManager.cpp | 42 +++++++++++++++++++++++ OpenGLEngine/GLFWInputManager.h | 12 ++++++- OpenGLEngine/InputManager.cpp | 28 +++++++-------- OpenGLEngine/InputManager.h | 20 ++++++----- OpenGLEngine/MyApplication.cpp | 40 +++++++++++++-------- OpenGLEngine/MyApplication.h | 10 +++--- OpenGLEngine/MyBatch.cpp | 1 - OpenGLEngine/MyObjectOrientedScene.cpp | 38 ++++++++++++++++++++ OpenGLEngine/MyObjectOrientedScene.h | 29 ++++++++++++++++ OpenGLEngine/MyShaderProgram.cpp | 2 +- OpenGLEngine/MyShaderProgram.h | 10 ++++-- OpenGLEngine/MySimpleScene.cpp | 7 ++-- OpenGLEngine/MySimpleScene.h | 2 -- OpenGLEngine/MyTriangle.cpp | 18 ++-------- OpenGLEngine/MyTriangle.h | 2 +- OpenGLEngine/OpenGLEngine.vcxproj | 2 ++ OpenGLEngine/OpenGLEngine.vcxproj.filters | 6 ++++ OpenGLEngine/main.cpp | 2 +- 20 files changed, 212 insertions(+), 80 deletions(-) create mode 100644 OpenGLEngine/MyObjectOrientedScene.cpp create mode 100644 OpenGLEngine/MyObjectOrientedScene.h diff --git a/OpenGLEngine/Application.cpp b/OpenGLEngine/Application.cpp index 107195f..827bb87 100644 --- a/OpenGLEngine/Application.cpp +++ b/OpenGLEngine/Application.cpp @@ -2,8 +2,7 @@ #include "Exception.h" -Application::Application(const char* class_name, HINSTANCE h_instance) - : m_client_size(1280, 720) +Application::Application() { base_init(); } @@ -22,6 +21,7 @@ int Application::run() while (!glfwWindowShouldClose(m_p_window)) { // Handle all messages + m_glfw_input_manager.mark(); glfwPollEvents(); float delta_time = m_fps.mark(); clock_t clock = m_fps.get_clock(); @@ -55,13 +55,15 @@ void Application::base_init() { throw EXCEPTION("Unable to Initialize GLFW"); } - m_p_window = glfwCreateWindow(m_client_size.x, m_client_size.y, "OpenGLEngine", NULL, NULL); + m_p_window = glfwCreateWindow(1280, 720, "OpenGLEngine", NULL, NULL); if (!m_p_window) { glfwTerminate(); throw EXCEPTION("Unable to Create GLFW Window"); } + glfwMakeContextCurrent(m_p_window); + glewExperimental = GL_TRUE; GLenum glew_err = glewInit(); if (glew_err != GLEW_OK) @@ -77,6 +79,9 @@ void Application::base_init() OutputDebugString((char*)glGetString(GL_VERSION)); OutputDebugString("\n\n"); + m_glfw_input_manager.init(m_p_window); + glfwSetKeyCallback(m_p_window, &GLFWInputManager::key_callback); + m_fps.prepare(); } diff --git a/OpenGLEngine/Application.h b/OpenGLEngine/Application.h index bd551a7..72e2001 100644 --- a/OpenGLEngine/Application.h +++ b/OpenGLEngine/Application.h @@ -4,6 +4,7 @@ #include "vec2.h" +#include "GLFWInputManager.h" #include "FPS.h" using namespace egm; @@ -13,7 +14,7 @@ using namespace egm; class Application { public: - Application(const char* class_name, HINSTANCE h_instance); + Application(); virtual ~Application(); int run(); @@ -29,13 +30,10 @@ protected: // Called on closing of the application (called before base_close) virtual void close(); - // The size of the window - ivec2 m_client_size; - - // The GLFWwindow that is used by this application GLFWwindow* m_p_window; - // The FPS counter of this application + GLFWInputManager m_glfw_input_manager; + FPS m_fps; private: void base_init(); diff --git a/OpenGLEngine/GLFWInputManager.cpp b/OpenGLEngine/GLFWInputManager.cpp index 30e3fb2..2e41394 100644 --- a/OpenGLEngine/GLFWInputManager.cpp +++ b/OpenGLEngine/GLFWInputManager.cpp @@ -1,6 +1,48 @@ #include "GLFWInputManager.h" +#include "Exception.h" + +std::map GLFWInputManager::s_glfw_windows; + +GLFWInputManager::~GLFWInputManager() +{ + s_glfw_windows.erase(m_p_window); +} + +void GLFWInputManager::init(GLFWwindow* p_window) +{ + if (m_p_window != nullptr) + { + throw EXCEPTION("GLFWInputManager Already Initialized."); + } + m_p_window = p_window; + s_glfw_windows.insert(std::map::value_type(m_p_window, this)); +} + void GLFWInputManager::key_callback(GLFWwindow* p_window, int key, int scancode, int action, int mods) { + std::map::iterator iter = s_glfw_windows.find(p_window); + if (iter == s_glfw_windows.end()) + { + // Ignore Unknown Windows + return; + } + GLFWInputManager& input_manager = *iter->second; + if (action == GLFW_PRESS) + { + input_manager.key_down(key); + } + else if (action == GLFW_RELEASE) + { + input_manager.key_up(key); + } + else if (action == GLFW_REPEAT) + { + // Ignored + } + else + { + throw Exception("Invalid GLFW Key Action: " + std::to_string(action) + " (" + std::to_string(scancode) + ")", "class GLFWInputManager"); + } } diff --git a/OpenGLEngine/GLFWInputManager.h b/OpenGLEngine/GLFWInputManager.h index baab267..3d5f6e2 100644 --- a/OpenGLEngine/GLFWInputManager.h +++ b/OpenGLEngine/GLFWInputManager.h @@ -4,8 +4,18 @@ #include "InputManager.h" +#include + class GLFWInputManager : public InputManager { public: - void key_callback(GLFWwindow* p_window, int key, int scancode, int action, int mods); + ~GLFWInputManager(); + + void init(GLFWwindow* p_window); + + static void key_callback(GLFWwindow* p_window, int key, int scancode, int action, int mods); +private: + GLFWwindow* m_p_window = nullptr; + + static std::map s_glfw_windows; }; \ No newline at end of file diff --git a/OpenGLEngine/InputManager.cpp b/OpenGLEngine/InputManager.cpp index 66f5e6f..032a9fe 100644 --- a/OpenGLEngine/InputManager.cpp +++ b/OpenGLEngine/InputManager.cpp @@ -16,19 +16,19 @@ void InputManager::mark() m_scroll_distance = 0; } -void InputManager::key_down(const unsigned long& keyCode) +void InputManager::key_down(KeyCode key_code) { - if (!m_keys_down[keyCode]) + if (!m_keys_down[key_code]) { - m_keys_down[keyCode] = true; - m_keys_pressed[keyCode] = true; + m_keys_down[key_code] = true; + m_keys_pressed[key_code] = true; } } -void InputManager::key_up(const unsigned long& keyCode) +void InputManager::key_up(KeyCode key_code) { - m_keys_down[keyCode] = false; - m_keys_pressed[keyCode] = false; + m_keys_down[key_code] = false; + m_keys_pressed[key_code] = false; } void InputManager::mouse_move(const ivec2& position) @@ -37,28 +37,28 @@ void InputManager::mouse_move(const ivec2& position) m_mouse_position = position; } -void InputManager::mouse_scroll(const unsigned int& distance) +void InputManager::mouse_scroll(int distance) { m_scroll_distance += distance; } -bool InputManager::is_key_down(const unsigned long& keyCode) +bool InputManager::is_key_down(KeyCode key_code) { - return m_keys_down[keyCode]; + return m_keys_down[key_code]; } -bool InputManager::is_key_pressed(const unsigned long& keyCode) +bool InputManager::is_key_pressed(KeyCode key_code) { - auto iter = m_keys_pressed.find(keyCode); + auto iter = m_keys_pressed.find(key_code); if (iter == m_keys_pressed.end()) return false; else return iter->second; } -bool InputManager::is_key_released(const unsigned long& keyCode) +bool InputManager::is_key_released(KeyCode key_code) { - auto iter = m_keys_pressed.find(keyCode); + auto iter = m_keys_pressed.find(key_code); if (iter == m_keys_pressed.end()) return false; else diff --git a/OpenGLEngine/InputManager.h b/OpenGLEngine/InputManager.h index 7963d30..3bd5b5a 100644 --- a/OpenGLEngine/InputManager.h +++ b/OpenGLEngine/InputManager.h @@ -4,7 +4,7 @@ #include "vec2.h" -//Define the Virtual Keys for the numbers & letters +// Define the Windows Virtual Keys for the numbers & letters #define K_0 0x30 #define K_1 0x31 @@ -49,34 +49,36 @@ using namespace egm; class InputManager { public: + typedef int KeyCode; + InputManager(); virtual ~InputManager(); //Should be called after each frame to reset the keysPressed void mark(); - bool is_key_down(const unsigned long& keyCode); - bool is_key_pressed(const unsigned long& keyCode); - bool is_key_released(const unsigned long& keyCode); + bool is_key_down(KeyCode key_code); + bool is_key_pressed(KeyCode key_code); + bool is_key_released(KeyCode key_code); const ivec2& get_mouse_position(); const ivec2& get_mouse_delta(); const int& get_scroll_distance(); protected: - void key_down(const unsigned long& keyCode); - void key_up(const unsigned long& keyCode); + void key_down(KeyCode key_code); + void key_up(KeyCode key_code); void mouse_move(const ivec2& position); - void mouse_scroll(const unsigned int& distance); + void mouse_scroll(int distance); private: //Keys pressed since the last frame //The existance of a value in this array means that the key has changed to that state //since the last mark() call. //A value of true means the key was pressed, false means the value was released - std::map m_keys_pressed; + std::map m_keys_pressed; //Keys that are down - std::map m_keys_down; + std::map m_keys_down; //Current Mouse Position ivec2 m_mouse_position; diff --git a/OpenGLEngine/MyApplication.cpp b/OpenGLEngine/MyApplication.cpp index e483665..43d5715 100644 --- a/OpenGLEngine/MyApplication.cpp +++ b/OpenGLEngine/MyApplication.cpp @@ -1,34 +1,44 @@ #include "MyApplication.h" -MyApplication::MyApplication(const char* class_name, HINSTANCE h_instance) - : Application(class_name, h_instance) -{ -} - - -MyApplication::~MyApplication() -{ -} - void MyApplication::init() { - m_scene.init(); - m_scene.use(); + m_simple_scene.init(); + m_object_oriented_scene.init(); + + m_p_current_scene = &m_simple_scene; + m_p_current_scene->use(); } void MyApplication::update(float delta_time, clock_t clock) { - m_scene.update(delta_time, clock); + if (m_glfw_input_manager.is_key_pressed(GLFW_KEY_1)) + { + swap_scene(&m_simple_scene); + } + else if (m_glfw_input_manager.is_key_pressed(GLFW_KEY_2)) + { + swap_scene(&m_object_oriented_scene); + } + m_p_current_scene->update(delta_time, clock); } void MyApplication::render() { - m_scene.render(); + m_p_current_scene->render(); } void MyApplication::close() { - m_scene.unuse(); + m_p_current_scene->unuse(); } +void MyApplication::swap_scene(Scene* scene) +{ + if (m_p_current_scene != scene) + { + m_p_current_scene->unuse(); + m_p_current_scene = scene; + m_p_current_scene->use(); + } +} diff --git a/OpenGLEngine/MyApplication.h b/OpenGLEngine/MyApplication.h index 97c58e8..2b584cc 100644 --- a/OpenGLEngine/MyApplication.h +++ b/OpenGLEngine/MyApplication.h @@ -2,14 +2,12 @@ #include "Application.h" #include "MySimpleScene.h" +#include "MyObjectOrientedScene.h" class MyApplication : public Application { public: - MyApplication(const char* class_name, HINSTANCE h_instance); - ~MyApplication(); - void init() override; void update(float delta_time, clock_t clock) override; @@ -19,6 +17,10 @@ public: void close() override; private: - MySimpleScene m_scene; + void swap_scene(Scene* scene); + + Scene* m_p_current_scene = nullptr; + MySimpleScene m_simple_scene; + MyObjectOrientedScene m_object_oriented_scene; }; diff --git a/OpenGLEngine/MyBatch.cpp b/OpenGLEngine/MyBatch.cpp index 69ea9fc..ac7e897 100644 --- a/OpenGLEngine/MyBatch.cpp +++ b/OpenGLEngine/MyBatch.cpp @@ -8,7 +8,6 @@ MyBatch::MyBatch(const MyTriangle& triangle) void MyBatch::render() const { - // For now, just render everything! glBindVertexArray(m_vao); glDrawArrays(GL_TRIANGLES, 0, 3); } diff --git a/OpenGLEngine/MyObjectOrientedScene.cpp b/OpenGLEngine/MyObjectOrientedScene.cpp new file mode 100644 index 0000000..84be14a --- /dev/null +++ b/OpenGLEngine/MyObjectOrientedScene.cpp @@ -0,0 +1,38 @@ +#include "MyObjectOrientedScene.h" + +MyObjectOrientedScene::MyObjectOrientedScene() + : m_batch(m_triangle) +{ +} + +MyObjectOrientedScene::~MyObjectOrientedScene() +{ +} + +void MyObjectOrientedScene::init() +{ + m_batch.init(); +} + +void MyObjectOrientedScene::use() +{ + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); +} + +void MyObjectOrientedScene::unuse() +{ + +} + +void MyObjectOrientedScene::update(float delta_time, clock_t clock) +{ + +} + +void MyObjectOrientedScene::render() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_shader_program.use(); + m_batch.render(); +} diff --git a/OpenGLEngine/MyObjectOrientedScene.h b/OpenGLEngine/MyObjectOrientedScene.h new file mode 100644 index 0000000..262c926 --- /dev/null +++ b/OpenGLEngine/MyObjectOrientedScene.h @@ -0,0 +1,29 @@ +#pragma once + +#include "Scene.h" + +#include "MyBatch.h" +#include "MyShaderProgram.h" + +#include "MyTriangle.h" + +class MyObjectOrientedScene : public Scene +{ +public: + MyObjectOrientedScene(); + ~MyObjectOrientedScene(); + + void init() override; + + void use() override; + + void unuse() override; + + void update(float delta_time, clock_t clock) override; + + void render() override; +private: + MyBatch m_batch; + MyTriangle m_triangle; + MyShaderProgram m_shader_program; +}; \ No newline at end of file diff --git a/OpenGLEngine/MyShaderProgram.cpp b/OpenGLEngine/MyShaderProgram.cpp index 68946c3..4743ebe 100644 --- a/OpenGLEngine/MyShaderProgram.cpp +++ b/OpenGLEngine/MyShaderProgram.cpp @@ -3,7 +3,7 @@ #include "Util.h" MyShaderProgram::MyShaderProgram() - // TEMP Hardcode in the path + // TEMP Hardcode in the path. (Should Use Relative Path to General Shader Dir) : 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) { diff --git a/OpenGLEngine/MyShaderProgram.h b/OpenGLEngine/MyShaderProgram.h index 09bcfd4..ae55c2c 100644 --- a/OpenGLEngine/MyShaderProgram.h +++ b/OpenGLEngine/MyShaderProgram.h @@ -7,14 +7,18 @@ class MyShaderProgram : public ShaderProgram { public: - struct Vertex + struct VertexType { + VertexType(float x, float y, float z) + : x(x), y(y), z(z) + { + } float x; float y; float z; }; - typedef unsigned int Index; - typedef Renderable RenderableType; + typedef unsigned int IndexType; + typedef Renderable RenderableType; MyShaderProgram(); diff --git a/OpenGLEngine/MySimpleScene.cpp b/OpenGLEngine/MySimpleScene.cpp index 350b0b2..0d03733 100644 --- a/OpenGLEngine/MySimpleScene.cpp +++ b/OpenGLEngine/MySimpleScene.cpp @@ -11,9 +11,6 @@ MySimpleScene::~MySimpleScene() void MySimpleScene::init() { - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - float points[] = { 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, @@ -27,12 +24,14 @@ void MySimpleScene::init() glGenVertexArrays(1, &m_vao); glBindVertexArray(m_vao); glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, m_vao); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); } void MySimpleScene::use() { + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); } void MySimpleScene::unuse() diff --git a/OpenGLEngine/MySimpleScene.h b/OpenGLEngine/MySimpleScene.h index 36922c9..249152d 100644 --- a/OpenGLEngine/MySimpleScene.h +++ b/OpenGLEngine/MySimpleScene.h @@ -1,7 +1,5 @@ #pragma once -#include - #include "Scene.h" #include "MyBatch.h" diff --git a/OpenGLEngine/MyTriangle.cpp b/OpenGLEngine/MyTriangle.cpp index 3d98c28..bb792bc 100644 --- a/OpenGLEngine/MyTriangle.cpp +++ b/OpenGLEngine/MyTriangle.cpp @@ -7,9 +7,9 @@ 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 }, + { 0.0f, 0.75f, 0.0f }, + { 0.75f, -0.75f, 0.0f }, + { -0.75f, -0.75f, 0.0f }, }; mesh->vertex_count = 3; mesh->indices = new unsigned int[3] { 0, 1, 2, }; @@ -38,15 +38,3 @@ void MyTriangle::populate_vbo() const { glBufferData(GL_ARRAY_BUFFER, m_p_mesh->vertex_count * sizeof(VertexType), m_p_mesh->vertices, GL_STATIC_DRAW); } - -/* -GLuint MyTriangle::gen_vbo() const -{ - GLuint vbo; - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - 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 65b18e7..706d2fc 100644 --- a/OpenGLEngine/MyTriangle.h +++ b/OpenGLEngine/MyTriangle.h @@ -4,7 +4,7 @@ #include "MyShaderProgram.h" -class MyTriangle : public Renderable +class MyTriangle : public Renderable { public: MyTriangle(); diff --git a/OpenGLEngine/OpenGLEngine.vcxproj b/OpenGLEngine/OpenGLEngine.vcxproj index 029f553..354b670 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj +++ b/OpenGLEngine/OpenGLEngine.vcxproj @@ -157,6 +157,7 @@ + @@ -179,6 +180,7 @@ + diff --git a/OpenGLEngine/OpenGLEngine.vcxproj.filters b/OpenGLEngine/OpenGLEngine.vcxproj.filters index dc3fdec..dd5fd2b 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj.filters +++ b/OpenGLEngine/OpenGLEngine.vcxproj.filters @@ -72,6 +72,9 @@ Source Files + + Source Files\Example + @@ -140,6 +143,9 @@ Header Files + + Header Files\Example + diff --git a/OpenGLEngine/main.cpp b/OpenGLEngine/main.cpp index 50f5c1a..1a0c732 100644 --- a/OpenGLEngine/main.cpp +++ b/OpenGLEngine/main.cpp @@ -10,7 +10,7 @@ int WINAPI WinMain(HINSTANCE h_instance, HINSTANCE h_prev_instance, LPSTR cmd_li { try { - MyApplication my_app("my_app", h_instance); + MyApplication my_app; return my_app.run(); } catch (Exception& e)