Camera Class

Currently implemented a 2D camera class that creates an
orthographic projection matrix.

TODO is implementing a 3D camera class and test program.
This commit is contained in:
elipzer 2018-09-08 00:06:10 -04:00
parent 05363f94b7
commit 5a10a883fb
26 changed files with 590 additions and 283 deletions

View File

@ -2,9 +2,46 @@
#include "Exception.h" #include "Exception.h"
Application::Application() Application::Application(int width, int height)
: m_screen_size(width, height)
{ {
base_init(); if (width < 0 || height < 0)
throw EXCEPTION("Invalid screen dimensions");
if (!glfwInit())
throw EXCEPTION("Unable to Initialize GLFW");
m_p_window = glfwCreateWindow(width, height, "OpenGLEngine", NULL, NULL);
if (!m_p_window)
{
glfwTerminate();
throw EXCEPTION("Unable to Create GLFW Window");
}
glfwSwapInterval(1);
glfwMakeContextCurrent(m_p_window);
glewExperimental = GL_TRUE;
GLenum glew_err = glewInit();
if (glew_err != GLEW_OK)
{
glfwTerminate();
throw EXCEPTION("Unable to Initialize GLEW: " + std::string((char*)glewGetErrorString(glew_err)));
}
// Output Version Information
OutputDebugString("\nOpenGL Version Information:\nRenderer: ");
OutputDebugString((char*)glGetString(GL_RENDERER));
OutputDebugString("\nOpenGL Version: ");
OutputDebugString((char*)glGetString(GL_VERSION));
OutputDebugString("\n\n");
// TODO: Mouse Movement, Mouse Scroll
m_glfw_input_manager.init(m_p_window);
glfwSetKeyCallback(m_p_window, &GLFWInputManager::key_callback);
m_fps.prepare();
} }
@ -40,47 +77,6 @@ int Application::run()
glfwTerminate(); glfwTerminate();
throw e; throw e;
} }
}
void Application::close()
{
}
void Application::base_init()
{
if (!glfwInit())
{
throw EXCEPTION("Unable to Initialize GLFW");
}
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)
{
glfwTerminate();
throw EXCEPTION("Unable to Initialize GLEW: " + std::string((char*)glewGetErrorString(glew_err)));
}
// Output Version Information
OutputDebugString("\nOpenGL Version Information:\nRenderer: ");
OutputDebugString((char*)glGetString(GL_RENDERER));
OutputDebugString("\nOpenGL Version: ");
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();
} }
void Application::base_close() void Application::base_close()

View File

@ -14,11 +14,17 @@ using namespace egm;
class Application class Application
{ {
public: public:
Application(); Application(int width = -1, int height = -1);
virtual ~Application(); virtual ~Application();
int run(); int run();
const ivec2& get_screen_size() const { return m_screen_size; }
const GLFWInputManager& get_input_manager() const { return m_glfw_input_manager; }
const FPS& get_fps() const { return m_fps; }
protected: protected:
// Called on initialization of the application (called by base_init) // Called on initialization of the application (called by base_init)
virtual void init() = 0; virtual void init() = 0;
@ -28,15 +34,16 @@ protected:
virtual void render() = 0; virtual void render() = 0;
// Called on closing of the application (called before base_close) // Called on closing of the application (called before base_close)
virtual void close(); virtual void close() {}
GLFWwindow* m_p_window; GLFWwindow* m_p_window;
const ivec2 m_screen_size;
GLFWInputManager m_glfw_input_manager; GLFWInputManager m_glfw_input_manager;
FPS m_fps; FPS m_fps;
private: private:
void base_init();
void base_close(); void base_close();
}; };

18
OpenGLEngine/Camera.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include "mat4x4.h"
using namespace egm;
class Camera
{
public:
// Should update m_view_projection_matrix with the current
// view projection matrix.
virtual void update_view_projection_matrix() = 0;
const mat4x4& get_view_projection_matrix() const { return m_view_projection_matrix; }
protected:
mat4x4 m_view_projection_matrix;
};

59
OpenGLEngine/Camera2D.cpp Normal file
View File

@ -0,0 +1,59 @@
#include "Camera2D.h"
#include "operations.h"
Camera2D::Camera2D(const vec2& size, const vec2& position)
: Camera2D(vec3(size.x, size.y, 2.0f), vec3(position.x, position.y, 0.0f)) {}
Camera2D::Camera2D(const vec3& size, const vec3& position)
{
update_size(size);
update_position(position);
}
void Camera2D::update_size(const vec3& size)
{
m_size = size;
update_scale();
}
void Camera2D::update_position(const vec3& position)
{
m_position = position;
update_offset();
}
void Camera2D::translate(const vec2& position)
{
translate(vec3(position.x, position.y, 0.0f));
}
void Camera2D::translate(const vec3& position)
{
m_position += position;
update_offset();
}
void Camera2D::update_view_projection_matrix()
{
m_view_projection_matrix.a.x = m_scale.x;
m_view_projection_matrix.b.y = m_scale.y;
m_view_projection_matrix.c.z = m_scale.z;
m_view_projection_matrix.a.w = m_offset.x;
m_view_projection_matrix.b.w = m_offset.y;
m_view_projection_matrix.c.w = m_offset.z;
}
void Camera2D::update_scale()
{
m_scale.x = 2.0f / m_size.x;
m_scale.y = 2.0f / m_size.y;
m_scale.z = -2.0f / m_size.z;
}
void Camera2D::update_offset()
{
m_offset.x = -m_position.x;
m_offset.y = -m_position.y;
m_offset.z = -m_position.z;
}

