图形管道(pipeline)

9.3 图形管道
9.3.1 pipeline

​ 图形管道是将 3D 坐标转换为 2D 像素,图形管道可以分为两大部分:第一部分将 3D 坐标转换为 2D 坐标,第二部分将 2D 坐标转换为实际的彩色像素。

Vertex Data -----> Vertex SHADER -------->GEOMETRY SHADER ------->RASTERIZATION------>FRAGMENT SHADER -----> TEST AND BLENDING

顶点数据 -------> 顶点着色器 ------------> 几何着色器 ------------> 光栅化 -------->片段着色器----->测试和混合

9.3.2 VBO

​ VBO 是显存中的一片缓冲区域,存放从内存中提交过来的顶点数据。GPU 绘制时,需要对 VBO 中的数据进行解析,以便将数据正确的提交给着色器中对应的属性。

glVertexAttribPointer的作用:GPU 需要知道 VBO 中哪一块数据是某个顶点的坐标,哪一块数据是某个顶点的顶点颜色等,通过调用 glVertexAttribPointer 方法来设置解析规则

(1)使用步骤:

创建缓冲区,绑定对象,设置数据,使用对象,清理数据

具体参考博客:https://blog.csdn.net/qq_36383623/article/details/85123077

//第一步:生成和绑定VBO
unsigned int VBO;
glGenBuffers(1, &VBO);//这里的1表示VBO的数量
glBindBuffer(GL_ARRAY_BUFFER, VBO);//设置属性//第二步:传递顶点数据到 VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//第三步:使用VBO
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0); //启动顶点属性//第四步:清理资源
glDeleteBuffers(0, &VBO);

(2)函数解析

a. glGenBuffersg和lBindBuffer作用:glGenBuffersg在GPU上生成缓冲区对象;glBindBuffer是讲缓冲对象设置为数组缓冲对象;

注意此处VBO是unsigned int类型,是指缓冲区对象的标识符;

b. 设置数据

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

函数作用:数据复制到当前绑定缓冲的函数

第一个参数是目标缓冲的类型:顶点缓冲,成员顶点缓冲

第二个参数指定传输数据的大小

第三个参数是实际数据

第四个参数指定了管理给定的数据:

GL_STATIC_DRAW:数据不会或几乎不会改变。
GL_DYNAMIC_DRAW:数据会被改变很多。
GL_STREAM_DRAW :数据每次绘制时都会改变。

c. 使用VBO:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Position));
glEnableVertexAttribArray(0);
  • 第一个参数顶点属性。使用指定了顶点着色器的位置layout (location = 0)
  • 第一个参数指定顶点属性的大小。顶点属性是一个vec3,因此它由值组成3
  • 第三个参数指定数据类型GL_FLOAT由浮点值组成。
  • 第四个参数指定是否希望数据标准化
  • 第五个参数称为跨步,下一组位置数据是距离大小的 3 倍处,因此float我们将该值指定为步幅。
  • 第六个参数是偏移量,表示数据起始位置
9.3.3 VAO

VBO是为了向GPU传递顶点数据,那么VAO就是为了向GPU解释顶点数据具体参考博客:https://blog.csdn.net/danshiming/article/details/56286880

     unsigned int VBO, VAO;glGenVertexArrays(1, &VAO);//生成1个VAOglGenBuffers(1, &VBO);//生成一个VBO// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);//绑定VBOglBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//将顶点数据传递到VBO// position attribute 位置属性和颜色属性glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);//将当前顶点属性与VBO关联glEnableVertexAttribArray(0);//启动顶点属性// color attributeglVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);
9.3.4 VBO/EBO 和VAO的使用

EBO(Element Buffer Object,元素缓冲区对象)是 OpenGL 中用于存储索引数据的缓冲区对象

