以下是需要翻译的内容:
- 这个主状态机是什么?
- 它是OpenGL API、我正在尝试绘制的帧,还是用户定义的东西(例如管线)?
- 它可以存在哪些不同的状态?
- 它是否也是事件驱动的?
- 哪些输入会影响状态机可能处于的不同状态?
- 分层、面向对象的概念是否适用于此状态机?
这是什么状态机?
想象一下一个有几十个开关和旋钮的接线板,该接线板连接到加工厂中的机器上,根据这些开关和旋钮的切换方式,输入到工厂一侧的物料将沿着特定路径通过工厂。改变某些开关的状态,物料将走另一条路。
还有一种状态机,其中当物料通过某一处理步骤时,开关和旋钮会发生变化;OpenGL不属于这类。
OpenGL上下文就是一个具有处理厂的接线板,您可以通过API进行控制,而处理厂则是生成图像的地方。
它可以存在哪些不同的状态?
太多了,每个开关的状态数量乘以该开关可以处于的位置数量。假设您有20个切换开关、一个具有5个位置的旋钮和一个具有7个位置的旋钮,则您有36700160个可能的不同状态。2^20 * 5 * 7 = 36700160
。一些OpenGL版本有超过300个状态变量,其中许多不仅仅是布尔值。因此,试图列出每一个可能的状态是徒劳的。
它也是事件驱动的吗?
不是!
哪些输入会影响状态机可以处于的不同状态?
OpenGL API中显式调用状态更改函数和默认初始状态。
分层,面向对象的概念是否适用于此状态机?
不是。或者说,您可以尝试,但实话实说,唯一真实的表示将是一个持有所有状态的单个OpenGL上下文类。
在OpenGL上下文中有一些行为就像具有自己状态的单独对象。例如纹理,但这些对象与OpenGL上下文本身紧密相关,不能被单独查看。
关于你的评论的个人看法
我的大脑倾向于以分层、面向对象、组件式的方式构建概念。
停止这样做!计算机不是这样工作的。面向对象编程是一种组织项目的方法,但它并不是理解某些现有系统的很好的工具,特别是那些本质上非分层的系统。
我强烈建议你通过学习其他的项目结构方式来扩展你的视野。学习一下函数式编程怎么样?Haskell是目前流行的函数式编程语言之一,对于学习体验来说非常好,因为它专注于成为一种纯语言。这里有一本非常好的在线书籍/教程:http://learnyouahaskell.com/chapters——准备好了,你的思维可能会被扭曲,有些东西看起来像面向对象编程,但实际上不是;当你最终理解了这些概念时,所得到的好处(即有顿悟)是真正值得的。
请注意,OpenGL既不是函数式编程,也不是真正的面向对象编程。由于它不是函数式的,因此它不能很好地映射到纯函数式编程中。有Haskell的OpenGL绑定,但它们是通过一种叫做“单子”的东西实现的;单子是函数式程序用来与状态或甚至驱动环境联系起来的。
我推荐的另一个资源是https://mitpress.mit.edu/sicp/full-text/book/book.html——每个程序员都应该读过它。
glMatrixMode
、GL_FOG
、glPushMatrix
、glMultMatrix
和glPushAttrib
在现代OpenGL中已经不再使用,而且这个问题被标记为“opengl-4”。 - RamblingMad说实话,我发现理解这个问题的最佳方式是面向对象编程。
从我所了解的关于OpenGL的一切,以下是我对OpenGL API的最佳解释:
首先,如果你将其与其他API(如SDL)进行比较,它可能会更加复杂和不同,使用API来尝试描述它真的无法做到公正。
因此,在面向对象编程方面,
想象一下,如果你有一个类,这个类是私有的,其所有工作方法都不打算被用户查看,但它也有一个默认状态,以便如果你“开箱即用”,它将在该默认状态下执行其功能(基本上什么也不做)。
当你创建一个上下文时,就像你创建了这个类的一个实例(你可以创建任意多个这个类的实例,也就是说你可以创建多个上下文),这是运行OpenGL所必需的。在OOP中,你不能使用一个类,直到你从它创建了一个对象/实例,唯一的区别是构造函数需要你的硬件/操作系统/其他API/硬件信息来完成实例/对象,以便它可用,或者将其插入到某个“屏幕”中。
然而,这个类中包含的方法(函数)和字段(数据存储)是赋予您使用此实例并执行所需操作的能力的关键。当然,您如何执行某些操作取决于方法,您不能更改此类/实例/对象的任何内容而不使用其方法/字段(即允许使用的公共字段),您不能自己说“我想这样做”或选择在哪里存储字段(外部等),所有这些都必须与实例、类和方法相关,并且在此实例/对象/类中有数百种方法和字段(OpenGL 4.5具有超过500个命令(方法/字段)影响此实例/类),无论您对它进行何种更改,都会更改此特定实例/对象,就像您拥有一些黏土并将其塑造成您想要的任何形状一样,当然,您必须将某些东西插入此实例中,例如具有其特定功能的着色器。
因此,它确实有点像电视屏幕的遥控器,它有其方法/按钮,根据您在遥控器/实例/方法/函数上按下的内容来影响显示的上下文(屏幕/电视/监视器),但在这个比喻中的区别是需要更多的按钮操作以及数据和您可以呈现它的各种方式(这就是您绘制到屏幕上的内容)。