LearnOpenGL(十三)之网格

news2024/11/22 13:58:34

一、网格

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

一个网格应该至少需要一系列的顶点,每个顶点包含一个位置向量、一个法向量和一个纹理坐标向量。一个网格还应该包含用于索引绘制的索引以及纹理形式的材质数据(漫反射/镜面光贴图)。

在OpenGL中定义一个顶点:

struct Vertex {
    glm::vec3 Position;
    glm::vec3 Normal;
    glm::vec2 TexCoords;
};

我们将所有需要的向量储存到一个叫做Vertex的结构体中,我们可以用它来索引每个顶点属性。除了Vertex结构体之外,我们还需要将纹理数据整理到一个Texture结构体中。

struct Texture {
    unsigned int id;//纹理的id
    string type; //类型, 漫反射贴图 or 镜面光贴图
};

网格类的结构:

class Mesh {
    public:
        /*  网格数据  */
        vector<Vertex> vertices;
        vector<unsigned int> indices;
        vector<Texture> textures;
        /*  函数  */
        Mesh(vector<Vertex> vertices, vector<unsigned int> indices, vector<Texture> textures);
        void Draw(Shader shader);
    private:
        /*  渲染数据  */
        unsigned int VAO, VBO, EBO;
        /*  函数  */
        void setupMesh();
}; 

构造函数Mesh的实现:

Mesh(vector<Vertex> vertices, vector<unsigned int> indices, vector<Texture> textures)
{
    this->vertices = vertices;
    this->indices = indices;
    this->textures = textures;

    setupMesh();
}

setupMesh函数的实现:

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);
}  

渲染Draw代码如下:

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); // 在绑定之前激活相应的纹理单元
        // 获取纹理序号(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++);

        shader.setInt(("material." + 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);
}

demo下载:点击跳转

觉得有帮助的话,打赏一下呗。。

           

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1672637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android Compose 三:切换主题

1 先瞅瞅lightColorScheme / darkColorScheme 创建项目后 自带一个Theme.kt 判断了 使用哪个ColorScheme 下面看看LightColorScheme &#xff08;亮/暗主题差不多&#xff0c;就是颜色不一样罢了&#xff09; private val LightColorScheme lightColorScheme(primary Pur…

StackQueue+泛型简单理解

&#x1f341; 个人主页&#xff1a;爱编程的Tom&#x1f4ab; 本篇博文收录专栏&#xff1a;Java专栏&#x1f449; 目前其它专栏&#xff1a;c系列小游戏 c语言系列--万物的开始_ &#x1f389; 欢迎 &#x1f44d;点赞✍评论⭐收藏&#x1f496;三连支持一…

网络安全快速入门(十一)vi/vim

11.1 了解vi 前面我i们已经在基础命令中大致了解了vi&#xff0c;本章我们针对vi来细讲一下&#xff0c;vi和vim 11.1.1 什么是vi/vim&#xff1f; vi和vim&#xff0c;都是一个模块化的文本编辑工具&#xff0c;换句话讲&#xff0c;通过vi下的一系列的命令&#xff0c;可以实…

群晖NAS本地搭建Bitwarden密码管理服务并实现远程同步密码托管

文章目录 1. 拉取Bitwarden镜像2. 运行Bitwarden镜像3. 本地访问4. 群晖安装Cpolar5. 配置公网地址6. 公网访问Bitwarden7. 固定公网地址8. 浏览器密码托管设置 Bitwarden是一个密码管理器应用程序&#xff0c;适用于在多个设备和浏览器之间同步密码。自建密码管理软件bitwarde…

如何用时尚新姿讲好中国品牌故事?

品牌建设在推动高质量发展中扮演了双重角色&#xff0c;既是高质量发展的重要“承载者”&#xff0c;也是强有力的“助推器”。5月10日-11日&#xff0c;中国时尚品牌URBAN REVIVO&#xff08;以下简称UR&#xff09;以中国品牌日为起点&#xff0c;联合天猫超级品牌日&#xf…

paddle ocr v4 2.6.1实战笔记

目录 效果图&#xff1a; 安装 模型权重是自动下载&#xff0c;如果提前下载会报错。 识别orc&#xff0c;并opencv可视化结果&#xff0c;支持中文可视化 官方原版预测可视化&#xff1a; 效果图&#xff1a; 安装 安装2.5.2识别结果为空 pip install paddlepaddle-gpu…

操作系统实战(三)(linux+C语言实现)

实验目的 加深对进程调度概念的理解&#xff0c;体验进程调度机制的功能&#xff0c;了解Linux系统中进程调度策略的使用方法。 练习进程调度算法的编程和调试技术。 实验说明 1.在linux系统中调度策略分为3种 SCHED_OTHER&#xff1a;默认的分时调度策略&#xff0c;值为0…

