为什么OpenGL最初要设计成状态机?[关闭]

2024-03-13

在我的 OpenGL 体验中,我经常忘记设置一些状态。所以我认为状态机在今天可能不是一个好的设计。但现在它必须兼容。而且我还知道DirectX早期也是一个状态机。我想知道为什么OpenGL和DirectX最初被设计为状态机?


当人们提到“状态机”时,并不清楚他们的意思是什么,因为他们从不解释相反的是什么。因此,我将从 OpenGL“状态机”与当前 D3D“非状态机”的角度来一般性和具体地讨论它。

OpenGL 和 Direct3D 都使用全局状态。每个渲染命令都需要您设置一堆状态。

为了在这两个 API 中进行渲染,您必须设置一堆全局状态。您必须设置要使用的着色器。您必须设置要使用这些制服的当前参数。如果您使用纹理,则需要对其进行设置。您需要设置当前视口参数。等等。

的原因this某种“状态机”很简单:这就是硬件通常的工作方式。

每个状态位代表 GPU 中的一些寄存器。那些寄存器是状态。需要加载着色器才能渲染。您需要设置视口寄存器。您需要设置您正在使用的纹理寻址寄存器。等等。因此,API 是状态机,因为GPU是一个状态机。

You could想象一下这将通过渲染命令来完成。但只要看看您需要传递多少个对象即可。你必须传递一堆着色器、一堆纹理、顶点数据、帧缓冲区、视口设置、混合设置等。

因此,API 让您执行 GPU 执行的操作。你事先设置好所有这些东西。

另外,这使得 APIfaster。为什么?因为现在 API 知道您正在使用什么状态。例如,如果您想使用不同的纹理渲染一个网格的不同部分,则可以保持帧缓冲区、视口、顶点数据等全部相同。它们之间唯一需要更改的是使用哪些纹理。

如果您使用某种带有数十个参数的大型绘制调用,那么现在 API 必须查看每个参数以查看它是否与您上次绘制调用相同。如果不是,则必须更新 GPU 寄存器。

现在来说说OpenGL和D3D的区别。在这种情况下,问题的区别在于他们如何对待对象。

D3D 是基于对象的,因为修改对象的函数将对象作为参数。此外,大多数 D3D 对象都是不可变的;一旦创建它们,您就无法更改它们的大部分设置。一旦创建了特定尺寸、格式等的纹理,就完成了。如果不删除对象并创建新对象,则无法使用不同的大小/格式/等重新分配它。

OpenGL 是基于状态的。这意味着(大多数情况下)修改对象的 OpenGL 函数不会将其操作的对象作为参数。

这与其说是一种“设计”,不如说是 OpenGL 严格遵守向后兼容性。 OpenGL 中的对象只是全局状态的片段;这就是它们的定义方式。为什么?

因为最初,早在 OpenGL 1.0 中,没有物体(除了显示列表)。是的,甚至没有纹理对象。当他们认为这是愚蠢的并且他们需要对象时,他们决定以向后兼容的方式实现它们。每个人都已经在使用在全局状态下运行的函数。所以他们只是说通过绑定一个对象,你可以覆盖全局状态。那些曾经改变全局状态的函数现在改变对象的状态。

通过这种方式,他们可以将对象引入 API,而无需引入一堆仅适用于对象的新函数。因此,以前工作的代码只需进行非常小的调整就可以处理对象,而不是强制对代码进行重要的重写。这也意味着,如果他们需要引入新的纹理功能,他们会使用and没有物体。因此,它既向后又向前兼容。

