Loading model
介绍
Assimp 一个模型导入库的介绍,通常OpenGL所能用到的最小的渲染单元应该是mesh,一个model由多个mesh组成。
A single mesh is the minimal representation of what we need to draw an object in OpenGL (vertex data, indices and material properties). A model (usually) consists of several meshes.
mesh
初始化
核心是mesh类和几个数据结构体
注意,结构体在cpp内存中是连续的,这是个很重要的点。
比如,这个是等价的:
Vertex vertex;
vertex.Position = glm::vec3(0.2f, 0.4f, 0.6f);
vertex.Normal = glm::vec3(0.0f, 1.0f, 0.0f);
vertex.TexCoords = glm::vec2(1.0f, 0.0f);
// = [0.2f, 0.4f, 0.6f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f];
渲染
核心问题,不知道有多少个texture,我们在mesh.h中实现绘制mesh方法的时候,可以根据texture数组的size和type来确定有多少个什么样子的shader,然后经过字符处理将它传给shader。注意shader中我们可以定义很多texture,但是不一定都用到。。占存储空间吗?
代码
1 | struct Vertex { |
Model
这两天过OpenGL的这个过程中才发现,一个好的设计思路和清晰的思维比代码能力(我指的是编码能力)重要多了,这个的能力基础就是对IO、数据结构、算法、内存、显存、整个架构的正确理解。比如,我们这里要加载模型,根据模型文件的定义,我们核心要处理的是mesh。上一节,mesh搞定了,基于此我们来想model应该做什么:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class Model
{
public:
/* Functions */
Model(char *path)
{
loadModel(path);
}
void Draw(Shader shader);
private:
/* Model Data */
vector<Mesh> meshes;
string directory;
/* Functions */
void loadModel(string path);
void processNode(aiNode *node, const aiScene *scene);
Mesh processMesh(aiMesh *mesh, const aiScene *scene);
vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type,
string typeName);
};
剩下的实现,就是经验的问题了。
加载贴图的优化
这里需要主义的问题是,一个贴图资源,很有可能很多的模型都在用,所以避免重复加载资源或者优化处理比较重要。这是模型加载的性能瓶颈。
怎么解决呢,我们把已经加载的texture在global空间存起来,每次加载前先看是不是已经加载过了。
代码
1 | unsigned int TextureFromFile(const char *path, const string &directory, bool gamma = false); |
整体结构
1 |
|