Modern OpenGL 3.x 及更高版本如何绘制图元?

Posted

技术标签:

【中文标题】Modern OpenGL 3.x 及更高版本如何绘制图元?【英文标题】:How does Modern OpenGL 3.x and above draw primitives? 【发布时间】:2011-10-14 22:53:33 【问题描述】:

我必须使用 OpenGL (3.3, 4.2) 绘制大量图元,我知道使用 glutSolidTeapot() ;我可以用 glut 画一个茶壶图元。

但是这个命令好像不会生成顶点数组,不知道这种命令有没有被弃用。

而且我注意到许多现代 OpenGL 教程只是加载他们自己的图元并避免只使用 glut,他们甚至从 3d 网格格式文件加载简单的几何图形。

我的目的是尽可能快地绘制这些图元。并尽可能多地使用新的 OpenGL。

那么如何在现代 OpenGL 中绘制图元?

【问题讨论】:

那么如何从 glut 中的图元中获取顶点缓冲区? 弹出打开 GLUT 源代码并将函数转换为吐出顶点而不是绘图。 【参考方案1】:

由于 GLUT(以任何方式不是 OpenGL 的一部分)使用即时模式 glBegin/glEnd 并使用已弃用的固定函数内置属性绘制其基元,因此您将无法使用如果您想专注于未弃用的现代核心功能,这些不再是了。

除了使用内置属性(如glVertexglNormal、...),您必须使用自己的通用顶点属性(当然要结合适当的顶点着色器)而不是glBegin/glEnd调用您必须使用由 VBO 提供的顶点数组来绘制图元,并使用 glDrawArrays/glDrawElements 及其衍生物进行绘制。

虽然没有什么可以阻止您将这些对象的顶点数据作为变量存储在源代码中或手动生成它们,但从文件中加载它们是最简单和最通用的方法,至少对于像犹他茶壶这样相当复杂的对象而言. Wavefront OBJ format 是一种相当简单的基于 ASCII 的网格文件格式,非常易于阅读,可能是研究的起点,因为它几乎可以通过任何建模软件导出。

【讨论】:

但是 glut 在原语上的准确性如何?我注意到如果从 fbx 或 obj 文件加载一个球体,将会有超过 50 行... @tomriddle_1234:这 50 行处理文件 I/O 解析、创建缓冲区等。实际上 50 行相当短。绘制立方体很容易。仅使用 C++ 代码绘制 UV 球体,而不是从我在此处解释的文件中加载:***.com/questions/5988686/… GLUT 茶壶以类似的方式创建(评估参数补丁)。 @tomriddle_1234:到目前为止,我只是为那个 SO 答案写下了这个球体生成代码。但是,我正在考虑为 OpenGL 编写一个小型、简单的基元库。无论如何,立方体非常简单,圆柱体和圆锥体是直截了当的。茶壶是最复杂的,因为它需要评估参数曲面。您可以查看 GLUT 源代码以了解它是如何完成的。 我从这里bitbucket.org/alfonse/gltut/downloads 找到了很多单元原语,他编写了一些lua 脚本来生成单元原语xml 文件。他创建了自己的格式,加载起来很复杂但并不难,而且非常方便【参考方案2】:

使用新的(非弃用)OpenGL 标准进行渲染只能通过使用着色器来完成。

Shader 属性只能是缓冲区对象。

简而言之,客户端内存不是一组指定顶点位置、颜色、纹理坐标等的数组,而是您必须将它们上传到缓冲区对象中。

【讨论】:

在哪里可以找到这些带有 3d 模型文件的单元对象并轻松加载它们?如果我想要不同级别的细分怎么办

以上是关于Modern OpenGL 3.x 及更高版本如何绘制图元?的主要内容,如果未能解决你的问题,请参考以下文章

处理新版本 Android(3.x 及更高版本)中缺少的 MENU 按钮

有关为 iOS 6.0 及更高版本安排睡眠/唤醒设备的信息在哪里?

Modern OpenGL - 顶点数组、属性与绑定点(OpenGL 4.5+)

如何在 android 2.3 及更高版本中获取当前启动器的包名?

在 Java 11 及更高版本中使用 HttpClient 时如何跟踪 HTTP 303 状态代码?

如何使用支持库 25.0.0 及更高版本获取片段()