VBO/EBO 和VAO 只有在创建缓冲对象是不一样的,后面部分代码是共用的;

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);const char *vertexShaderSource = "#version 330 core\n""layout (location = 0) in vec3 aPos;\n""layout (location = 1) in vec3 aColor;\n""out vec3 ourColor;\n""void main()\n""{\n""   gl_Position = vec4(aPos, 1.0);\n""   ourColor = aColor;\n""}\0";
const char *fragmentShaderSource = "#version 330 core\n""out vec4 FragColor;\n""in vec3 ourColor;\n""void main()\n""{\n""   FragColor = vec4(ourColor, 1.0f);\n""}\n\0";int main()
{glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);if (window == NULL){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}// 创建顶点着色器对象GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);// 检查顶点着色器是否编译成功int success;char infoLog[512];glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;}// 创建片段着色器对象GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glCompileShader(fragmentShader);// 检查片段着色器是否编译成功glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;}// 创建着色器程序GLuint shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);// 检查着色器程序是否链接成功glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success){glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);// 定义三角形的顶点数据float vertices[] = {// 位置             // 颜色0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f, // 右下角-0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f, // 左下角0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f  // 顶部};// 创建并绑定 VAOGLuint VAO, VBO, EBO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glGenBuffers(1, &EBO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);// 设置顶点属性指针glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);// 解绑 VBO 和 VAOglBindBuffer(GL_ARRAY_BUFFER, 0);glBindVertexArray(0);// 渲染循环while (!glfwWindowShouldClose(window)){processInput(window);glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);glUseProgram(shaderProgram);glBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);glBindVertexArray(0);glfwSwapBuffers(window);glfwPollEvents();}// 释放资源glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);glDeleteProgram(shaderProgram);glfwTerminate();return 0;
}void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height);
}void processInput(GLFWwindow *window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}

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

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

相关文章

【文献管理】zotero插件4——获取知网pdf、中文文献识别与目录生成

文章目录 zotero获取知网PDFzotero——中文文献识别&#xff08;茉莉花插件&#xff09;学位论文目录生成 zotero获取知网PDF zotero——中文文献识别&#xff08;茉莉花插件&#xff09; 为下载的学位论文添加目录中文文献识别&#xff1a;jasminum 下载pdflabs下载茉莉花插…

C++——类的6个默认成员函数

目录 类中的6个默认成员函数 构造函数 构造函数的特点 初始化列表 隐式类型转换 析构函数 拷贝构造函数 赋值重载 运算符重载 赋值重载 取地址重载 类中的6个默认成员函数 类中的6个默认成员函数根据不同的作用可以分为&#xff1a; 初始化和使用后清理&#xff1a;…

YOLOv8改进,添加GSConv+Slim Neck,有效提升目标检测效果,代码改进(超详细)

目录 摘要 主要想法 GSConv GSConv代码实现 slim-neck slim-neck代码实现 yaml文件 完整代码分享 总结 摘要 目标检测是计算机视觉中重要的下游任务。对于车载边缘计算平台来说&#xff0c;巨大的模型很难达到实时检测的要求。而且&#xff0c;由大量深度可分离卷积层构…

Java Web(十一)--JSON Ajax

JSON JSon在线文档&#xff1a; JSON 简介 JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。轻量级指的是跟xml做比较。数据交换指的是客户端和服务器之间业务数据的传递格式。 它基于 ECMAScript (W3C制定的JS规范)的一个子集&#xff0c;采…

Stable Cascade发布:比SDXL更快、更强的图像生成模型

前言 StabilityAI在春节期间发布了新的一代文生图模型Stable Cascade&#xff0c;Stable Cascade是基于Wuerstchen架构包含三阶段的文生图扩散模型&#xff0c;为质量、灵活性、微调和效率设定了新的标准&#xff0c;着重于进一步消除硬件障碍。相比Stable Diffusion XL&#…

《Decoupling Representation and Classifier for Long-Tailed Recognition》阅读笔记

论文标题 《Decoupling Representation and Classifier for Long-Tailed Recognition》 用于长尾识别的解耦表示和分类器 作者 Bingyi Kang、Saining Xie、Marcus Rohrbach、Zhicheng Yan、 Albert Gordo、Jiashi Feng 和 Yannis Kalantidis 来自 Facebook AI 和 新加坡国…

Linux笔记--文件权限

一、相关概念 Linux最优秀的地方之一就在于多人多任务环境。为了让各个使用者有较为保密的文件数据&#xff0c;文件的权限管理尤为重要。 ●文件的可存取身份: owner:文件拥有者 group:文件所属用户组 others:其他人 ●文件权限: r: read&#xff0c;读 文件:是否能查看文件内…

如何创建自己的Spring Boot Starter并为其编写单元测试

当我们想要封装一些自定义功能给别人使用的时候&#xff0c;创建Spring Boot Starter的形式是最好的实现方式。如果您还不会构建自己的Spring Boot Starter的话&#xff0c;本文将带你一起创建一个自己的Spring Boot Starter。 快速入门 创建一个新的 Maven 项目。第三方封装的…

