• 和材质和网格(Mesh)一样,所有的场景/模型数据都包含在Scene对象中。Scene对象也包含了场景根节点的引用。
  • 场景的Root node(根节点)可能包含子节点(和其它的节点一样),它会有一系列指向场景对象中mMeshes数组中储存的网格数据的索引。Scene下的mMeshes数组储存了真正的Mesh对象,节点中的mMeshes数组保存的只是场景中网格数组的索引。
  • 一个Mesh对象本身包含了渲染所需要的所有相关数据,像是顶点位置、法向量、纹理坐标、面(Face)和物体的材质。
  • 一个网格包含了多个面。Face代表的是物体的渲染图元(Primitive)(三角形、方形、点)。一个面包含了组成图元的顶点的索引。由于顶点和索引是分开的,使用一个索引缓冲来渲染是非常简单的(见你好,三角形)。
    最后,一个网格也包含了一个Material对象,它包含了一些函数能让我们获取物体的材质属性,比如说颜色和纹理贴图(比如漫反射和镜面光贴图)。

结构:

  • MESH.h代码:注意这里边的setupmesh函数已经取代了VOAset,注意这里边将纹理部分分为绑定纹理放到主文件的构造mesh中和绘制纹理放到mesh文件的Draw中
#pragma once
#ifndef MESH_H
#define MESH_H#include <glad/glad.h> // holds all OpenGL type declarations#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>#include "Shader.h"#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>using namespace std;struct Vertex {// positionglm::vec3 Position;// normalglm::vec3 Normal;// texCoordsglm::vec2 TexCoords;
};struct Texture {unsigned int id;string type;string path;
};class Mesh {public:/*  Mesh Data  */vector<Vertex> vertices;vector<unsigned int> indices;vector<Texture> textures;unsigned int VAO;/*  Functions  */// constructorMesh(vector<Vertex> vertices, vector<unsigned int> indices, vector<Texture> textures){this->vertices = vertices;this->indices = indices;this->textures = textures;// now that we have all the required data, set the vertex buffers and its attribute pointers.setupMesh();}// render the meshvoid Draw(Shader shader){   //加载与绘制纹理unsigned int diffuseNr = 1;unsigned int specularNr = 1;for (unsigned int i = 0; i < textures.size(); i++){glActiveTexture(GL_TEXTURE0 + i); // active proper texture unit before binding// retrieve texture number (the N in diffuse_textureN)//这里要绑定着色器里边的名字string number;string name = textures[i].type;if (name == "texture_diffuse")number = std::to_string((long double)diffuseNr++);else if (name == "texture_specular")number = std::to_string((long double)specularNr++); // transfer unsigned int to stream// now set the sampler to the correct texture unitglUniform1i(glGetUniformLocation(shader.ID, (name + number).c_str()), i);// and finally bind the textureglBindTexture(GL_TEXTURE_2D, textures[i].id);}// draw meshglBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);glBindVertexArray(0);// always good practice to set everything back to defaults once configured.glActiveTexture(GL_TEXTURE0);}private:/*  Render data  */unsigned int VBO, EBO;/*  Functions    */// initializes all the buffer objects/arraysvoid setupMesh()    //取代VAOset{glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glGenBuffers(1, &EBO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);//往显卡写值,分配显存空间GL_STATIC_DRAW表示,值不修改glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);//告诉显卡,值的结构 positionglVertexAttribPointer(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);glEnableVertexAttribArray(0);}
};
#endif

main函数修改:注:1.main函数中while循环里边在画函数之前绑定VAO这个操作因为使用的是glDrawElements函数,所以都不需要了;2.VAOset和texture函数都放到了mesh类当中,其中在创建mesh的时候就已经者加载好了,mesh类中的直接进行纹理绑定

  • main函数的修改:注意没有了vao和texture函数,使用了mesh的draw函数进行纹理绑定并且最终绘制结果
