Added transformables
This commit is contained in:
parent
98425f45c8
commit
f86fcad89f
|
@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.10)
|
|||
|
||||
project(OpenGLUtility)
|
||||
|
||||
# set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
set(build_examples ON CACHE BOOL "Build examples")
|
||||
set(build_documentation ON CACHE BOOL "Generate documentation")
|
||||
|
||||
|
@ -26,7 +28,7 @@ add_library(openglu SHARED
|
|||
${include_files}
|
||||
${source_files}
|
||||
"cpp.hint"
|
||||
)
|
||||
"src/transformable.cpp")
|
||||
|
||||
target_compile_definitions(openglu PRIVATE OGLU_BUILD_DLL)
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "openglu.hpp"
|
||||
#include "transformable.hpp"
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
|
@ -79,16 +83,32 @@ int main(int argc, char** argv)
|
|||
oglu::Texture crate = oglu::MakeTexture("assets/crate.jpg");
|
||||
oglu::Texture opengl = oglu::MakeTexture("assets/opengl.png");
|
||||
|
||||
oglu::Transformable model;
|
||||
//model.SetRotation(-55.0f, 0.0f, 0.0f);
|
||||
|
||||
glm::mat4 view = glm::mat4(1.0f);
|
||||
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
|
||||
|
||||
glm::mat4 projection;
|
||||
projection = glm::perspective(glm::radians(45.f), 1.0f, 0.1f, 100.0f);
|
||||
|
||||
glm::mat4 test = glm::make_mat4(model.GetMatrix());
|
||||
|
||||
// Window loop
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
processInput(window);
|
||||
|
||||
oglu::ClearScreen(GL_COLOR_BUFFER_BIT, oglu::Color(0.29f, 0.13f, 0.23f));
|
||||
oglu::ClearScreen(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, oglu::Color(0.29f, 0.13f, 0.23f));
|
||||
|
||||
model.Rotate(6.0f, 0.0f, 0.0f);
|
||||
|
||||
shader->Use();
|
||||
shader->SetUniform("texture1", crate, 0);
|
||||
shader->SetUniform("texture2", opengl, 1);
|
||||
shader->SetUniformMatrix4fv("model", 1, GL_FALSE, model.GetMatrix());
|
||||
shader->SetUniformMatrix4fv("view", 1, GL_FALSE, glm::value_ptr(view));
|
||||
shader->SetUniformMatrix4fv("projection", 1, GL_FALSE, glm::value_ptr(projection));
|
||||
|
||||
square->BindAndDraw();
|
||||
|
||||
|
|
|
@ -6,9 +6,13 @@ layout (location = 2) in vec2 aUV;
|
|||
out vec3 oCol;
|
||||
out vec2 oUV;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
oCol = aCol;
|
||||
oUV = aUV;
|
||||
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
}
|
248
include/transformable.hpp
Normal file
248
include/transformable.hpp
Normal file
|
@ -0,0 +1,248 @@
|
|||
/*****************************************************************//**
|
||||
* \file transformable.hpp
|
||||
* \brief Contains utility for anything that has a geometry
|
||||
*
|
||||
* \author Lauchmelder
|
||||
* \date January 2021
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef TRANSFORMABLE_HPP
|
||||
#define TRANSFORMABLE_HPP
|
||||
|
||||
#include <core.hpp>
|
||||
|
||||
namespace oglu
|
||||
{
|
||||
/**
|
||||
* @brief Defines position, rotation and scale.
|
||||
*
|
||||
* This class wraps a 4x4 transformation matrix and provides useful
|
||||
* helper functions to perform translations, rotations and scalings.
|
||||
*/
|
||||
class OGLU_API Transformable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create new identity transformation.
|
||||
*
|
||||
* An identity transformation is a matrix with all 1's on the diagonal.
|
||||
* When applied to a vector it leaves it unchanged.
|
||||
*/
|
||||
Transformable();
|
||||
|
||||
/**
|
||||
* @brief Copies another transformation.
|
||||
*
|
||||
* The transformation matrix of @p other is copied.
|
||||
*/
|
||||
Transformable(const Transformable& other);
|
||||
~Transformable();
|
||||
|
||||
/**
|
||||
* @brief Sets the position.
|
||||
*
|
||||
* This sets an absolute position, means that it resets any previous
|
||||
* translations.
|
||||
*
|
||||
* @param[in] x New x position
|
||||
* @param[in] y New y position
|
||||
* @param[in] z New z position
|
||||
*/
|
||||
void SetPosition(float x, float y, float z);
|
||||
|
||||
/**
|
||||
* @brief Sets the position.
|
||||
*
|
||||
* This sets an absolute position, means that it resets any previous
|
||||
* translations.
|
||||
*
|
||||
* @param[in] position An array of floats containing three scalars
|
||||
*/
|
||||
void SetPosition(const float* translation);
|
||||
|
||||
/**
|
||||
* @brief Sets the rotation.
|
||||
*
|
||||
* This sets an absolute rotation, means that it resets any previous
|
||||
* rotations.
|
||||
*
|
||||
* @param[in] rotX New rotation around x axis
|
||||
* @param[in] rotY New rotation around y axis
|
||||
* @param[in] rotZ New rotation around z axis
|
||||
*/
|
||||
void SetRotation(float rotX, float rotY, float rotZ);
|
||||
|
||||
/**
|
||||
* @brief Sets the rotation.
|
||||
*
|
||||
* This sets an absolute rotation, means that it resets any previous
|
||||
* rotations.
|
||||
*
|
||||
* @param[in] rotation An array of floats containing three scalars
|
||||
*/
|
||||
void SetRotation(const float* rotation);
|
||||
|
||||
/**
|
||||
* @brief Sets the rotation.
|
||||
*
|
||||
* This sets an absolute rotation, means that it resets any previous
|
||||
* rotations.
|
||||
*
|
||||
* @param[in] angle The angle to rotate by
|
||||
* @param[in] xAxis The x component of the rotation axis
|
||||
* @param[in] yAxis The y component of the rotation axis
|
||||
* @param[in] zAxis The z component of the rotation axis
|
||||
*/
|
||||
void SetRotation(float angle, float xAxis, float yAxis, float zAxis);
|
||||
|
||||
/**
|
||||
* @brief Sets the rotation.
|
||||
*
|
||||
* This sets an absolute rotation, means that it resets any previous
|
||||
* rotations.
|
||||
*
|
||||
* @param[in] angle The angle to rotate by
|
||||
* @param[in] axis An array of floats containing the three rotation axis components
|
||||
*/
|
||||
void SetRotation(float angle, const float* axis);
|
||||
|
||||
/**
|
||||
* @brief Sets the scaling.
|
||||
*
|
||||
* This sets an absolute scaling, means that it resets any previous
|
||||
* scaling.
|
||||
*
|
||||
* @param[in] scaleX The scaling in x direction
|
||||
* @param[in] scaleY The scaling in y direction
|
||||
* @param[in] scaleZ The scaling in z direction
|
||||
*/
|
||||
void SetScale(float scaleX, float scaleY, float scaleZ);
|
||||
|
||||
/**
|
||||
* @brief Sets the scaling.
|
||||
*
|
||||
* This sets an absolute scaling, means that it resets any previous
|
||||
* scaling.
|
||||
*
|
||||
* @param[in] scale An array of floats containing three scalars
|
||||
*/
|
||||
void SetScale(const float* scale);
|
||||
|
||||
/**
|
||||
* @brief Performs a translation.
|
||||
*
|
||||
* This function applies a translation to the object, it operates
|
||||
* operates on the current position.
|
||||
*
|
||||
* @param[in] x Offset along the x axis
|
||||
* @param[in] y Offset along the y axis
|
||||
* @param[in] z Offset along the z axis
|
||||
*/
|
||||
void Move(float x, float y, float z);
|
||||
|
||||
/**
|
||||
* @brief Performs a translation.
|
||||
*
|
||||
* This function applies a translation to the object, it operates
|
||||
* operates on the current position.
|
||||
*
|
||||
* @param[in] position An array of floats containing the offset values
|
||||
*/
|
||||
void Move(const float* translation);
|
||||
|
||||
/**
|
||||
* @brief Performs a rotation.
|
||||
*
|
||||
* This function applies a rotation to the object, it operates
|
||||
* operates on the current rotation.
|
||||
*
|
||||
* @param[in] rotX Rotation around the x axis
|
||||
* @param[in] rotY Rotation around the y axis
|
||||
* @param[in] rotZ Rotation around the z axis
|
||||
*/
|
||||
void Rotate(float rotX, float rotY, float rotZ);
|
||||
|
||||
/**
|
||||
* @brief Performs a rotation.
|
||||
*
|
||||
* This function applies a rotation to the object, it operates
|
||||
* operates on the current rotation.
|
||||
*
|
||||
* @param[in] rotation An array of floats containing the rotation values
|
||||
*/
|
||||
void Rotate(const float* rotation);
|
||||
|
||||
/**
|
||||
* @brief Performs a rotation.
|
||||
*
|
||||
* This function applies a rotation to the object, it operates
|
||||
* operates on the current rotation.
|
||||
*
|
||||
* @param[in] angle The angle to rotate by
|
||||
* @param[in] xAxis x component of the rotation axis
|
||||
* @param[in] yAxis y component of the rotation axis
|
||||
* @param[in] zAxis z component of the rotation axis
|
||||
*/
|
||||
void Rotate(float angle, float xAxis, float yAxis, float zAxis);
|
||||
|
||||
/**
|
||||
* @brief Performs a rotation.
|
||||
*
|
||||
* This function applies a rotation to the object, it operates
|
||||
* operates on the current rotation.
|
||||
*
|
||||
* @param[in] angle The angle to rotate by
|
||||
* @param[in] An array of floats containing the components of the rotation axis
|
||||
*/
|
||||
void Rotate(float angle, const float* axis);
|
||||
|
||||
/**
|
||||
* @brief Performs scaling.
|
||||
*
|
||||
* This function applies scaling to the object, it operates
|
||||
* operates on the current scaling.
|
||||
*
|
||||
* @param[in] scaleX Scaling in x direction
|
||||
* @param[in] scaleX Scaling in y direction
|
||||
* @param[in] scaleX Scaling in z direction
|
||||
*/
|
||||
void Scale(float scaleX, float scaleY, float scaleZ);
|
||||
|
||||
/**
|
||||
* @brief Performs scaling.
|
||||
*
|
||||
* This function applies scaling to the object, it operates
|
||||
* operates on the current scaling.
|
||||
*
|
||||
* @param[in] scale An array of floats containing three scaling values
|
||||
*/
|
||||
void Scale(const float* scale);
|
||||
|
||||
/**
|
||||
* @brief Returns a transformation matrix.
|
||||
*
|
||||
* Internally, this function multiplies the translation, rotation,
|
||||
* and scaling matrices into one transformation matrix which is
|
||||
* then returned.
|
||||
*
|
||||
* This multiplication is only performed when a change occured to one
|
||||
* of those matrices (so when there was a translation, rotation or scaling).
|
||||
* So it is okay to call this function multiple times without huge performance
|
||||
* loss, as long as no transformations occur inbetween.
|
||||
*
|
||||
* @return An array of 16 floats representing the transformation matrix
|
||||
*/
|
||||
const float* GetMatrix();
|
||||
|
||||
private:
|
||||
// TODO: Separate translation, rotation and scaling matrices.
|
||||
// Combine them only when the user wants the transformation matrix
|
||||
float* translation; ///< Translation matrix
|
||||
float* rotation; ///< Rotation matrix
|
||||
float* scaling; ///< Scaling matrix
|
||||
|
||||
bool calculateMatrix; ///< Wether GetMatrix() needs to re-calculate the transformation matrix
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
267
src/transformable.cpp
Normal file
267
src/transformable.cpp
Normal file
|
@ -0,0 +1,267 @@
|
|||
#include "transformable.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
namespace oglu
|
||||
{
|
||||
oglu::Transformable::Transformable() :
|
||||
translation(new float[16]), rotation(new float[16]), scaling(new float[16]), calculateMatrix(false)
|
||||
{
|
||||
glm::mat4 identity(1.0f);
|
||||
memcpy(
|
||||
translation,
|
||||
glm::value_ptr(identity),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
memcpy(
|
||||
rotation,
|
||||
glm::value_ptr(identity),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
memcpy(
|
||||
scaling,
|
||||
glm::value_ptr(identity),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
}
|
||||
|
||||
Transformable::Transformable(const Transformable& other) :
|
||||
translation(new float[16]), rotation(new float[16]), scaling(new float[16]), calculateMatrix(true)
|
||||
{
|
||||
memcpy(
|
||||
this->translation,
|
||||
other.translation,
|
||||
16 * sizeof(float)
|
||||
);
|
||||
|
||||
memcpy(
|
||||
this->rotation,
|
||||
other.rotation,
|
||||
16 * sizeof(float)
|
||||
);
|
||||
|
||||
memcpy(
|
||||
this->scaling,
|
||||
other.scaling,
|
||||
16 * sizeof(float)
|
||||
);
|
||||
}
|
||||
|
||||
Transformable::~Transformable()
|
||||
{
|
||||
delete[] scaling;
|
||||
delete[] rotation;
|
||||
delete[] translation;
|
||||
}
|
||||
|
||||
void Transformable::SetPosition(float x, float y, float z)
|
||||
{
|
||||
memcpy(
|
||||
this->translation,
|
||||
glm::value_ptr(glm::translate(glm::mat4(1.0f), glm::vec3(x, y, z))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::SetPosition(const float* translation)
|
||||
{
|
||||
memcpy(
|
||||
this->translation,
|
||||
glm::value_ptr(glm::translate(glm::mat4(1.0f), glm::make_vec3(translation))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::SetRotation(float rotX, float rotY, float rotZ)
|
||||
{
|
||||
// TODO: Using rotation matrices is stupid. Eventually this could (should) be done with quaternions
|
||||
// For now we'll just risk gimbal locking the model
|
||||
memcpy(
|
||||
this->rotation,
|
||||
glm::value_ptr(
|
||||
glm::rotate(
|
||||
glm::rotate(
|
||||
glm::rotate(
|
||||
glm::mat4(1.0f), glm::radians(rotX), glm::vec3(1.0f, 0.0f, 0.0f)
|
||||
), glm::radians(rotY), glm::vec3(0.0f, 1.0f, 0.0f)
|
||||
), glm::radians(rotZ), glm::vec3(0.0f, 0.0f, 1.0f)
|
||||
)
|
||||
),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::SetRotation(const float* rotation)
|
||||
{
|
||||
memcpy(
|
||||
this->rotation,
|
||||
glm::value_ptr(
|
||||
glm::rotate(
|
||||
glm::rotate(
|
||||
glm::rotate(
|
||||
glm::mat4(1.0f), glm::radians(rotation[0]), glm::vec3(1.0f, 0.0f, 0.0f)
|
||||
), glm::radians(rotation[1]), glm::vec3(0.0f, 1.0f, 0.0f)
|
||||
), glm::radians(rotation[2]), glm::vec3(0.0f, 0.0f, 1.0f)
|
||||
)
|
||||
),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::SetRotation(float angle, float xAxis, float yAxis, float zAxis)
|
||||
{
|
||||
memcpy(
|
||||
this->rotation,
|
||||
glm::value_ptr(glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::vec3(xAxis, yAxis, zAxis))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::SetRotation(float angle, const float* axis)
|
||||
{
|
||||
memcpy(
|
||||
this->rotation,
|
||||
glm::value_ptr(glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::make_vec3(axis))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::SetScale(float scaleX, float scaleY, float scaleZ)
|
||||
{
|
||||
memcpy(
|
||||
this->scaling,
|
||||
glm::value_ptr(glm::scale(glm::mat4(1.0f), glm::vec3(scaleX, scaleY, scaleZ))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::SetScale(const float* scale)
|
||||
{
|
||||
memcpy(
|
||||
this->scaling,
|
||||
glm::value_ptr(glm::scale(glm::mat4(1.0f), glm::make_vec3(scale))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::Move(float x, float y, float z)
|
||||
{
|
||||
memcpy(
|
||||
this->translation,
|
||||
glm::value_ptr(glm::translate(glm::make_mat4(this->translation), glm::vec3(x, y, z))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::Move(const float* translation)
|
||||
{
|
||||
memcpy(
|
||||
this->translation,
|
||||
glm::value_ptr(glm::translate(glm::make_mat4(this->translation), glm::make_vec3(translation))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::Rotate(float rotX, float rotY, float rotZ)
|
||||
{
|
||||
memcpy(
|
||||
this->rotation,
|
||||
glm::value_ptr(
|
||||
glm::rotate(
|
||||
glm::rotate(
|
||||
glm::rotate(
|
||||
glm::make_mat4(this->rotation), glm::radians(rotX), glm::vec3(1.0f, 0.0f, 0.0f)
|
||||
), glm::radians(rotY), glm::vec3(0.0f, 1.0f, 0.0f)
|
||||
), glm::radians(rotZ), glm::vec3(0.0f, 0.0f, 1.0f)
|
||||
)
|
||||
),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::Rotate(const float* rotation)
|
||||
{
|
||||
memcpy(
|
||||
this->rotation,
|
||||
glm::value_ptr(
|
||||
glm::rotate(
|
||||
glm::rotate(
|
||||
glm::rotate(
|
||||
glm::make_mat4(this->rotation), glm::radians(rotation[0]), glm::vec3(1.0f, 0.0f, 0.0f)
|
||||
), glm::radians(rotation[1]), glm::vec3(0.0f, 1.0f, 0.0f)
|
||||
), glm::radians(rotation[2]), glm::vec3(0.0f, 0.0f, 1.0f)
|
||||
)
|
||||
),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::Rotate(float angle, float xAxis, float yAxis, float zAxis)
|
||||
{
|
||||
memcpy(
|
||||
this->rotation,
|
||||
glm::value_ptr(glm::rotate(glm::make_mat4(this->rotation), glm::radians(angle), glm::vec3(xAxis, yAxis, zAxis))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::Rotate(float angle, const float* axis)
|
||||
{
|
||||
memcpy(
|
||||
this->rotation,
|
||||
glm::value_ptr(glm::rotate(glm::make_mat4(this->rotation), glm::radians(angle), glm::make_vec3(axis))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::Scale(float scaleX, float scaleY, float scaleZ)
|
||||
{
|
||||
memcpy(
|
||||
this->scaling,
|
||||
glm::value_ptr(glm::scale(glm::make_mat4(this->scaling), glm::vec3(scaleX, scaleY, scaleZ))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
void Transformable::Scale(const float* scale)
|
||||
{
|
||||
memcpy(
|
||||
this->scaling,
|
||||
glm::value_ptr(glm::translate(glm::make_mat4(this->scaling), glm::make_vec3(scale))),
|
||||
16 * sizeof(float)
|
||||
);
|
||||
calculateMatrix = true;
|
||||
}
|
||||
|
||||
const float* Transformable::GetMatrix()
|
||||
{
|
||||
static glm::mat4 transformation(1.0f);
|
||||
|
||||
if (calculateMatrix)
|
||||
{
|
||||
transformation = glm::make_mat4(translation) * glm::make_mat4(rotation) * glm::make_mat4(scaling);
|
||||
calculateMatrix = false;
|
||||
}
|
||||
|
||||
return glm::value_ptr(transformation);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue