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