diff --git a/private/sdl_gpu_test/7_3d_scene/app.cpp b/private/sdl_gpu_test/7_3d_scene/app.cpp index 8b0cfd0..403c755 100644 --- a/private/sdl_gpu_test/7_3d_scene/app.cpp +++ b/private/sdl_gpu_test/7_3d_scene/app.cpp @@ -14,8 +14,8 @@ namespace sdl_gpu_test { namespace { -inline constexpr float Y_POS_MIN = -10.f; -inline constexpr float Y_POS_MAX = 10.f; +inline constexpr float PITCH_MIN = -89.f; +inline constexpr float PITCH_MAX = 89.f; inline constexpr Uint16 AXIS_DEADZONE = 5000; } @@ -67,6 +67,8 @@ void ThreeDSceneApp::init(const AppInitArgs& args) { mButton->setText("Thanks!"); }); + + mWindow.setRelativeMouseMode(true); } void ThreeDSceneApp::update(const AppUpdateArgs& args) @@ -74,7 +76,7 @@ void ThreeDSceneApp::update(const AppUpdateArgs& args) Application::update(args); processInput(args); - mLabel->setText(std::format("Rotation: {}{}\n$rUI vertices: $f8c{}", mRotation > 180.f ? "$8cf": "$fff" , mRotation, mUIRenderer.getNumVertices())); + mLabel->setText(std::format("Pitch: {:.1f}\nYaw: {:.1f}", mPitch, mYaw)); mWidgetTree.revalidateWidgets(); // begin rendering @@ -97,6 +99,11 @@ void ThreeDSceneApp::update(const AppUpdateArgs& args) // render the scene mSceneRenderer.render({ + .camera = { + .position = mPosition, + .pitch = glm::radians(mPitch), + .yaw = glm::radians(mYaw) + }, .cmdBuffer = &cmdBuffer, .targetTexture = &swapchainTexture, .depthTexture = &mDepthBuffer, @@ -134,11 +141,8 @@ void ThreeDSceneApp::handleMouseMotionEvent(const sdlpp::MouseMotionEvent& event { mWidgetTree.notifyMouseMoved(event); - if (event.state.left) - { - mRotation += 0.5f * event.xrel; - mYPos = std::clamp(mYPos + 0.02f * event.yrel, Y_POS_MIN, Y_POS_MAX); - } + mYaw -= 0.5f * event.xrel; + mPitch -= 0.5f * event.yrel; } void ThreeDSceneApp::handleMouseButtonEvent(const sdlpp::MouseButtonEvent& event) @@ -148,39 +152,30 @@ void ThreeDSceneApp::handleMouseButtonEvent(const sdlpp::MouseButtonEvent& event void ThreeDSceneApp::processInput(const AppUpdateArgs& args) { - const std::span keystates = sdlpp::getKeyboardState(); - if (keystates[SDL_SCANCODE_LEFT]) - { - mRotation -= 40.f * args.tickSeconds; - } - if (keystates[SDL_SCANCODE_RIGHT]) - { - mRotation += 40.f * args.tickSeconds; - } - if (keystates[SDL_SCANCODE_UP]) - { - mYPos -= 2.f * args.tickSeconds; - } - if (keystates[SDL_SCANCODE_DOWN]) - { - mYPos += 2.f * args.tickSeconds; - } if (mGamepad) { - const Sint16 xAxis = mGamepad.getAxis(sdlpp::GamepadAxis::LEFTX); - if (std::abs(xAxis) > AXIS_DEADZONE) + Sint16 axisValue = mGamepad.getAxis(sdlpp::GamepadAxis::RIGHTX); + if (std::abs(axisValue) > AXIS_DEADZONE) { - mRotation += 0.001f * args.tickSeconds * static_cast(xAxis); + mYaw -= 0.005f * args.tickSeconds * static_cast(axisValue); } - const Sint16 yAxis = mGamepad.getAxis(sdlpp::GamepadAxis::LEFTY); - if (std::abs(yAxis) > AXIS_DEADZONE) + + axisValue = mGamepad.getAxis(sdlpp::GamepadAxis::RIGHTY); + if (std::abs(axisValue) > AXIS_DEADZONE) { - mYPos += 0.0002f * args.tickSeconds * yAxis; + mPitch -= 0.005f * args.tickSeconds * static_cast(axisValue); + } + + axisValue = mGamepad.getAxis(sdlpp::GamepadAxis::LEFTY); + if (std::abs(axisValue) > AXIS_DEADZONE) + { + mPosition.x += 0.0005f * args.tickSeconds * std::sin(mYaw) * static_cast(axisValue); + mPosition.z += 0.0005f * args.tickSeconds * std::cos(mYaw) * static_cast(axisValue); } } - while (mRotation >= 360.f) { mRotation -= 360.f; } - while (mRotation < 0.f) { mRotation += 360.f; } - mYPos = std::clamp(mYPos, Y_POS_MIN, Y_POS_MAX); + while (mYaw >= 360.f) { mYaw -= 360.f; } + while (mYaw < 0.f) { mYaw += 360.f; } + mPitch = std::clamp(mPitch, PITCH_MIN, PITCH_MAX); } } diff --git a/private/sdl_gpu_test/7_3d_scene/app.hpp b/private/sdl_gpu_test/7_3d_scene/app.hpp index 20393d8..4919ee0 100644 --- a/private/sdl_gpu_test/7_3d_scene/app.hpp +++ b/private/sdl_gpu_test/7_3d_scene/app.hpp @@ -32,8 +32,9 @@ private: sdlpp::Gamepad mGamepad; Uint32 mLastSwapchainWidth = 1280; Uint32 mLastSwapchainHeight = 720; - float mRotation = 0.f; - float mYPos = 1.5f; + glm::vec3 mPosition = {0.f, 0.f, 5.f}; + float mYaw = 0.f; + float mPitch = 0.f; public: void init(const AppInitArgs& args) override; void update(const AppUpdateArgs& args) override; diff --git a/private/sdl_gpu_test/gui/ui_renderer.hpp b/private/sdl_gpu_test/gui/ui_renderer.hpp index 334e1e3..3540c72 100644 --- a/private/sdl_gpu_test/gui/ui_renderer.hpp +++ b/private/sdl_gpu_test/gui/ui_renderer.hpp @@ -6,6 +6,7 @@ #include #include + #include "../application.hpp" #include "../sdlpp/gpu.hpp" #include "../util/font_map.hpp" diff --git a/private/sdl_gpu_test/scene/scene_renderer.cpp b/private/sdl_gpu_test/scene/scene_renderer.cpp index f43bd00..81cee72 100644 --- a/private/sdl_gpu_test/scene/scene_renderer.cpp +++ b/private/sdl_gpu_test/scene/scene_renderer.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "./mesh.hpp" #include "../util/bitmap.hpp" @@ -75,19 +76,18 @@ std::shared_ptr SceneRenderer::getTexture(const std::string& resou void SceneRenderer::render(const SceneRendererRenderArgs& args) { - // just temporary - const float mYPos = 1.5f; - const float mRotation = 0.f; - VertexShaderParameters vertexShaderParameters = { - .worldToView = glm::lookAt(glm::vec3(2.f, mYPos, 2.f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f)) - * glm::rotate(glm::mat4(1.f), glm::radians(mRotation), glm::vec3(0.f, 1.f, 0.f)), + // note that we are transforming the world, but are passed the camera transform, so invert it + .worldToView = glm::translate( + glm::yawPitchRoll(-args.camera.yaw, -args.camera.pitch, -args.camera.roll), + -args.camera.position + ), .viewToClip = glm::perspectiveFov( /* fov = */ glm::radians(90.f), /* width = */ static_cast(args.targetTextureWidth), /* height = */ static_cast(args.targetTextureHeight), - /* zNear = */ 0.1f, - /* zFar = */ 100.f + /* zNear = */ args.camera.zNear, + /* zFar = */ args.camera.zFar ) }; diff --git a/private/sdl_gpu_test/scene/scene_renderer.hpp b/private/sdl_gpu_test/scene/scene_renderer.hpp index f77a18f..53e887d 100644 --- a/private/sdl_gpu_test/scene/scene_renderer.hpp +++ b/private/sdl_gpu_test/scene/scene_renderer.hpp @@ -26,8 +26,20 @@ struct SceneTexture sdlpp::GPUTexture texture; }; +struct CameraOptions +{ + glm::vec3 position = glm::vec3(0.f); + float roll = 0.f; + float pitch = 0.f; + float yaw = 0.f; + float fovh = glm::radians(90.f); + float zNear = 0.f; + float zFar = 100.f; +}; + struct SceneRendererRenderArgs { + CameraOptions camera; const sdlpp::GPUCommandBuffer* cmdBuffer; const sdlpp::GPUTexture* targetTexture; const sdlpp::GPUTexture* depthTexture; diff --git a/private/sdl_gpu_test/sdlpp/window.hpp b/private/sdl_gpu_test/sdlpp/window.hpp index 48f3ba8..0b2c60d 100644 --- a/private/sdl_gpu_test/sdlpp/window.hpp +++ b/private/sdl_gpu_test/sdlpp/window.hpp @@ -90,6 +90,11 @@ public: mHandle = nullptr; } } + + bool setRelativeMouseMode(bool enabled) + { + return SDL_SetWindowRelativeMouseMode(mHandle, enabled); + } }; } // namespace sdlpp