大多数 OpenGL 对象都是这样工作的 http://www.opengl.org/wiki/OpenGL_Object:如果你想改变它们,你必须绑定它们,然后修改“全局”状态。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么OpenGL最初要设计成状态机?[关闭] 的相关文章

  • NV_path_rendering替代方案[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我刚刚观看了 Siggraph 2012 的一个非常令人印象深刻的演示 http nvidia fullviewmedia com sig
  • 为什么OpenGL使用float而不是double? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 当 OpenGL 中同时绑定 1D 和 2D 纹理时,正确的行为是什么?

    假设你有这样的东西 glBindTexture GL TEXTURE 2D my2dTex glBindTexture GL TEXTURE 1D my1dTex glBegin 正确的 OpenGL 行为是什么 要绘制一维纹理 二维纹理还
  • 将带有 glut 的点击坐标添加到向量链接列表中

    我想创建一个向量链接列表 并在 GLUT 库的帮助下获取点击的位置并将它们附加到链接列表中 这些是我写的结构 typedef struct vector int x int y Vector typedef struct VectorLis
  • Glew+GLFW Win32 无依赖项 Visual Studio

    是否可以在不将文件复制到 C 的情况下构建并链接 Glew 和 GLFW 我找不到任何说明如何在不将 DLL 复制到 C 上的 Visual Studio 目录的情况下使用这些库的文档 我只想包含项目目录中所需的所有 dll 和 lib 文
  • 如何仅剪切剪切平面的交集(而不是并集)?

    在 OpenGL JOGL 中 当使用多个剪切平面时 似乎会应用所有剪切平面的并集 我想要的是路口要应用的所有剪裁平面 这可能吗 请参阅下面的简化二维示例 Edit An example of clipping by vertex shad
  • 在 OpenGL 中只使用纹理的 Alpha 通道?

    嘿 我正在尝试将恒定颜色绘制到帧缓冲区 并使用 RGBA 纹理中的 Alpha 通道将其混合 我一直在研究 glBlendFunc 和 glBlendColor 但似乎无法找到忽略纹理中的 RGB 值的方法 我想我必须自己提取 alpha
  • 编译 GLUI 库,VS2010 给我一个奇怪的命名空间错误

    我有一个针对我所在班级的 OpenGL 项目 它基于 GLUI 提供的 GLUI 库无法工作 这就是我尝试自己编译它的原因 因此 我从 SourceForge 下载了源代码并尝试编译 glui 库 它给了我这个 但我找不到任何相关信息 1
  • 在windows + opengl中选择图形设备

    我知道如何使用 openGL 打开窗口 使用 Win32 或其他工具包 但是当系统有2块显卡时 如何选择要渲染的图形设备 我的编程语言是 C 我专注于 Windows 但任何示例都将受到欢迎 编辑 也许更好地解释我的问题是个好主意 以便添加
  • 纹理的内部格式

    看下面的OpenGL函数 void glTexImage2D GLenum target GLint level GLint internalFormat GLsizei width GLsizei height GLint border
  • 帧缓冲区和在 opengl 中使用着色器

    我对帧缓冲区有点困惑 我想要做的是使用附加了多个纹理的帧缓冲区 填充每个纹理 然后使用着色器组合 混合 所有纹理以创建新的输出 听起来很容易 是的 我也是这么想的 但我不明白 如何将当前绑定的纹理传递给着色器 您需要的是将纹理放入特定的槽中
  • 截取 DirectX 全屏应用程序的屏幕截图

    这让我很困惑 DirectX 绕过一切并直接与设备驱动程序对话 因此 GDI 和其他常用方法将不起作用 除非 Aero 被禁用 或不可用 否则出现的只是屏幕左上角的黑色矩形 我已经尝试过其他人在几个论坛上建议的方法 使用 DirectX 获
  • 为什么 OpenGL 有远裁剪平面,以及使用什么惯用法来处理这个问题?

    我一直在学习 OpenGL 持续困扰我的一个话题是远裁剪平面 虽然我可以理解近剪裁平面和侧剪裁平面 它们永远不会产生任何实际效果 因为它们之外的对象无论如何都不会被渲染 背后的推理 但远剪裁平面似乎只是一个烦恼 由于 OpenGL 背后的人
  • 为什么 glClear 不清除我的屏幕?

    这是我编写的一个简单的 opengl 程序 我试图在绘制三角形之前清除屏幕 我在 init 函数中调用了 glClear 但是 它似乎无法清除屏幕 include
  • 如何在 SceneKit 中以编程方式将 png 纹理包裹在立方体周围

    我是 SceneKit 的新手 试图让一些基本的东西工作 但到目前为止还没有取得多大成功 由于某种原因 当我尝试将 png 纹理应用于 CNBox 时 我最终除了黑色之外什么也没有 这是我在 viewDidLoad 中的简单代码片段 let
  • 云或烟雾的粒子系统

    我正在尝试使用 OpenGL 和 CUDA 制作一个简单的用于云和烟雾模拟的粒子系统 如何使粒子系统中的粒子表现得像真正的云或烟雾在低湍流风中的表现 我现在遇到的一些问题是 颗粒聚集成一个大球 粒子扩散到无限远 粒子突然弹射离开 我已经完成
  • FFMPEG 帧到 DirectX 表面

    给定一个指向 FFMPEG 的 AVFrame 的指针avcodec decode video 函数如何将图像复制到 DirectX 表面 假设我有一个指向适当大小的 DX X8R8G8B8 表面的指针 Thanks John 您可以使用
  • 使用 glGetFloatv 检索 pyglet 中的模型视图矩阵

    我正在使用 pyglet 在 python 中进行 3D 可视化 并且需要检索模型视图和投影矩阵来进行一些选择 我使用以下方式定义我的窗口 from pyglet gl import from pyglet window import wi
  • 渲染具有透明度的纹理时,OpenGL 不需要的像素

    我已经为这个问题苦苦挣扎了一段时间了 当我使用 OpenGL 渲染 2D 纹理 在无透明度和部分透明度之间的过渡上具有透明度值 时 我得到了一些烦人的灰色像素 我认为这是像素值插值的产物 关于如何改进这一点有什么想法吗 I m attach
  • 渲染 TTF SDL2.0 opengl 3.1

    我正在使用 SDL2 0 并使用 半现代 opengl 3 1 我希望向我的应用程序添加文本叠加 并在应用程序中呈现 TTF 我将如何使用现代 OpenGL 来解决这个问题 编辑 根据 genpfault 的建议 我尝试使用 SDL TTF

随机推荐

  • 自定义验证摘要模板 Asp.net MVC 3

    我正在开发一个使用 Asp Net MVC3 的项目 在我的视图中 Html ValidationSummary true 像往常一样它会产生 div class validation summary errors ul li Someth
  • Twinx/Secondary-y:不要从第一种颜色开始

    我有一个配色方案来自 plt style use ggplot so 我不想手动选取颜色 或从颜色循环器中选取它们 但是 当我有辅助轴时 fig ax plt subplots ax2 ax twinx ax plot np array 1
  • Scala 泛型和数字隐式

    我需要将两个函数作为参数传递给 scala 函数 然后 该函数应该评估它们并从中获取一个数字 然后对其进行操作 该数字可以是 Int Double 或任何其他数字类型 我希望该函数能够工作 无论它使用什么类型 下面的例子解释了这个问题 im
  • Android 中访问错误的原始资源

    我有以下代码 我的想法是在 OnCreate 中 我会将 res raw 中的文本文件中的一些类别填充到我的数据库中 首先按行对读取的文件进行标记 myCatToken 然后我再次拆分每个文件以获取 id 和名称 由于某种原因 我没有读取r
  • 如何仅从元素的一侧删除边框?

    I have
  • ReferenceError getValuesOfAutofillInputs,找不到变量:PaymentAutofillConfig [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 自 2022 年 6 月 2 日以来 我们的哨兵日志中一直面临代码中的引用错误 而且它只发生在 iOS iphone 设
  • 如何向网站发送查询并解析结果?

    我想用Java做一些开发 我希望能够访问一个网站 例如 www chipotle com 在右上角 您可以输入邮政编码 它会为您提供所有最近的位置 该程序只有一个空框供用户输入邮政编码 并且它将查询实际的 chipotle 服务器以检索最近
  • R 中值的累积计数

    我希望你做得很好 我想知道如何计算特定条件下数据集的累积和 我的数据集的简化版本如下所示 t id A 22 A 22 R 22 A 41 A 98 A 98 A 98 R 98 A 46 A 46 R 46 A 46 A 46 A 46
  • 在日期/因子向量字段上使用 sapply - 包括递增值

    我有一个带有缺失值的日期字段 因子类转换为字符串 我想用每个缺失值的序列号来填充该字段 到目前为止 这是我的代码 f lt function x counter if x counter counter 1 return toString
  • 非阻塞 BIO_do_connect 当没有互联网连接时被阻塞

    我使用 Openssl 0 9 8x 如下 bio BIO new ssl connect ctx BIO get ssl bio ssl SSL set mode ssl SSL MODE AUTO RETRY BIO set nbio
  • 如何在黑莓中裁剪特定形状的图像?

    大家好 感谢阅读我的回答希望你能帮助我 我正在黑莓手机上进行图像裁剪 在我的应用程序中包含 3 个主要内容 1 将图像加载到屏幕上 2 选择裁剪区域的形状 3 在下一个屏幕上显示裁剪图像而不丢失其形状 第1步 我可以完成图像加载部分 步骤2
  • Tweepy:现在可以使用 Twitter 搜索 api 获取旧推文了吗?

    根据http www theverge com 2014 11 18 7242477 twitter search now lets you find any tweet ever sent http www theverge com 20
  • 使用批处理文件按键盘按键[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我正在尝试开发一个批处理文件 它可以自动按向左箭头和向右箭头键 n 次 中间有一些暂停 有人可以帮我解决这个问题吗 P
  • 如何避免在 Scala 中调用 asInstanceOf

    这是我的代码的简化版本 怎样才能避免打电话asInstanceOf 因为这是一个设计不佳的解决方案的味道 sealed trait Location final case class Single bucket String extends
  • 使用框架会妨碍我掌握 JavaScript 吗?

    如果我一直用框架 自己什么都不做 我怎么能成为 JavaScript 高手呢 我问了一个关于 JavaScript 的问题 每个人都建议我使用框架 它不会向我展示 JS 的真正核心 而不是手动编码 你在自己发现JS的时候有没有编写自己的所谓
  • JavaFX 嵌套控制器 (FXML )

    In this http docs oracle com javafx 2 api javafx fxml doc files introduction to fxml html nested controllers教程中 有一个示例说明如
  • PHP foreach 循环中的多个索引变量

    是否有可能有一个foreach在 PHP 中使用多个 索引 变量循环 类似于以下内容 未使用正确的语法 foreach courses as course sections as section 如果没有 有没有好的方法可以达到相同的结果
  • springboot + webpack 开发服务器,重建后不会更改 localhost 捆绑文件

    点击这张图片 请阅读下面的内容 https i stack imgur com BYXDA png 1 第一张图片是运行 webpack dev server hot inline 之后的 第二张图片是我的html 我调用js文件的方式 我
  • 如何在 Xcode 8/Swift 3 中创建 iOS liveView [重复]

    这个问题在这里已经有答案了 我不知道如何在 Xcode 8 Swift 3 Playground 中创建和显示实时视图 如果 Apple 有关于 Playground 和实时视图的综合文档 我找不到它 而且我所有的在线搜索都显示 Xcode
  • 为什么OpenGL最初要设计成状态机?[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi