【openGL入门(一)】

openGL入门(一)

  • OpenGL(Open Graphics Library)
  • GLAD & GLFW
  • 通过代码片段滤清流程
    • 1. 画面绘制基础
    • 2.VAO,VBO,EBO
      • (1) VAO : Vertex Array Object
      • (2) VBO: Vertex Buffer Object
      • EBO:Element Buffer Object
  • 总结


OpenGL(Open Graphics Library)

OpenGL,图形绘制接口通常用于3D渲染需求中,多数平台如移动终端,PC端,web端都支持(Webgl是Opengl的子集)。有初学者想要整体了解如何使用C++调用Opengl接口绘制图形,以及渲染管线流程等可以参考入口.本文结合基本的绘制逻辑以及常见问题,用于记录和分享开发时基本逻辑和常见问题。

GLAD & GLFW

GLFW:它提供了创建和管理窗口的功能、一系列处理用户输入的函数,跨平台且与Opengl完美集成,为开发者提供一个绘制空间和窗口(既开发者绘制的图形都会在GLFW初始化的窗口中展示出来)且使用方便。
GLAD:GLAD 简单来说可以使开发者轻松初始化Opengl,加载函数指针,并快速进入到VAO,VBO,shaderlab等的开发流程中。

通过代码片段滤清流程

opengl不论对于2D绘制还是3D绘制,都是通过对模型物体的描述,最终通过计算,将坐标空间转换到屏幕空间,并在计算好的像素点上展示不同的颜色。

1. 画面绘制基础

首先我们需要创建一个窗口,这个窗口作为图形绘制的载体,最终将开发者使用Opengl绘制的图像绘制在窗口中。

	//初始化glfw库glfwInit();// 下面着三行代码表示制定了opengl的版本,其中GLFW_OPENGL_CORE_PROFILE 更是确定了使用Opengl的核心模式// 这种模式指定主要是为了明确版本和剔除不必要的引入。glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//创建代码如下,设置了windows的宽高,窗口名称GLFWwindow* window = glfwCreateWindow(800, 600, "title", NULL, NULL);

上述代码指定opengl版本,确定使用核心模式,并创建了展示绘制结果的窗口,那么后续按照逻辑,开发者需要:
(1) 能够使用Opengl指定版本的接口
(2) 能够让结果绘制到窗口中。
首先我们来解决(2):

glfwMakeContextCurrent(window);

此函数使得当前操作的上下文结果都关于window,也就是可以将数据正确地绘制到window上。
再解决问题(1):

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}

此方法执行成功将加载Opengl所有的函数指针,既接下来开发者需要使用到的,绘制图形的各种接口,如果不初始化,您将遇到类似如下的问题:
在这里插入图片描述
归根结底是因为开发者没有加载函数指针,再后续又操作了函数指针,所以会出错。

以上便是常规的初始化行为,如果是在项目中,会更加的结构化,但是流程基本是一致的,初始化后,开发者便可以进入真正的Opengl图形绘制流程。

2.VAO,VBO,EBO

(1) VAO : Vertex Array Object

顶点数组对象,是对顶点属性配置的一种封装,VAO本身是一个Handler,其代表着对开发者提供的数组对象的内部数据,为Gpu解释如何拆分Buffer中的数据,简单直接地说,就是您拥有如下一组数据:

    float vertices[] = {// positions          // colors           // texture coords0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right-0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left-0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left };

那么通过对多维数组地注释标记,我们将数据从意识上分成了三大组类别数据,如何告知Gpu呢,既通过VAO告知:
(1)生成VAO
(2) 使用 glVertexAttribPointer 对多维数组进行竖向分割,举例如上:八个float数据分成三组,(3,3,2)分别为position,colors and texture.
具体的代码如下:

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);// color attributeglVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);// texture coord attributeglVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));glEnableVertexAttribArray(2);

需要注意的是,在使用过程中glVertexAttribPointer & glEnableVertexAttribArray 往往绑定在一起使用,真是项目中我们往往会做二次封装。这里不在解释参数含义。

(2) VBO: Vertex Buffer Object

