qtk/src/qtk/model.h

204 lines
7.6 KiB
C
Raw Normal View History

2021-09-03 16:56:57 +00:00
/*##############################################################################
## Author: Shaun Reed ##
2023-01-02 03:26:58 +00:00
## Legal: All Content (c) 2023 Shaun Reed, all rights reserved ##
## About: Model class for importing with Assimp ##
2021-09-03 16:56:57 +00:00
## From following tutorials on learnopengl.com ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#ifndef QTK_MODEL_H
#define QTK_MODEL_H
2023-01-02 03:26:58 +00:00
// Qt
2021-09-03 16:56:57 +00:00
#include <QOpenGLFunctions>
// Assimp
#include <assimp/postprocess.h>
#include <assimp/scene.h>
2022-11-24 22:26:53 +00:00
#include <assimp/Importer.hpp>
2021-09-03 16:56:57 +00:00
2023-01-02 03:26:58 +00:00
// Qtk
#include "modelmesh.h"
#include "qtkapi.h"
2021-09-03 16:56:57 +00:00
namespace Qtk {
2022-11-26 18:24:38 +00:00
/**
* Model object that has a ModelMesh.
* Top-level object that represents 3D models stored within a scene.
*/
class QTKAPI Model : public Object {
2022-11-24 22:26:53 +00:00
public:
2022-11-26 18:24:38 +00:00
/*************************************************************************
* Typedefs
************************************************************************/
2023-01-02 03:26:58 +00:00
/** ModelManager typedef that will manage global model access. */
2022-11-26 18:24:38 +00:00
typedef QHash<QString, Model *> ModelManager;
/*************************************************************************
* Constructors, Destructors
************************************************************************/
2023-01-02 03:26:58 +00:00
/**
* Constructs a Model
* If no shaders are provided we will use default shaders.
*
* @param name Name to use for the Model's objectName.
* @param path Path to the model to load for construction.
* @param vertexShader Optional path to custom vertex shader.
* @param fragmentShader Optional path to custom fragment shader.
*/
2022-11-24 22:26:53 +00:00
inline Model(
const char * name, const char * path,
const char * vertexShader = ":/model-basic.vert",
const char * fragmentShader = ":/model-basic.frag") :
2023-01-02 03:26:58 +00:00
Object(name, QTK_MODEL),
2022-11-26 18:24:38 +00:00
mModelPath(path), mVertexShader(vertexShader),
mFragmentShader(fragmentShader) {
loadModel(mModelPath);
2022-11-24 22:26:53 +00:00
}
2021-09-03 16:56:57 +00:00
inline ~Model() override { mManager.remove(getName()); }
2021-09-03 16:56:57 +00:00
2022-11-26 18:24:38 +00:00
/*************************************************************************
* Public Methods
************************************************************************/
2023-01-02 03:26:58 +00:00
/**
* Draws the model using attached shader program.
*/
2022-11-24 22:26:53 +00:00
void draw();
2023-01-02 03:26:58 +00:00
/**
* Draws the model using a custom shader program.
*
* @param shader Shader program to use to draw the model.
*/
2022-11-24 22:26:53 +00:00
void draw(QOpenGLShaderProgram & shader);
2021-09-03 16:56:57 +00:00
2022-11-26 18:24:38 +00:00
/**
* Flip a texture associated with this model
*
* @param fileName The name of the texture to flip as it is stored on disk
* @param flipX Flip the texture along the X axis
* @param flipY Flip the texture along the Y axis
*/
2022-11-24 22:26:53 +00:00
void flipTexture(
const std::string & fileName, bool flipX = false, bool flipY = true);
2021-09-03 16:56:57 +00:00
2022-11-26 18:24:38 +00:00
/*************************************************************************
* Setters
************************************************************************/
/**
2023-01-02 03:26:58 +00:00
* Sets a uniform value for each ModelMesh within this Model.
2022-11-26 18:24:38 +00:00
*
* @tparam T The type of the value we are settings
* @param location The uniform location
* @param value The value to assign to the uniform
*/
2023-01-02 03:26:58 +00:00
template <typename T> inline void setUniform(const char * location, T value) {
2022-11-24 22:26:53 +00:00
for(auto & mesh : mMeshes) {
mesh.mProgram->bind();
mesh.mProgram->setUniformValue(location, value);
mesh.mProgram->release();
}
}
2021-09-03 16:56:57 +00:00
2022-11-26 18:24:38 +00:00
/*************************************************************************
* Accessors
************************************************************************/
2022-11-24 22:26:53 +00:00
2022-11-26 18:24:38 +00:00
/**
* Accessor function for retrieving a ModelMesh globally.
* The mesh is retrieved from the mManager private member.
*
* @param name The name of the model to load as it was constructed.
* @return Pointer to the model stored within the scene.
*/
2023-01-02 03:26:58 +00:00
[[nodiscard]] static Model * getInstance(const char * name);
2021-09-03 16:56:57 +00:00
2023-01-02 03:26:58 +00:00
/**
* @return Transform3D attached to this Model.
*/
inline Transform3D & getTransform() { return mTransform; }
2021-09-03 16:56:57 +00:00
2022-11-24 22:26:53 +00:00
private:
2022-11-26 18:24:38 +00:00
/*************************************************************************
* Private Methods
************************************************************************/
/**
* Loads a model in .obj, .fbx, .gltf, and other formats.
* For a full list of formats see assimp documentation:
* https://github.com/assimp/assimp/blob/master/doc/Fileformats.md
*
2023-01-02 03:26:58 +00:00
* Large models should not be loaded into Qt resource system.
2022-11-26 18:24:38 +00:00
* Instead pass an *absolute* path to this function.
* Relative paths will break if Qtk is executed from different locations.
*
* @param path Absolute path to a model in .obj or another format accepted
* by assimp.
*/
2022-11-24 22:26:53 +00:00
void loadModel(const std::string & path);
2022-11-26 18:24:38 +00:00
2023-01-02 03:26:58 +00:00
/**
* Process a node in the model's geometry using Assimp.
*
* @param node The Assimp node to process.
* @param scene The Assimp scene for the loaded model.
*/
2022-11-24 22:26:53 +00:00
void processNode(aiNode * node, const aiScene * scene);
2022-11-26 18:24:38 +00:00
2023-01-02 03:26:58 +00:00
/**
* Process a mesh within a node using Assimp.
*
* @param mesh The Assimp mesh to process.
* @param scene The Assimp scene for the loaded model.
* @return
*/
2022-11-24 22:26:53 +00:00
ModelMesh processMesh(aiMesh * mesh, const aiScene * scene);
2022-11-26 18:24:38 +00:00
2023-01-02 03:26:58 +00:00
/**
* Load a collection of material texture using Assimp.
* This function loads diffuse, specular, and narmal material textures.
* A Mesh may have many of any or all of the texture types above.
* Models can have many Meshes attached.
* This function returns all textures for a single Mesh within a Model.
*
* @param mat Loaded Assimp material.
* @param type Type of the material.
* @param typeName Texture type name in string format.
* @return Collection of all textures for a single ModelMesh.
*/
2022-11-24 22:26:53 +00:00
ModelMesh::Textures loadMaterialTextures(
aiMaterial * mat, aiTextureType type, const std::string & typeName);
2022-11-26 18:24:38 +00:00
2023-01-02 03:26:58 +00:00
/**
* Sorts each mesh in the Model based on distance from the camera.
* This is for efficient drawing in OpenGL by preventing the drawing of
* objects not visible due to being partially or entirely behind another
* object.
*/
void sortModelMeshes();
2021-09-03 16:56:57 +00:00
2022-11-26 18:24:38 +00:00
/*************************************************************************
* Private Members
************************************************************************/
2023-01-02 03:26:58 +00:00
/** Static QHash used to store and access models globally. */
2022-11-26 18:24:38 +00:00
static ModelManager mManager;
2021-09-03 16:56:57 +00:00
2023-01-02 03:26:58 +00:00
/** Container to store N loaded textures for this model. */
2022-11-24 22:26:53 +00:00
ModelMesh::Textures mTexturesLoaded {};
2023-01-02 03:26:58 +00:00
/** Container to store N loaded meshes for this model. */
2022-11-24 22:26:53 +00:00
std::vector<ModelMesh> mMeshes {};
2023-01-02 03:26:58 +00:00
/** The directory this model and it's textures are stored. */
2022-11-24 22:26:53 +00:00
std::string mDirectory {};
2023-01-02 03:26:58 +00:00
/** File names for shaders and 3D model on disk. */
2022-11-26 18:24:38 +00:00
const char *mVertexShader, *mFragmentShader, *mModelPath;
};
2022-11-24 22:26:53 +00:00
} // namespace Qtk
2021-09-03 16:56:57 +00:00
2022-11-24 22:26:53 +00:00
#endif // QTK_MODEL_H