Opengl、DrawArrays 无需绑定 VBO
我正在使用自定义顶点着色器渲染点数组。 着色器看起来像:
void mainVP()
in varying int in_vertex_id : VERTEXID
{
foo(in_vertex_id);
}
所以我唯一需要的就是顶点 id。 但我需要很多顶点,并且我不想为它们存储假 VBO(它需要大约 16mb 内存)。
我尝试在不绑定任何 VBO 的情况下运行我的代码。有用。 所以我的渲染看起来像:
size_t num_vertices = ...
glDrawArrays(GL_POINTS, 0, num_vertices);
但是我能确定不绑定VBO的渲染是安全的吗?
I am rendering array of points with a custom vertex shader.
Shaders looks like:
void mainVP()
in varying int in_vertex_id : VERTEXID
{
foo(in_vertex_id);
}
So the only thing I need - is vertex id.
But I need a lot of vertices and I don't want to store fake VBO for them (it takes around 16mb of memory).
I tried to run my code without binding any VBO. It works.
So my rendering looks like:
size_t num_vertices = ...
glDrawArrays(GL_POINTS, 0, num_vertices);
But can I be sure that rendering without binding VBO is safe?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你不能。
OpenGL 规范的核心配置文件(3.2 及更高版本)明确指出应该允许它,您可以在禁用所有属性的情况下进行渲染。 OpenGL 规范的兼容性配置文件或 3.2 之前的任何版本都清楚地表明您不能执行此操作。
当然,无论如何这都无所谓。 NVIDIA 驱动程序允许您在任何 OpenGL 版本和配置文件上执行此操作。 ATI 的驱动程序不允许您在任何 OpenGL 版本或配置文件上执行此操作。它们都是驱动程序错误,只是方式不同。
您只需要接受您需要一个虚拟顶点属性即可。然而:
虚拟属性将占用 4 个字节(单个浮点数或标准化字节的 4 个向量。记住:您不关心数据)。所以 16MB 可以容纳 400 万个。
或者,您可以通过 glDrawArraysInstanced 使用实例化渲染。在那里,您只需渲染一个顶点,但带有
num_vertices
实例。当然,您的着色器必须使用实例 ID。You can't.
The OpenGL specification's core profile (3.2 and above) clearly states that it should be allowed, that you can render with all attributes disabled. The OpenGL specification's compatibility profile or any versions before 3.2 just as clearly state that you cannot do this.
Of course, that doesn't matter anyway. NVIDIA drivers allow you to do this on any OpenGL version and profile. ATI's drivers don't allow you to do it on any OpenGL version or profile. They're both driver bugs, just in different ways.
You'll just have to accept that you need a dummy vertex attribute. However:
A dummy attribute would take up 4 bytes (a single float, or a 4-vector of normalized bytes. Remember: you don't care about the data). So you could fit 4 million of them in 16MB.
Alternatively, you could use instanced rendering via glDrawArraysInstanced. There, you just render one vertex, but with
num_vertices
instances. Your shader will have to use the instance ID, of course.