From dc946e77f260f94ebec87cd13b08cb222e2fb49e Mon Sep 17 00:00:00 2001 From: Benjamin Kyd Date: Mon, 16 Oct 2023 14:30:39 +0100 Subject: [PATCH] fixed camera viewport bug and implemented basic flow of rays --- libhart/scene/camera.hpp | 10 +- src/inferno.cpp | 68 +++------ src/inferno.hpp | 4 +- src/preview_renderer/renderer.cpp | 69 ++++----- src/preview_renderer/renderer.hpp | 6 +- src/renderer/renderer.cpp | 233 +++++++++++++++--------------- src/renderer/renderer.hpp | 16 +- src/scene/camera.cpp | 58 +++++++- 8 files changed, 249 insertions(+), 215 deletions(-) diff --git a/libhart/scene/camera.hpp b/libhart/scene/camera.hpp index 83e3267..f294803 100644 --- a/libhart/scene/camera.hpp +++ b/libhart/scene/camera.hpp @@ -39,6 +39,8 @@ typedef struct Camera { Camera* camera_create(); void camera_cleanup(Camera* camera); +void camera_draw_ui(Camera* camera); + void camera_update(Camera* camera); bool camera_did_update(Camera* camera); void camera_new_frame(Camera* camera); @@ -47,11 +49,11 @@ glm::mat4 camera_get_view(Camera* camera); glm::mat4 camera_get_projection(Camera* camera); glm::mat4 camera_get_look(Camera* camera); -void raster_set_viewport(Camera* camera, glm::ivec2 viewport); -glm::ivec2 raster_get_viewport(Camera* camera); +void camera_raster_set_viewport(Camera* camera, glm::ivec2 viewport); +glm::ivec2 camera_raster_get_viewport(Camera* camera); -void ray_set_viewport(Camera* camera, glm::ivec2 viewport); -glm::ivec2 ray_get_viewport(Camera* camera); +void camera_ray_set_viewport(Camera* camera, glm::ivec2 viewport); +glm::ivec2 camera_ray_get_viewport(Camera* camera); void camera_move(Camera* camera, uint8_t movement_delta); void camera_mouse_move(Camera* camera, glm::vec2 mouse_delta); diff --git a/src/inferno.cpp b/src/inferno.cpp index e16e0e3..0e800e0 100644 --- a/src/inferno.cpp +++ b/src/inferno.cpp @@ -42,8 +42,7 @@ InfernoApp* inferno_create() basicMaterial->setGlShader(basicShader); scene::Mesh* mesh = new scene::Mesh; - // mesh->loadOBJ("res/cornell-box.obj"); - mesh->loadOBJ("res/sponza.obj"); + mesh->loadOBJ("res/cornell-box.obj"); mesh->ready(); mesh->setMaterial(basicMaterial); @@ -53,6 +52,7 @@ InfernoApp* inferno_create() scene::scene_add_object(app->Scene, object); app->PreviewRenderer = graphics::preview_create(); + app->RayRenderer = graphics::rayr_create(app->Scene); return app; } @@ -185,8 +185,9 @@ int inferno_run(InfernoApp* app) inferno_stop_move_input(app); } - graphics::raster_set_viewport(scene::scene_get_camera(app->Scene), + graphics::camera_raster_set_viewport(scene::scene_get_camera(app->Scene), { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y }); + graphics::preview_set_viewport(app->PreviewRenderer, app->Scene->Camera); graphics::preview_draw(app->PreviewRenderer, app->Scene); ImTextureID texture = (ImTextureID)graphics::preview_get_rendered_texture(app->PreviewRenderer); @@ -201,54 +202,25 @@ int inferno_run(InfernoApp* app) if (showRenderSettings && ImGui::Begin("Inferno HART")) { if (ImGui::TreeNode("Camera")) { - ImGui::PushItemWidth(100); - ImGui::Text("Camera Position X,Y,Z"); - graphics::Camera* camera = scene::scene_get_camera(app->Scene); - - bool positionUpdated = false; - ImGui::DragFloat("X", &camera->Position.x, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); - ImGui::SameLine(); - if (ImGui::IsItemEdited()) - positionUpdated = true; - ImGui::DragFloat("Y", &camera->Position.y, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); - ImGui::SameLine(); - if (ImGui::IsItemEdited()) - positionUpdated = true; - ImGui::DragFloat("Z", &camera->Position.z, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); - if (ImGui::IsItemEdited()) - positionUpdated = true; - if (positionUpdated) - graphics::camera_set_position(camera, graphics::camera_get_position(camera)); - - bool viewUpdated = false; - ImGui::Text("Camera Look Yaw, Pitch, Roll"); - ImGui::DragFloat("Yaw", &camera->Yaw, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); - ImGui::SameLine(); - if (ImGui::IsItemEdited()) - viewUpdated = true; - ImGui::DragFloat("Pitch", &camera->Pitch, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); - ImGui::SameLine(); - if (ImGui::IsItemEdited()) - viewUpdated = true; - ImGui::DragFloat("Roll", &camera->Roll, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); - if (ImGui::IsItemEdited()) - viewUpdated = true; - - ImGui::PopItemWidth(); - ImGui::PushItemWidth(300); - - ImGui::Text("Camera Zoom"); - ImGui::DragFloat("Zoom", &camera->FOV, -0.1f, 0.01f, 180.0f, "%.2f", ImGuiSliderFlags_None); - ImGui::SameLine(); - if (ImGui::IsItemEdited()) - viewUpdated = true; - if (viewUpdated) - graphics::camera_update(camera); - - ImGui::PopItemWidth(); + graphics::camera_draw_ui(camera); ImGui::TreePop(); } + if (ImGui::TreeNode("Preview Render")) { + ImGui::Checkbox("Show Preview", &showPreview); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("RayTraced Render")) { + ImGui::Text("Lol"); + graphics::rayr_draw_ui(app->RayRenderer); + ImGui::TreePop(); + } + ImGui::End(); + } + + if (ImGui::Begin("Render")) { + ImGui::End(); } diff --git a/src/inferno.hpp b/src/inferno.hpp index 5d895bf..c8b4c3c 100644 --- a/src/inferno.hpp +++ b/src/inferno.hpp @@ -3,7 +3,7 @@ #include "graphics.hpp" #include "scene/scene.hpp" #include "scene/camera.hpp" -// #include "renderer/renderer.hpp" +#include "renderer/renderer.hpp" #include "preview_renderer/renderer.hpp" #include @@ -27,7 +27,7 @@ typedef struct InfernoApp { InfernoInput* Input; scene::Scene* Scene; graphics::PreviewRenderer* PreviewRenderer; - // graphics::RayRenderer* RayRenderer; + graphics::RayRenderer* RayRenderer; } InfernoApp; InfernoApp* inferno_create(); diff --git a/src/preview_renderer/renderer.cpp b/src/preview_renderer/renderer.cpp index 0036a97..4dbe7c1 100644 --- a/src/preview_renderer/renderer.cpp +++ b/src/preview_renderer/renderer.cpp @@ -53,10 +53,43 @@ void preview_cleanup(PreviewRenderer* renderer) { } -void preview_set_viewport(PreviewRenderer* renderer, Viewport* viewport) +void preview_draw_ui(PreviewRenderer* renderer) { } +void preview_set_viewport(PreviewRenderer* renderer, Camera* camera) +{ + auto viewport = camera_raster_get_viewport(camera); + renderer->Viewport = &viewport; + + glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget); + + glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGB, + renderer->Viewport->x, + renderer->Viewport->y, + 0, + GL_RGB, + GL_UNSIGNED_BYTE, + NULL); + + glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetDepthTexture); + glTexImage2D(GL_TEXTURE_2D, + 0, + GL_DEPTH24_STENCIL8, + renderer->Viewport->x, + renderer->Viewport->y, + 0, + GL_DEPTH_COMPONENT, + GL_FLOAT, + NULL); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + GLuint preview_get_rendered_texture(PreviewRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget); @@ -65,48 +98,18 @@ GLuint preview_get_rendered_texture(PreviewRenderer* renderer) void preview_draw(PreviewRenderer* renderer, scene::Scene* scene) { - const glm::ivec2& viewport = graphics::raster_get_viewport(scene::scene_get_camera(scene)); - glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget); - - glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_RGB, - viewport.x, - viewport.y, - 0, - GL_RGB, - GL_UNSIGNED_BYTE, - NULL); - - glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetDepthTexture); - glTexImage2D(GL_TEXTURE_2D, - 0, - GL_DEPTH24_STENCIL8, - viewport.x, - viewport.y, - 0, - GL_DEPTH_COMPONENT, - GL_FLOAT, - NULL); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - // clear - glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget); glClearColor(0.1, 0.1, 0.1, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER, 0); // draw - glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget); glViewport(0, 0, - renderer->Viewport.x, - renderer->Viewport.y); + renderer->Viewport->x, + renderer->Viewport->y); glEnable(GL_DEPTH_TEST); diff --git a/src/preview_renderer/renderer.hpp b/src/preview_renderer/renderer.hpp index 4120d8b..2f388d5 100644 --- a/src/preview_renderer/renderer.hpp +++ b/src/preview_renderer/renderer.hpp @@ -11,9 +11,10 @@ struct Scene; namespace inferno::graphics { struct Viewport; +struct Camera; typedef struct PreviewRenderer { - glm::ivec2 Viewport; + glm::ivec2* Viewport; GLuint RenderTarget = 0; GLuint RenderTargetTexture = 0; @@ -23,6 +24,9 @@ typedef struct PreviewRenderer { PreviewRenderer* preview_create(); void preview_cleanup(PreviewRenderer* renderer); +void preview_draw_ui(PreviewRenderer* renderer); +void preview_set_viewport(PreviewRenderer* renderer, Camera* camera); + GLuint preview_get_rendered_texture(PreviewRenderer* renderer); void preview_draw(PreviewRenderer* renderer, scene::Scene* scene); diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 628aeae..4e37f7f 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -1,111 +1,113 @@ -// #include "renderer.hpp" -// -// #include -// -// #include -// #include -// #include -// #include -// #include -// -// #include "ray_source.hpp" -// -// #include -// -// #include -// -// namespace inferno::graphics { -// -// RayRenderer* rayr_create(glm::ivec2 viewport, HHM* accelIface) +#include "renderer.hpp" + +#include + +#include +#include +#include +#include +#include + +#include "ray_source.hpp" + +#include + +#include + +#include + +namespace inferno::graphics { + +RayRenderer* rayr_create(scene::Scene* scene) +{ + RayRenderer* renderer = new RayRenderer; + + renderer->Scene = scene; + + auto camera = scene::scene_get_camera(scene); + auto viewport = camera_ray_get_viewport(camera); + renderer->Viewport = &viewport; + + renderer->RenderData = new glm::fvec4[renderer->Viewport->x * renderer->Viewport->y]; + + glGenTextures(1, &renderer->RenderTargetTexture); + glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, renderer->Viewport->x, renderer->Viewport->y, 0, GL_RGBA, GL_FLOAT, renderer->RenderData); + + glBindTexture(GL_TEXTURE_2D, 0); + + return renderer; +} + +void rayr_cleanup(RayRenderer* renderer) +{ + delete[] renderer->RenderData; +} + +void rayr_draw_ui(RayRenderer* renderer) +{ +} + +void rayr_set_viewport(RayRenderer* renderer, glm::ivec2 size) +{ + renderer->Viewport = &size; + + delete renderer->RenderData; + renderer->RenderData = new glm::fvec4[renderer->Viewport->x * renderer->Viewport->y]; + + glGenTextures(1, &renderer->RenderTargetTexture); + glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, renderer->Viewport->x, renderer->Viewport->y, 0, GL_RGBA, GL_FLOAT, renderer->RenderData); + + glBindTexture(GL_TEXTURE_2D, 0); +} + +GLuint rayr_get_rendered_texture(RayRenderer*& renderer) +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture); + return renderer->RenderTargetTexture; +} + +glm::fvec4* rayr_get_render_data(RayRenderer*& renderer) +{ + return renderer->RenderData; +} + +void rayr_prepare(RayRenderer*& renderer) +{ + assert(renderer->Scene != nullptr); + if (scene::scene_did_update(renderer->Scene)) { + yolo::debug("Scene updated, rebuilding acceleration structure"); + // renderer->AccelerationInterface->newScene(renderer->CurrentScene); + } +} + +// void rayr_draw(RayRenderer*& renderer) // { -// RayRenderer* renderer = new RayRenderer; -// renderer->RenderTargetSize = viewport; -// renderer->RenderData = new glm::fvec4[renderer->RenderTargetSize.x * renderer->RenderTargetSize.y]; -// -// glGenTextures(1, &renderer->RenderTargetTexture); -// glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture); -// -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -// -// glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); -// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, renderer->RenderTargetSize.x, renderer->RenderTargetSize.y, 0, GL_RGBA, GL_FLOAT, renderer->RenderData); -// -// glBindTexture(GL_TEXTURE_2D, 0); -// -// return renderer; -// } -// -// void rayr_cleanup(RayRenderer* renderer) -// { -// delete[] renderer->RenderData; -// } -// -// void rayr_set_scene(RayRenderer* renderer, std::shared_ptr scene) -// { -// renderer->CurrentScene = scene; -// if (renderer->RaySource != nullptr) -// { -// delete renderer->RaySource; -// } -// // renderer->RaySource = new RaySource(scene->getCamera()); -// // the scene will be sent to the module on prepare -// // as it did update during initialisation -// -// // mIface->newScene(scene); -// } -// -// void rayr_set_viewport(RayRenderer* &renderer, glm::ivec2 size) -// { -// renderer->RenderTargetSize = size; -// } -// -// glm::ivec2 rayr_get_viewport(RayRenderer* &renderer) -// { -// return renderer->RenderTargetSize; -// } -// -// GLuint rayr_get_rendered_texture(RayRenderer* &renderer) -// { -// std::lock_guard lock(renderer->RenderDataMutex); -// glBindFramebuffer(GL_FRAMEBUFFER, 0); -// glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture); -// return renderer->RenderTargetTexture; -// } -// -// glm::fvec4* rayr_get_render_data(RayRenderer* &renderer) -// { -// std::lock_guard lock(renderer->RenderDataMutex); -// return renderer->RenderData; -// } -// -// void rayr_prepare(RayRenderer* &renderer) -// { -// assert(renderer->CurrentScene != nullptr); -// // here, scene_did_update takes a unique_ptr, but we have a shared_ptr -// // so we need to call unique() to get the unique_ptr but that will error -// // with non-const ltype so we need to const_cast it -// if (scene::scene_did_update(renderer->CurrentScene)) -// { -// yolo::debug("New Scene!"); -// // renderer->AccelerationInterface->newScene(renderer->CurrentScene); -// } -// } -// -// void rayr_draw(RayRenderer* &renderer) -// { -// scene::scene_frame_tick(renderer->CurrentScene); +// scene::scene_frame_tick(renderer->Scene); // // TODO: Rays should definately be bump allocated if possible, this is KBs of // // ray data and nothing else being reallocated every frame for no reason -// ReferencedRayField startRays = mRaySource->getInitialRays(true); +// // ReferencedRayField startRays = mRaySource->getInitialRays(true); // // for (int x = 0; x < mRenderTargetSize.x; x++) -// for (int y = 0; y < mRenderTargetSize.y; y++) -// { -// mTarget[y * mRenderTargetSize.x + x] = { 0.1f, 0.1f, 0.1f, 1.0f }; -// } +// for (int y = 0; y < mRenderTargetSize.y; y++) { +// mTarget[y * mRenderTargetSize.x + x] = { 0.1f, 0.1f, 0.1f, 1.0f }; +// } // mCurrentRefTable = &startRays.Reference; // // // before we start we now want to check that it hasn't been force-stopped @@ -113,8 +115,7 @@ // // yolo::info("Sample complete"); // -// for (auto* ray : startRays.Field) -// { +// for (auto* ray : startRays.Field) { // delete ray; // } // } @@ -122,22 +123,20 @@ // void RayRenderer::computeHit(HitInfo* info) // { // static float mind = 100000.0f; -// static float maxd = 0.0f; +// static float maxd = 0.0f; // // TODO: Make sure signal is started -// if (!(*mCurrentRefTable).count(info->Caller->Reference)) -// { +// if (!(*mCurrentRefTable).count(info->Caller->Reference)) { // yolo::warn("Why is the ray not in the map?!"); // return; // } // glm::ivec2 pos = (*mCurrentRefTable)[info->Caller->Reference]; -// float d = info->Distance; -// if (d < mind) mind = d; -// if (d > maxd) maxd = d; +// float d = info->Distance; +// if (d < mind) +// mind = d; +// if (d > maxd) +// maxd = d; // float n = (d - mind) / (maxd - mind); -// mTarget[pos.y * mRenderTargetSize.x + pos.x] = { n, n, n, 1.0f}; -// } -// void mHaultWait(); -// std::unordered_map* mCurrentRefTable; -// -// +// mTarget[pos.y * mRenderTargetSize.x + pos.x] = { n, n, n, 1.0f }; // } + +} diff --git a/src/renderer/renderer.hpp b/src/renderer/renderer.hpp index d3ac31d..67fe60b 100644 --- a/src/renderer/renderer.hpp +++ b/src/renderer/renderer.hpp @@ -8,13 +8,12 @@ #include namespace inferno::scene { -struct Scene; + struct Scene; } namespace inferno::graphics { -class HHM; - +class Camera; class HitInfo; class RaySource; class RenderDispatcher; @@ -22,17 +21,22 @@ class RenderDispatcher; typedef struct RayRenderer { glm::ivec2* Viewport; - // TODO: Can this be direct 2 GPU? + // TODO: Can this be direct to GPU? + // NOTE: Probably not glm::fvec4* RenderData = nullptr; GLuint RenderTargetTexture = 0; // Internal stuffs - RaySource* RaySource = nullptr; + // RaySource* RaySource = nullptr; + + scene::Scene* Scene = nullptr; } RayRenderer; -RayRenderer* rayr_create(glm::ivec2 viewport, HHM* accelIface); +// Expects complete scene +RayRenderer* rayr_create(scene::Scene* scene); void rayr_cleanup(RayRenderer* renderer); +void rayr_draw_ui(RayRenderer* renderer); void rayr_set_viewport(RayRenderer* renderer, glm::ivec2 size); GLuint rayr_get_rendered_texture(RayRenderer* renderer); diff --git a/src/scene/camera.cpp b/src/scene/camera.cpp index 90c30b3..c9945cd 100644 --- a/src/scene/camera.cpp +++ b/src/scene/camera.cpp @@ -1,5 +1,7 @@ #include +#include + namespace inferno::graphics { Camera* camera_create() @@ -35,6 +37,54 @@ void camera_cleanup(Camera* camera) delete camera; } +void camera_draw_ui(Camera* camera) +{ + ImGui::PushItemWidth(100); + ImGui::Text("Camera Position X,Y,Z"); + + bool positionUpdated = false; + ImGui::DragFloat("X", &camera->Position.x, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); + ImGui::SameLine(); + if (ImGui::IsItemEdited()) + positionUpdated = true; + ImGui::DragFloat("Y", &camera->Position.y, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); + ImGui::SameLine(); + if (ImGui::IsItemEdited()) + positionUpdated = true; + ImGui::DragFloat("Z", &camera->Position.z, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); + if (ImGui::IsItemEdited()) + positionUpdated = true; + if (positionUpdated) + graphics::camera_set_position(camera, graphics::camera_get_position(camera)); + + bool viewUpdated = false; + ImGui::Text("Camera Look Yaw, Pitch, Roll"); + ImGui::DragFloat("Yaw", &camera->Yaw, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); + ImGui::SameLine(); + if (ImGui::IsItemEdited()) + viewUpdated = true; + ImGui::DragFloat("Pitch", &camera->Pitch, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); + ImGui::SameLine(); + if (ImGui::IsItemEdited()) + viewUpdated = true; + ImGui::DragFloat("Roll", &camera->Roll, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); + if (ImGui::IsItemEdited()) + viewUpdated = true; + + ImGui::PopItemWidth(); + ImGui::PushItemWidth(300); + + ImGui::Text("Camera Zoom"); + ImGui::DragFloat("Zoom", &camera->FOV, -0.1f, 0.01f, 180.0f, "%.2f", ImGuiSliderFlags_None); + ImGui::SameLine(); + if (ImGui::IsItemEdited()) + viewUpdated = true; + if (viewUpdated) + graphics::camera_update(camera); + + ImGui::PopItemWidth(); +} + void camera_update(Camera* camera) { glm::mat4 matRoll = glm::mat4(1.0f); @@ -100,7 +150,7 @@ glm::mat4 camera_get_look(Camera* camera) return camera->LookMatrix; } -void raster_set_viewport(Camera* camera, glm::ivec2 viewport) +void camera_raster_set_viewport(Camera* camera, glm::ivec2 viewport) { std::lock_guard lock(camera->_impl->CamMutex); camera->Views.Raster = viewport; @@ -111,19 +161,19 @@ void raster_set_viewport(Camera* camera, glm::ivec2 viewport) 1000.0f); } -glm::ivec2 raster_get_viewport(Camera* camera) +glm::ivec2 camera_raster_get_viewport(Camera* camera) { std::lock_guard lock(camera->_impl->CamMutex); return camera->Views.Raster; } -void ray_set_viewport(Camera* camera, glm::ivec2 viewport) +void camera_ray_set_viewport(Camera* camera, glm::ivec2 viewport) { std::lock_guard lock(camera->_impl->CamMutex); camera->Views.Ray = viewport; } -glm::ivec2 ray_get_viewport(Camera* camera) +glm::ivec2 camera_ray_get_viewport(Camera* camera) { std::lock_guard lock(camera->_impl->CamMutex); return camera->Views.Ray;