OpenGL,VAO和多个缓冲区 [英] OpenGL, VAOs and multiple buffers

查看:243
本文介绍了OpenGL,VAO和多个缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用OpenGL(通过使用C#的OpenTK)编写一个小的图形引擎.

I am writing a little graphics engine using OpenGL ( via OpenTK with C# ).

要定义顶点属性,我有一个VertexDeclaration类,其中包含一个VertexElement结构数组,这些结构映射到glEnableVertexAttribArray/glVertexAttribPointer调用.

To define vertex attributes, I have a VertexDeclaration class with an array of VertexElement structures that are mapped to glEnableVertexAttribArray/glVertexAttribPointer calls.

另外,为了支持多个顶点流,我有一个特殊的结构来保存顶点缓冲区,顶点声明,顶点偏移和实例频率(如XNA的VertexBufferBinding结构).

Also, to support multiple vertex streams, I have a special structure holding a vertex buffer, vertex declaration, vertex offset and instance frequency (like the XNA's VertexBufferBinding structure).

当前,每当调用图形调用时,我都会遍历所有设置的顶点流,并且 绑定其顶点缓冲区,应用顶点声明,禁用未使用的顶点属性并绘制图元.

Currently, whenever a drawing call is invoked, I iterate over all the set vertex streams and bind their vertex buffers, apply vertex declarations, disable unused vertex attributes and draw the primitives.

我想使用VAO将glEnableVertexAttribArray调用缓存到其中, 只要应用了顶点流,就绑定VAO并更改其数组缓冲区绑定.

I would like to use VAOs to cache the glEnableVertexAttribArray calls into them, and whenever a vertex stream is applied, bind the VAO and change its array buffer binding.

VAO是否正确使用?

Is that a correct usage of VAOs?

推荐答案

VAO是否正确使用?

Is that a correct usage of VAOs?

1 .

glVertexAttribPointer 使用当前绑定到GL_ARRAY_BUFFER 的缓冲区对象该功能称为 .所以你不能这样做:

glVertexAttribPointer uses the buffer object that was bound to GL_ARRAY_BUFFER at the moment the function was called. So you can't do this:

glVertexAttribPointer(...);
glBindBuffer(GL_ARRAY_BUFFER, bufferObject);
glDrawArrays(...);

这将使用bufferObject;它将使用最初调用glVertexAttribPointer时绑定到GL_ARRAY_BUFFER的任何内容.

This will not use bufferObject; it will use whatever was bound to GL_ARRAY_BUFFER when glVertexAttribPointer was originally called.

VAO捕获此状态.因此,VAO将针对每个顶点属性存储调用时绑定到GL_ARRAY_BUFFER的任何缓冲区对象.这使您可以执行以下操作:

VAOs capture this state. So the VAO will, for each vertex attribute, store whatever buffer object was bound to GL_ARRAY_BUFFER when it was called. This allows you to do things like this:

glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, buffer1);
glVertexAttribPointer(0, ...);
glVertexAttribPointer(1, ...);
glBindBuffer(GL_ARRAY_BUFFER, buffer2);
glVertexAttribPointer(2, ...);

属性0和1将来自buffer1,属性2将来自buffer2.现在,VAO会捕获所有状态.要渲染,只需执行以下操作:

Attributes 0 and 1 will come from buffer1, and attribute 2 will come from buffer2. VAO now captures all of that state. To render, you just do this:

glBindVertexArray(VAO);
glDraw*();

简而言之,如果要更改OpenGL中属性存储的来源,还必须更改其格式.即使格式相同,也必须再次调用glVertexAttribPointer.

In short, if you want to change where an attribute's storage comes from in OpenGL, you must also change it's format. Even if it's the same format, you must call glVertexAttribPointer again.

1 :此讨论假定您不是使用新的> Direct3D完全如何进行顶点属性绑定. 如果您碰巧正在使用提供此扩展的实现,则可以有效地执行您正在谈论的事情,因为属性格式与缓冲区对象的存储空间无关.同样,glVertexAttribPointer的折磨逻辑也消失了.

1: This discussion assumes you're not using the new ARB_vertex_attrib_binding. Or, as it is otherwise known, "Exactly how Direct3D does vertex attribute binding." If you happen to be using an implementation that offers this extension, you can effectively do what you're talking about, because the attribute format is not tied with the buffer object's storage. Also, the tortured logic of glVertexAttribPointer is gone.

通常,我们在OpenGL世界中解决此问题的方法是在同一个缓冲区对象中放入尽可能多的内容.如果失败,只需对每个对象使用一个VAO.

In general, the way we solve this in the OpenGL world is to put as many things as possible in the same buffer object. Failing that, just use one VAO for each object.

这篇关于OpenGL,VAO和多个缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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