Carla自动驾驶仿真八:两种查找CARLA地图坐标点的方法

文章目录 前言一、通过Spectator获取坐标二、通过道路ID获取坐标总结 前言 CARLA没有直接的方法给使用者查找地图坐标点来生成车辆&#xff0c;这里推荐两种实用的方法在特定的地方生成车辆。 一、通过Spectator获取坐标 1、Spectator&#xff08;观察者&#xff09;&#xf…

2W字-35页PDF谈谈自己对QT某些知识点的理解

2W字-35页PDF谈谈自己对QT某些知识点的理解 前言与总结总体知识点的概况一些笔记的概况笔记阅读清单 前言与总结 最近&#xff0c;也在对自己以前做的项目做一个知识点的梳理&#xff0c;发现可能自己以前更多的是用某个控件&#xff0c;以及看官方手册&#xff0c;但是没有更…

springboot + shiro + jwt权限验证

JWT &#xff08;Json Web Token&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;用于在不同系统之间传递安全声明&#xff08;例如身份验证信息&#xff09;的一种紧凑且自包含的方式。是轻量级的、跨平台的、自包含的&#xff08;含有足够的信息&…

深入探究【观察者模式】:简单音乐会售票系统案例分析

文章目录 1.观察者模式概述基本概念&#xff1a;工作原理&#xff1a; 2.案例-音乐会抢票2.1.具体实现2.1.1.被观察者接口2.1.2.被观察者实现类2.1.3.定义观察者接口2.1.3.定义观察者实现类2.1.4.测试观察者 3.总结3.1.优点和局限性3.2.思考 1.观察者模式概述 观察者模式是一种…

如何远程访问内网数据库?

远程访问内网数据库是在安全可靠的前提下&#xff0c;能够实现从外部网络访问内网数据库的一种技术。在现代信息化的背景下&#xff0c;随着企业发展和分布式办公的普及&#xff0c;远程访问内网数据库成为了一项必需的技术。通过远程访问内网数据库&#xff0c;企业可以在不同…

2.3~2.7碎片

P是位置&#xff0c;v是速度

弹窗内容由后端返回,如何让点击按钮的事件交由前端控制?

一、场景 背景&#xff1a;因为系统里经常有新活动或者公告需要通知所有用户&#xff0c;希望前端维护的这个弹窗里的内容可以由后端接口返回。这样就不需要每次上新活动的时候&#xff0c;前端项目都发版了。因此&#xff0c;前端维护了这个弹窗和它的关闭事件&#xff0c;至…

qt5.15 升级 qt 6.5 部分问题 解决修复

报错 QT5_USE_MODULES 升级 QT6_ADD_RESOURCES qt_add_resources Compiles binary resources into source code. CMake Commands in Qt6 Core | Qt Core 6.6.2

用Flutter开发App:助力您的移动业务腾飞

一、Flutter简介 Flutter是Google推出的用于构建多平台应用程序的开源UI框架。它使用Dart语言编写&#xff0c;可以编译为原生机器代码&#xff0c;从而提供卓越的性能和流畅的用户体验。 二、Flutter的优势 一套代码&#xff0c;多平台部署&#xff1a;Flutter可以使用一套代…

《互联网的世界》第二讲-最短路径优先

昨天讲 dns 时讲过&#xff0c;“你问一个当地人最近的厕所在哪&#xff0c;路人给你一个地址…”&#xff0c;可是只有地址还不够&#xff0c;如何到达那里呢&#xff1f;这是本节的内容。 自然的方式是&#xff0c;一边走一边问&#xff0c;根据路人的指示继续一边走一边问…

Redis(理论版)

Redis 1.Redis是什么 Redis其实就是一个数据库&#xff0c;它是一个文档型数据库&#xff08;非关系型数据库&#xff09;,而mysql是一个关系型数据库。它是一个开源的、基于内存的高性能键值存储数据库&#xff0c;支持多种数据结构&#xff0c;广泛用于缓存、消息队列、应用…

德人合科技 | 天锐绿盾终端安全管理系统

德人合科技提到的“天锐绿盾终端安全管理系统”是一款专业的信息安全防泄密软件。这款软件基于核心驱动层&#xff0c;为企业提供信息化防泄密一体化方案。 www.drhchina.com 其主要特点包括&#xff1a; 数据防泄密管理&#xff1a;天锐绿盾终端安全管理系统能够确保数据在创…