36
OpenGLEngine/Camera2D.h Normal file
View File

@ -0,0 +1,36 @@
#pragma once
#include "Camera.h"
#include "vec2.h"
#include "vec3.h"
using namespace egm;
class Camera2D : public Camera
{
public:
Camera2D(const vec2& size, const vec2& position = vec2(0.0f, 0.0f));
Camera2D(const vec3& size = vec3(2.0f, 2.0f, 2.0f), const vec3& position = vec3(0.0f, 0.0f, 0.0f));
void update_size(const vec3& size);
void update_position(const vec3& position);
void translate(const vec2& translation);
void translate(const vec3& translation);
const vec3& get_size() { return m_size; }
const vec3& get_position() { return m_position; }
void update_view_projection_matrix() override;
private:
void update_scale();
void update_offset();
vec3 m_size;
vec3 m_position;
vec3 m_scale;
vec3 m_offset;
};

View File

@ -12,9 +12,7 @@ GLFWInputManager::~GLFWInputManager()
void GLFWInputManager::init(GLFWwindow* p_window) void GLFWInputManager::init(GLFWwindow* p_window)
{ {
if (m_p_window != nullptr) if (m_p_window != nullptr)
{
throw EXCEPTION("GLFWInputManager Already Initialized."); throw EXCEPTION("GLFWInputManager Already Initialized.");
}
m_p_window = p_window; m_p_window = p_window;
s_glfw_windows.insert(std::map<GLFWwindow*, GLFWInputManager*>::value_type(m_p_window, this)); s_glfw_windows.insert(std::map<GLFWwindow*, GLFWInputManager*>::value_type(m_p_window, this));
} }
@ -23,26 +21,14 @@ void GLFWInputManager::key_callback(GLFWwindow* p_window, int key, int scancode,
{ {
std::map<GLFWwindow*, GLFWInputManager*>::iterator iter = s_glfw_windows.find(p_window); std::map<GLFWwindow*, GLFWInputManager*>::iterator iter = s_glfw_windows.find(p_window);
if (iter == s_glfw_windows.end()) if (iter == s_glfw_windows.end())
{ return; // Ignore Unknown Windows
// Ignore Unknown Windows
return;
}
GLFWInputManager& input_manager = *iter->second; GLFWInputManager& input_manager = *iter->second;
if (action == GLFW_PRESS) if (action == GLFW_PRESS)
{
input_manager.key_down(key); input_manager.key_down(key);
}
else if (action == GLFW_RELEASE) else if (action == GLFW_RELEASE)
{
input_manager.key_up(key); input_manager.key_up(key);
} else if (action == GLFW_REPEAT) { /* Ignored */}
else if (action == GLFW_REPEAT)
{
// Ignored
}
else else
{
throw Exception("Invalid GLFW Key Action: " + std::to_string(action) + " (" + std::to_string(scancode) + ")", "class GLFWInputManager"); throw Exception("Invalid GLFW Key Action: " + std::to_string(action) + " (" + std::to_string(scancode) + ")", "class GLFWInputManager");
}
} }

View File

@ -38,12 +38,16 @@ void InputManager::mouse_scroll(int distance)
m_scroll_distance += distance; m_scroll_distance += distance;
} }
bool InputManager::is_key_down(KeyCode key_code) bool InputManager::is_key_down(KeyCode key_code) const
{ {
return m_keys_down[key_code]; auto iter = m_keys_down.find(key_code);
if (iter == m_keys_down.end())
return false;
else
return iter->second;
} }
bool InputManager::is_key_pressed(KeyCode key_code) bool InputManager::is_key_pressed(KeyCode key_code) const
{ {
auto iter = m_keys_pressed.find(key_code); auto iter = m_keys_pressed.find(key_code);
if (iter == m_keys_pressed.end()) if (iter == m_keys_pressed.end())
@ -52,7 +56,7 @@ bool InputManager::is_key_pressed(KeyCode key_code)
return iter->second; return iter->second;
} }
bool InputManager::is_key_released(KeyCode key_code) bool InputManager::is_key_released(KeyCode key_code) const
{ {
auto iter = m_keys_pressed.find(key_code); auto iter = m_keys_pressed.find(key_code);
if (iter == m_keys_pressed.end()) if (iter == m_keys_pressed.end())
@ -61,17 +65,17 @@ bool InputManager::is_key_released(KeyCode key_code)
return !iter->second; return !iter->second;
} }
const ivec2& InputManager::get_mouse_position() const ivec2& InputManager::get_mouse_position() const
{ {
return m_mouse_position; return m_mouse_position;
} }
const ivec2& InputManager::get_mouse_delta() const ivec2& InputManager::get_mouse_delta() const
{ {
return m_mouse_delta; return m_mouse_delta;
} }
const int& InputManager::get_scroll_distance() const int& InputManager::get_scroll_distance() const
{ {
return m_scroll_distance; return m_scroll_distance;
} }

View File