弹幕播放器源码

下 载 地 址 &#xff1a; runruncode.com/php/19761.html 1. 将弹幕播放器的源码上传到服务器。 2. 通过访问你的域名/dmku/install/index.php来进行弹幕库的安装。 3. 修改播放器后台的密码&#xff0c;配置文件为/config.php&#xff0c;并配置json接口。 4. 后台账号为…

国内环境也可以开发好玩的LLM应用 - 环境准备篇

在开发基于LLM(大语言模型)的AI应用前, 我们首先要准备好必要的环境. 主要就是Python环境以及大模型应用开发部署环境. 01 Python开发环境准备 Python开发环境有如下四种, 根据个人喜好选其一即可: 本地安装Python及IDE, 适合学习测试开发; 本地安装Python环境, 使用Jupyter …

享元模式详解

享元模式 1 概述 定义&#xff1a; ​ 运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似对象的开销&#xff0c;从而提高系统资源的利用率。 2 结构 享元&#xff08;Flyweight &#xff09;模式中存…

【卫星影像三维重建-全流程代码实现】点云Mesh重构

点云—>Mesh模型 1.介绍1.1 背景1.2 效果示意 2 算法实现2.1 依赖库2.2 实验数据2.3 代码实现2.4 实验效果 3.总结 1.介绍 1.1 背景 &#xff08;1&#xff09;本文主要内容是将三维点云&#xff08;离散的三维点&#xff09;进行表面重建生成Mesh网格&#xff0c;之前有篇…

UIKit常用API:Transform

需求 使用Transform系列的API&#xff0c;该API中提供了旋转、平移等功能。其中函数中带make的效果是只变化一次&#xff0c;不带make可变化多次。此外&#xff0c;还有恢复函数&#xff1a;CGAffineTransformIdentity。 代码实现 注意按钮绑定的是同一个响应事件&#xff0…

【AIGC】Mac Intel 本地 LLM 部署经验汇总(CPU Only)

书接上文&#xff0c;在《【AIGC】本地部署 ollama(gguf) 与项目整合》章节的最后&#xff0c;我在 ollama 中部署 qwen1_5-14b-chat-q4_k_m.gguf 预量化模型&#xff0c;在非 Stream 模式下需要 89 秒才完成一轮问答&#xff0c;响应速度实在是太慢&#xff0c;后续需要想办法…

Qt与QWebEngineView 交互-调试窗口-JS拓扑图完整示例参考

1&#xff1a;介绍&#xff1a; Qt与QWebEngineView的交互 简介之前文章解释过&#xff0c;链接在下面 传送门&#xff1a;Qt与QWebEngineView 交互完整示例参考_qt qwebview-CSDN博客 一般在使用这种方式时&#xff0c;可能会出现各种问题而不好调试&#xff0c;如果能够像…

【C++】继承相关(基类与派生类的继承关系以及细节整理)

目录 00.引言 01.继承的定义 02.基类和派生类对象 03.继承中的作用域 04.派生类的默认成员函数 05.友元、静态成员 00.引言 继承是面向对象编程中的一个重要概念&#xff0c;它的作用是创建一个新的类&#xff0c;该类可以从一个已存在的类&#xff08;父类/基类&#x…

sipeed 的 MaixCam显示图片

WiFi联网后&#xff0c;把固件升级到最新 一根tpyc-c连接线为MaixCam供电&#xff0c;点击液晶屏settings 在WiFi中设置确保联网&#xff0c;在更新MaixPy中升级固件 可以选择国内源加速&#xff0c;将固件升级到最新版 MaixVision的操作 1&#xff0c;在MaixVision左下角…

谷歌Gboard应用的语言模型创新:提升打字体验的隐私保护技术

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

C语言 | Leetcode C语言题解之第87题扰乱字符串

题目&#xff1a; 题解&#xff1a; struct HashTable {int key;int val;UT_hash_handle hh; };void modifyHashTable(struct HashTable** hashTable, int x, int inc) {struct HashTable* tmp;HASH_FIND_INT(*hashTable, &x, tmp);if (tmp NULL) {tmp malloc(sizeof(st…

【数据结构与算法 刷题系列】合并两个有序链表

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;数据结构与算法刷题系列&#xff08;C语言&#xff09; 目录 一、问题描述 二、解题思路详解 合并两个有序链表的思路 解题的步…

HTML飘落的花瓣

目录 写在前面 HTML​​​​​​​简介 完整代码 代码分析 系列推荐 写在最后 写在前面 本期小编给大家推荐HTML实现的飘落的花瓣&#xff0c;无需安装软件&#xff0c;直接下载即可打开~ HTML​​​​​​​简介 HTML&#xff08;Hypertext Markup Language&#xff…