Fix window resize in wayland

This commit is contained in:
Bailey Harrison 2024-04-13 12:11:36 +01:00
parent f9422346bd
commit 5b60668f71
13 changed files with 424 additions and 523 deletions

2
dependencies/SDL vendored

@ -1 +1 @@
Subproject commit 2f4a7bbcedaaf49c8bf87e34081120a6a49a0d26 Subproject commit 859844eae358447be8d66e6da59b6fb3df0ed778

@ -1 +1 @@
Subproject commit c351692490513cdb0e5a2c925aaf7ea4a9b672f4 Subproject commit a6bfc237255a6bac1513f7c1ebde6d8aed6b5191

View File

@ -23,7 +23,7 @@ class GFXDevice {
void ShutdownImguiBackend(); void ShutdownImguiBackend();
void CmdRenderImguiDrawData(gfx::DrawBuffer* draw_buffer, ImDrawData* draw_data); void CmdRenderImguiDrawData(gfx::DrawBuffer* draw_buffer, ImDrawData* draw_data);
gfx::DrawBuffer* BeginRender(); gfx::DrawBuffer* BeginRender(bool window_resized);
/* - draw_buffer MUST be a valid pointer returned by BeginRender(). /* - draw_buffer MUST be a valid pointer returned by BeginRender().
- draw_buffer is invalid after this function has been called. */ - draw_buffer is invalid after this function has been called. */

View File

@ -35,10 +35,8 @@ class Renderer : private ApplicationComponent {
~Renderer(); ~Renderer();
void PreRender(bool window_is_resized, glm::mat4 camera_transform);
// staticList can be nullptr to render nothing // staticList can be nullptr to render nothing
void Render(const RenderList* static_list, const RenderList* dynamic_list, const std::vector<Line>& debug_lines); void Render(bool window_is_resized, glm::mat4 camera_transform, const RenderList* static_list, const RenderList* dynamic_list, const std::vector<Line>& debug_lines);
// getters // getters

View File

@ -413,8 +413,7 @@ void Application::GameLoop()
static_list = mesh_render_system->GetStaticRenderList(); static_list = mesh_render_system->GetStaticRenderList();
dynamic_list = mesh_render_system->GetDynamicRenderList(); dynamic_list = mesh_render_system->GetDynamicRenderList();
} }
renderer_->PreRender(window()->GetWindowResized(), camera_transform); renderer_->Render(window()->GetWindowResized(), camera_transform, static_list, dynamic_list, debug_lines);
renderer_->Render(static_list, dynamic_list, debug_lines);
debug_lines.clear(); // gets remade every frame :0 debug_lines.clear(); // gets remade every frame :0
/* poll events */ /* poll events */

View File