@ -57,12 +57,12 @@ public:
//Should be called after each frame to reset the keysPressed //Should be called after each frame to reset the keysPressed
void mark(); void mark();
bool is_key_down(KeyCode key_code); bool is_key_down(KeyCode key_code) const;
bool is_key_pressed(KeyCode key_code); bool is_key_pressed(KeyCode key_code) const;
bool is_key_released(KeyCode key_code); bool is_key_released(KeyCode key_code) const;
const ivec2& get_mouse_position(); const ivec2& get_mouse_position() const;
const ivec2& get_mouse_delta(); const ivec2& get_mouse_delta() const;
const int& get_scroll_distance(); const int& get_scroll_distance() const;
protected: protected:
void key_down(KeyCode key_code); void key_down(KeyCode key_code);

View File

@ -1,5 +1,10 @@
#include "MyApplication.h" #include "MyApplication.h"
MyApplication::MyApplication(int width, int height)
: Application(width, height), m_simple_scene(*this), m_object_oriented_scene(*this)
{
}
void MyApplication::init() void MyApplication::init()
{ {
m_simple_scene.init(); m_simple_scene.init();

View File

@ -8,6 +8,8 @@ class MyApplication :
public Application public Application
{ {
public: public:
MyApplication(int width = -1, int height = -1);
void init() override; void init() override;
void update(float delta_time, clock_t clock) override; void update(float delta_time, clock_t clock) override;

View File

@ -7,6 +7,11 @@
class MyBatch : public Batch<MyBatchTestShaderProgram::Vertex, MyBatchTestShaderProgram::Index, 2> class MyBatch : public Batch<MyBatchTestShaderProgram::Vertex, MyBatchTestShaderProgram::Index, 2>
{ {
public: public:
MyBatch(
const MyBatchTestShaderProgram::Renderable* renderable,
const SizeType& element_count
) : MyBatch(renderable, element_count, element_count) {}
MyBatch( MyBatch(
const MyBatchTestShaderProgram::Renderable* renderable, const MyBatchTestShaderProgram::Renderable* renderable,
const SizeType& element_count, const SizeType& element_count,

View File

@ -1,10 +1,14 @@
#version 400 #version 430
layout(location = 0) in vec3 vertex_position; layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec4 vertex_color; layout(location = 1) in vec4 vertex_color;
layout(location = 2) in vec3 vertex_offset;
// TODO: Try this with location 0
layout(location = 3) uniform mat4 vp;
out vec4 vert_color; out vec4 vert_color;
void main() void main()
{ {
gl_Position = vec4(vertex_position, 1.0); gl_Position = vp * vec4(vertex_position + vertex_offset, 1.0);
vert_color = vertex_color; vert_color = vertex_color;
} }

View File

@ -1,16 +1,24 @@
#include "MyObjectOrientedScene.h" #include "MyObjectOrientedScene.h"
#include <math.h>
#include "constants.h"
#include "DrawMode.h" #include "DrawMode.h"
#include "MeshFactory.h" #include "MeshFactory.h"
MyObjectOrientedScene::MyObjectOrientedScene() MyObjectOrientedScene::MyObjectOrientedScene(Application& application)
: m_shape(MeshFactory<MyBatchTestShaderProgram::Vertex, MyBatchTestShaderProgram::Index>::gen( : Scene(application),
m_shape(MeshFactory<MyBatchTestShaderProgram::Vertex, MyBatchTestShaderProgram::Index>::gen(
DrawMode::DRAW_TRIANGLES, DrawMode::DRAW_TRIANGLES,
MyBatchTestShaderProgram::Vertex(-0.1f, 0.1f, 0.0f), MyBatchTestShaderProgram::Vertex(-50.0f, 50.0f, 0.0f),
MyBatchTestShaderProgram::Vertex(0.1f, 0.1f, 0.0f), MyBatchTestShaderProgram::Vertex(50.0f, 150.0f, 0.0f),
MyBatchTestShaderProgram::Vertex(-0.15f, -0.1f, 0.0f), MyBatchTestShaderProgram::Vertex(-100.0f, -50.0f, 0.0f),
MyBatchTestShaderProgram::Vertex(0.15f, -0.1f, 0.0f) MyBatchTestShaderProgram::Vertex(100.0f, -50.0f, 0.0f)
), DrawMode::DRAW_TRIANGLES), m_batch(&m_shape, 1, 1) ),
DrawMode::DRAW_TRIANGLES),
m_batch(&m_shape, 2),
m_camera(m_screen_size)
{ {
} }
@ -36,26 +44,57 @@ void MyObjectOrientedScene::unuse()
void MyObjectOrientedScene::update(float delta_time, clock_t clock) void MyObjectOrientedScene::update(float delta_time, clock_t clock)
{ {
float n; float brightness;
float radians;
clock_t c; clock_t c;
c = (clock / 10) % 512; const clock_t intervals = 512 * CLOCKS_PER_SEC / 100;
if (c < 256) const clock_t half_interval = 256 * CLOCKS_PER_SEC / 100;
{ c = clock % intervals;
n = (float)c / 256; if (c < half_interval)
} brightness = (float)c / half_interval;
else else
brightness = (float)(intervals - c) / half_interval;
radians = (float)egm::TAU * c / intervals;
{ {
n = (float)(512 - c) / 256; MyBatchTestShaderProgram::Color& color = m_batch.get_color(0);
color.r = brightness;
color.g = brightness;
color.b = brightness;
color.a = 1.0f;
MyBatchTestShaderProgram::Offset& offset = m_batch.get_offset(0);
offset.x = 200 * (float)cos(radians);
offset.y = 0.0f;
offset.z = 0.0f;
} }
// TODO: Movement Test {
MyBatchTestShaderProgram::Color& color = m_batch.get_color(1);
MyBatchTestShaderProgram::Color& color = m_batch.get_color(0); color.r = 1.0f - brightness;
color.r = n; color.g = 1.0f - brightness;
color.g = n; color.b = 1.0f - brightness;
color.b = n;
color.a = 1.0f; color.a = 1.0f;
MyBatchTestShaderProgram::Offset& offset = m_batch.get_offset(1);
offset.x = 0.0f;
offset.y = 200 * (float)sin(radians);
offset.z = 0.0f;
}
vec2 camera_translation;
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;
m_camera.translate(camera_translation * delta_time);
m_camera.update_view_projection_matrix();
// TODO: Make a prerender function or move this to render // TODO: Make a prerender function or move this to render
m_batch.prerender(); m_batch.prerender();
} }
@ -64,5 +103,6 @@ void MyObjectOrientedScene::render()
{ {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_shader_program.use(); m_shader_program.use();
glUniformMatrix4fv(3, 1, GL_TRUE, &m_camera.get_view_projection_matrix().a.x);
m_batch.render(); m_batch.render();
} }

View File

@ -2,13 +2,15 @@
#include "Scene.h" #include "Scene.h"
#include "Camera2D.h"
#include "MyBatch.h" #include "MyBatch.h"
#include "MyBatchTestShaderProgram.h" #include "MyBatchTestShaderProgram.h"
class MyObjectOrientedScene : public Scene class MyObjectOrientedScene : public Scene
{ {
public: public:
MyObjectOrientedScene(); MyObjectOrientedScene(Application& application);
~MyObjectOrientedScene(); ~MyObjectOrientedScene();
void init() override; void init() override;
@ -24,4 +26,5 @@ private:
MyBatch m_batch; MyBatch m_batch;
MyBatchTestShaderProgram::Renderable m_shape; MyBatchTestShaderProgram::Renderable m_shape;
MyBatchTestShaderProgram m_shader_program; MyBatchTestShaderProgram m_shader_program;
Camera2D m_camera;
}; };

View File

@ -1,6 +1,7 @@
#include "MySimpleScene.h" #include "MySimpleScene.h"
MySimpleScene::MySimpleScene() MySimpleScene::MySimpleScene(Application& application)
: Scene(application)
{ {
} }

View File

@ -9,7 +9,7 @@ class MySimpleScene :
public Scene public Scene
{ {
public: public:
MySimpleScene(); MySimpleScene(Application& application);
~MySimpleScene(); ~MySimpleScene();
void init() override; void init() override;

View File

@ -150,6 +150,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Application.cpp" /> <ClCompile Include="Application.cpp" />
<ClCompile Include="Camera2D.cpp" />
<ClCompile Include="Exception.cpp" /> <ClCompile Include="Exception.cpp" />
<ClCompile Include="FPS.cpp" /> <ClCompile Include="FPS.cpp" />
<ClCompile Include="GLFWInputManager.cpp" /> <ClCompile Include="GLFWInputManager.cpp" />
@ -172,6 +173,9 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="Application.h" /> <ClInclude Include="Application.h" />
<ClInclude Include="Batch.h" /> <ClInclude Include="Batch.h" />
<ClInclude Include="Camera.h" />
<ClInclude Include="Camera2D.h" />
<ClInclude Include="constants.h" />
<ClInclude Include="DrawMode.h" /> <ClInclude Include="DrawMode.h" />
<ClInclude Include="Exception.h" /> <ClInclude Include="Exception.h" />
<ClInclude Include="FPS.h" /> <ClInclude Include="FPS.h" />
@ -186,6 +190,7 @@
<ClInclude Include="MyObjectOrientedScene.h" /> <ClInclude Include="MyObjectOrientedScene.h" />
<ClInclude Include="MyShaderProgram.h" /> <ClInclude Include="MyShaderProgram.h" />
<ClInclude Include="MySimpleScene.h" /> <ClInclude Include="MySimpleScene.h" />
<ClInclude Include="operations.h" />
<ClInclude Include="Renderable.h" /> <ClInclude Include="Renderable.h" />
<ClInclude Include="Scene.h" /> <ClInclude Include="Scene.h" />
<ClInclude Include="Shader.h" /> <ClInclude Include="Shader.h" />

View File

@ -13,164 +13,209 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter> </Filter>
<Filter Include="Header Files\math">
<UniqueIdentifier>{3011da99-7ced-44b5-b379-754b5db0a1c3}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Example"> <Filter Include="Header Files\Example">
<UniqueIdentifier>{6a527248-fa21-4720-8864-49088116987e}</UniqueIdentifier> <UniqueIdentifier>{6a527248-fa21-4720-8864-49088116987e}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Source Files\Example"> <Filter Include="Source Files\Example">
<UniqueIdentifier>{6f8b9833-6eed-478e-a52d-38bdb2573b92}</UniqueIdentifier> <UniqueIdentifier>{6f8b9833-6eed-478e-a52d-38bdb2573b92}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Source Files\Example\Shader Code"> <Filter Include="Header Files\Engine">
<UniqueIdentifier>{053be292-7a70-4d73-8b07-dcb85d3d6ace}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Engine">
<UniqueIdentifier>{c38724ea-6e5b-4561-bb97-74da2a031319}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Engine\Rendering">
<UniqueIdentifier>{51327f54-6f84-477f-8db8-883b91ebc5c2}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Engine\Application">
<UniqueIdentifier>{2d1806dc-3a5d-4237-b7e3-4fe6d6576dc2}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Engine\Application">
<UniqueIdentifier>{e8ae51e5-5508-47c6-804c-6d13408b8d13}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Engine\Rendering">
<UniqueIdentifier>{1bb31cb4-7b36-47b6-b9ee-3d5de57f8f0c}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Example\Application">
<UniqueIdentifier>{3f9911e0-108f-4258-99c4-3f56e80ac27e}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Example\Rendering">
<UniqueIdentifier>{fd515372-39af-44d2-af2c-634b28e91878}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Example\Application">
<UniqueIdentifier>{dab3e00b-75ef-4281-b922-5ca6576c2dee}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Example\Rendering">
<UniqueIdentifier>{3361920b-2846-44ef-a1d1-5f867859bbbf}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Example\Rendering\Shader Code">
<UniqueIdentifier>{0c68fb1a-eaef-450c-ab9e-56bcfd75fdff}</UniqueIdentifier> <UniqueIdentifier>{0c68fb1a-eaef-450c-ab9e-56bcfd75fdff}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Header Files\Example\Scenes"> <Filter Include="Source Files\Example\Application\Scenes">
<UniqueIdentifier>{9b6de612-281e-42cd-99a8-1917e2ba77bf}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Example\Application\Scenes">
<UniqueIdentifier>{922d67ef-ebba-4810-b4c4-fab05be62c9a}</UniqueIdentifier> <UniqueIdentifier>{922d67ef-ebba-4810-b4c4-fab05be62c9a}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Source Files\Example\Scenes"> <Filter Include="Header Files\Engine\math">
<UniqueIdentifier>{9b6de612-281e-42cd-99a8-1917e2ba77bf}</UniqueIdentifier> <UniqueIdentifier>{3011da99-7ced-44b5-b379-754b5db0a1c3}</UniqueIdentifier>
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="InputManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Application.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FPS.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MyApplication.cpp">
<Filter>Source Files\Example</Filter>
</ClCompile>
<ClCompile Include="main.cpp"> <ClCompile Include="main.cpp">
<Filter>Source Files\Example</Filter> <Filter>Source Files\Example</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Shader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ShaderProgram.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MyShaderProgram.cpp">
<Filter>Source Files\Example</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Exception.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MyBatch.cpp">
<Filter>Source Files\Example</Filter>
</ClCompile>
<ClCompile Include="GLFWInputManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MyObjectOrientedScene.cpp"> <ClCompile Include="MyObjectOrientedScene.cpp">
<Filter>Source Files\Example\Scenes</Filter> <Filter>Source Files\Example\Application\Scenes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="MySimpleScene.cpp"> <ClCompile Include="MySimpleScene.cpp">
<Filter>Source Files\Example\Scenes</Filter> <Filter>Source Files\Example\Application\Scenes</Filter>
</ClCompile>
<ClCompile Include="Exception.cpp">
<Filter>Source Files\Engine</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files\Engine</Filter>
</ClCompile>
<ClCompile Include="Util.cpp">
<Filter>Source Files\Engine</Filter>
</ClCompile>
<ClCompile Include="Application.cpp">
<Filter>Source Files\Engine\Application</Filter>
</ClCompile>
<ClCompile Include="FPS.cpp">
<Filter>Source Files\Engine\Application</Filter>
</ClCompile>
<ClCompile Include="GLFWInputManager.cpp">
<Filter>Source Files\Engine\Application</Filter>
</ClCompile>
<ClCompile Include="InputManager.cpp">
<Filter>Source Files\Engine\Application</Filter>
</ClCompile>
<ClCompile Include="ShaderProgram.cpp">
<Filter>Source Files\Engine\Rendering</Filter>
</ClCompile>
<ClCompile Include="Shader.cpp">
<Filter>Source Files\Engine\Rendering</Filter>
</ClCompile>
<ClCompile Include="MyBatch.cpp">
<Filter>Source Files\Example\Rendering</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="MyBatchTestShaderProgram.cpp"> <ClCompile Include="MyBatchTestShaderProgram.cpp">
<Filter>Source Files\Example</Filter> <Filter>Source Files\Example\Rendering</Filter>
</ClCompile>
<ClCompile Include="MyShaderProgram.cpp">
<Filter>Source Files\Example\Rendering</Filter>
</ClCompile>
<ClCompile Include="MyApplication.cpp">
<Filter>Source Files\Example\Application</Filter>
</ClCompile>
<ClCompile Include="Camera2D.cpp">
<Filter>Source Files\Engine\Rendering</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="InputManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mat4x4.h"> <ClInclude Include="mat4x4.h">
<Filter>Header Files\math</Filter> <Filter>Header Files\Engine\math</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="vec2.h"> <ClInclude Include="vec2.h">
<Filter>Header Files\math</Filter> <Filter>Header Files\Engine\math</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="vec3.h"> <ClInclude Include="vec3.h">
<Filter>Header Files\math</Filter> <Filter>Header Files\Engine\math</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="vec4.h"> <ClInclude Include="vec4.h">
<Filter>Header Files\math</Filter> <Filter>Header Files\Engine\math</Filter>
</ClInclude>
<ClInclude Include="Application.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MyApplication.h">
<Filter>Header Files\Example</Filter>
</ClInclude>
<ClInclude Include="Scene.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FPS.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Renderable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Shader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ShaderProgram.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MyShaderProgram.h">
<Filter>Header Files\Example</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Exception.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Mesh.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Batch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MyBatch.h">
<Filter>Header Files\Example</Filter>
</ClInclude>
<ClInclude Include="GLFWInputManager.h">
<Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="MyObjectOrientedScene.h"> <ClInclude Include="MyObjectOrientedScene.h">
<Filter>Header Files\Example\Scenes</Filter> <Filter>Header Files\Example\Application\Scenes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="MySimpleScene.h"> <ClInclude Include="MySimpleScene.h">
<Filter>Header Files\Example\Scenes</Filter> <Filter>Header Files\Example\Application\Scenes</Filter>
</ClInclude>
<ClInclude Include="constants.h">
<Filter>Header Files\Engine\math</Filter>
</ClInclude>
<ClInclude Include="operations.h">
<Filter>Header Files\Engine\math</Filter>
</ClInclude>
<ClInclude Include="Exception.h">
<Filter>Header Files\Engine</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="MeshFactory.h"> <ClInclude Include="MeshFactory.h">
<Filter>Header Files</Filter> <Filter>Header Files\Engine</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>Header Files\Engine</Filter>
</ClInclude>
<ClInclude Include="Util.h">
<Filter>Header Files\Engine</Filter>
</ClInclude>
<ClInclude Include="Application.h">
<Filter>Header Files\Engine\Application</Filter>
</ClInclude>
<ClInclude Include="FPS.h">
<Filter>Header Files\Engine\Application</Filter>
</ClInclude>
<ClInclude Include="GLFWInputManager.h">
<Filter>Header Files\Engine\Application</Filter>
</ClInclude>
<ClInclude Include="InputManager.h">
<Filter>Header Files\Engine\Application</Filter>
</ClInclude>
<ClInclude Include="Scene.h">
<Filter>Header Files\Engine\Application</Filter>
</ClInclude>
<ClInclude Include="ShaderProgram.h">
<Filter>Header Files\Engine\Rendering</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="DrawMode.h"> <ClInclude Include="DrawMode.h">
<Filter>Header Files</Filter> <Filter>Header Files\Engine\Rendering</Filter>
</ClInclude>
<ClInclude Include="Shader.h">
<Filter>Header Files\Engine\Rendering</Filter>
</ClInclude>
<ClInclude Include="Mesh.h">
<Filter>Header Files\Engine\Rendering</Filter>
</ClInclude>
<ClInclude Include="Camera.h">
<Filter>Header Files\Engine\Rendering</Filter>
</ClInclude>
<ClInclude Include="Batch.h">
<Filter>Header Files\Engine\Rendering</Filter>
</ClInclude>
<ClInclude Include="Renderable.h">
<Filter>Header Files\Engine\Rendering</Filter>
</ClInclude>
<ClInclude Include="MyBatch.h">
<Filter>Header Files\Example\Rendering</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="MyBatchTestShaderProgram.h"> <ClInclude Include="MyBatchTestShaderProgram.h">
<Filter>Header Files\Example</Filter> <Filter>Header Files\Example\Rendering</Filter>
</ClInclude>
<ClInclude Include="MyShaderProgram.h">
<Filter>Header Files\Example\Rendering</Filter>
</ClInclude>
<ClInclude Include="MyApplication.h">
<Filter>Header Files\Example\Application</Filter>
</ClInclude>
<ClInclude Include="Camera2D.h">
<Filter>Header Files\Engine\Rendering</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="MyVertexShader.glsl"> <None Include="MyVertexShader.glsl">
<Filter>Source Files\Example\Shader Code</Filter> <Filter>Source Files\Example\Rendering\Shader Code</Filter>
</None> </None>
<None Include="MyFragmentShader.glsl"> <None Include="MyFragmentShader.glsl">
<Filter>Source Files\Example\Shader Code</Filter> <Filter>Source Files\Example\Rendering\Shader Code</Filter>
</None> </None>
<None Include="MyBatchTestFragmentShader.glsl"> <None Include="MyBatchTestFragmentShader.glsl">
<Filter>Source Files\Example\Shader Code</Filter> <Filter>Source Files\Example\Rendering\Shader Code</Filter>
</None> </None>
<None Include="MyBatchTestVertexShader.glsl"> <None Include="MyBatchTestVertexShader.glsl">
<Filter>Source Files\Example\Shader Code</Filter> <Filter>Source Files\Example\Rendering\Shader Code</Filter>
</None> </None>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -4,9 +4,15 @@
#include <time.h> #include <time.h>
#include "Application.h"
class Scene class Scene
{ {
public: public:
Scene(Application& application)
: m_screen_size(application.get_screen_size()),
m_input_manager(application.get_input_manager()),
m_fps(application.get_fps()) {};
virtual ~Scene() { }; virtual ~Scene() { };
// Called when the scene is ready to be initialized // Called when the scene is ready to be initialized
@ -25,5 +31,9 @@ public:
// Called when the frame is being rendered // Called when the frame is being rendered
virtual void render() = 0; virtual void render() = 0;
protected:
const ivec2& m_screen_size;
const GLFWInputManager& m_input_manager;
const FPS& m_fps;
}; };

10
OpenGLEngine/constants.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
namespace egm
{
// 3.141592653589793238462643383279502884197169399375105820974944...
const double PI = 3.14159265358979323846;
// 6.283185307179586476925286766559005768394338798750211641949889...
const double TAU = 6.28318530717958647693;
}

View File

@ -10,7 +10,7 @@ int main(int argc, char** argv)
{ {
try try
{ {
MyApplication my_app; MyApplication my_app(1280, 720);
return my_app.run(); return my_app.run();
} }
catch (Exception& e) catch (Exception& e)

View File

@ -1,7 +1,5 @@
#pragma once #pragma once
#include <d3d11.h>
#include "vec4.h" #include "vec4.h"
namespace egm namespace egm
@ -80,7 +78,7 @@ namespace egm
b + o.b, b + o.b,
c + o.c, c + o.c,
d + o.d d + o.d
} };
} }
tmat4x4<T>& operator+=(const tmat4x4<T>& o) tmat4x4<T>& operator+=(const tmat4x4<T>& o)
@ -99,7 +97,7 @@ namespace egm
b - o.b, b - o.b,
c - o.c, c - o.c,
d - o.d d - o.d
} };
} }
tmat4x4<T>& operator-=(const tmat4x4<T>& o) tmat4x4<T>& operator-=(const tmat4x4<T>& o)
@ -148,7 +146,8 @@ namespace egm
m.a.z * d.x + m.b.z * d.y + m.c.z * d.z + m.d.z * d.w,//Column 3b m.a.z * d.x + m.b.z * d.y + m.c.z * d.z + m.d.z * d.w,//Column 3b
m.a.w * d.x + m.b.w * d.y + m.c.w * d.z + m.d.w * d.w,//Column 4b m.a.w * d.x + m.b.w * d.y + m.c.w * d.z + m.d.w * d.w,//Column 4b
}; };
//Backwards
// Backwards (multiply and transpose)
/*return { /*return {
//Row 1b //Row 1b
a.x * m.a.x + b.x * m.a.y + c.x * m.a.z + d.x * m.a.w,//Column 1a a.x * m.a.x + b.x * m.a.y + c.x * m.a.z + d.x * m.a.w,//Column 1a
@ -188,7 +187,7 @@ namespace egm
b * scalar, b * scalar,
c * scalar, c * scalar,
d * scalar d * scalar
} };
} }
tmat4x4<T>& operator*=(const T& scalar) tmat4x4<T>& operator*=(const T& scalar)
@ -207,7 +206,7 @@ namespace egm
b / scalar, b / scalar,
c / scalar, c / scalar,
d / scalar d / scalar
} };
} }
tmat4x4<T>& operator/=(const T& scalar) tmat4x4<T>& operator/=(const T& scalar)
@ -219,16 +218,6 @@ namespace egm
return *this; return *this;
} }
operator RECT()
{
return {
a,
b,
c,
d
}
}
float* data() float* data()
{ {
return &(a.x); return &(a.x);

98
OpenGLEngine/operations.h Normal file
View File

@ -0,0 +1,98 @@
#pragma once
#include "mat4x4.h"
namespace egm
{
// Multiplies a matrix into out
template <typename T>
void multiply(const tmat4x4<T>& a, const tmat4x4<T>& b, tmat4x4<T>& out)
{
out.a.x = a.a.x * b.a.x + a.a.y * b.b.x + a.a.z * b.c.x + a.a.w * b.d.x;
out.a.y = a.a.x * b.a.y + a.a.y * b.b.y + a.a.z * b.c.y + a.a.w * b.d.y;
out.a.z = a.a.x * b.a.z + a.a.y * b.b.z + a.a.z * b.c.z + a.a.w * b.d.z;
out.a.w = a.a.x * b.a.w + a.a.y * b.b.w + a.a.z * b.c.w + a.a.w * b.d.w;
out.b.x = a.b.x * b.a.x + a.b.y * b.b.x + a.b.z * b.c.x + a.b.w * b.d.x;
out.b.y = a.b.x * b.a.y + a.b.y * b.b.y + a.b.z * b.c.y + a.b.w * b.d.y;
out.b.z = a.b.x * b.a.z + a.b.y * b.b.z + a.b.z * b.c.z + a.b.w * b.d.z;
out.b.w = a.b.x * b.a.w + a.b.y * b.b.w + a.b.z * b.c.w + a.b.w * b.d.w;
out.c.x = a.c.x * b.a.x + a.c.y * b.b.x + a.c.z * b.c.x + a.c.w * b.d.x;
out.c.y = a.c.x * b.a.y + a.c.y * b.b.y + a.c.z * b.c.y + a.c.w * b.d.y;
out.c.z = a.c.x * b.a.z + a.c.y * b.b.z + a.c.z * b.c.z + a.c.w * b.d.z;
out.c.w = a.c.x * b.a.w + a.c.y * b.b.w + a.c.z * b.c.w + a.c.w * b.d.w;
out.d.x = a.d.x * b.a.x + a.d.y * b.b.x + a.d.z * b.c.x + a.d.w * b.d.x;
out.d.y = a.d.x * b.a.y + a.d.y * b.b.y + a.d.z * b.c.y + a.d.w * b.d.y;
out.d.w = a.d.x * b.a.z + a.d.y * b.b.z + a.d.z * b.c.z + a.d.w * b.d.z;
out.d.w = a.d.x * b.a.w + a.d.y * b.b.w + a.d.z * b.c.w + a.d.w * b.d.w;
}
// Multiplies and transposes a matrix into out.
template <typename T>
void multiply_and_transpose(const tmat4x4<T>& a, const tmat4x4<T>& b, tmat4x4<T>& out)
{
out.a.x = a.a.x * b.a.x + a.b.x * b.a.y + a.c.x * b.a.z + a.d.x * b.a.w;
out.a.y = a.a.y * b.a.x + a.b.y * b.a.y + a.c.y * b.a.z + a.d.y * b.a.w;
out.a.z = a.a.z * b.a.x + a.b.z * b.a.y + a.c.z * b.a.z + a.d.z * b.a.w;
out.a.w = a.a.w * b.a.x + a.b.w * b.a.y + a.c.w * b.a.z + a.d.w * b.a.w;
out.b.x = a.a.x * b.b.x + a.b.x * b.b.y + a.c.x * b.b.z + a.d.x * b.b.w;
out.b.y = a.a.y * b.b.x + a.b.y * b.b.y + a.c.y * b.b.z + a.d.y * b.b.w;
out.b.z = a.a.z * b.b.x + a.b.z * b.b.y + a.c.z * b.b.z + a.d.z * b.b.w;
out.b.w = a.a.w * b.b.x + a.b.w * b.b.y + a.c.w * b.b.z + a.d.w * b.b.w;
out.c.x = a.a.x * b.c.x + a.b.x * b.c.y + a.c.x * b.c.z + a.d.x * b.c.w;
out.c.y = a.a.y * b.c.x + a.b.y * b.c.y + a.c.y * b.c.z + a.d.y * b.c.w;
out.c.z = a.a.z * b.c.x + a.b.z * b.c.y + a.c.z * b.c.z + a.d.z * b.c.w;
out.c.w = a.a.w * b.c.x + a.b.w * b.c.y + a.c.w * b.c.z + a.d.w * b.c.w;
out.d.x = a.a.x * b.d.x + a.b.x * b.d.y + a.c.x * b.d.z + a.d.x * b.d.w;
out.d.y = a.a.y * b.d.x + a.b.y * b.d.y + a.c.y * b.d.z + a.d.y * b.d.w;
out.d.w = a.a.z * b.d.x + a.b.z * b.d.y + a.c.z * b.d.z + a.d.z * b.d.w;
out.d.w = a.a.w * b.d.x + a.b.w * b.d.y + a.c.w * b.d.z + a.d.w * b.d.w;
}
// Creates an orthoganal matrix
template <typename T>
void ortho(const T& left, const T& right, const T& bottom, const T& top, const T& near, const T& far, tmat4x4<T>& out)
{
out = tmat4x4<T>();
out.a.x = T(2) / (right - left);
out.b.y = T(2) / (top - bottom);
out.c.z = -T(2) / (far - near);
out.a.w = -(right + left) / (right - left);
out.b.w = -(top + bottom) / (top - bottom);
out.c.w = -(far + near) / (far - near);
}
// Creates an orthogonal matrix centered at the origin
template <typename T>
void ortho(const T& width, const T& height, const T& depth, tmat4x4<T>& out)
{
out = tmat4x4<T>();
out.a.x = T(2) / width;
out.a.y = T(2) / height;
out.a.z = T(2) / depth;
}
template <typename T>
void translation(const T& x, const T& y, const T& z, tmat4x4<T>& out)
{
out = tmat4x4<T>();
out.a.w = x;
out.b.w = y;
out.c.w = z;
}
template <typename T>
void apply_translation(const T& x, const T& y, const T& z, tmat4x4<T>& out)
{
out.a.w = x;
out.b.w = y;
out.c.w = z;
}
// TODO: Transpose function
}

View File

@ -1,7 +1,5 @@
#pragma once #pragma once
#include <d3d11.h>
namespace egm namespace egm
{ {

View File

@ -1,7 +1,5 @@
#pragma once #pragma once
#include <d3d11.h>
namespace egm namespace egm
{ {

View File

@ -1,7 +1,5 @@
#pragma once #pragma once
#include <d3d11.h>
#include "vec2.h" #include "vec2.h"
namespace egm namespace egm
@ -61,7 +59,7 @@ namespace egm
y + o.y, y + o.y,
z + o.z, z + o.z,
w + o.w w + o.w
} };
} }
tvec4<T>& operator+=(const tvec4<T>& o) tvec4<T>& operator+=(const tvec4<T>& o)
@ -80,7 +78,7 @@ namespace egm
y - o.y, y - o.y,
z - o.z, z - o.z,
w - o.w w - o.w
} };
} }
tvec4<T>& operator-=(const tvec4<T>& o) tvec4<T>& operator-=(const tvec4<T>& o)
@ -99,7 +97,7 @@ namespace egm
y * o.y, y * o.y,
z * o.z, z * o.z,
w * o.w w * o.w
} };
} }
tvec4<T>& operator*=(const tvec4<T>& o) tvec4<T>& operator*=(const tvec4<T>& o)
@ -118,7 +116,7 @@ namespace egm
y * scalar, y * scalar,
z * scalar, z * scalar,
w * scalar w * scalar
} };
} }
tvec4<T>& operator*=(const T& scalar) tvec4<T>& operator*=(const T& scalar)
@ -137,7 +135,7 @@ namespace egm
y / o.y, y / o.y,
z / o.z, z / o.z,
w / o.w w / o.w
} };
} }
tvec4<T>& operator/=(const tvec4<T>& o) tvec4<T>& operator/=(const tvec4<T>& o)
@ -168,16 +166,6 @@ namespace egm
return *this; return *this;
} }
operator RECT()
{
return {
x,
y,
z,
w
}
}
float* data() float* data()
{ {
return &x; return &x;