int main() {//初始化GLFWwindow* window = init(); //创建一个窗口指针,因为里边是一个空指针所有init函数必须改变类型//着色    Shader lightShader("lamp.vert", "lamp.frag");Shader cubeShader("cube.vert", "cube.frag");    //使用封装shader类glm::mat4 trans = glm::mat4(1.0f);  //单位矩阵glm::mat4 model = glm::mat4(1.0f);  //模型矩阵:用于物体坐标转化为世界坐标glm::mat4 view = glm::mat4(1.0f);glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);   //防止窗口对鼠标进行拦截//渲染引擎glEnable(GL_DEPTH_TEST);    //打开深度缓存//使用mesh生成一个mesh对象Mesh mesh = processCubeMesh();while (!glfwWindowShouldClose(window)) {    //当需要退出时候退出//因为每一个循环的进入时间不一样,确保推进的距离一样,要用到时间差currentFrame = glfwGetTime();deltaTime = currentFrame - lastFrame;lastFrame = currentFrame;processInput(window); //每个周期都调用键位函数//动态变化摄像机位置float radius = 10.0f;   //半径float camX = sin(glfwGetTime()) * radius;float camZ = cos(glfwGetTime()) * radius;//设置颜色值和透明度,需要链接opengl32库才行glClearColor(0.2f, 0.3f, 0.3f, 0.1f);   //背景glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   //清理颜色或者深度缓存//绘制立方体trans = glm::mat4(1.0f);model = glm::translate(trans, cubePositions[0]);    //只变换位置用来区分不同的立方体model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(1.5f, 3.0f, 0.0f));  //角度(逆向),绕view = camera.GetViewMatrix();glm::mat4 projection;   //投影projection = glm::perspective(glm::radians(camera.fov), 800.0f / 600.0f, 0.1f, 100.0f);  //透视投影:FOV,屏幕长宽比,近,远。cubeShader.useShader();//传值给传送多个矩阵glUniformMatrix4fv(glGetUniformLocation(cubeShader.ID, "projection"), 1, GL_FALSE, glm::value_ptr(projection));glUniformMatrix4fv(glGetUniformLocation(cubeShader.ID, "view"), 1, GL_FALSE, glm::value_ptr(view));glUniformMatrix4fv(glGetUniformLocation(cubeShader.ID, "model"), 1, GL_FALSE, glm::value_ptr(model));glUniform4f(glGetUniformLocation(cubeShader.ID, "lightPos"), cubePositions[1].r, cubePositions[1].g, cubePositions[1].b, 1);   //注意lightposion的三个值,现在是齐次坐标glUniform3f(glGetUniformLocation(cubeShader.ID, "viewPos"), camera.Position.r, camera.Position.g, camera.Position.b);   //观察的方向glUniform3f(glGetUniformLocation(cubeShader.ID, "front"), camera.Front.r, camera.Front.g, camera.Front.b);   //相机朝向的方向glUniform3f(glGetUniformLocation(cubeShader.ID, "objectColor"), 1.0f, 0.5f, 0.31f);glUniform3f(glGetUniformLocation(cubeShader.ID, "lightColor"), 1.0f, 1.0f, 1.0f);//绘制meshmesh.Draw(cubeShader);//绑定第二个立方体model = glm::translate(trans, cubePositions[2]);glUniformMatrix4fv(glGetUniformLocation(cubeShader.ID, "model"), 1, GL_FALSE, glm::value_ptr(model));mesh.Draw(cubeShader);//画第二个立方体//绘制光源trans = glm::mat4(1.0f);model = glm::translate(trans, cubePositions[1]);model = glm::scale(model, glm::vec3(0.2f, 0.2f, 0.2f));trans = projection * view * model;lightShader.useShader();    //注意这是新的useShader了glUniform3f(glGetUniformLocation(lightShader.ID, "lightColor"), 1.0f, 1.0f, 1.0f);glUniformMatrix4fv(glGetUniformLocation(lightShader.ID, "transform"), 1/*个矩阵*/, GL_FALSE,glm::value_ptr(trans));  //设置偏移矩阵mesh.Draw(lightShader);glfwSwapBuffers(window);glfwPollEvents();   //立即处理已经到位的事件,如果没有这个就会一直渲染而不触发事件       }//退出glfwTerminate();return 0;
}
  • 创建初始mesh函数
//创建初始mesh
Mesh processCubeMesh()
{vector<Vertex> Vers;vector<unsigned int> Indis;Vers.reserve(36);Indis.reserve(288);for (int i = 0; i < 288; i++){Indis.push_back(i);}for (int i = 0; i < 36; i++){Vertex vertex;vertex.Position[0] = vertices[i * 8 + 0];vertex.Position[1] = vertices[i * 8 + 1];vertex.Position[2] = vertices[i * 8 + 2];vertex.Normal[0] = vertices[i * 8 + 3];vertex.Normal[1] = vertices[i * 8 + 4];vertex.Normal[2] = vertices[i * 8 + 5];vertex.TexCoords[0] = vertices[i * 8 + 6];vertex.TexCoords[1] = vertices[i * 8 + 7];Vers.push_back(vertex);}vector<Texture> textures;Texture _tex;_tex.id = 1;_tex.type = "texture_diffuse";_tex.path = "container2.png";textures.push_back(_tex);_tex.id = 2;_tex.type = "texture_specular";_tex.path = "container2_specular.png";textures.push_back(_tex);Mesh ourMesh(Vers, Indis, textures);//加载纹理unsigned int texture[16];for (unsigned int i = 0; i < textures.size(); i++){//textures有多少个纹理就加载多少次glGenTextures(1, &texture[i]);int width, height, nrChannels;unsigned char* data;stbi_set_flip_vertically_on_load(true);glBindTexture(GL_TEXTURE_2D, texture[i]);data = stbi_load(textures[i].path.c_str(), &width, &height, &nrChannels, 0);GLenum format;if (nrChannels == 1)format = GL_RED;else if (nrChannels == 3)format = GL_RGB;else if (nrChannels == 4)format = GL_RGBA;glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);glGenerateMipmap(GL_TEXTURE_2D);stbi_image_free(data);}return ourMesh;
}
  • 注意因为在使用mesh的Draw函数中的纹理绑定名字发生了改变所以,立方体的glsl着色器语言当中,所以着色器语言中的传值和用值都要发生改变