@ -621,7 +621,7 @@ void GFXDevice::CmdRenderImguiDrawData(gfx::DrawBuffer* draw_buffer, ImDrawData*
ImGui_ImplVulkan_RenderDrawData(draw_data, draw_buffer->frameData.drawBuf); ImGui_ImplVulkan_RenderDrawData(draw_data, draw_buffer->frameData.drawBuf);
} }
gfx::DrawBuffer* GFXDevice::BeginRender() gfx::DrawBuffer* GFXDevice::BeginRender(bool window_resized)
{ {
VkResult res; VkResult res;
@ -703,6 +703,12 @@ gfx::DrawBuffer* GFXDevice::BeginRender()
uint32_t swapchainImageIndex; uint32_t swapchainImageIndex;
if (window_resized && pimpl->FRAMECOUNT != 0) { // resize flag is true on first frame
pimpl->swapchainIsOutOfDate = true;
LOG_TRACE("Window resized, framecount == {}", pimpl->FRAMECOUNT);
}
// THIS FUNCTION BLOCKS UNTIL AN IMAGE IS AVAILABLE (it waits for vsync)
do { do {
if (pimpl->swapchainIsOutOfDate) { if (pimpl->swapchainIsOutOfDate) {
// re-create swapchain // re-create swapchain
@ -714,7 +720,8 @@ gfx::DrawBuffer* GFXDevice::BeginRender()
res = vkAcquireNextImageKHR(pimpl->device.device, pimpl->swapchain.swapchain, 1000000000LL, frameData.presentSemaphore, VK_NULL_HANDLE, res = vkAcquireNextImageKHR(pimpl->device.device, pimpl->swapchain.swapchain, 1000000000LL, frameData.presentSemaphore, VK_NULL_HANDLE,
&swapchainImageIndex); &swapchainImageIndex);
if (res != VK_SUBOPTIMAL_KHR && res != VK_ERROR_OUT_OF_DATE_KHR) VKCHECK(res); if (res != VK_SUBOPTIMAL_KHR && res != VK_ERROR_OUT_OF_DATE_KHR) VKCHECK(res);
if (res == VK_SUCCESS) pimpl->swapchainIsOutOfDate = false; if (res == VK_ERROR_OUT_OF_DATE_KHR) pimpl->swapchainIsOutOfDate = true;
if (res == VK_SUCCESS || res == VK_SUBOPTIMAL_KHR) pimpl->swapchainIsOutOfDate = false;
} while (pimpl->swapchainIsOutOfDate); } while (pimpl->swapchainIsOutOfDate);
/* record command buffer */ /* record command buffer */
@ -970,8 +977,8 @@ void GFXDevice::FinishRender(gfx::DrawBuffer* drawBuffer)
.pImageIndices = &swapchainImageIndex, .pImageIndices = &swapchainImageIndex,
.pResults = nullptr}; .pResults = nullptr};
res = vkQueuePresentKHR(pimpl->device.queues.presentQueue, &presentInfo); res = vkQueuePresentKHR(pimpl->device.queues.presentQueue, &presentInfo);
if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR) { if (res == VK_ERROR_OUT_OF_DATE_KHR) {
// flag to re-create the swapchain before next render // flag to re-create the swapchain next frame
pimpl->swapchainIsOutOfDate = true; pimpl->swapchainIsOutOfDate = true;
} }
else if (res != VK_SUCCESS) else if (res != VK_SUCCESS)
@ -1351,9 +1358,9 @@ gfx::Pipeline* GFXDevice::CreatePipeline(const gfx::PipelineInfo& info)
if (info.depth_attachment_only) { if (info.depth_attachment_only) {
// use depth bias if only rendering to a depth attachment // use depth bias if only rendering to a depth attachment
rasterizer.depthBiasEnable = VK_TRUE; rasterizer.depthBiasEnable = VK_TRUE;
rasterizer.depthBiasConstantFactor = 2.0f;//1.25f; rasterizer.depthBiasConstantFactor = 2.0f; // 1.25f;
rasterizer.depthBiasClamp = 0.0f; rasterizer.depthBiasClamp = 0.0f;
rasterizer.depthBiasSlopeFactor = 3.5f;//1.75f; rasterizer.depthBiasSlopeFactor = 3.5f; // 1.75f;
} }
else { else {
rasterizer.depthBiasEnable = VK_FALSE; rasterizer.depthBiasEnable = VK_FALSE;

View File

@ -249,8 +249,9 @@ Renderer::~Renderer()
device_->DestroyDescriptorSetLayout(global_uniform.layout); device_->DestroyDescriptorSetLayout(global_uniform.layout);
} }
void Renderer::PreRender(bool window_is_resized, glm::mat4 camera_transform) void Renderer::Render(bool window_is_resized, glm::mat4 camera_transform, const RenderList* static_list, const RenderList* dynamic_list, const std::vector<Line>& debug_lines)
{ {
if (window_is_resized) { if (window_is_resized) {
uint32_t w, h; uint32_t w, h;
device_->GetViewportSize(&w, &h); device_->GetViewportSize(&w, &h);
@ -265,10 +266,6 @@ void Renderer::PreRender(bool window_is_resized, glm::mat4 camera_transform)
const glm::mat4 view_matrix = glm::inverse(camera_transform); const glm::mat4 view_matrix = glm::inverse(camera_transform);
frame_uniform.uniform_buffer_data.data = view_matrix; frame_uniform.uniform_buffer_data.data = view_matrix;
device_->WriteUniformBuffer(frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data); device_->WriteUniformBuffer(frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data);
}
void Renderer::Render(const RenderList* static_list, const RenderList* dynamic_list, const std::vector<Line>& debug_lines)
{
if (rendering_started == false) { if (rendering_started == false) {
// render to shadow map // render to shadow map
@ -292,7 +289,7 @@ void Renderer::Render(const RenderList* static_list, const RenderList* dynamic_l
last_bound_pipeline_ = nullptr; last_bound_pipeline_ = nullptr;
gfx::DrawBuffer* draw_buffer = device_->BeginRender(); gfx::DrawBuffer* draw_buffer = device_->BeginRender(window_is_resized);
if (static_list) { if (static_list) {
if (!static_list->empty()) { if (!static_list->empty()) {

View File

@ -271,7 +271,8 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic)
} }
// occlusion roughness metallic // occlusion roughness metallic
materials.back()->SetOcclusionRoughnessMetallicTexture(scene.app()->GetResource<Texture>("builtin.white")); // default ao = 1.0, rough = 1.0, metal = 1.0 materials.back()->SetOcclusionRoughnessMetallicTexture(
scene.app()->GetResource<Texture>("builtin.white")); // default ao = 1.0, rough = 1.0, metal = 1.0
if (material.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) { if (material.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) {
if (material.pbrMetallicRoughness.metallicRoughnessTexture.texCoord == 0) { if (material.pbrMetallicRoughness.metallicRoughnessTexture.texCoord == 0) {
LOG_DEBUG("Setting occlusion roughness metallic texture!"); LOG_DEBUG("Setting occlusion roughness metallic texture!");
@ -283,7 +284,8 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic)
} }
else { else {
LOG_DEBUG("Creating occlusion roughness metallic texture..."); LOG_DEBUG("Creating occlusion roughness metallic texture...");
const std::vector<double> mr_values{1.0f /* no AO */, material.pbrMetallicRoughness.roughnessFactor, material.pbrMetallicRoughness.metallicFactor, 1.0f}; const std::vector<double> mr_values{1.0f /* no AO */, material.pbrMetallicRoughness.roughnessFactor, material.pbrMetallicRoughness.metallicFactor,
1.0f};
Color mr(mr_values); Color mr(mr_values);
if (metal_rough_textures.contains(mr) == false) { if (metal_rough_textures.contains(mr) == false) {
const uint8_t pixel[4] = {mr.r, mr.g, mr.b, mr.a}; const uint8_t pixel[4] = {mr.r, mr.g, mr.b, mr.a};
@ -302,7 +304,8 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic)
if (material.occlusionTexture.index != -1) { if (material.occlusionTexture.index != -1) {
if (material.occlusionTexture.texCoord == 0) { if (material.occlusionTexture.texCoord == 0) {
if (material.occlusionTexture.index != material.pbrMetallicRoughness.metallicRoughnessTexture.index) { if (material.occlusionTexture.index != material.pbrMetallicRoughness.metallicRoughnessTexture.index) {
throw std::runtime_error(std::string("Material ") + material.name + std::string(" has an ambient occlusion texture different to the metal-rough texture.")); throw std::runtime_error(std::string("Material ") + material.name +
std::string(" has an ambient occlusion texture different to the metal-rough texture."));
} }
} }
else { else {
@ -518,8 +521,8 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic)
assert(num_unq_vertices >= 0); assert(num_unq_vertices >= 0);
// get new vertices into the vector // get new vertices into the vector
vertices.resize(num_unq_vertices); vertices.resize(static_cast<size_t>(num_unq_vertices));
for (size_t i = 0; i < num_unq_vertices; ++i) { for (size_t i = 0; i < static_cast<size_t>(num_unq_vertices); ++i) {
vertices[i] = vertex_data_out[i]; vertices[i] = vertex_data_out[i];
} }
@ -578,6 +581,7 @@ engine::Entity LoadGLTF(Scene& scene, const std::string& path, bool isStatic)
// glTF uses the Y-up convention so the parent object must be rotated to Z-up // glTF uses the Y-up convention so the parent object must be rotated to Z-up
const Entity parent = scene.CreateEntity(name, 0, glm::vec3{}, glm::quat{glm::one_over_root_two<float>(), glm::one_over_root_two<float>(), 0.0f, 0.0f}); const Entity parent = scene.CreateEntity(name, 0, glm::vec3{}, glm::quat{glm::one_over_root_two<float>(), glm::one_over_root_two<float>(), 0.0f, 0.0f});
scene.GetTransform(parent)->is_static = isStatic;
std::vector<Entity> entities(model.nodes.size(), 0); std::vector<Entity> entities(model.nodes.size(), 0);
std::function<void(Entity, const tg::Node&)> generateEntities = [&](Entity parent_entity, const tg::Node& node) -> void { std::function<void(Entity, const tg::Node&)> generateEntities = [&](Entity parent_entity, const tg::Node& node) -> void {

View File

@ -1,5 +1,7 @@
#include <assert.h> #include <assert.h>
#include <cstdio> // snprintf for vma
#include <volk.h> #include <volk.h>
#define VMA_STATIC_VULKAN_FUNCTIONS 0 #define VMA_STATIC_VULKAN_FUNCTIONS 0

View File

@ -19,8 +19,6 @@ namespace engine {
sc->device = info.device; sc->device = info.device;
sc->allocator = info.allocator; sc->allocator = info.allocator;
LOG_DEBUG("Recreating swapchain!\n");
// get surface caps and features // get surface caps and features
VkResult res; VkResult res;
res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(info.physicalDevice, info.surface, &sc->surfaceCapabilities); res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(info.physicalDevice, info.surface, &sc->surfaceCapabilities);
@ -249,6 +247,8 @@ namespace engine {
} }
LOG_INFO("Recreating swapchain! w: {} h: {}\n", sc->extent.width, sc->extent.height);
} }
void destroySwapchain(const Swapchain& sc) void destroySwapchain(const Swapchain& sc)

View File

@ -5,13 +5,14 @@
#include <imgui/imgui_impl_sdl2.h> #include <imgui/imgui_impl_sdl2.h>
#include "log.h"
static const uint64_t BILLION = 1000000000; static const uint64_t BILLION = 1000000000;
namespace engine { namespace engine {
Window::Window(const std::string& title, bool resizable, bool fullscreen) Window::Window(const std::string& title, bool resizable, bool fullscreen) : title_(title), resizable_(resizable), fullscreen_(fullscreen)
: title_(title), resizable_(resizable), fullscreen_(fullscreen) {
{
// init SDL // init SDL
if (SDL_Init(SDL_INIT_VIDEO) != 0) { if (SDL_Init(SDL_INIT_VIDEO) != 0) {
@ -38,11 +39,7 @@ namespace engine {
} }
// create the window // create the window
handle_ = SDL_CreateWindow( handle_ = SDL_CreateWindow(title_.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, static_cast<int>(win_size_.x), static_cast<int>(win_size_.y),
title_.c_str(),
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
static_cast<int>(win_size_.x),
static_cast<int>(win_size_.y),
windowFlags); windowFlags);
if (handle_ == NULL) { if (handle_ == NULL) {
SDL_Quit(); SDL_Quit();
@ -58,28 +55,27 @@ namespace engine {
SDL_GetWindowSize(handle_, &winWidth, &winHeight); SDL_GetWindowSize(handle_, &winWidth, &winHeight);
OnResize(winWidth, winHeight); OnResize(winWidth, winHeight);
}
} Window::~Window()
{
Window::~Window()
{
SDL_DestroyWindow(handle_); SDL_DestroyWindow(handle_);
SDL_Quit(); SDL_Quit();
} }
// private methods // private methods
void Window::OnResize(Sint32 width, Sint32 height) void Window::OnResize(Sint32 width, Sint32 height)
{ {
// get window size // get window size
win_size_.x = static_cast<int>(width); win_size_.x = static_cast<int>(width);
win_size_.y = static_cast<int>(height); win_size_.y = static_cast<int>(height);
just_resized_ = true; just_resized_ = true;
} }
void Window::ResetInputDeltas() void Window::ResetInputDeltas()
{ {
just_resized_ = false; just_resized_ = false;
keyboard_.deltas.fill(ButtonDelta::kSame); keyboard_.deltas.fill(ButtonDelta::kSame);
@ -89,15 +85,15 @@ namespace engine {
mouse_.dy = 0; mouse_.dy = 0;
mouse_.xscroll = 0.0f; mouse_.xscroll = 0.0f;
mouse_.yscroll = 0.0f; mouse_.yscroll = 0.0f;
} }
// TODO event methods (like callbacks) // TODO event methods (like callbacks)
void Window::OnWindowEvent(SDL_WindowEvent& e)
{
void Window::OnWindowEvent(SDL_WindowEvent& e)
{
switch (e.event) { switch (e.event) {
case SDL_WINDOWEVENT_SIZE_CHANGED: case SDL_WINDOWEVENT_SIZE_CHANGED:
LOG_TRACE("SDL size changed event!");
OnResize(e.data1, e.data2); OnResize(e.data1, e.data2);
break; break;
case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_FOCUS_GAINED:
@ -107,10 +103,10 @@ namespace engine {
keyboard_focus_ = false; keyboard_focus_ = false;
break; break;
} }
} }
void Window::OnKeyEvent(SDL_KeyboardEvent& e) void Window::OnKeyEvent(SDL_KeyboardEvent& e)
{ {
const ImGuiIO& io = ImGui::GetIO(); const ImGuiIO& io = ImGui::GetIO();
if (io.WantCaptureKeyboard) { if (io.WantCaptureKeyboard) {
keyboard_.deltas.fill(ButtonDelta::kSame); keyboard_.deltas.fill(ButtonDelta::kSame);
@ -123,10 +119,10 @@ namespace engine {
keyboard_.deltas[e.keysym.scancode] = keyIsDown ? ButtonDelta::kPressed : ButtonDelta::kReleased; keyboard_.deltas[e.keysym.scancode] = keyIsDown ? ButtonDelta::kPressed : ButtonDelta::kReleased;
} }
} }
} }
void Window::OnMouseButtonEvent(SDL_MouseButtonEvent& e) void Window::OnMouseButtonEvent(SDL_MouseButtonEvent& e)
{ {
const ImGuiIO& io = ImGui::GetIO(); const ImGuiIO& io = ImGui::GetIO();
if (io.WantCaptureMouse) { if (io.WantCaptureMouse) {
mouse_.deltas.fill(ButtonDelta::kSame); mouse_.deltas.fill(ButtonDelta::kSame);
@ -161,10 +157,10 @@ namespace engine {
} }
} }
} }
} }
void Window::OnMouseMotionEvent(SDL_MouseMotionEvent& e) void Window::OnMouseMotionEvent(SDL_MouseMotionEvent& e)
{ {
const ImGuiIO& io = ImGui::GetIO(); const ImGuiIO& io = ImGui::GetIO();
if (io.WantCaptureMouse) { if (io.WantCaptureMouse) {
mouse_.dx = 0; mouse_.dx = 0;
@ -176,10 +172,10 @@ namespace engine {
mouse_.dx = e.xrel; mouse_.dx = e.xrel;
mouse_.dy = e.yrel; mouse_.dy = e.yrel;
} }
} }
void Window::OnMouseWheelEvent(SDL_MouseWheelEvent& e) void Window::OnMouseWheelEvent(SDL_MouseWheelEvent& e)
{ {
const ImGuiIO& io = ImGui::GetIO(); const ImGuiIO& io = ImGui::GetIO();
if (!io.WantCaptureMouse) { if (!io.WantCaptureMouse) {
if (e.direction == SDL_MOUSEWHEEL_NORMAL) { if (e.direction == SDL_MOUSEWHEEL_NORMAL) {
@ -191,22 +187,16 @@ namespace engine {
mouse_.yscroll = -e.preciseY; mouse_.yscroll = -e.preciseY;
} }
} }
} }
// public methods // public methods
SDL_Window* Window::GetHandle() const SDL_Window* Window::GetHandle() const { return handle_; }
{
return handle_;
}
std::string Window::GetTitle() const std::string Window::GetTitle() const { return title_; }
{
return title_;
}
void Window::GetInputAndEvents() void Window::GetInputAndEvents()
{ {
frames_++; frames_++;
uint64_t currentFrameStamp = GetNanos(); uint64_t currentFrameStamp = GetNanos();
@ -246,60 +236,34 @@ namespace engine {
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
OnMouseWheelEvent(e.wheel); OnMouseWheelEvent(e.wheel);
break; break;
} }
} }
}
} void Window::SetTitle(std::string title) { SDL_SetWindowTitle(handle_, title.c_str()); }
void Window::SetTitle(std::string title) bool Window::GetWindowResized() const { return just_resized_; }
{
SDL_SetWindowTitle(handle_, title.c_str());
}
bool Window::GetWindowResized() const void Window::SetResizedFlag() { just_resized_ = true; }
{
return just_resized_;
}
void Window::SetResizedFlag() void Window::Show() { SDL_ShowWindow(handle_); }
{
just_resized_ = true;
}
void Window::Show() void Window::Hide() { SDL_HideWindow(handle_); }
{
SDL_ShowWindow(handle_);
}
void Window::Hide() void Window::Focus()
{ {
SDL_HideWindow(handle_);
}
void Window::Focus()
{
SDL_RaiseWindow(handle_); SDL_RaiseWindow(handle_);
keyboard_focus_ = true; keyboard_focus_ = true;
} }
bool Window::HasFocus() const bool Window::HasFocus() const { return keyboard_focus_; }
{
return keyboard_focus_;
}
void Window::SetCloseFlag() void Window::SetCloseFlag() { should_close_ = true; }
{
should_close_ = true;
}
bool Window::IsRunning() const bool Window::IsRunning() const { return !should_close_; }
{
return !should_close_;
}
void Window::SetFullscreen(bool fullscreen, bool exclusive) void Window::SetFullscreen(bool fullscreen, bool exclusive)
{ {
if (resizable_) { if (resizable_) {
@ -307,31 +271,20 @@ namespace engine {
SDL_GetDesktopDisplayMode(SDL_GetWindowDisplayIndex(handle_), &mode); SDL_GetDesktopDisplayMode(SDL_GetWindowDisplayIndex(handle_), &mode);
SDL_SetWindowDisplayMode(handle_, &mode); SDL_SetWindowDisplayMode(handle_, &mode);
// this will only resize the window at the end of the frame
if (SDL_SetWindowFullscreen(handle_, fullscreen ? (exclusive ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP) : 0) != 0) { if (SDL_SetWindowFullscreen(handle_, fullscreen ? (exclusive ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP) : 0) != 0) {
throw std::runtime_error("Unable to set window to fullscreen/windowed"); throw std::runtime_error("Unable to set window to fullscreen/windowed");
} }
fullscreen_ = fullscreen; fullscreen_ = fullscreen;
if (fullscreen) { }
}
int width, height; void Window::ToggleFullscreen() { SetFullscreen(!fullscreen_, true); }
SDL_GetWindowSize(handle_, &width, &height);
OnResize(width, height);
}
}
}
void Window::ToggleFullscreen() bool Window::IsFullscreen() const { return fullscreen_; }
{
SetFullscreen(!fullscreen_, true);
}
bool Window::IsFullscreen() const bool Window::SetRelativeMouseMode(bool enabled)
{ {
return fullscreen_;
}
bool Window::SetRelativeMouseMode(bool enabled)
{
mouse_.captured = enabled; mouse_.captured = enabled;
int code = SDL_SetRelativeMouseMode(static_cast<SDL_bool>(enabled)); int code = SDL_SetRelativeMouseMode(static_cast<SDL_bool>(enabled));
if (code != 0) { if (code != 0) {
@ -340,92 +293,47 @@ namespace engine {
else { else {
return true; return true;
} }
} }
bool Window::MouseCaptured() bool Window::MouseCaptured() { return mouse_.captured; }
{
return mouse_.captured;
}
// getting input // getting input
bool Window::GetKey(inputs::Key key) const bool Window::GetKey(inputs::Key key) const { return keyboard_.keys[static_cast<int>(key)]; }
{
return keyboard_.keys[static_cast<int>(key)];
}
bool Window::GetKeyPress(inputs::Key key) const bool Window::GetKeyPress(inputs::Key key) const { return keyboard_.deltas[static_cast<int>(key)] == ButtonDelta::kPressed; }
{
return keyboard_.deltas[static_cast<int>(key)] == ButtonDelta::kPressed;
}
bool Window::GetKeyRelease(inputs::Key key) const bool Window::GetKeyRelease(inputs::Key key) const { return keyboard_.deltas[static_cast<int>(key)] == ButtonDelta::kReleased; }
{
return keyboard_.deltas[static_cast<int>(key)] == ButtonDelta::kReleased;
}
// TODO mouse input // TODO mouse input
bool Window::GetButton(inputs::MouseButton button) const bool Window::GetButton(inputs::MouseButton button) const { return mouse_.buttons[static_cast<int>(button)]; }
{
return mouse_.buttons[static_cast<int>(button)];
}
bool Window::GetButtonPress(inputs::MouseButton button) const bool Window::GetButtonPress(inputs::MouseButton button) const { return mouse_.deltas[static_cast<int>(button)] == ButtonDelta::kPressed; }
{
return mouse_.deltas[static_cast<int>(button)] == ButtonDelta::kPressed;
}
bool Window::GetButtonRelease(inputs::MouseButton button) const bool Window::GetButtonRelease(inputs::MouseButton button) const { return mouse_.deltas[static_cast<int>(button)] == ButtonDelta::kReleased; }
{
return mouse_.deltas[static_cast<int>(button)] == ButtonDelta::kReleased;
}
int Window::GetMouseX() const int Window::GetMouseX() const { return static_cast<int>(mouse_.x); }
{
return static_cast<int>(mouse_.x);
}
int Window::GetMouseY() const int Window::GetMouseY() const { return static_cast<int>(mouse_.y); }
{
return static_cast<int>(mouse_.y);
}
float Window::GetMouseNormX() const float Window::GetMouseNormX() const { return ((float)mouse_.x * 2.0f / (float)win_size_.x) - 1.0f; }
{
return ((float)mouse_.x * 2.0f / (float)win_size_.x) - 1.0f;
}
float Window::GetMouseNormY() const float Window::GetMouseNormY() const { return ((float)mouse_.y * -2.0f / (float)win_size_.y) + 1.0f; }
{
return ((float)mouse_.y * -2.0f / (float)win_size_.y) + 1.0f;
}
int Window::GetMouseDX() const int Window::GetMouseDX() const { return static_cast<int>(mouse_.dx); }
{
return static_cast<int>(mouse_.dx);
}
int Window::GetMouseDY() const int Window::GetMouseDY() const { return static_cast<int>(mouse_.dy); }
{
return static_cast<int>(mouse_.dy);
}
float Window::GetMouseScrollX() const float Window::GetMouseScrollX() const { return mouse_.xscroll; }
{
return mouse_.xscroll;
}
float Window::GetMouseScrollY() const float Window::GetMouseScrollY() const { return mouse_.yscroll; }
{
return mouse_.yscroll;
}
// TODO game pad // TODO game pad
// get timer value // get timer value
uint64_t Window::GetNanos() const uint64_t Window::GetNanos() const
{ {
uint64_t count; uint64_t count;
count = SDL_GetPerformanceCounter(); count = SDL_GetPerformanceCounter();
@ -435,49 +343,37 @@ namespace engine {
else { else {
return count * (BILLION / counter_freq_); return count * (BILLION / counter_freq_);
} }
} }
uint64_t Window::GetLastFrameStamp() const uint64_t Window::GetLastFrameStamp() const { return last_frame_stamp_; }
{
return last_frame_stamp_;
}
uint64_t Window::GetFrameCount() const uint64_t Window::GetFrameCount() const { return frames_; }
{
return frames_;
}
uint64_t Window::GetStartTime() const uint64_t Window::GetStartTime() const { return start_time_; }
{
return start_time_;
}
float Window::dt() const float Window::dt() const { return (float)last_frame_time_ / (float)BILLION; }
{
return (float)last_frame_time_ / (float)BILLION;
}
uint64_t Window::GetFPS() const uint64_t Window::GetFPS() const
{ {
if (last_frame_time_ == 0) return 0; if (last_frame_time_ == 0) return 0;
return BILLION / last_frame_time_; return BILLION / last_frame_time_;
} }
uint64_t Window::GetAvgFPS() const uint64_t Window::GetAvgFPS() const
{ {
uint64_t delta_t = GetNanos() - avg_fps_start_; uint64_t delta_t = GetNanos() - avg_fps_start_;
if (delta_t == 0) return 0; if (delta_t == 0) return 0;
return BILLION * (frames_ - avg_fps_start_count_) / delta_t; return BILLION * (frames_ - avg_fps_start_count_) / delta_t;
} }
void Window::ResetAvgFPS() void Window::ResetAvgFPS()
{ {
avg_fps_start_ = GetNanos(); avg_fps_start_ = GetNanos();
avg_fps_start_count_ = GetFrameCount(); avg_fps_start_count_ = GetFrameCount();
} }
bool Window::InfoBox(const std::string& title, const std::string& msg) bool Window::InfoBox(const std::string& title, const std::string& msg)
{ {
if (IsFullscreen() == false) { if (IsFullscreen() == false) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, title.c_str(), msg.c_str(), handle_); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, title.c_str(), msg.c_str(), handle_);
return true; return true;
@ -485,14 +381,11 @@ namespace engine {
else { else {
return false; return false;
} }
}
/* STATIC METHODS */
// Display an error message box
void Window::ErrorBox(const std::string& message)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Game Error", message.c_str(), NULL);
}
} }
/* STATIC METHODS */
// Display an error message box
void Window::ErrorBox(const std::string& message) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Game Error", message.c_str(), NULL); }
} // namespace engine

View File

@ -64,7 +64,7 @@ void CameraControllerSystem::OnUpdate(float ts)
// jumping // jumping
if (scene_->app()->input_manager()->GetButtonPress("jump") && (c->grounded || c->noclip)) { if (scene_->app()->input_manager()->GetButtonPress("jump") && (c->grounded || c->noclip)) {
c->vel.z += CameraControllerComponent::kJumpHeight; // m/s c->vel.z += CameraControllerComponent::kJumpVelocity; // m/s
} }
// update position with velocity: // update position with velocity:

View File

@ -16,7 +16,7 @@ struct CameraControllerComponent {
static constexpr float kSpeedForwardBack = 4.0f; static constexpr float kSpeedForwardBack = 4.0f;
static constexpr float kSpeedStrafe = 4.0f; static constexpr float kSpeedStrafe = 4.0f;
static constexpr float kSprintMultiplier = 2.0f; static constexpr float kSprintMultiplier = 2.0f;
static constexpr float kJumpHeight = /*4.4f*/ 8.8f; static constexpr float kJumpVelocity = 4.4f;
// collision // collision
static constexpr float kPlayerHeight = 2.0f; // 71.0f * 25.4f / 1000.0f; static constexpr float kPlayerHeight = 2.0f; // 71.0f * 25.4f / 1000.0f;
@ -25,6 +25,7 @@ struct CameraControllerComponent {
static constexpr size_t kNumHorizontalRays = 20; static constexpr size_t kNumHorizontalRays = 20;
static constexpr float kGravAccel = -9.81f; static constexpr float kGravAccel = -9.81f;
// static constexpr float kGravAccel = -1.625f; // moon gravity
static constexpr float kMaxDistanceFromOrigin = 200.0f; static constexpr float kMaxDistanceFromOrigin = 200.0f;
bool noclip = false; bool noclip = false;