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.
This commit is contained in:
elipzer 2018-09-05 19:10:38 -04:00
parent 6db2ba4f21
commit a8c4b05d2f
20 changed files with 212 additions and 80 deletions

View File

@ -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();
}

View File

@ -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();

View File

@ -1,6 +1,48 @@
#include "GLFWInputManager.h"
#include "Exception.h"
std::map<GLFWwindow*, GLFWInputManager*> 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<GLFWwindow*, GLFWInputManager*>::value_type(m_p_window, this));
}
void GLFWInputManager::key_callback(GLFWwindow* p_window, int key, int scancode, int action, int mods)
{
std::map<GLFWwindow*, GLFWInputManager*>::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");
}
}

View File

@ -4,8 +4,18 @@
#include "InputManager.h"
#include <map>
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<GLFWwindow*, GLFWInputManager*> s_glfw_windows;
};

View File

@ -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

View File

@ -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<unsigned long, bool> m_keys_pressed;
std::map<KeyCode, bool> m_keys_pressed;
//Keys that are down
std::map<unsigned long, bool> m_keys_down;
std::map<KeyCode, bool> m_keys_down;
//Current Mouse Position
ivec2 m_mouse_position;

View File

@ -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();
}
}

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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;
};

View File

@ -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)
{

View File

@ -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<Vertex, Index> RenderableType;
typedef unsigned int IndexType;
typedef Renderable<VertexType, IndexType> RenderableType;
MyShaderProgram();

View File

@ -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()

View File

@ -1,7 +1,5 @@
#pragma once
#include <time.h>
#include "Scene.h"
#include "MyBatch.h"

View File

@ -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;
}
*/

View File

@ -4,7 +4,7 @@
#include "MyShaderProgram.h"
class MyTriangle : public Renderable<MyShaderProgram::Vertex, MyShaderProgram::Index>
class MyTriangle : public Renderable<MyShaderProgram::VertexType, MyShaderProgram::IndexType>
{
public:
MyTriangle();

View File

@ -157,6 +157,7 @@
<ClCompile Include="main.cpp" />
<ClCompile Include="MyApplication.cpp" />
<ClCompile Include="MyBatch.cpp" />
<ClCompile Include="MyObjectOrientedScene.cpp" />
<ClCompile Include="MyShaderProgram.cpp" />
<ClCompile Include="MySimpleScene.cpp" />
<ClCompile Include="MyTriangle.cpp" />
@ -179,6 +180,7 @@
<ClInclude Include="Mesh.h" />
<ClInclude Include="MyApplication.h" />
<ClInclude Include="MyBatch.h" />
<ClInclude Include="MyObjectOrientedScene.h" />
<ClInclude Include="MyShaderProgram.h" />
<ClInclude Include="MySimpleScene.h" />
<ClInclude Include="MyTriangle.h" />

View File

@ -72,6 +72,9 @@
<ClCompile Include="GLFWInputManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MyObjectOrientedScene.cpp">
<Filter>Source Files\Example</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="InputManager.h">
@ -140,6 +143,9 @@
<ClInclude Include="GLFWInputManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MyObjectOrientedScene.h">
<Filter>Header Files\Example</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="MyVertexShader.glsl">

View File

@ -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)