为什么将OpenGL最初设计为状态机? [英] Why does OpenGL be designed as a state machine originally?

查看:477
本文介绍了为什么将OpenGL最初设计为状态机?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

During my OpenGL experience, I often forgot to set some states. So I think state machine may not be a good design today. But now it has to be compatible. And I also know that DirectX was also a state machine in the early days. I'd like to know why OpenGL as well as DirectX was originally designed as a state machine?

推荐答案

目前尚不清楚人们指的是状态机"是什么意思,因为他们从不解释相反的意思.因此,我将就OpenGL状态机"与当前的D3D非状态机"进行一般性和专门的讨论.

It's not clear what people mean when they refer to "state machine", as they never explain what the opposite is. So I'll talk about it both generally and specifically in terms of OpenGL "state machine" vs. current D3D "not a state machine".

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

Both OpenGL and Direct3D use global state. Every rendering command requires that you set a bunch of state.

为了同时在两个API中进行渲染,您必须设置一堆全局状态.您必须设置要使用的着色器.您必须设置要使用这些制服的当前参数.如果您使用的是纹理,则需要进行设置.您需要设置当前的视口参数.依此类推.

In order to render in both APIs, you must set a bunch of global state. You have to set which shaders you're going to use. You have to set the current parameters you want to use those uniforms with. If you're using textures, you need to set those up. You need to set your current viewport parameters. And so forth.

产生这种状态机"的原因很简单:硬件通常就是这样工作的.

The reason for this kind of "state machine" is simple: that's how the hardware generally works.

每个状态位代表GPU中的某些寄存器.这些寄存器是状态.需要加载明暗器以进行渲染.您需要设置视口寄存器.您需要设置要使用的纹理寻址寄存器.依此类推.因此,API是状态机,因为 GPU 是状态机.

Each bit of state represents some registers in the GPU. Those registers are state. Shaders need to be loaded in order to render. You need to set the viewport registers. You need to set up which texture addressing registers you're using. And so forth. Thus, the APIs are state machines because the GPU is a state machine.

可以想象一下,这将由渲染命令完成.但是,只需查看您需要传递多少个对象即可.您必须传递一堆着色器,一堆纹理,顶点数据,帧缓冲区,视口设置,混合设置等.

You could imagine that such would be done by a rendering command. But just look at how many objects you'd need to pass. You'd have to pass a bunch of shaders, a bunch of textures, your vertex data, your framebuffer, your viewport settings, your blend settings, etc.

因此,API让您完成了GPU的工作.您已经将所有这些东西预先设置好了.

So instead, the APIs have you do what the GPU does. You set all this stuff up beforehand.

此外,这使API 更快.为什么?因为现在API知道您正在使用的状态.例如,如果要渲染具有不同纹理的一个网格的不同部分,则可以使帧缓冲区,视口,顶点数据等保持相同.在它们之间唯一改变的是使用哪种纹理.

Plus, this makes the API faster. Why? Because now the API knows what state you're using. If you want to render, say, different parts of one mesh with different textures, you can keep the framebuffer, viewport, vertex data, etc all the same. The only thing you change between them is which textures you use.

如果您使用了带有数十个参数的巨型Draw调用,那么API必须查看每个参数以查看其是否与上一次绘制调用相同.如果不是,则必须更新GPU寄存器.

If you used some kind of giant Draw call with dozens of parameters, now the API has to look at each parameter to see if it's the same as your last draw call. And if it's not, it has to update the GPU registers.

现在,关于OpenGL和D3D之间的区别.在这种情况下,所讨论的区别是它们如何处理对象.

Now, as for the differences between OpenGL and D3D. In this case, the difference in question is how they treat objects.

D3D是基于对象的,因为修改对象的函数将对象作为参数.而且,大多数D3D对象都是不可变;创建它们后,您将无法更改它们的大多数设置.一旦创建了一定大小,格式等的纹理,就完成了.您不能在不删除对象并创建新对象的情况下用其他大小/格式/等重新分配它.

D3D is object-based, in that functions that modify objects take the object as a parameter. Also, most D3D objects are immutable; once you create them, you can't change most of their settings. Once you create a texture of a certain size, format, etc, it's done. You can't reallocate it with a different size/format/etc without deleting the object and creating a new one.

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

OpenGL is state-based. What this means is that OpenGL functions that modify objects (for the most part) do not take the object they operate on as parameters.

这不是一个设计",而仅仅是OpenGL严格地向后兼容. OpenGL中的对象只是全局状态的片段;这就是它们的定义方式.为什么?

This is not a "design" so much as simply OpenGL's strict adherence to backwards compatibility. Objects in OpenGL are just fragments of global state; that's how they're defined. Why?

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

Because originally, back in OpenGL 1.0, there were no objects (besides display lists). Yes, not even texture objects. When they decided that this was stupid and that they needed objects, they decided to implement them in a backwards compatible way. Everyone was already using functions that operated on global state. So they just said that by binding an object, you override the global state. Those functions that used to change global state now change the object's state.

通过这种方式,他们可以将对象引入API,而无需引入一堆只能与对象一起使用的新功能.因此,以前起作用的代码仅需很小的调整就可以与对象一起工作,而不是强制对其进行非平凡的重写.这也意味着,如果他们需要引入戳戳纹理的新功能,则它们可以在没有对象的情况下与一起使用.因此,它既向后兼容又向前兼容.

In this way, they could introduce objects into the API without also introducing a bunch of new functions that only work with objects. Thus, code that worked before could work with objects with only very minor tweaking, rather than forcing a non-trivial rewrite of the code. It also means that if they needed to introduce new functions that poke at textures, they would work with and without objects. Thus, it was both backwards and forwards compatible.

大多数OpenGL对象都以这种方式工作:如果要更改它们,则必须将其绑定,然后修改全局"状态.

Most OpenGL objects work this way: if you want to change them, you have to bind them, then modify the "global" state.

这篇关于为什么将OpenGL最初设计为状态机?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