컴퓨터 그래픽스/OpenGL

#4 gulender 개발일지 : mesh, model 그리고 assimp 세팅

san10 2024. 5. 12. 16:24

GUI를 만들고, UI에 맞춰 상태 머신을 만들다가 느낀것이..

우선 메쉬를 따로 분리해야 할 것 같았다.

그래야 지금 내가 조작중인 메쉬에 접근해서 뭘 할수 있으니깐..

지금은 vbo, vao, ebo 모두 대충 메인에 박혀있다.

 

그래서 분리하고자 mesh, model 클래스를 만들었다.

class Mesh{
    public:
        Mesh(std::vector<Vertex> vert,
        std::vector<unsigned int> idx,
        std::vector<Texture> tex,
        const GLchar* vertexPath,
        const GLchar* fragPath
        );

        std::vector<Vertex> vertices;
        std::vector<unsigned int> indice;
        std::vector<Texture> textures;
        void Draw();
        void DrawSelected();
        unsigned int GetVBO() const {return mVBO;}

    private:
        void setMesh();
        unsigned int mVAO, mVBO, mEBO;
        bool bVisible;
        Shader mShader;
        
};

 

class Model
{
    public:
        Model(std::string path,const GLchar* vertexPath,const GLchar* fragPath);
        ~Model();
        std::vector<Mesh>* GetMeshes() {return &mMeshes;}
        void Draw();

    private:
        const GLchar* mVertexPath;
        const GLchar* mFragPath;
        std::vector<Mesh> mMeshes;
        std::string mDirectory;
        void loadModel(std::string path);
        void processNode(aiNode *node, const aiScene *scene);
        Mesh processMesh(aiMesh *mesh, const aiScene *scene);

};

 

mesh와 model안의 내용은 learnopengl의 내용과 거의 똑같다.

https://learnopengl.com/Model-Loading/Mesh

 

LearnOpenGL - Mesh

Mesh Model-Loading/Mesh With Assimp we can load many different models into the application, but once loaded they're all stored in Assimp's data structures. What we eventually want is to transform that data to a format that OpenGL understands so that we can

learnopengl.com

learnopenGL아니였음 어떻게 개발했을까..

 

 

Collection

씬에는 여러 메쉬들이 들어가 있고,

이러한 메쉬를 관리해주는 하이어라키가 필요하다

그래서 현재 씬에 있는 메쉬들을 관리해주는 Collection을 만들었다.

class Collection{
    public:
        static Collection* GetInstance();
        Mesh* GetSelectedMesh() const {return mMeshes[mSelected];}

        void SetMesh(Mesh* mesh);
        void SelectMesh(int idx);
        void Rendering();

    private:
        static Collection* instance;
        std::vector<Mesh*> mMeshes;
        int mSelected;

};

왜 이름이 Collection이냐면..

블렌더에서 이런 역할을 하는 것 이름이 Collection이라서 이렇게 지었다

 

그리고 Collection은 싱글톤으로 만들었다.

특성상 접근할 객체들이 많을것 같고..

이정도는 싱글톤 해도 괜찮지 않을까?

 

현재 가지고 있는 메시들을 rendering 해주고,

선택된 메시를 리턴할 수도 있다.

 

 

Assimp

assimp 라이브러리는 모델을 import하거나 export할때 쓰이는 라이브러리다.

이 라이브러리 세팅할때 잘 안되서 삽질좀 했는데

인터넷에 나와있는 거 다 때려박으니 되기는 했다

 

brew로 라이브러리 설치도 하고..

안되서 cmake로 빌드도 해보고..

여기까지 하니깐 include가 된것같긴한데

 

Undefined symbols for architecture x86_64:
  "Assimp::Importer::ReadFile(char const*, unsigned int)", referenced from:

컴파일할때 위와같은 오류가 계속 떴다.

 

아 좀 잘 찾아보라고!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 

해결방안은 tasks.json에 args에

"-lassimp" 를 추가하면 된다

"args": [
        "-fcolor-diagnostics",
        "-fansi-escape-codes",
        "-g",
        "-std=c++11",
        "-std=c++14",
        "-I${workspaceFolder}/include",
        "-L${workspaceFolder}/lib",
        "${workspaceFolder}/libglfw.3.dylib",
        //"/usr/local/lib/libglfw.3.dylib",
        "${workspaceFolder}/src/glad.c",
        "${file}",
        "-o",
        "${fileDirname}/${fileBasenameNoExtension}",
        "-framework",
        "OpenGL",
        "-framework",
        "IOKit",
        "-lglfw3",
        "-L/usr/local/Cellar/assimp/5.4.0/lib/",
        "-lassimp"
    ]

 

여기까지하고

obj파일을 불러오면?

 

3d 모델이 임포트되었다!

 

아직 조명시스템을 안만들어서

노말값을 컬러로 출력하게 해놓아서 저런 무지개빛이다.

 

이제 메쉬를 관리할 수 있게 되었으니

진짜로 상태머신을 만들기로 했다.