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]);
posted @ 2022-08-20 11:21  IamIron-Man  阅读(250)  评论(0)    收藏  举报