diff --git a/cbt/opengl/context.cpp b/cbt/opengl/context.cpp index a2047a7..29535be 100644 --- a/cbt/opengl/context.cpp +++ b/cbt/opengl/context.cpp @@ -34,6 +34,9 @@ context::context(window const& win) { return; } m_valid = true; + + // Set initial viewport to match window size + glViewport(0, 0, win.width(), win.height()); } context::~context() {} @@ -42,4 +45,8 @@ auto context::valid() const -> bool { return m_valid; } +auto context::set_size(int width, int height) -> void { + glViewport(0, 0, width, height); +} + } diff --git a/cbt/opengl/context.hpp b/cbt/opengl/context.hpp index dfa11c2..54cc085 100644 --- a/cbt/opengl/context.hpp +++ b/cbt/opengl/context.hpp @@ -10,6 +10,7 @@ public: ~context(); auto valid() const -> bool; + auto set_size(int width, int height) -> void; private: bool m_valid = false; diff --git a/cbt/scene.cpp b/cbt/scene.cpp index 0ffdd5d..b85fafe 100644 --- a/cbt/scene.cpp +++ b/cbt/scene.cpp @@ -8,6 +8,6 @@ auto scene::init() -> bool { auto scene::update(float) -> void {} -auto scene::render() -> void {} +auto scene::render(int, int) -> void {} } diff --git a/cbt/scene.hpp b/cbt/scene.hpp index d0629dd..8d855f3 100644 --- a/cbt/scene.hpp +++ b/cbt/scene.hpp @@ -10,7 +10,7 @@ public: virtual auto init() -> bool; virtual auto update(float delta_time) -> void; - virtual auto render() -> void; + virtual auto render(int width, int height) -> void; }; } diff --git a/cbt/window.cpp b/cbt/window.cpp index 2f7b061..9c10b47 100644 --- a/cbt/window.cpp +++ b/cbt/window.cpp @@ -52,6 +52,12 @@ window::window(std::string title, int width, int height) { return; } + m_width = width; + m_height = height; + + glfwSetWindowUserPointer(m_window, this); + glfwSetWindowSizeCallback(m_window, resize_callback_impl); + #ifdef _WIN32 auto hwnd = glfwGetWin32Window(m_window); BOOL use_dark_mode = TRUE; @@ -94,6 +100,29 @@ auto window::stop() -> void { } } +auto window::width() const -> int { + return m_width; +} + +auto window::height() const -> int { + return m_height; +} + +auto window::on_resize(resize_callback cb) -> void { + m_resize_cb = cb; +} + +auto window::resize_callback_impl(GLFWwindow* glfw_window, int width, int height) -> void { + auto* self = static_cast(glfwGetWindowUserPointer(glfw_window)); + if (self) { + self->m_width = width; + self->m_height = height; + if (self->m_resize_cb) { + self->m_resize_cb(width, height); + } + } +} + auto window::screenshot(std::string filepath) const -> bool { if (!m_window || !valid()) { return false; diff --git a/cbt/window.hpp b/cbt/window.hpp index 8654165..180f2d3 100644 --- a/cbt/window.hpp +++ b/cbt/window.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #define GLFW_INCLUDE_NONE @@ -19,13 +20,22 @@ public: auto raw() const -> GLFWwindow*; auto stop() -> void; auto screenshot(std::string filepath = "screenshot.png") const -> bool; + auto width() const -> int; + auto height() const -> int; + + using resize_callback = std::function; + auto on_resize(resize_callback cb) -> void; private: GLFWwindow* m_window = nullptr; + int m_width = 0; + int m_height = 0; + resize_callback m_resize_cb; bool m_glfw_initialized = false; static auto init_glfw() -> bool; static auto terminate_glfw() -> void; + static auto resize_callback_impl(GLFWwindow* glfw_window, int width, int height) -> void; }; } diff --git a/cuber.cpp b/cuber.cpp index 9700c57..64a7c00 100644 --- a/cuber.cpp +++ b/cuber.cpp @@ -57,6 +57,11 @@ auto main(int argc, char const* argv[]) -> int { return 1; } + // Wire up resize callback + win.on_resize([&ctx](int width, int height) { + ctx.set_size(width, height); + }); + auto cube_scn = cbt::scenes::cube(); auto sphere_scn = cbt::scenes::sphere(); @@ -118,7 +123,7 @@ auto main(int argc, char const* argv[]) -> int { prev = now; active_scene->update(dt); - active_scene->render(); + active_scene->render(win.width(), win.height()); win.swap_buffers(); win.poll_events(); diff --git a/scenes/cube.cpp b/scenes/cube.cpp index cf20214..f466509 100644 --- a/scenes/cube.cpp +++ b/scenes/cube.cpp @@ -23,14 +23,14 @@ auto cube::init() -> bool { auto cube::update(float) -> void {} -auto cube::render() -> void { +auto cube::render(int width, int height) -> void { auto now = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration(now - m_start).count(); glClearColor(0.15f, 0.15f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - auto aspect = 1280.0f / 720.0f; + auto aspect = float(width) / float(height); auto proj = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 100.0f); auto view = glm::translate(glm::mat4{1.0f}, glm::vec3{0.0f, 0.0f, -3.0f}); auto model = glm::rotate(glm::mat4{1.0f}, elapsed, glm::vec3{1.0f, 0.5f, 0.3f}); diff --git a/scenes/cube.hpp b/scenes/cube.hpp index 923de66..016faf4 100644 --- a/scenes/cube.hpp +++ b/scenes/cube.hpp @@ -16,7 +16,7 @@ public: cube(); auto init() -> bool override; auto update(float delta_time) -> void override; - auto render() -> void override; + auto render(int width, int height) -> void override; private: opengl::shader m_prog; diff --git a/scenes/sphere.cpp b/scenes/sphere.cpp index 37d4276..f81411c 100644 --- a/scenes/sphere.cpp +++ b/scenes/sphere.cpp @@ -25,14 +25,14 @@ auto sphere::init() -> bool { auto sphere::update(float) -> void {} -auto sphere::render() -> void { +auto sphere::render(int width, int height) -> void { auto now = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration(now - m_start).count(); glClearColor(0.15f, 0.15f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - auto aspect = 1280.0f / 720.0f; + auto aspect = float(width) / float(height); auto proj = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 100.0f); auto view = glm::translate(glm::mat4{1.0f}, glm::vec3{0.0f, 0.0f, -4.0f}); auto model = glm::rotate(glm::mat4{1.0f}, elapsed, glm::vec3{1.0f, 0.3f, 0.2f}); diff --git a/scenes/sphere.hpp b/scenes/sphere.hpp index 191c71a..448df3c 100644 --- a/scenes/sphere.hpp +++ b/scenes/sphere.hpp @@ -16,7 +16,7 @@ public: sphere(); auto init() -> bool override; auto update(float delta_time) -> void override; - auto render() -> void override; + auto render(int width, int height) -> void override; private: opengl::shader m_prog;