assimp
安装
参考博客即可。
mesh
mesh对象里包含了顶点位置、法向量、纹理坐标、面和物体的材质
面是指物体的渲染图元(三角形等),包含了组成图元的顶点的索引(EBO)
先定义基本结构体:
点。顶点位置、法线、纹理坐标
纹理。纹理id(后面GenTexture的时候就对这个id生成,所以存好了就行了)、diffuse还是specular、路径(检查是否加载过)
struct Vertex
{
glm::vec3 Position;
glm::vec3 Normal;
glm::vec2 TexCoords;
}
struct Texture
{
unsigned int id;
string type;
aiString path;
}
mesh类包括了所有的渲染操作,它上层的Model类才是对整个模型的调用。
fragmentshader里面,采样器已经写在了结构体material里面,
class Mesh
{
public:
vector<Vertex> vertices;
vector<unsigned int> indices;
vector<Texture> textures;
Mesh(vector<Vertex> vertices, vector<unsigned int> indices, vector<Texture> textures)
{
this->vertices = vertices;
this->indices = indices;
this->textures = textures;
setupMesh();
}
void Draw(Shader shader)
{
unsigned int diffuseNr = 1;
unsigned int specularNr = 1;
for (unsigned int i = 0; i < textures.size(); i++)
{
glActiveTexture(GL_TEXTURE0 + i);
string number;
string name = textures[i].type;
if (name == "texture_diffuse")
{
number = std::to_string(diffuseNr++);
}
if (name == "texture_specular")
number = std::to_string(specularNr++);
shader.setInt(("material." + name + number).c_str(), i);
glBindTexture(GL_TEXTURE_2D, textures[i].id);
}
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
}
setupmesh函数是一种那个只初始化一次的那部分,顶点加载了位置、法线和纹理坐标。
C++的结构体的内存是连续的,直接传入一大列的Vertex结构体的《指针》,就可以完美转化为数据:
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
private:
unsigned int VAO, VBO, EBO;
void setupMesh()
{
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
}
Model
model类包含了Mesh对象vector来遍历存储Mesh们,
unsigned int texture[2];
glGenTextures(2, texture);
int width, height, nrChannels;
unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
if (data)
{
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
//risk no mipmap
stbi_image_free(data);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
data = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);
if (data)
{
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
//risk no mipmap
stbi_image_free(data);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
glActiveTexture(texture[0]);
Cubeshader.setInt("material.texture_diffuse_1", texture[0]);
glActiveTexture(texture[1]);
Cubeshader.setInt("material.texture_diffuse_2", texture[1]);

浙公网安备 33010602011771号