假设我想在两个视口中渲染OpenGL场景。第一个视口渲染彩色图像,第二个视口渲染深度图像。每个都有自己的顶点着色器和片段着色器,每个都有自己的着色器程序。着色器是相似的,唯一的区别在于对于彩色图像,顶点着色是基于顶点法线在顶点着色器中定义的,而对于深度图像,顶点颜色是基于顶点深度在片段着色器中定义的。 。要执行渲染,我glUseProgram()
颜色着色器程序,绘制颜色场景,然后glUseProgram()
深度着色器程序,并绘制深度场景。
我不确定的是,当有两个着色器程序时glClear()
如何工作。我是否需要在每个渲染循环中调用它两次 - 在渲染彩色图像之前调用一次,在渲染深度图像之前调用一次?当我只召唤一次它似乎有效,但这对我来说似乎很奇怪。我原以为每个着色器程序一次写入颜色和深度缓冲区。因此,在渲染深度图像时,它会留下渲染彩色图像的缓冲区......但似乎并非如此。有人可以向我解释一下吗?谢谢!
答案 0 :(得分:5)
我不确定的是,当有两个着色器程序时,glClear()是如何工作的。
如果您不确定清除如何与着色器进行交互,那么您就会对正在发生的事情产生某种误解。
glClear
clears the framebuffer。使用哪些着色器程序在该帧缓冲区中创建像素完全无关紧要。使用多少程序生成像素数据无关紧要。
概念上与此没有什么不同:
int foo = <insert large expression here>;
foo = 5;
无论初始化表达式有多大和多么复杂,向变量写入5将覆盖那里的任何内容。就像清除帧缓冲区一样,清除帧缓冲区,无论它是如何到达的。
我是否需要在每个渲染循环中调用它两次 - 在渲染彩色图像之前调用一次,在渲染深度图像之前调用一次?
视口不是OpenGL中的真实构造。它们只是NDC-to-window-space transformation的一部分。裁剪后,您的顶点将转换为窗口内的位置;视口只是让您决定它们在窗口中的位置。您没有看到视口之外的部分,因为这些顶点被裁剪阶段剪切了。
视口不会创建帧缓冲区,子帧缓冲区,迷你帧缓冲区或任何与帧缓冲区有关的东西。视口只是原语的转换技巧。
帧缓冲清除操作不涉及primitives。因此,帧缓冲区清除不关心关于当前视口。它们会影响整个帧缓冲区。
如果在发出清除时启用了剪刀测试,则Framebuffer会清除执行尊重scissor box。但视口与清算无关。