欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenGL模型加载之网格

程序员文章站 2022-07-04 09:09:40
...

Mesh.h

#pragma once
#ifndef MESH_H
#define MESH_H
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include "Shader.h"
using namespace std;
struct Vertex {
	glm::vec3 Position;
	glm::vec3 Normal;
	glm::vec2 TexCoords;
	/*glm::vec3 Tangent;
	glm::vec3 Bitanent;*/ //目前用不到的注释掉了
};
struct Texture {
	unsigned int id;
	string type;	//	是漫反射贴图或者是镜面光贴图
	string path;
};
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;

			/*unsigned int normalNr = 1;
			unsigned int heightNr = 1;*/

			for (unsigned int i = 0; i < textures.size(); i++)
			{
				glActiveTexture(GL_TEXTURE0 + i);//在绑定之前**相应的纹理单元
				//获取纹理序号(diffuse_textureN 中的N)
				string number;
				string name = textures[i].type;
				if (name == "texture_diffuse")
					number = std::to_string(diffuseNr++);
				else if (name == "texture_specular")
					number = std::to_string(specularNr++);

				//else if (name == "texture_normal")			//目前不需要注释掉
				//	number = std::to_string(normalNr++);
				//else if (name == "texture_height")
				//	number = std::to_string(heightNr++);

				//shader.setInt(("material." + name + number).c_str(), i);
				glUniform1i(glGetUniformLocation(shader.ID, (name + number).c_str()), i);
				glBindTexture(GL_TEXTURE_2D, textures[i].id);
			}
			glActiveTexture(GL_TEXTURE0);

			//绘制网格
			glBindVertexArray(VAO);
			glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
			glBindVertexArray(0);
		}
	private:
		/*渲染数据*/
		unsigned int VAO, VBO, EBO;
		/*函数*/
		void setupMesh()
		{
			glGenVertexArrays(1, &VAO);
			glGenBuffers(1, &VBO);
			glGenBuffers(1, &EBO);

			glBindVertexArray(VAO);
			glBindBuffer(GL_ARRAY_BUFFER, VBO);

			glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);

			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

			//顶点位置
			glEnableVertexAttribArray(0);
			glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);

			//顶点法线
			glEnableVertexAttribArray(1);
			glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));

			//顶点纹理坐标
			glEnableVertexAttribArray(2);
			glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, TexCoords));
			glBindVertexArray(0);
		}
};
#endif

 

相关标签: OpenGL Mesh