/*############################################################################## ## Author: Shaun Reed ## ## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## ## About: Model classes for importing with Assimp ## ## From following tutorials on learnopengl.com ## ## ## ## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## ##############################################################################*/ #ifndef QTK_MODEL_H #define QTK_MODEL_H // QT #include #include #include #include #include #include #include // Assimp #include #include #include // QTK #include struct ModelVertex { QVector3D mPosition; QVector3D mNormal; QVector3D mTangent; QVector3D mBitangent; QVector2D mTextureCoord; }; struct ModelTexture { GLuint mID; QOpenGLTexture * mTexture; std::string mType; std::string mPath; }; class Model; class ModelMesh : protected QOpenGLFunctions { public: friend Model; typedef std::vector Vertices; typedef std::vector Indices; typedef std::vector Textures; // Constructors, Destructors ModelMesh(Vertices vertices, Indices indices, Textures textures, const char * vertexShader=":/model-basic.vert", const char * fragmentShader=":/model-basic.frag") : mProgram(new QOpenGLShaderProgram), mVAO(new QOpenGLVertexArrayObject), mVBO(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)), mEBO(new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer)), mVertices(std::move(vertices)), mIndices(std::move(indices)), mTextures(std::move(textures)) { initMesh(vertexShader, fragmentShader);} ~ModelMesh() {} private: void initMesh(const char * vert, const char * frag); // ModelMesh Private Members QOpenGLBuffer * mVBO, * mEBO; QOpenGLVertexArrayObject * mVAO; QOpenGLShaderProgram * mProgram; public: inline void draw() { draw(*mProgram);} void draw(QOpenGLShaderProgram & shader); // ModelMesh Public Members Vertices mVertices; Indices mIndices; Textures mTextures; Transform3D mTransform; }; class Model : public QObject { Q_OBJECT public: inline Model(const char * name, const char * path, const char * vertexShader=":/model-basic.vert", const char * fragmentShader=":/model-basic.frag") : mName(name), mVertexShader(vertexShader), mFragmentShader(fragmentShader) { loadModel(path);} inline ~Model() { mManager.remove(mName);} void draw(); void draw(QOpenGLShaderProgram & shader); void flipTexture(const std::string & fileName, bool flipX=false, bool flipY=true); template void setUniform(const char * location, T value) { for (auto & mesh : mMeshes) { mesh.mProgram->bind(); mesh.mProgram->setUniformValue(location, value); mesh.mProgram->release(); } } Transform3D mTransform; static Model * getInstance(const char * name); typedef QHash ModelManager; private: static ModelManager mManager; void loadModel(const std::string & path); void processNode(aiNode * node, const aiScene * scene); ModelMesh processMesh(aiMesh * mesh, const aiScene * scene); ModelMesh::Textures loadMaterialTextures(aiMaterial * mat, aiTextureType type, const std::string & typeName); void sortModels(); // Model Private Members ModelMesh::Textures mTexturesLoaded; std::vector mMeshes; std::string mDirectory; const char * mVertexShader, * mFragmentShader, * mName; }; #endif // QTK_MODEL_H