Started implementing "first person controls".

This commit is contained in:
Patrick 2024-09-25 15:47:17 +02:00
parent 161dfc95bf
commit 9a5638670a
6 changed files with 58 additions and 44 deletions

View File

@ -14,8 +14,8 @@ namespace sdl_gpu_test
{ {
namespace namespace
{ {
inline constexpr float Y_POS_MIN = -10.f; inline constexpr float PITCH_MIN = -89.f;
inline constexpr float Y_POS_MAX = 10.f; inline constexpr float PITCH_MAX = 89.f;
inline constexpr Uint16 AXIS_DEADZONE = 5000; inline constexpr Uint16 AXIS_DEADZONE = 5000;
} }
@ -67,6 +67,8 @@ void ThreeDSceneApp::init(const AppInitArgs& args)
{ {
mButton->setText("Thanks!"); mButton->setText("Thanks!");
}); });
mWindow.setRelativeMouseMode(true);
} }
void ThreeDSceneApp::update(const AppUpdateArgs& args) void ThreeDSceneApp::update(const AppUpdateArgs& args)
@ -74,7 +76,7 @@ void ThreeDSceneApp::update(const AppUpdateArgs& args)
Application::update(args); Application::update(args);
processInput(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(); mWidgetTree.revalidateWidgets();
// begin rendering // begin rendering
@ -97,6 +99,11 @@ void ThreeDSceneApp::update(const AppUpdateArgs& args)
// render the scene // render the scene
mSceneRenderer.render({ mSceneRenderer.render({
.camera = {
.position = mPosition,
.pitch = glm::radians(mPitch),
.yaw = glm::radians(mYaw)
},
.cmdBuffer = &cmdBuffer, .cmdBuffer = &cmdBuffer,
.targetTexture = &swapchainTexture, .targetTexture = &swapchainTexture,
.depthTexture = &mDepthBuffer, .depthTexture = &mDepthBuffer,
@ -134,11 +141,8 @@ void ThreeDSceneApp::handleMouseMotionEvent(const sdlpp::MouseMotionEvent& event
{ {
mWidgetTree.notifyMouseMoved(event); mWidgetTree.notifyMouseMoved(event);
if (event.state.left) mYaw -= 0.5f * event.xrel;
{ mPitch -= 0.5f * event.yrel;
mRotation += 0.5f * event.xrel;
mYPos = std::clamp(mYPos + 0.02f * event.yrel, Y_POS_MIN, Y_POS_MAX);
}
} }
void ThreeDSceneApp::handleMouseButtonEvent(const sdlpp::MouseButtonEvent& event) void ThreeDSceneApp::handleMouseButtonEvent(const sdlpp::MouseButtonEvent& event)
@ -148,39 +152,30 @@ void ThreeDSceneApp::handleMouseButtonEvent(const sdlpp::MouseButtonEvent& event
void ThreeDSceneApp::processInput(const AppUpdateArgs& args) void ThreeDSceneApp::processInput(const AppUpdateArgs& args)
{ {
const std::span<const SDL_bool> 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) if (mGamepad)
{ {
const Sint16 xAxis = mGamepad.getAxis(sdlpp::GamepadAxis::LEFTX); Sint16 axisValue = mGamepad.getAxis(sdlpp::GamepadAxis::RIGHTX);
if (std::abs(xAxis) > AXIS_DEADZONE) if (std::abs(axisValue) > AXIS_DEADZONE)
{ {
mRotation += 0.001f * args.tickSeconds * static_cast<float>(xAxis); mYaw -= 0.005f * args.tickSeconds * static_cast<float>(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<float>(axisValue);
}
axisValue = mGamepad.getAxis(sdlpp::GamepadAxis::LEFTY);
if (std::abs(axisValue) > AXIS_DEADZONE)
{
mPosition.x += 0.0005f * args.tickSeconds * std::sin(mYaw) * static_cast<float>(axisValue);
mPosition.z += 0.0005f * args.tickSeconds * std::cos(mYaw) * static_cast<float>(axisValue);
} }
} }
while (mRotation >= 360.f) { mRotation -= 360.f; } while (mYaw >= 360.f) { mYaw -= 360.f; }
while (mRotation < 0.f) { mRotation += 360.f; } while (mYaw < 0.f) { mYaw += 360.f; }
mYPos = std::clamp(mYPos, Y_POS_MIN, Y_POS_MAX); mPitch = std::clamp(mPitch, PITCH_MIN, PITCH_MAX);
} }
} }

View File

@ -32,8 +32,9 @@ private:
sdlpp::Gamepad mGamepad; sdlpp::Gamepad mGamepad;
Uint32 mLastSwapchainWidth = 1280; Uint32 mLastSwapchainWidth = 1280;
Uint32 mLastSwapchainHeight = 720; Uint32 mLastSwapchainHeight = 720;
float mRotation = 0.f; glm::vec3 mPosition = {0.f, 0.f, 5.f};
float mYPos = 1.5f; float mYaw = 0.f;
float mPitch = 0.f;
public: public:
void init(const AppInitArgs& args) override; void init(const AppInitArgs& args) override;
void update(const AppUpdateArgs& args) override; void update(const AppUpdateArgs& args) override;

View File

@ -6,6 +6,7 @@
#include <glm/vec2.hpp> #include <glm/vec2.hpp>
#include <glm/vec4.hpp> #include <glm/vec4.hpp>
#include "../application.hpp" #include "../application.hpp"
#include "../sdlpp/gpu.hpp" #include "../sdlpp/gpu.hpp"
#include "../util/font_map.hpp" #include "../util/font_map.hpp"

View File

@ -3,6 +3,7 @@
#include <glm/mat4x4.hpp> #include <glm/mat4x4.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/euler_angles.hpp>
#include "./mesh.hpp" #include "./mesh.hpp"
#include "../util/bitmap.hpp" #include "../util/bitmap.hpp"
@ -75,19 +76,18 @@ std::shared_ptr<SceneTexture> SceneRenderer::getTexture(const std::string& resou
void SceneRenderer::render(const SceneRendererRenderArgs& args) void SceneRenderer::render(const SceneRendererRenderArgs& args)
{ {
// just temporary
const float mYPos = 1.5f;
const float mRotation = 0.f;
VertexShaderParameters vertexShaderParameters = { 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)) // note that we are transforming the world, but are passed the camera transform, so invert it
* glm::rotate(glm::mat4(1.f), glm::radians(mRotation), glm::vec3(0.f, 1.f, 0.f)), .worldToView = glm::translate(
glm::yawPitchRoll(-args.camera.yaw, -args.camera.pitch, -args.camera.roll),
-args.camera.position
),
.viewToClip = glm::perspectiveFov( .viewToClip = glm::perspectiveFov(
/* fov = */ glm::radians(90.f), /* fov = */ glm::radians(90.f),
/* width = */ static_cast<float>(args.targetTextureWidth), /* width = */ static_cast<float>(args.targetTextureWidth),
/* height = */ static_cast<float>(args.targetTextureHeight), /* height = */ static_cast<float>(args.targetTextureHeight),
/* zNear = */ 0.1f, /* zNear = */ args.camera.zNear,
/* zFar = */ 100.f /* zFar = */ args.camera.zFar
) )
}; };

View File

@ -26,8 +26,20 @@ struct SceneTexture
sdlpp::GPUTexture texture; 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 struct SceneRendererRenderArgs
{ {
CameraOptions camera;
const sdlpp::GPUCommandBuffer* cmdBuffer; const sdlpp::GPUCommandBuffer* cmdBuffer;
const sdlpp::GPUTexture* targetTexture; const sdlpp::GPUTexture* targetTexture;
const sdlpp::GPUTexture* depthTexture; const sdlpp::GPUTexture* depthTexture;

View File

@ -90,6 +90,11 @@ public:
mHandle = nullptr; mHandle = nullptr;
} }
} }
bool setRelativeMouseMode(bool enabled)
{
return SDL_SetWindowRelativeMouseMode(mHandle, enabled);
}
}; };
} // namespace sdlpp } // namespace sdlpp