我试图使用
在顶点着色器中直接定义的单个三角形渲染全屏四边形out vec2 tex_coord;
const vec2 pos_data[3] = vec2[] (
vec2(-1.0, -1.0),
vec2( 3.0, -1.0),
vec2(-1.0, 3.0)
);
const vec2 tex_data[3] = vec2[] (
vec2(0.0, 0.0),
vec2(2.0, 0.0),
vec2(0.0, 2.0)
);
void main() {
tex_coord = tex_data[ gl_VertexID ];
gl_Position = vec4( pos_data[ gl_VertexID ], 0.0, 1.0 );
}
一切正常,直到我切换到核心配置文件的上下文。 出现错误1282并关闭我的程序。 原因是我没有用于渲染的VerteArrayObject绑定。 因为我不需要它填充数据,我只需绑定一个虚拟的,一切都可以再次工作。
有没有办法绕过这个虚拟对象并仍然遵循规范?
答案 0 :(得分:7)
有没有办法绕过这个虚拟对象并仍然遵循规范?
没有。根据规范,每个glDraw*
调用都必须具有非零VAO限制。
<强>更新强>:
在current OpenGL 4.5 core profile specification中,您将在10.4&#34;使用顶点数组绘制命令&#34;中找到以下语言:
命令
GL中不存在void DrawArraysOneInstance( enum mode, int first, sizei count, int instance, uint baseinstance );
但用于描述本节其余部分的功能。
[...]
<强>错误强>
[...]
如果没有绑定顶点数组对象,则会生成
INVALID_OPERATION
错误(参见第10.3.1节)
所有其他glDraw*
命令都是根据此假设命令进行解释的,因此其中描述的所有属性都将由所有其他绘制命令继承,包括可能生成的错误。
其他替代方案
由于您似乎只想绘制全屏四边形,因此某些特殊情况有一些潜在的替代方案。
如果您只想绘制一些纹理,而不在着色器中应用任何特殊效果,您可以将该纹理附加到FBO的颜色附件,并将其用作glBlitFramebuffer
的来源,以便您基本上只是将这个纹理blit到屏幕上,而根本不改变任何与绘图相关的状态。
还有特定于NV的扩展GL_NV_draw_texture,它们朝着相同的方向发展。引用&#34;概述&#34;所述延期部分(我的重点):
此扩展提供了一个新功能
DrawTextureNV()
,允许应用程序绘制一个屏幕对齐的矩形,显示二维或矩形纹理的部分或全部内容。 [...]
DrawTextureNV
没有使用着色器; <>的结果纹理查找用于代替片段着色器 输出。 [...]虽然可以通过绘制a在未扩展的OpenGL中获得此功能 矩形并使用片段着色器进行纹理查找,
DrawTextureNV()
可能会提高电源效率 支持此扩展的实现。 另外,使用此 扩展使应用程序开发人员不必设置 专用着色器,变换矩阵,顶点属性和 各种其他状态,以呈现矩形。
但是,我在这里讨论的两种方法只解决了你基本上想要通过过滤将一些纹理加入到屏幕的情况,但没有任何自定义的每片段操作。
如果要进行自定义每片段处理,则必须使用某些glDraw*()
命令(并且需要VAO)来完成渲染管道,或者还可以使用计算着色器写入2D纹理通过image_load_store
功能。在一般情况下,我怀疑它是否值得,但这当然取决于您实际使用案例的具体情况。