//引用
uniform sampler2D texture_diffuse1;
uniform sampler2D texture_specular1;
 //材质光material.ambient = vec3(texture(texture_diffuse1,TexCoords)); material.diffuse = vec3(texture(texture_diffuse1,TexCoords));  //这里使用材质漫反射贴图而不用向量material.specular = vec3(texture(texture_specular1,TexCoords));  //这里使用的是第二个金属反光图片

结果没有发生改变

opengl网格mesh相关推荐

  1. OpenGL 网格Mesh

    OpenGL 网格Mesh 网格Mesh简介 初始化 渲染 网格Mesh简介 通过使用Assimp,我们可以加载不同的模型到程序中,但是载入后它们都被储存为Assimp的数据结构.我们最终仍要将这些数 ...

  2. QT下使用OpenGL渲染Mesh的框架

    说说我的QT下使用OpenGL渲染Mesh的框架 http://www.xpc-yx.com/2015/03/13/%E8%AF%B4%E8%AF%B4%E6%88%91%E7%9A%84qt%E4% ...

  3. 【MATLAB】三维图形绘制 ( 三维平面图 | 二维网格 | meshgrid 函数 | 绘制网格 | mesh 函授 | 绘制平面 | surf 函数 | 绘制等高线 | contour 函数 )

    文章目录 一.二维网格 1.线图 与 平面图 2.meshgrid 函数生成二维网格 二.绘制网格 1.mesh 函数绘制网格 2.代码示例 三.绘制平面 1.surf 函数绘制平面 2.代码示例 四 ...

  4. D3D中的网格(Mesh)

    该教程基于DirectX 8.0 Graphics, 一部分内容由DirectX 8.0 SDK 英文文档翻译而来,一部分是自己工作经验的总结,作者对此享有著作权,读者可任意拷贝和传播,但不包含商业的 ...

  5. 【Shader】网格 Mesh

    Mesh 1. 网格 Mesh 2. Mesh的组成 2.1 Vertex Data 2.2 Topology 2.3 Index data 1. 网格 Mesh Mesh指的就是模型的网格,它决定物 ...

  6. Silvaco TCAD仿真8——网格mesh的意义(举例说明)

    离子注入形成的掺杂分布,不同网格密度产生的效果 网格点稀疏  #启功工艺仿真器 go athena#定义网格 # x:0-1,间距是1.即x方向有1个网格点. # y:0-5,间距是0.1.即y方向有 ...

  7. OpenGL完整教程专栏完整目录

    OpenGL完整教程专栏完整目录 专栏说明如下 专栏目录 专栏说明如下 内容:OpenGL完整教程 数量:314篇博文(2023年2月15日截止) 更新时间至:2023年2月15日(后续加上去的博文, ...

  8. OPenGL 学习笔记之 Mesh 网格知识

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

  9. OpenGL基础27:网格

    一.网格 网格(Mesh):一个模型会由几个子模型/形状组合拼接而成,而模型中的那些子模型/形状就是一个网格,一个网格在OpenGL中是绘制物体的最小单位 从字面上的意思来看就是下面这个东西: 其实差 ...

最新文章

  1. 用例子说明MVC 设计模式(以Objective-C 实现)
  2. java BigDecimal实现精确加减乘除运算
  3. [BZOJ] 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐
  4. 纯CSS无hacks的跨游览器多列布局(转)
  5. 【传统PSTN与互联网通信】
  6. ReactiveCocoa基础
  7. MogoH5+基于Hbuilder做ios真机测试
  8. C数组 奇偶分开,奇前偶后
  9. Windows XP下使用 whoami 命令
  10. 这些你曾深信不疑的大众心理学观点,都是谬论!
  11. linux技术发展方向,linux技术的发展方向有哪些?Linux运维入门
  12. Ignoring invalid timezone passed to Connection
  13. win10进程太多怎么优化_你应该这样用win10(优化篇)
  14. java实现根据高德地图API接口进行地址位置解析,将地址转化为经纬度
  15. 小学生计算机按键分布图,小学生计算器上各种按键的作用
  16. 曼哈顿算法公式_距离计算方法总结 | Public Library of Bioinformatics
  17. Mezzanine user 扩展
  18. 在ubuntu18.04上安装vmware
  19. Elasticsearch之Mapping设置详解
  20. linux 嵌入式汇编 adc,嵌入式Linux ARM汇编(四)——ARM汇编程序设计

热门文章

  1. 怎么在html中加入js,在HTML中怎么引用js?
  2. C++常用命名法与书写规范
  3. utc时间 单位换算_一些时间的概念与区分(UTC、GMT、LT、TAI等)
  4. burpsuite+captcha-killer插件识别图片验证码进行爆破
  5. “量子霸权”道路上的是与非,物理学家如何做到“信达雅”?
  6. Tikz作图教程:pgfplots宏包二维数据可视化的数据导入方法
  7. 小心,别被“免费”忽悠了
  8. 什么是weak symbol?
  9. 人教版初中信息技术电子课本_青岛版初中数学七年级上册电子课本
  10. 狮子、豹、狼-----看管理