【LearnOpenGL】11.网格基础

【LearnOpenGL】11.网格基础开发环境Windows 10Visual Studio Community 2022前言当使用建模工具对物体建模的时候,艺术家通常不会用单个形状

大家好,欢迎来到IT知识分享网。

开发环境

  • Windows 10
  • Visual Studio Community 2022

前言

当使用建模工具对物体建模的时候,艺术家通常不会用单个形状创建出整个模型。通常每个模型都由几个子模型/形状组合而成。组合模型的每个单独的形状就叫做一个网格(Mesh)。比如说有一个人形的角色:艺术家通常会将头部、四肢、衣服、武器建模为分开的组件,并将这些网格组合而成的结果表现为最终的模型。一个网格是我们在OpenGL中绘制物体所需的最小单位(顶点数据、索引和材质属性)。一个模型(通常)会包括多个网格。

【LearnOpenGL】11.网格基础

通过使用Assimp,我们可以加载不同的模型到程序中,但是载入后它们都被储存为Assimp的数据结构。我们最终仍要将这些数据转换为OpenGL能够理解的格式,这样才能渲染这个物体。

网格(Mesh)

网格(Mesh)代表的是单个的可绘制实体,一个网格要想被绘制出来,至少需要一系列的顶点,每个顶点最少包含一个位置向量,以及包含用于索引绘制的索引。

我们定义一个最简单的顶点结构:

struct Vertex { glm::vec3 Position; };

网格类的定义:

Mesh.h

class Mesh { public: /// <summary> /// 顶点数组 /// </summary> std::vector<Vertex> vertices; /// <summary> /// 索引数组 /// </summary> std::vector<unsigned int> indices; /// <summary> /// 构造函数 /// </summary> /// <param name="vertices">顶点数组</param> /// <param name="indices">索引数组</param> Mesh(std::vector<Vertex> vertices, std::vector<unsigned int>indices); /// <summary> /// 绑定(绘制) /// </summary> void Bind() const; /// <summary> /// 解绑(清理) /// </summary> void Unbind() const; private: unsigned int m_VBO, m_IBO; void setupMesh(); };

Mesh.cpp

Mesh::Mesh(std::vector<Vertex> vertices, std::vector<unsigned int>indices) { this->vertices = vertices; this->indices = indices; setupMesh(); } void Mesh::setupMesh() { // 顶点缓存对象 glGenBuffers(1, &m_VBO); glBindBuffer(GL_ARRAY_BUFFER, m_VBO); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); // 索引缓存对象 glGenBuffers(1, &m_IBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO); 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); } void Mesh::Bind() const { // 绘制网格 glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); } void Mesh::Unbind() const { // 删除缓存对象 glDeleteBuffers(1, &m_VBO); glDeleteBuffers(1, &m_IBO); }

项目实例

1.新建一个C++项目:11_Mesh,并设置为启动项目。

2.配置项目环境

  • 配置 GLFW:参考【LearnOpenGL】01.创建窗口
  • 配置 GLEW:参考【LearnOpenGL】03.配置GLEW
  • 导入 glm 库
  • 导入 stb_image 库
  • 配置 Assimp:参考【LearnOpenGL】10.Assimp构建和导入
  • 拷贝 Shader 类
  • 拷贝 Texture2D 类

3.文件结构

【LearnOpenGL】11.网格基础

主函数

简单的绘制一个由2个三角形组成的长方形:

#include <GL/glew.h> #include <GLFW/glfw3.h> #include <iostream> #include "src/Mesh.h" #include <vector> const unsigned int screen_width = 640; const unsigned int screen_height = 480; Mesh* mesh; void init() { // 顶点数据 std::vector<Vertex> vertices = { {glm::vec3(-0.5f, -0.5f, 0.0f)}, {glm::vec3(-0.5f, 0.5f, 0.0f)}, {glm::vec3( 0.5f, 0.5f, 0.0f)}, {glm::vec3( 0.5f, -0.5f, 0.0f)} }; // 绘制顶点的顺序 std::vector<unsigned int> indices = { 0, 1, 2, // 第一个三角形的顶点数组下标 2, 0, 3 // 第二个三角形的顶点数组下标 }; mesh = new Mesh(vertices, indices); } void display() { // 绘制 mesh->Bind(); } void clear() { mesh->Unbind(); } // main int main(void) { GLFWwindow* window; /* Initialize the library */ if (!glfwInit()) return -1; /* Create a windowed mode window and its OpenGL context */ window = glfwCreateWindow(screen_width, screen_height, "Mesh", NULL, NULL); if (!window) { glfwTerminate(); return -1; } /* Make the window's context current */ glfwMakeContextCurrent(window); // glew init if (glewInit() != GLEW_OK) { std::cout << "glew init error!" << std::endl; } // print opengl version std::cout << "OpenGL version :" << glGetString(GL_VERSION) << std::endl; /* init */ init(); /* Loop until the user closes the window */ while (!glfwWindowShouldClose(window)) { /* Render here */ glClear(GL_COLOR_BUFFER_BIT); /* display */ display(); /* Swap front and back buffers */ glfwSwapBuffers(window); /* Poll for and process events */ glfwPollEvents(); } glfwTerminate(); /* clear */ clear(); return 0; }

运行结果:

【LearnOpenGL】11.网格基础

从代码上看,我们把处理顶点数据都封装在Mesh类的setupMesh方法中,使得主函数代码更新简洁清晰。

GitHub[作揖]

https://github.com/zGameDeveloper/LearnOpenGL/tree/main/Project/11_Mesh

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/78730.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信