Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • vulkan2021/vkcv-framework
1 result
Select Git revision
Show changes
Commits on Source (62)
Showing
with 1208 additions and 511 deletions
......@@ -15,4 +15,7 @@
url = https://github.com/nothings/stb.git
[submodule "modules/camera/lib/glm"]
path = modules/camera/lib/glm
url = https://github.com/g-truc/glm.git
\ No newline at end of file
url = https://github.com/g-truc/glm.git
[submodule "modules/shader_compiler/lib/glslang"]
path = modules/shader_compiler/lib/glslang
url = https://github.com/KhronosGroup/glslang.git
......@@ -41,7 +41,6 @@ set(vkcv_sources
${vkcv_source}/vkcv/ShaderProgram.cpp
${vkcv_include}/vkcv/PipelineConfig.hpp
${vkcv_source}/vkcv/PipelineConfig.cpp
${vkcv_source}/vkcv/PipelineManager.hpp
${vkcv_source}/vkcv/PipelineManager.cpp
......
......@@ -7,38 +7,20 @@
#include <vector>
#include <cstdint>
#include "vkcv/Handles.hpp"
#include "Handles.hpp"
#include "ShaderProgram.hpp"
#include <vkcv/VertexLayout.hpp>
#include "VertexLayout.hpp"
namespace vkcv {
struct PipelineConfig {
/**
* Constructor for the pipeline. Creates a pipeline using @p vertexCode, @p fragmentCode as well as the
* dimensions of the application window @p width and @p height. A handle for the Render Pass is also needed, @p passHandle.
*
* @param shaderProgram shaders of the pipeline
* @param height height of the application window
* @param width width of the application window
* @param passHandle handle for Render Pass
*/
PipelineConfig(
const ShaderProgram& shaderProgram,
uint32_t width,
uint32_t height,
const PassHandle &passHandle,
const std::vector<VertexAttribute> &vertexAttributes,
const std::vector<vk::DescriptorSetLayout> &descriptorLayouts,
bool useDynamicViewport);
ShaderProgram m_ShaderProgram;
uint32_t m_Height;
uint32_t m_Width;
PassHandle m_PassHandle;
std::vector<VertexAttribute> m_VertexAttributes;
std::vector<vk::DescriptorSetLayout> m_DescriptorLayouts;
bool m_UseDynamicViewport;
ShaderProgram m_ShaderProgram;
uint32_t m_Width;
uint32_t m_Height;
PassHandle m_PassHandle;
VertexLayout m_VertexLayout;
std::vector<vk::DescriptorSetLayout> m_DescriptorLayouts;
bool m_UseDynamicViewport;
};
......
......@@ -12,9 +12,9 @@
#include <filesystem>
#include <vulkan/vulkan.hpp>
#include <spirv_cross.hpp>
#include "vkcv/VertexLayout.hpp"
#include "vkcv/ShaderStage.hpp"
#include "vkcv/DescriptorConfig.hpp"
#include "VertexLayout.hpp"
#include "ShaderStage.hpp"
#include "DescriptorConfig.hpp"
namespace vkcv {
......@@ -48,17 +48,23 @@ namespace vkcv {
bool existsShader(ShaderStage shaderStage) const;
void reflectShader(ShaderStage shaderStage);
const VertexLayout &getVertexLayout() const;
const std::vector<VertexAttachment> &getVertexAttachments() const;
size_t getPushConstantSize() const;
const std::vector<std::vector<DescriptorBinding>> getReflectedDescriptors() const;
const std::vector<std::vector<DescriptorBinding>>& getReflectedDescriptors() const;
private:
/**
* Called after successfully adding a shader to the program.
* Fills vertex input attachments and descriptor sets (if present).
* @param shaderStage the stage to reflect data from
*/
void reflectShader(ShaderStage shaderStage);
std::unordered_map<ShaderStage, Shader> m_Shaders;
VertexLayout m_VertexLayout;
// contains all vertex input attachments used in the vertex buffer
std::vector<VertexAttachment> m_VertexAttachments;
std::vector<std::vector<DescriptorBinding>> m_DescriptorSets;
size_t m_pushConstantSize = 0;
};
......
#pragma once
#include <unordered_map>
#include <vector>
#include <iostream>
#include <string>
namespace vkcv{
/* With these enums, 0 is reserved to signal uninitialized or invalid data. */
enum class PrimitiveType : uint32_t {
UNDEFINED = 0,
POSITION = 1,
NORMAL = 2,
TEXCOORD_0 = 3
};
/* This struct describes one vertex attribute of a vertex buffer. */
typedef struct {
PrimitiveType type; // POSITION, NORMAL, ...
uint32_t offset; // offset in bytes
uint32_t length; // length of ... in bytes
uint32_t stride; // stride in bytes
uint16_t componentType; // eg. 5126 for float
uint8_t componentCount; // eg. 3 for vec3
} VertexAttribute;
enum class VertexFormat{
enum class VertexAttachmentFormat{
FLOAT,
FLOAT2,
FLOAT3,
......@@ -35,23 +16,51 @@ namespace vkcv{
INT4
};
uint32_t getFormatSize(VertexFormat format);
uint32_t getFormatSize(VertexAttachmentFormat format);
struct VertexInputAttachment{
VertexInputAttachment() = delete;
VertexInputAttachment(uint32_t location, uint32_t binding, std::string name, VertexFormat format, uint32_t offset) noexcept;
struct VertexAttachment{
friend struct VertexBinding;
/**
* Describes an individual vertex input attribute/attachment.
* @param inputLocation its location in the vertex shader.
* @param name the name referred to in the shader.
* @param format the format (and therefore, the size) this attachment is in.
* The offset is calculated when a collection of attachments forms a binding, hence the friend declaration.
*/
VertexAttachment(uint32_t inputLocation, const std::string &name, VertexAttachmentFormat format) noexcept;
VertexAttachment() = delete;
uint32_t location;
uint32_t binding;
std::string name;
VertexFormat format;
uint32_t offset;
uint32_t inputLocation;
std::string name;
VertexAttachmentFormat format;
uint32_t offset;
};
struct VertexBinding{
/**
* Describes all vertex input attachments _one_ buffer contains to create a vertex buffer binding.
* NOTE: multiple vertex layouts may contain various (mutually exclusive) vertex input attachments
* to form one complete vertex buffer binding!
* @param bindingLocation its entry in the buffers that make up the whole vertex buffer.
* @param attachments the vertex input attachments this specific buffer layout contains.
*/
VertexBinding(uint32_t bindingLocation, const std::vector<VertexAttachment> &attachments) noexcept;
VertexBinding() = delete;
uint32_t bindingLocation;
uint32_t stride;
std::vector<VertexAttachment> vertexAttachments;
};
struct VertexLayout{
/**
* Describes the complete layout of one vertex, e.g. all of the vertex input attachments used,
* and all of the buffer bindings that refer to the attachments (for when multiple buffers are used).
* @param bindings bindings the complete vertex buffer is comprised of.
*/
VertexLayout() noexcept;
VertexLayout(const std::vector<VertexInputAttachment> &inputs) noexcept;
std::unordered_map<uint32_t, VertexInputAttachment> attachmentMap;
uint32_t stride;
VertexLayout(const std::vector<VertexBinding> &bindings) noexcept;
std::vector<VertexBinding> vertexBindings;
};
}
\ No newline at end of file
......@@ -2,4 +2,5 @@
# Add new modules here:
add_subdirectory(asset_loader)
add_subdirectory(camera)
add_subdirectory(shader_compiler)
add_subdirectory(testing)
......@@ -8,7 +8,6 @@
#include <string>
#include <vector>
#include <cstdint>
#include <vkcv/VertexLayout.hpp>
/* These macros define limits of the following structs. Implementations can
* test against these limits when performing sanity checks. The main constraint
......@@ -53,6 +52,23 @@ enum PrimitiveMode {
/* The indices in the index buffer can be of different bit width. */
enum IndexType { UINT32=0, UINT16=1, UINT8=2 };
/* With these enums, 0 is reserved to signal uninitialized or invalid data. */
enum class PrimitiveType : uint32_t {
UNDEFINED = 0,
POSITION = 1,
NORMAL = 2,
TEXCOORD_0 = 3
};
/* This struct describes one vertex attribute of a vertex buffer. */
typedef struct {
PrimitiveType type; // POSITION, NORMAL, ...
uint32_t offset; // offset in bytes
uint32_t length; // length of ... in bytes
uint32_t stride; // stride in bytes
uint16_t componentType; // eg. 5126 for float
uint8_t componentCount; // eg. 3 for vec3
} VertexAttribute;
typedef struct {
// TODO not yet needed for the first (unlit) triangle
} Material;
......@@ -71,7 +87,7 @@ typedef struct {
} indexBuffer;
struct {
std::vector<uint8_t> data; // binary data of the vertex buffer
std::vector<VertexAttribute> attributes;
std::vector<VertexAttribute> attributes; // description of one
} vertexBuffer;
struct { float x, y, z; } min; // bounding box lower left
struct { float x, y, z; } max; // bounding box upper right
......
......@@ -11,10 +11,13 @@ set(vkcv_camera_include ${PROJECT_SOURCE_DIR}/include)
set(vkcv_camera_sources
${vkcv_camera_include}/vkcv/camera/Camera.hpp
${vkcv_camera_source}/vkcv/camera/Camera.cpp
${vkcv_camera_include}/vkcv/camera/TrackballCamera.hpp
${vkcv_camera_source}/vkcv/camera/TrackballCamera.cpp
${vkcv_camera_include}/vkcv/camera/CameraManager.hpp
${vkcv_camera_source}/vkcv/camera/CameraManager.cpp
${vkcv_camera_include}/vkcv/camera/CameraController.hpp
${vkcv_camera_include}/vkcv/camera/PilotCameraController.hpp
${vkcv_camera_source}/vkcv/camera/PilotCameraController.cpp
${vkcv_camera_include}/vkcv/camera/TrackballCameraController.hpp
${vkcv_camera_source}/vkcv/camera/TrackballCameraController.cpp
)
# adding source files to the project
......
#pragma once
#define GLM_DEPTH_ZERO_TO_ONE
#define GLM_FORCE_LEFT_HANDED
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/matrix_access.hpp>
namespace vkcv {
namespace vkcv::camera {
class Camera {
/**
* @brief Used to create a camera which governs the view and projection matrices.
*/
class Camera final {
protected:
glm::mat4 m_view;
glm::mat4 m_projection;
int m_width;
int m_height;
float m_near;
float m_far;
float m_fov;
float m_ratio;
glm::vec3 m_up;
glm::vec3 m_up;
glm::vec3 m_position;
float m_cameraSpeed;
glm::vec3 m_center;
float m_pitch;
float m_yaw;
int m_fov_nsteps;
float m_fov_min;
float m_fov_max;
bool m_forward;
bool m_backward;
bool m_left;
bool m_right;
/**
* @brief Sets the view matrix of the camera to @p view
* @param[in] view The view matrix
*/
void setView(const glm::mat4& view);
/**
* @brief Sets the projection matrix of the camera to @p projection
* @param[in] projection The projection matrix
*/
void setProjection(const glm::mat4& projection);
public:
Camera();
virtual ~Camera();
/**
* @brief The default constructor of the camera
*/
Camera();
/**
* @brief The destructor of the camera (default behavior)
*/
~Camera();
/**
* @brief Sets the perspective object according to @p fov, @p ratio, @p near and @p far. This leads to changes in the projection matrix of the camera
* @param[in] fov The desired field of view in radians
* @param[in] ratio The aspect ratio
* @param[in] near Distance to near clipping plane
* @param[in] far Distance to far clipping plane
*/
void setPerspective(float fov, float ratio, float near, float far);
const glm::mat4 getView() const;
void getView(glm::vec3 &x, glm::vec3 &y, glm::vec3 &z, glm::vec3 &pos);
glm::mat4 updateView(double deltatime);
void lookAt(glm::vec3 position, glm::vec3 center, glm::vec3 up);
/**
* @brief Gets the view matrix of the camera
* @return The view matrix of the camera
*/
const glm::mat4& getView() const;
/**
* @brief Sets the view matrix of the camera according to @p position, @p center and @p up
* @param[in] position The position of the camera
* @param[in] center The target position the camera is looking at
* @param[in] up The vector that defines which direction is 'up' depending on the camera's orientation
*/
void lookAt(const glm::vec3& position, const glm::vec3& center, const glm::vec3& up);
/**
* @brief Gets the current projection of the camera
* @return The current projection matrix
*/
const glm::mat4& getProjection() const;
void setProjection(const glm::mat4 projection);
/**
* @brief Gets the model-view-projection matrix of the camera with y-axis-correction applied
* @return The model-view-projection matrix
*/
glm::mat4 getMVP() const;
/**
* @brief Gets the near and far bounds of the view frustum of the camera.
* @param[out] near The near bound of the view frustum
* @param[out] far The far bound of the view frustum
*/
void getNearFar(float &near, float &far) const;
void setUp(const glm::vec3 &Up);
/**
* @brief Gets the current field of view of the camera in radians
* @return[in] The current field of view in radians
*/
float getFov() const;
/**
* @brief Sets the field of view of the camera to @p fov in radians
* @param[in] fov The new field of view in radians
*/
void setFov(float fov);
void changeFov(double fov);
void updateRatio(int width, int height);
/**
* @brief Gets the current aspect ratio of the camera
* @return The current aspect ratio of the camera
*/
float getRatio() const;
/**
* @brief Updates the aspect ratio of the camera with @p ratio and, thus, changes the projection matrix
* @param[in] ratio The new aspect ratio of the camera
*/
void setRatio(float ratio);
/**
* @brief Sets @p near and @p far as new values for the view frustum of the camera. This leads to changes in the projection matrix according to these two values.
* @param[in] near The new near bound of the view frustum
* @param[in] far The new far bound of the view frustum
*/
void setNearFar(float near, float far);
/**
* @brief Gets the current front vector of the camera in world space
* @return The current front vector of the camera
*/
glm::vec3 getFront() const;
glm::vec3 getPosition() const;
void setPosition( glm::vec3 position );
/**
* @brief Sets the front vector of the camera in world space to @p front
* @param[in] front The new front vector of the camera
*/
void setFront(const glm::vec3& front);
/**
* @brief Gets the current position of the camera in world space
* @return The current position of the camera in world space
*/
const glm::vec3& getPosition() const;
/**
* @brief Sets the position of the camera to @p position
* @param[in] position The new position of the camera
*/
void setPosition( const glm::vec3& position );
/**
* @brief Gets the center point.
* @return The center point.
*/
const glm::vec3& getCenter() const;
/**
* @brief Sets @p center as the new center point.
* @param[in] center The new center point.
*/
void setCenter(const glm::vec3& center);
/**
* @brief Gets the pitch value of the camera in degrees.
* @return The pitch value in degrees.
*/
float getPitch() const;
/**
* @brief Sets the pitch value of the camera to @p pitch in degrees.
* @param[in] pitch The new pitch value in degrees.
*/
void setPitch(float pitch);
/**
* @brief Gets the yaw value of the camera in degrees.
* @return The yaw value in degrees.
*/
float getYaw() const;
/**
* @brief Sets the yaw value of the camera to @p yaw.
* @param[in] yaw The new yaw value in degrees.
*/
void setYaw(float yaw);
void panView( double xOffset, double yOffset );
void updatePosition(double deltatime);
void moveForward(int action);
void moveBackward(int action);
void moveLeft(int action);
void moveRight(int action);
/**
* @brief Gets the up vector.
* @return The up vector.
*/
const glm::vec3& getUp() const;
/**
* @brief Sets @p up as the new up vector.
* @param[in] up The new up vector.
*/
void setUp(const glm::vec3 &up);
};
}
#pragma once
#include "Camera.hpp"
#include "vkcv/Window.hpp"
namespace vkcv::camera {
/**
* @brief Used as a base class for defining camera controller classes with different behaviors, e.g. the
* #PilotCameraController.
*/
class CameraController {
public:
/**
* @brief The constructor of the #CameraController (default behavior).
*/
CameraController() = default;
/**
* @brief Updates @p camera in respect to @p deltaTime.
* @param[in] deltaTime The time that has passed since last update.
* @param[in] camera The camera object.
*/
virtual void updateCamera(double deltaTime, Camera &camera) = 0;
/**
* @brief A callback function for key events.
* @param[in] key The keyboard key.
* @param[in] scancode The platform-specific scancode.
* @param[in] action The key action.
* @param[in] mods The modifier bits.
* @param[in] camera The camera object.
*/
virtual void keyCallback(int key, int scancode, int action, int mods, Camera &camera) = 0;
/**
* @brief A callback function for mouse scrolling events.
* @param[in] offsetX The offset in horizontal direction.
* @param[in] offsetY The offset in vertical direction.
* @param[in] camera The camera object.
*/
virtual void scrollCallback( double offsetX, double offsetY, Camera &camera) = 0;
/**
* @brief A callback function for mouse movement events.
* @param[in] x The horizontal mouse position.
* @param[in] y The vertical mouse position.
* @param[in] camera The camera object.
*/
virtual void mouseMoveCallback(double offsetX, double offsetY, Camera &camera) = 0;
/**
* @brief A callback function for mouse button events.
* @param[in] button The mouse button.
* @param[in] action The button action.
* @param[in] mods The modifier bits.
* @param[in] camera The camera object.
*/
virtual void mouseButtonCallback(int button, int action, int mods, Camera &camera) = 0;
};
}
\ No newline at end of file
#pragma once
#include "TrackballCamera.hpp"
#include "PilotCameraController.hpp"
#include "TrackballCameraController.hpp"
#include "CameraController.hpp"
#include "vkcv/Window.hpp"
#include <GLFW/glfw3.h>
#include <functional>
namespace vkcv{
namespace vkcv::camera {
/**
* @brief Used for specifying existing types of camera controllers when adding a new controller object to the
* #CameraManager.
*/
enum class ControllerType {
NONE,
PILOT,
TRACKBALL,
TRACE
};
/**
* @brief Used for managing an arbitrary amount of camera controllers.
*/
class CameraManager{
private:
std::function<void(int, int, int, int)> e_keyHandle;
std::function<void(double, double)> e_mouseMoveHandle;
std::function<void(double, double)> e_mouseScrollHandle;
std::function<void(int, int, int)> e_mouseButtonHandle;
std::function<void(int, int)> e_resizeHandle;
Window &m_window;
Camera m_camera;
float m_width;
float m_height;
// std::shared_ptr<vkcv::TrackballCamera> m_trackball;
bool m_roationActive = false;
double m_lastX ;
double m_lastY ;
void bindCamera();
std::function<void(int, int, int, int)> m_keyHandle;
std::function<void(double, double)> m_mouseMoveHandle;
std::function<void(double, double)> m_mouseScrollHandle;
std::function<void(int, int, int)> m_mouseButtonHandle;
std::function<void(int, int)> m_resizeHandle;
Window& m_window;
std::vector<Camera> m_cameras;
std::vector<ControllerType> m_cameraControllerTypes;
uint32_t m_activeCameraIndex;
PilotCameraController m_pilotController;
TrackballCameraController m_trackController;
double m_lastX;
double m_lastY;
/**
* @brief Binds the camera object to the window event handles.
*/
void bindCameraToEvents();
/**
* @brief A callback function for key events. Currently, cycling between all existing camera controllers via Tab,
* window closure via Esc and polling key events from the active camera controller are supported.
* @param[in] key The keyboard key.
* @param[in] scancode The platform-specific scancode.
* @param[in] action The key action.
* @param[in] mods The modifier bits.
*/
void keyCallback(int key, int scancode, int action, int mods);
void scrollCallback( double offsetX, double offsetY);
void mouseMoveCallback( double offsetX, double offsetY);
/**
* @brief A callback function for mouse scrolling events.
* @param[in] offsetX The offset in horizontal direction.
* @param[in] offsetY The offset in vertical direction.
*/
void scrollCallback(double offsetX, double offsetY);
/**
* @brief A callback function for mouse movement events.
* @param[in] x The horizontal mouse position.
* @param[in] y The vertical mouse position.
*/
void mouseMoveCallback(double x, double y);
/**
* @brief A callback function for mouse button events.
* @param[in] button The mouse button.
* @param[in] action The button action.
* @param[in] mods The modifier bits.
*/
void mouseButtonCallback(int button, int action, int mods);
/**
* @brief A callback function for handling the window resizing event. Each existing camera is resized in respect
* of the window size.
* @param[in] width The new width of the window.
* @param[in] height The new height of the window.
*/
void resizeCallback(int width, int height);
/**
* @brief Gets a camera controller object of specified @p controllerType.
* @param[in] controllerType The type of the camera controller.
* @return The specified camera controller object.
*/
CameraController& getControllerByType(ControllerType controllerType);
/**
* @briof A method to get the currently active controller for the active camera.
* @return Reference to the active #CameraController
*/
CameraController& getActiveController();
public:
CameraManager(Window &window, float width, float height, glm::vec3 up = glm::vec3(0.0f,-1.0f,0.0f), glm::vec3 position = glm::vec3(0.0f,0.0f,0.0f));
Camera &getCamera();
/**
* @brief The constructor of the #CameraManager.
* @param[in] window The window.
*/
CameraManager(Window &window);
/**
* @brief The destructor of the #CameraManager. Destroying the #CameraManager leads to deletion of all stored
* camera objects and camera controller objects.
*/
~CameraManager();
/**
* @brief Adds a new camera object to the #CameraManager and binds it to a camera controller object of specified
* @p controllerType.
* @param[in] controllerType The type of the camera controller.
* @return The index of the newly created camera object.
*/
uint32_t addCamera(ControllerType controllerType = ControllerType::NONE);
/**
* @brief Adds a new camera object to the #CameraManager and binds it to a camera controller object of specified
* @p controllerType.
* @param[in] controllerType The type of the camera controller.
* @param[in] camera The new camera object.
* @return The index of the newly bound camera object.
*/
uint32_t addCamera(ControllerType controllerType, const Camera& camera);
/**
* @brief Gets the stored camera object located at @p cameraIndex.
* @param[in] cameraIndex The camera index.
* @return The camera object at @p cameraIndex.
* @throws std::runtime_error If @p cameraIndex is not a valid camera index.
*/
Camera& getCamera(uint32_t cameraIndex);
/**
* @brief Gets the stored camera object set as the active camera.
* @return The active camera.
*/
Camera& getActiveCamera();
/**
* @brief Sets the stored camera object located at @p cameraIndex as the active camera.
* @param[in] cameraIndex The camera index.
* @throws std::runtime_error If @p cameraIndex is not a valid camera index.
*/
void setActiveCamera(uint32_t cameraIndex);
/**
* @brief Gets the index of the stored active camera object.
* @return The active camera index.
*/
uint32_t getActiveCameraIndex() const;
/**
* @brief Binds a stored camera object located at @p cameraIndex to a camera controller of specified
* @p controllerType.
* @param[in] cameraIndex The camera index.
* @param[in] controllerType The type of the camera controller.
* @throws std::runtime_error If @p cameraIndex is not a valid camera index.
*/
void setControllerType(uint32_t cameraIndex, ControllerType controllerType);
/**
* @brief Gets the currently bound camera controller type of the stored camera object located at @p cameraIndex.
* @param[in] cameraIndex The camera index.
* @return The type of the camera controller of the specified camera object.
* @throws std::runtime_error If @p cameraIndex is not a valid camera index.
*/
ControllerType getControllerType(uint32_t cameraIndex);
/**
* @brief Updates all stored camera controllers in respect to @p deltaTime.
* @param[in] deltaTime The time that has passed since last update.
*/
void update(double deltaTime);
};
}
#pragma once
#include <vkcv/camera/CameraController.hpp>
namespace vkcv::camera {
/**
* @brief Used to move around a camera object in world space.
*/
class PilotCameraController final : public CameraController {
private:
// camera movement indicators
bool m_forward;
bool m_backward;
bool m_upward;
bool m_downward;
bool m_left;
bool m_right;
bool m_rotationActive;
float m_cameraSpeed;
int m_fov_nsteps;
float m_fov_min;
float m_fov_max;
/**
* @brief Indicates forward movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveForward(int action);
/**
* @brief Indicates backward movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveBackward(int action);
/**
* @brief Indicates left movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveLeft(int action);
/**
* @brief Indicates right movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveRight(int action);
/**
* @brief Indicates upward movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveUpward(int action);
/**
* @brief Indicates downward movement of the camera depending on the performed @p action.
* @param[in] action The performed action.
*/
void moveDownward(int action);
public:
/**
* @brief The default constructor of the #PilotCameraController.
*/
PilotCameraController();
/**
* @brief The destructor of the #PilotCameraController (default behavior).
*/
~PilotCameraController() = default;
/**
* @brief Changes the field of view of @p camera with an @p offset in degrees.
* @param[in] offset The offset in degrees.
* @param[in] camera The camera object.
*/
void changeFov(double offset, Camera &camera);
/**
* @brief Pans the view of @p camera according to the pitch and yaw values and additional offsets @p xOffset
* and @p yOffset.
* @param[in] xOffset The offset added to the yaw value.
* @param[in] yOffset The offset added to the pitch value.
* @param[in] camera The camera object.
*/
void panView(double xOffset, double yOffset, Camera &camera);
/**
* @brief Updates @p camera in respect to @p deltaTime.
* @param[in] deltaTime The time that has passed since last update.
* @param[in] camera The camera object.
*/
void updateCamera(double deltaTime, Camera &camera);
/**
* @brief A callback function for key events. Currently, 3D camera movement via W, A, S, D, E, Q are supported.
* @param[in] key The keyboard key.
* @param[in] scancode The platform-specific scancode.
* @param[in] action The key action.
* @param[in] mods The modifier bits.
* @param[in] camera The camera object.
*/
void keyCallback(int key, int scancode, int action, int mods, Camera &camera);
/**
* @brief A callback function for mouse scrolling events. Currently, this leads to changes in the field of view
* of @p camera.
* @param[in] offsetX The offset in horizontal direction.
* @param[in] offsetY The offset in vertical direction.
* @param[in] camera The camera object.
*/
void scrollCallback(double offsetX, double offsetY, Camera &camera);
/**
* @brief A callback function for mouse movement events. Currently, this leads to panning the view of the camera,
* if #mouseButtonCallback(int button, int action, int mods) enabled panning.
* @param[in] x The horizontal mouse position
* @param[in] y The vertical mouse position
* @param[in] camera The camera object.
*/
void mouseMoveCallback(double x, double y, Camera &camera);
/**
* @brief A callback function for mouse button events. Currently, the right mouse button enables panning the
* view of the camera as long as it is pressed.
* @param[in] button The mouse button
* @param[in] action The button action
* @param[in] mods The modifier bits
* @param[in] camera The camera object.
*/
void mouseButtonCallback(int button, int action, int mods, Camera &camera);
};
}
\ No newline at end of file
#pragma once
#include "Camera.hpp"
namespace vkcv {
class TrackballCamera : public vkcv::Camera {
public:
TrackballCamera( int width, int height, glm::mat4 projection);
TrackballCamera(int width, int height);
~TrackballCamera();
float getSensitivity() const;
void setSensitivity(float sensitivity);
float getStepSize() const;
void setStepSize(float stepSize);
float getTheta() const;
void setTheta(float theta);
float getPhi() const;
void setPhi(float phi);
float getRadius() const;
void setRadius(float radius);
const glm::vec3& getCenter() const;
void setCenter(const glm::vec3 &center);
private:
float m_sensitivity;
float m_stepSize, m_theta, m_phi, m_radius;
glm::vec3 m_center;
float m_oldX;
float m_oldY;
};
}
\ No newline at end of file
#pragma once
#include "CameraController.hpp"
namespace vkcv::camera {
/**
* @brief Used to orbit a camera around its center point.
*/
class TrackballCameraController final : public CameraController {
private:
bool m_rotationActive;
float m_cameraSpeed;
float m_scrollSensitivity;
float m_radius;
/**
* @brief Updates the current radius of @p camera in respect to the @p offset.
* @param[in] offset The offset between the old and new radius.
* @param[in] camera The camera object.
*/
void updateRadius(double offset, Camera &camera);
public:
/**
* @brief The default constructor of the #TrackballCameraController.
*/
TrackballCameraController();
/**
* @brief The destructor of the #TrackballCameraController (default behavior).
*/
~TrackballCameraController() = default;
/**
* @brief Sets @p radius as the new radius for orbiting around the camera's center point.
* @param[in] radius The new radius.
*/
void setRadius(const float radius);
/**
* @brief Pans the view of @p camera according to the pitch and yaw values and additional offsets @p xOffset
* and @p yOffset.
* @param[in] xOffset The offset added to the yaw value.
* @param[in] yOffset The offset added to the pitch value.
* @param[in] camera The camera object.
*/
void panView(double xOffset, double yOffset, Camera &camera);
/**
* @brief Updates @p camera in respect to @p deltaTime.
* @param[in] deltaTime The time that has passed since last update.
* @param[in] camera The camera object
*/
void updateCamera(double deltaTime, Camera &camera);
/**
* @brief A callback function for key events. Currently, the trackball camera does not support camera movement.
* It can only orbit around its center point.
* @param[in] key The keyboard key.
* @param[in] scancode The platform-specific scancode.
* @param[in] action The key action.
* @param[in] mods The modifier bits.
* @param[in] camera The camera object.
*/
void keyCallback(int key, int scancode, int action, int mods, Camera &camera);
/**
* @brief A callback function for mouse scrolling events. Currently, this leads to changes in the field of view
* of the camera object.
* @param[in] offsetX The offset in horizontal direction.
* @param[in] offsetY The offset in vertical direction.
* @param[in] camera The camera object.
*/
void scrollCallback(double offsetX, double offsetY, Camera &camera);
/**
* @brief A callback function for mouse movement events. Currently, this leads to panning the view of the
* camera, if #mouseButtonCallback(int button, int action, int mods) enabled panning.
* @param[in] xoffset The horizontal mouse position.
* @param[in] yoffset The vertical mouse position.
* @param[in] camera The camera object.
*/
void mouseMoveCallback(double xoffset, double yoffset, Camera &camera);
/**
* @brief A callback function for mouse button events. Currently, the right mouse button enables panning the
* view of the camera as long as it is pressed.
* @param[in] button The mouse button.
* @param[in] action The button action.
* @param[in] mods The modifier bits.
* @param[in] camera The camera object.
*/
void mouseButtonCallback(int button, int action, int mods, Camera &camera);
};
}
\ No newline at end of file
#include "vkcv/camera/Camera.hpp"
#include <iostream>
namespace vkcv {
#define _USE_MATH_DEFINES
#include <math.h>
Camera::Camera(){
m_up = glm::vec3(0.0f, -1.0f, 0.0f);
m_position = glm::vec3(0.0f, 0.0f, 0.0f);
m_cameraSpeed = 2.f;
// front
m_pitch = 0.0;
m_yaw = 180.0;
namespace vkcv::camera {
m_fov_nsteps = 100;
m_fov_min = 10;
m_fov_max = 120;
m_forward = false;
m_backward = false;
m_left = false;
m_right = false;
Camera::Camera() {
lookAt(
glm::vec3(0.0f, 0.0f, -1.0f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f)
);
setFront(glm::normalize(m_center - m_position));
}
Camera::~Camera() = default;
void Camera::lookAt(glm::vec3 position, glm::vec3 center, glm::vec3 up){
m_view = glm::lookAt(position, center, up);
}
glm::mat4 Camera::updateView(double deltatime){
updatePosition(deltatime);
return m_view = glm::lookAt(m_position, m_position + getFront() , m_up);
}
void Camera::getView(glm::vec3 &x, glm::vec3 &y, glm::vec3 &z, glm::vec3 &pos){
x = glm::vec3( glm::row(m_view, 0));
y = glm::vec3( glm::row(m_view, 1));
z = glm::vec3( glm::row(m_view, 2));
pos = glm::vec3( glm::column(m_view, 3));
glm::mat3 mat_inv = glm::inverse( glm::mat3(m_view));
pos = -mat_inv * pos;
void Camera::lookAt(const glm::vec3& position, const glm::vec3& center, const glm::vec3& up) {
m_position = position;
m_center = center;
m_up = up;
setView(glm::lookAt(position, center, up));
}
void Camera::getNearFar( float &near, float &far) const {
......@@ -46,98 +30,111 @@ namespace vkcv {
far = m_far;
}
const glm::mat4 Camera::getView() const {
const glm::mat4& Camera::getView() const {
return m_view;
}
void Camera::setView(const glm::mat4 &view) {
m_view = view;
}
const glm::mat4& Camera::getProjection() const {
return m_projection;
}
void Camera::setProjection(const glm::mat4 projection){
m_projection = projection;
void Camera::setProjection(const glm::mat4& projection) {
m_projection = projection;
}
float Camera::getFov() const {
return m_fov;
glm::mat4 Camera::getMVP() const {
const glm::mat4 y_correction (
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
);
return y_correction * m_projection * m_view;
}
void Camera::setFov( float fov){
m_fov = fov;
setPerspective( m_fov, m_ratio, m_near, m_far);
float Camera::getFov() const {
const float tanHalfFovy = 1.0f / m_projection[1][1];
float halfFovy = std::atan(tanHalfFovy);
if (halfFovy < 0) {
halfFovy += static_cast<float>(M_PI);
}
return halfFovy * 2.0f;
}
void Camera::changeFov(double offset){
float fov = m_fov;
float fov_range = m_fov_max - m_fov_min;
float fov_stepsize = glm::radians(fov_range)/m_fov_nsteps;
fov -= (float) offset*fov_stepsize;
if (fov < glm::radians(m_fov_min)) {
fov = glm::radians(m_fov_min);
}
if (fov > glm::radians(m_fov_max)) {
fov = glm::radians(m_fov_max);
}
setFov(fov);
void Camera::setFov( float fov){
setPerspective(fov, getRatio(), m_near, m_far);
}
void Camera::updateRatio( int width, int height){
m_width = width;
m_height = height;
m_ratio = static_cast<float>(width)/glm::max(height, 1);
setPerspective( m_fov, m_ratio, m_near, m_far);
float Camera::getRatio() const {
const float aspectProduct = 1.0f / m_projection[0][0];
const float tanHalfFovy = 1.0f / m_projection[1][1];
return aspectProduct / tanHalfFovy;
}
float Camera::getRatio() const {
return m_ratio;
void Camera::setRatio(float ratio){
setPerspective( getFov(), ratio, m_near, m_far);
}
void Camera::setNearFar( float near, float far){
m_near = near;
m_far = far;
setPerspective(m_fov, m_ratio, m_near, m_far);
void Camera::setNearFar(float near, float far){
setPerspective(getFov(), getRatio(), near, far);
}
void Camera::setPerspective(float fov, float ratio, float near, float far){
m_fov = fov;
m_ratio = ratio;
m_near = near;
m_far = far;
m_projection = glm::perspective( m_fov, ratio, m_near, m_far);
void Camera::setPerspective(float fov, float ratio, float near, float far) {
m_near = near;
m_far = far;
setProjection(glm::perspective(fov, ratio, near, far));
}
glm::vec3 Camera::getFront() const {
glm::vec3 direction;
direction.x = sin(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
direction.y = sin(glm::radians(m_pitch));
direction.z = cos(glm::radians(m_yaw)) * cos(glm::radians(m_pitch));
direction.x = std::sin(glm::radians(m_yaw)) * std::cos(glm::radians(m_pitch));
direction.y = std::sin(glm::radians(m_pitch));
direction.z = std::cos(glm::radians(m_yaw)) * std::cos(glm::radians(m_pitch));
return glm::normalize(direction);
}
void Camera::setFront(const glm::vec3 &front) {
m_pitch = std::atan2(front.y, std::sqrt(front.x * front.x + front.z * front.z));
m_yaw = std::atan2(front.x, front.z);
}
glm::vec3 Camera::getPosition() const {
const glm::vec3& Camera::getPosition() const {
return m_position;
}
void Camera::setPosition( glm::vec3 position ){
m_position = position;
void Camera::setPosition( const glm::vec3& position ){
lookAt(position, m_center, m_up);
}
void Camera::setUp(const glm::vec3 &up) {
m_up = up;
const glm::vec3& Camera::getCenter() const {
return m_center;
}
void Camera::setCenter(const glm::vec3& center) {
lookAt(m_position, center, m_up);
}
const glm::vec3& Camera::getUp() const {
return m_up;
}
void Camera::setUp(const glm::vec3 &up) {
lookAt(m_position, m_center, up);
}
float Camera::getPitch() const {
return m_pitch;
}
void Camera::setPitch(float pitch) {
if (pitch > 89.0f) {
pitch = 89.0f;
}
if (pitch < -89.0f) {
pitch = -89.0f;
}
m_pitch = pitch;
}
......@@ -149,31 +146,4 @@ namespace vkcv {
m_yaw = yaw;
}
void Camera::panView(double xOffset, double yOffset) {
m_yaw += xOffset;
m_pitch += yOffset;
}
void Camera::updatePosition(double deltatime ){
m_position += (m_cameraSpeed * getFront() * static_cast<float> (m_forward) * static_cast<float>(deltatime));
m_position -= (m_cameraSpeed * getFront() * static_cast<float> (m_backward) * static_cast<float>(deltatime));
m_position -= (glm::normalize(glm::cross(getFront(), m_up)) * m_cameraSpeed * static_cast<float> (m_left) * static_cast<float>(deltatime));
m_position += (glm::normalize(glm::cross(getFront(), m_up)) * m_cameraSpeed * static_cast<float> (m_right) * static_cast<float>(deltatime));
}
void Camera::moveForward(int action){
m_forward = static_cast<bool>(action);
}
void Camera::moveBackward(int action){
m_backward = static_cast<bool>(action);
}
void Camera::moveLeft(int action){
m_left = static_cast<bool>(action);
}
void Camera::moveRight(int action){
m_right = static_cast<bool>(action);
}
}
\ No newline at end of file
#include <iostream>
#include "vkcv/camera/CameraManager.hpp"
namespace vkcv{
#include <vkcv/Logger.hpp>
namespace vkcv::camera {
CameraManager::CameraManager(Window &window, float width, float height, glm::vec3 up, glm::vec3 position):
m_window(window), m_width(width), m_height(height)
CameraManager::CameraManager(Window& window)
: m_window(window)
{
m_camera.setUp(up);
m_camera.setPosition(position);
m_camera.setPerspective( glm::radians(60.0f), m_width / m_height, 0.1f, 10.f);
m_lastX = width/2.0;
m_lastY = height/2.0;
bindCamera();
bindCameraToEvents();
m_activeCameraIndex = 0;
m_lastX = static_cast<float>(window.getWidth()) / 2.0f;
m_lastY = static_cast<float>(window.getHeight()) / 2.0f;
}
void CameraManager::bindCamera(){
e_keyHandle = m_window.e_key.add( [&](int key, int scancode, int action, int mods) { this->keyCallback(key, scancode, action, mods); });
e_mouseMoveHandle = m_window.e_mouseMove.add( [&]( double offsetX, double offsetY) {this->mouseMoveCallback( offsetX, offsetY);} );
e_mouseScrollHandle = m_window.e_mouseScroll.add([&](double offsetX, double offsetY) {this->scrollCallback( offsetX, offsetY);} );
e_mouseButtonHandle = m_window.e_mouseButton.add([&] (int button, int action, int mods) {this->mouseButtonCallback( button, action, mods);});
e_resizeHandle = m_window.e_resize.add([&] (int width, int height) {this->resizeCallback( width, height);});
CameraManager::~CameraManager() {}
void CameraManager::bindCameraToEvents() {
m_keyHandle = m_window.e_key.add( [&](int key, int scancode, int action, int mods) { this->keyCallback(key, scancode, action, mods); });
m_mouseMoveHandle = m_window.e_mouseMove.add( [&]( double offsetX, double offsetY) {this->mouseMoveCallback( offsetX, offsetY);} );
m_mouseScrollHandle = m_window.e_mouseScroll.add([&](double offsetX, double offsetY) {this->scrollCallback( offsetX, offsetY);} );
m_mouseButtonHandle = m_window.e_mouseButton.add([&] (int button, int action, int mods) {this->mouseButtonCallback( button, action, mods);});
m_resizeHandle = m_window.e_resize.add([&](int width, int height) {this->resizeCallback(width, height);});
}
void CameraManager::resizeCallback(int width, int height) {
for (size_t i = 0; i < m_cameras.size(); i++) {
getCamera(i).setRatio(static_cast<float>(width) / static_cast<float>(height));;
}
}
void CameraManager::mouseButtonCallback(int button, int action, int mods){
if(button == GLFW_MOUSE_BUTTON_2 && m_roationActive == false && action == GLFW_PRESS){
if(button == GLFW_MOUSE_BUTTON_2 && action == GLFW_PRESS){
glfwSetInputMode(m_window.getWindow(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
m_roationActive = true;
}else if(button == GLFW_MOUSE_BUTTON_2 && m_roationActive == true && action == GLFW_RELEASE){
}
else if(button == GLFW_MOUSE_BUTTON_2 && action == GLFW_RELEASE){
glfwSetInputMode(m_window.getWindow(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
m_roationActive = false;
}
getActiveController().mouseButtonCallback(button, action, mods, getActiveCamera());
}
void CameraManager::mouseMoveCallback(double x, double y){
float xoffset = x - m_lastX;
float yoffset = m_lastY - y;
auto xoffset = static_cast<float>(x - m_lastX);
auto yoffset = static_cast<float>(y - m_lastY);
m_lastX = x;
m_lastY = y;
getActiveController().mouseMoveCallback(xoffset, yoffset, getActiveCamera());
}
if(!m_roationActive){
return;
void CameraManager::scrollCallback(double offsetX, double offsetY) {
getActiveController().scrollCallback(offsetX, offsetY, getActiveCamera());
}
void CameraManager::keyCallback(int key, int scancode, int action, int mods) {
switch (action) {
case GLFW_RELEASE:
switch (key) {
case GLFW_KEY_TAB:
if (m_activeCameraIndex + 1 == m_cameras.size()) {
m_activeCameraIndex = 0;
}
else {
m_activeCameraIndex++;
}
return;
case GLFW_KEY_ESCAPE:
glfwSetWindowShouldClose(m_window.getWindow(), 1);
return;
default:
break;
}
default:
getActiveController().keyCallback(key, scancode, action, mods, getActiveCamera());
break;
}
}
CameraController& CameraManager::getActiveController() {
const ControllerType type = getControllerType(getActiveCameraIndex());
return getControllerByType(type);
}
uint32_t CameraManager::addCamera(ControllerType controllerType) {
const float ratio = static_cast<float>(m_window.getWidth()) / static_cast<float>(m_window.getHeight());
Camera camera;
camera.setPerspective(glm::radians(60.0f), ratio, 0.1f, 10.0f);
return addCamera(controllerType, camera);
}
uint32_t CameraManager::addCamera(ControllerType controllerType, const Camera &camera) {
const uint32_t index = static_cast<uint32_t>(m_cameras.size());
m_cameras.push_back(camera);
m_cameraControllerTypes.push_back(controllerType);
return index;
}
float sensitivity = 0.05f;
xoffset *= sensitivity;
yoffset *= sensitivity;
Camera& CameraManager::getCamera(uint32_t cameraIndex) {
if (cameraIndex < 0 || cameraIndex > m_cameras.size() - 1) {
vkcv_log(LogLevel::ERROR, "Invalid camera index: The index must range from 0 to %lu", m_cameras.size());
return getActiveCamera();
}
return m_cameras[cameraIndex];
}
m_camera.panView( xoffset , yoffset );
Camera& CameraManager::getActiveCamera() {
return m_cameras[getActiveCameraIndex()];
}
void CameraManager::scrollCallback(double offsetX, double offsetY) {
m_camera.changeFov(offsetY);
void CameraManager::setActiveCamera(uint32_t cameraIndex) {
if (cameraIndex < 0 || cameraIndex > m_cameras.size() - 1) {
vkcv_log(LogLevel::ERROR, "Invalid camera index: The index must range from 0 to %lu", m_cameras.size());
return;
}
m_activeCameraIndex = cameraIndex;
}
void CameraManager::keyCallback(int key, int scancode, int action, int mods) {
uint32_t CameraManager::getActiveCameraIndex() const {
return m_activeCameraIndex;
}
switch (key) {
case GLFW_KEY_W:
m_camera.moveForward(action);
break;
case GLFW_KEY_S:
m_camera.moveBackward(action);
break;
case GLFW_KEY_A:
m_camera.moveLeft(action);
break;
case GLFW_KEY_D:
m_camera.moveRight(action);
break;
case GLFW_KEY_ESCAPE:
glfwSetWindowShouldClose(m_window.getWindow(), 1);
break;
default:
break;
void CameraManager::setControllerType(uint32_t cameraIndex, ControllerType controllerType) {
if (cameraIndex < 0 || cameraIndex > m_cameras.size() - 1) {
vkcv_log(LogLevel::ERROR, "Invalid camera index: The index must range from 0 to %lu", m_cameras.size());
return;
}
m_cameraControllerTypes[cameraIndex] = controllerType;
}
void CameraManager::resizeCallback(int width, int height){
m_camera.updateRatio(width, height);
ControllerType CameraManager::getControllerType(uint32_t cameraIndex) {
if (cameraIndex < 0 || cameraIndex > m_cameras.size() - 1) {
vkcv_log(LogLevel::ERROR, "Invalid camera index: The index must range from 0 to %lu", m_cameras.size());
return ControllerType::NONE;
}
return m_cameraControllerTypes[cameraIndex];
}
Camera &CameraManager::getCamera(){
return m_camera;
CameraController& CameraManager::getControllerByType(ControllerType controllerType) {
switch(controllerType) {
case ControllerType::PILOT:
return m_pilotController;
case ControllerType::TRACKBALL:
return m_trackController;
default:
return m_pilotController;
}
}
void CameraManager::update(double deltaTime) {
getActiveController().updateCamera(deltaTime, getActiveCamera());
}
}
\ No newline at end of file
#include "vkcv/camera/PilotCameraController.hpp"
#include <GLFW/glfw3.h>
namespace vkcv::camera {
PilotCameraController::PilotCameraController() {
m_forward = false;
m_backward = false;
m_upward = false;
m_downward = false;
m_left = false;
m_right = false;
m_rotationActive = false;
m_cameraSpeed = 2.0f;
m_fov_nsteps = 100;
m_fov_min = 10;
m_fov_max = 120;
}
void PilotCameraController::changeFov(double offset, Camera &camera){
float fov = camera.getFov();
float fov_range = m_fov_max - m_fov_min;
float fov_stepsize = glm::radians(fov_range) / static_cast<float>(m_fov_nsteps);
fov -= (float) offset*fov_stepsize;
if (fov < glm::radians(m_fov_min)) {
fov = glm::radians(m_fov_min);
}
if (fov > glm::radians(m_fov_max)) {
fov = glm::radians(m_fov_max);
}
camera.setFov(fov);
}
void PilotCameraController::panView(double xOffset, double yOffset, Camera &camera) {
// handle yaw rotation
float yaw = camera.getYaw() + xOffset;
if (yaw < -180.0f) {
yaw += 360.0f;
}
else if (yaw > 180.0f) {
yaw -= 360.0f;
}
camera.setYaw(yaw);
// handle pitch rotation
float pitch = camera.getPitch() - yOffset;
if (pitch > 89.0f) {
pitch = 89.0f;
}
if (pitch < -89.0f) {
pitch = -89.0f;
}
camera.setPitch(pitch);
}
constexpr float getDirectionFactor(bool positive, bool negative) {
return static_cast<float>(positive) - static_cast<float>(negative);
}
void PilotCameraController::updateCamera(double deltaTime, Camera &camera) {
glm::vec3 position = camera.getPosition();
const glm::vec3 front = camera.getFront();
const glm::vec3 up = camera.getUp();
const glm::vec3 left = glm::normalize(glm::cross(front, up));
const float distance = m_cameraSpeed * static_cast<float>(deltaTime);
position += distance * getDirectionFactor(m_forward, m_backward) * front;
position += distance * getDirectionFactor(m_left, m_right) * left;
position += distance * getDirectionFactor(m_upward, m_downward) * up;
camera.lookAt(position, position + front, up);
}
void PilotCameraController::keyCallback(int key, int scancode, int action, int mods, Camera &camera) {
switch (key) {
case GLFW_KEY_W:
moveForward(action);
break;
case GLFW_KEY_S:
moveBackward(action);
break;
case GLFW_KEY_A:
moveLeft(action);
break;
case GLFW_KEY_D:
moveRight(action);
break;
case GLFW_KEY_E:
moveUpward(action);
break;
case GLFW_KEY_Q:
moveDownward(action);
break;
default:
break;
}
}
void PilotCameraController::scrollCallback(double offsetX, double offsetY, Camera &camera) {
changeFov(offsetY, camera);
}
void PilotCameraController::mouseMoveCallback(double xoffset, double yoffset, Camera &camera) {
if(!m_rotationActive){
return;
}
float sensitivity = 0.05f;
xoffset *= sensitivity;
yoffset *= sensitivity;
panView(xoffset , yoffset, camera);
}
void PilotCameraController::mouseButtonCallback(int button, int action, int mods, Camera &camera) {
if(button == GLFW_MOUSE_BUTTON_2 && m_rotationActive == false && action == GLFW_PRESS){
m_rotationActive = true;
}
else if(button == GLFW_MOUSE_BUTTON_2 && m_rotationActive == true && action == GLFW_RELEASE){
m_rotationActive = false;
}
}
void PilotCameraController::moveForward(int action){
m_forward = static_cast<bool>(action);
}
void PilotCameraController::moveBackward(int action){
m_backward = static_cast<bool>(action);
}
void PilotCameraController::moveLeft(int action){
m_left = static_cast<bool>(action);
}
void PilotCameraController::moveRight(int action){
m_right = static_cast<bool>(action);
}
void PilotCameraController::moveUpward(int action){
m_upward = static_cast<bool>(action);
}
void PilotCameraController::moveDownward(int action){
m_downward = static_cast<bool>(action);
}
}
\ No newline at end of file
#include "vkcv/camera/TrackballCamera.hpp"
namespace vkcv{
TrackballCamera::TrackballCamera( int width, int height, glm::mat4 projection)
{
setPosition( glm::vec3(0.0f, 0.0f, 5.0) );
m_center = glm::vec3( 0.0f, 0.0f, 0.0f);
m_up = glm::vec3(0.0f, 1.0f, 0.0f);
m_width = width;
m_height = height;
m_sensitivity = 0.010f;
m_stepSize = 0.1f;
m_theta = glm::pi<float>() / 2.0f;
m_phi = 0.f;
m_radius = 1.5;
m_view = glm::lookAt( m_center + getPosition(), m_center, m_up);
m_oldX = width/2.f;
m_oldY = height/2.f;
setProjection(projection);
}
TrackballCamera::TrackballCamera(int width, int height)
{
setPosition( glm::vec3(0.0f, 0.0f, 5.0));
m_center = glm::vec3( 0.0f, 0.0f, 0.0f);
m_up = glm::vec3(0.0f, 1.0f, 0.0f);
m_width = width;
m_height = height;
m_sensitivity = 0.010f;
m_stepSize = 0.1f;
m_theta = glm::pi<float>() / 2.0f;
m_phi = 0.f;
m_radius = 1.5;
m_view = glm::lookAt( m_center + getPosition(), m_center, m_up);
m_oldX = width/2.f;
m_oldY = height/2.f;
m_fov = glm::radians(60.f);
m_ratio = m_width / (float) m_height;
m_near = 0.001f;
m_far = 10.f;
glm::mat4 projection = glm::perspective(m_fov, m_ratio, m_near, m_far);
setProjection(projection);
}
TrackballCamera::~TrackballCamera()
{
}
// TODO: Can be done as events... (mouseMove, mouseDown, mouseUp)
/*void TrackballCamera::update( GLFWwindow* window) {
double x, y;
glfwGetCursorPos( window, &x, &y);
if (glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
{
float changeX = ((float) x - m_oldX) * m_sensitivity;
float changeY = ((float) y - m_oldY) * m_sensitivity;
m_theta -= changeY;
if (m_theta < 0.01f) m_theta = 0.01f;
else if (m_theta > glm::pi<float>() - 0.01f) m_theta = glm::pi<float>() - 0.01f;
m_phi -= changeX;
if (m_phi < 0) m_phi += 2*glm::pi<float>();
else if (m_phi > 2*glm::pi<float>()) m_phi -= 2*glm::pi<float>();
}
m_oldX = (float) x;
m_oldY = (float) y;
if (glfwGetKey( window, GLFW_KEY_UP) == GLFW_PRESS)
m_radius -= m_stepSize;
if (glfwGetKey( window, GLFW_KEY_DOWN) == GLFW_PRESS)
m_radius += m_stepSize;
if (m_radius < 0.1f) m_radius = 0.1f;
m_position.x = m_center.x + m_radius * sin(m_theta) * sin(m_phi);
m_position.y = m_center.y + m_radius * cos(m_theta);
m_position.z = m_center.z + m_radius * sin(m_theta) * cos(m_phi);
m_view = glm::lookAt( m_position, m_center, m_up);
}*/
float TrackballCamera::getSensitivity() const {
return m_sensitivity;
}
void TrackballCamera::setSensitivity(float sensitivity) {
m_sensitivity = sensitivity;
}
float TrackballCamera::getStepSize() const {
return m_stepSize;
}
void TrackballCamera::setStepSize(float stepSize) {
m_stepSize = stepSize;
}
float TrackballCamera::getTheta() const {
return m_theta;
}
void TrackballCamera::setTheta(float theta) {
m_theta = theta;
}
float TrackballCamera::getPhi() const {
return m_phi;
}
void TrackballCamera::setPhi(float phi) {
m_phi = phi;
}
float TrackballCamera::getRadius() const {
return m_radius;
}
void TrackballCamera::setRadius(float radius) {
m_radius = radius;
}
const glm::vec3& TrackballCamera::getCenter() const {
return m_center;
}
void TrackballCamera::setCenter(const glm::vec3 &center) {
m_center = center;
}
}
\ No newline at end of file
#include "vkcv/camera/TrackballCameraController.hpp"
#include <GLFW/glfw3.h>
namespace vkcv::camera {
TrackballCameraController::TrackballCameraController() {
m_rotationActive = false;
m_radius = 3.0f;
m_cameraSpeed = 2.5f;
m_scrollSensitivity = 0.2f;
}
void TrackballCameraController::setRadius(const float radius) {
if (radius < 0.1f) {
m_radius = 0.1f;
}
else {
m_radius = radius;
}
}
void TrackballCameraController::panView(double xOffset, double yOffset, Camera &camera) {
// handle yaw rotation
float yaw = camera.getYaw() + xOffset * m_cameraSpeed;
if (yaw < 0.0f) {
yaw += 360.0f;
}
else if (yaw > 360.0f) {
yaw -= 360.0f;
}
camera.setYaw(yaw);
// handle pitch rotation
float pitch = camera.getPitch() + yOffset * m_cameraSpeed;
if (pitch < 0.0f) {
pitch += 360.0f;
}
else if (pitch > 360.0f) {
pitch -= 360.0f;
}
camera.setPitch(pitch);
}
void TrackballCameraController::updateRadius(double offset, Camera &camera) {
glm::vec3 cameraPosition = camera.getPosition();
glm::vec3 cameraCenter = camera.getCenter();
float radius = glm::length(cameraCenter - cameraPosition); // get current camera radius
setRadius(radius - offset * m_scrollSensitivity);
}
void TrackballCameraController::updateCamera(double deltaTime, Camera &camera) {
float yaw = camera.getYaw();
float pitch = camera.getPitch();
const glm::vec3 yAxis = glm::vec3(0.0f, 1.0f, 0.0f);
const glm::vec3 xAxis = glm::vec3(1.0f, 0.0f, 0.0f);
const glm::mat4 rotationY = glm::rotate(glm::mat4(1.0f), glm::radians(yaw), yAxis);
const glm::mat4 rotationX = glm::rotate(rotationY, -glm::radians(pitch), xAxis);
const glm::vec3 translation = glm::vec3(
rotationX * glm::vec4(0.0f, 0.0f, m_radius, 0.0f)
);
const glm::vec3 center = camera.getCenter();
const glm::vec3 position = center + translation;
const glm::vec3 up = glm::vec3(
rotationX * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f)
);
camera.lookAt(position, center, up);
}
void TrackballCameraController::keyCallback(int key, int scancode, int action, int mods, Camera &camera) {}
void TrackballCameraController::scrollCallback(double offsetX, double offsetY, Camera &camera) {
updateRadius(offsetY, camera);
}
void TrackballCameraController::mouseMoveCallback(double xoffset, double yoffset, Camera &camera) {
if(!m_rotationActive){
return;
}
float sensitivity = 0.05f;
xoffset *= sensitivity;
yoffset *= sensitivity;
panView(xoffset , yoffset, camera);
}
void TrackballCameraController::mouseButtonCallback(int button, int action, int mods, Camera &camera) {
if(button == GLFW_MOUSE_BUTTON_2 && m_rotationActive == false && action == GLFW_PRESS){
m_rotationActive = true;
}
else if(button == GLFW_MOUSE_BUTTON_2 && m_rotationActive == true && action == GLFW_RELEASE){
m_rotationActive = false;
}
}
}
\ No newline at end of file
cmake_minimum_required(VERSION 3.16)
project(vkcv_shader_compiler)
# setting c++ standard for the module
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(vkcv_shader_compiler_source ${PROJECT_SOURCE_DIR}/src)
set(vkcv_shader_compiler_include ${PROJECT_SOURCE_DIR}/include)
# Add source and header files to the module
set(vkcv_shader_compiler_sources
${vkcv_shader_compiler_include}/vkcv/shader/GLSLCompiler.hpp
${vkcv_shader_compiler_source}/vkcv/shader/GLSLCompiler.cpp
)
# adding source files to the module
add_library(vkcv_shader_compiler STATIC ${vkcv_shader_compiler_sources})
# Setup some path variables to load libraries
set(vkcv_shader_compiler_lib lib)
set(vkcv_shader_compiler_lib_path ${PROJECT_SOURCE_DIR}/${vkcv_shader_compiler_lib})
# Check and load GLSLANG
include(config/GLSLANG.cmake)
# link the required libraries to the module
target_link_libraries(vkcv_shader_compiler ${vkcv_shader_compiler_libraries} vkcv)
# including headers of dependencies and the VkCV framework
target_include_directories(vkcv_shader_compiler SYSTEM BEFORE PRIVATE ${vkcv_shader_compiler_includes} ${vkcv_include})
# add the own include directory for public headers
target_include_directories(vkcv_shader_compiler BEFORE PUBLIC ${vkcv_shader_compiler_include})