VBO是在GPU内存中存储顶点数据的对象,也就是GPU真正操作的Gpu内存块真正相关的缓存块,它负责将顶点数据Copy给GPU,VBO与VAO:一个是负责数据供给,一个负责告诉Gpu如何解释块内数据。

	glGenBuffers(1, &VBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

可以观察到,不同于VAO,VBO使用glBufferData 直接关联到具体的数组数据,buffer<-> vertices,GL_STATIC_DRAW 这个宏是告知Gpu这组数据在后续不会变化。

EBO:Element Buffer Object

元素缓冲对象,也叫索引缓冲对象,有个前提,在Gpu绘制数据时,不论是平面模型还是3D模型,三角形是最小单位,而且如果接触过各类游戏引擎,也可以发现,在模型上,经常提到的减面,就是减少构成模型的三角形数量,从而提高绘制效率,但也降低了模型精细度。那么EBO可以指定重复利用的index,如果您像绘制一个矩形,不如使用两个三角形拼接:

    unsigned int indices[] = {0, 1, 3, // first triangle1, 2, 3  // second triangle};glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

indices的数据指代最开始vertices数组中的index,通过使用GL_ELEMENT_ARRAY_BUFFER 绑定buffer,也就是告知Gpu如何利用VBO中的数据,使用两个三角形便可绘制出一个矩形。(这样的设计更具有通用性)。


总结

朴素的讲,VAO EBO 都服务于VBO,VBO是真正的cpu 与gpu之间的数据中介,有了顶点数据,也告知了gpu如何解析数据,后续该通过渲染管线实际操作,将想要绘制的数据绘制到窗口中。

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

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

相关文章

DAY2 C++基础补充

作业1&#xff1a; 已知一个数组table,用宏定义求出数组元素的个数。 #define NUM sizeof(table)/sizeof(table[0]) 作业2&#xff1a; 嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a&#xff0c;写两段代码&#xff0c;第一个设置a的bit3&#xff0c;第…

图像滤波和卷积的不同及MATLAB应用实例

滤波与卷积在图像处理中都是非常重要的运算&#xff0c;但它们有着明显的区别。以下是滤波与卷积的主要不同点&#xff0c;并附带一个MATLAB实例来展示两者在图像处理中的效果差异。 一、滤波与卷积的不同 定义与目的&#xff1a; 1&#xff09;滤波&#xff1a;滤波是一种信…

SpringBoot整合knife4j,以及会遇到的一些bug

这篇文章主要讲解了“Spring Boot集成接口管理工具Knife4j怎么用”&#xff0c;文中的讲解内容简单清晰&#xff0c;易于学习与理解&#xff0c;下面请大家跟着小编的思路慢慢深入&#xff0c;一起来研究和学习“Spring Boot集成接口管理工具Knife4j怎么用”吧&#xff01; 一…

回归任务与分类任务应用及评价指标

能源系统中的回归任务与分类任务应用及评价指标 一、回归任务应用1.1 能源系统中的回归任务应用1.1.1 能源消耗预测1.1.2 负荷预测1.1.3 电池健康状态估计&#xff08;SOH预测&#xff09;1.1.4 太阳能发电量预测1.1.5 风能发电量预测 1.2 回归任务中的评价指标1.2.1 RMSE&…

在Ubuntu上使用IntelliJ IDEA:开启你的Java开发之旅!

你好&#xff0c;年轻的学徒&#xff01;&#x1f9d1;‍&#x1f4bb; 是时候踏上进入Java开发世界的史诗之旅了&#xff0c;我们的得力助手将是强大的IntelliJ IDEA。准备好了吗&#xff1f;出发吧&#xff01; 在我们开始之前&#xff0c;我们需要下载这个工具。但是&#…

Burp入门(7)-APP抓包

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址&#xff1a;burpsuite(5)web网页端抓包与app渗透测试_哔哩哔哩_bilibili 本文详细介绍如何使用burp suite去抓取APP的数据包。 一、安装 Burp 的 CA 证书 1…

【AI+网络/仿真数据集】1分钟搭建云原生端到端5G网络

导语&#xff1a; 近期智慧网络开放创新平台上线了端到端网络仿真能力&#xff0c;区别于传统的网络仿真工具需要复杂的领域知识可界面操作&#xff0c;该平台的网络仿真能力主打一个小白友好和功能专业。 https://jiutian.10086.cn/open/​jiutian.10086.cn/open/ 端到端仿…

学习实验室—招投标实务

在如今业务为王的市场竞争中&#xff0c;招投标的成功率不仅仅取决于方案的质量&#xff0c;更多的是一些“隐形”的诀窍和经验。许多成功的背后&#xff0c;往往隐藏着那些别人不愿提及的细节与技巧。突破盲点&#xff0c;往往意味着“知道与不知道”的差距。 今天&#xff0…

ElasticSearch7.8学习笔记

1. ElasticSearch概述 1.1 ElasticSearch是什么 Elaticsearch&#xff0c;简称为 ES&#xff0c;ES 是一个开源的高扩展的分布式全文搜索引擎&#xff0c;是整个Elastic Stack 技术栈的核心。它可以近乎实时的存储、检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到…

AI生成不了复杂前端页面?也许有解决方案了

在2024年&#xff0c;编程成为了人工智能领域最热门的赛道。AI编程技术正以惊人的速度进步&#xff0c;但在生成前端页面方面&#xff0c;AI的能力还是饱受质疑。自从ScriptEcho平台上线以来&#xff0c;我们收到了不少用户的反馈&#xff0c;他们表示&#xff1a;“生成的页面…

k8s部署odoo18(kubeshpere面板)

Postgresql部署 链接: kubesphere搭建 postgres15 因为我的是在另一台服务器使用kubesphere进行部署的&#xff0c;如果有和我一样情况的&#xff0c;可以参考上面的文档部署postgreasql。 注意事项&#xff1a; 因为odoo不允许使用postgresql的默认用户&#xff0c;也就是po…

友思特方案 | 精密制程的光影贴合:半导体制造中的高功率紫外光源

导读 为新能源锂电行业赋能第四站&#xff1a;半导体制造中的高功率紫外光源&#xff01;稳定输出、灵活控制的曝光设备是新能源/半导体行业高端生产中减少误差、提高效率的核心技术&#xff0c;友思特 ALE 系列 UV LED 紫外光源集合6大优势&#xff0c;为精密制造的健康发展提…

数据结构 (36)各种排序方法的综合比较

一、常见排序方法分类 插入排序类 直接插入排序&#xff1a;通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。希尔排序&#xff1a;是插入排序的一种改进版本&#xff0c;先将整个待排序的记录序列分割成为…

Datawhale AI冬令营 ——如何定制自己的专属大模型?

定制一个自己的专属大模型最方便的步骤 ≈ 指定数据集 开源大模型 微调平台&#xff08;如讯飞星辰Maas&#xff09; 内容很开门&#xff01;very goo(&#xffe3;▽&#xffe3;)&#xff44;&#xff01; 下面我将演示如何用讯飞星辰Maas平台甄嬛数据集构建Chat-嬛嬛。 …

03_Webpack模块打包工具

03_Webpack模块打包工具 目录 知识点自测 以下哪个选项是 ECMAScript 默认导出和导入的语法&#xff1f; A&#xff1a;export 和 require B&#xff1a;module.exports {} 和 import 变量名 C&#xff1a;export default 和 import 变量名 D&#xff1a;export 和 import {…

使用WebStorm开发Vue3项目

记录一下使用WebStorm开发Vu3项目时的配置 现在WebStorm可以个人免费使用啦&#xff01;?? 基本配置 打包工具&#xff1a;Vite 前端框架&#xff1a;ElementPlus 开发语言&#xff1a;Vue3、TypeScript、Sass 代码检查&#xff1a;ESLint、Prettier IDE&#xff1a;WebSt…

阿里云 云产品流转(实现设备与小程序交互)

一、准备工作 1、设备接入平台 创建两个设备接入到对应产品中&#xff0c;具体可以参考这里&#xff08;点击跳转&#xff09;。 二、云产品流转设置 在物联网平台下-->消息转发-->云产品流转->数据源 1、数据源 数据源-->创建数据源-->填写信息-->确定&…

【AIGC】如何获取ChatGPT外部GPTs应用的提示词Prompt指令和知识库文件

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AIGC | GPTs应用实例 文章目录 &#x1f4af;前言&#x1f4af;获取GPTs的提示词Prompt指令&#x1f4af;获取GPTs的知识库文件&#x1f4af;小结 关于GPTs指令如何在ChatGPT上使用&#xff0c;请看这篇文章&#xff…

沐风老师3DMAX摄相机阵列插件使用方法

3DMAX摄相机阵列插件&#xff0c;从网格对象或样条线的顶点法线快速创建摄相机阵列。该插件从网格的顶点或样条线的节点获取每个摄影机的位置和方向。 3DMAX摄相机阵列插件支持目前3dMax主流的物理相机、标准相机、VRay物理相机。 【版本要求】 3dMax 2015及更高版本 【安装方…

BMC VPD格式定义

1.说明 目前遇到有2种格式的VPD定义方式&#xff0c;特记录并分享出来。 本节可参考链接下载文件: https://gitee.com/wit_yuan/fru 2.参考PCI_Express_Base_6.0a.pdf 应用范围: 例如常见的定制raid卡&#xff0c;Hba卡采用的储存serial number等。 3.参考platform-manag…