为什么 GL_RASTERIZER_DISCARD 不允许我写入模板缓冲区?
Why GL_RASTERIZER_DISCARD does not enable me to write to stencil buffer?
我想在 3 遍中使用模板缓冲区绘制轮廓。
- 普通绘图通过
- 轮廓掩码生成过程
- 轮廓图通过
第二遍不需要片段着色器工作,因为它只写入模板缓冲区,所以我使用 glEnable(GL_RASTERIZER_DISCARD);
完全防止接触片段着色器。
问题是没有生成掩码(这是我的想法,也许是其他原因),因此轮廓四边形片段不会被丢弃。它被绘制但在我想要概述的四边形之上。如果说得通。
int main()
{
//create window, gl context etc. etc...
Shader colorShader("colorShader.glsl");
Shader maskShader("maskShader.glsl");
//Creates geometry for quad, also creates vertex array, vertex buffer and adds data glBufferData.
//this code is tested and works, so it is not neccessery to show what it does internaly.
Quad sceneQuad(colorShader);
Quad maskQuad(maskShader);
Quad outlineQuad(colorShader);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
bool quit = false;
while(!quit) {
glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_RASTERIZER_DISCARD);
glStencilMask(0x00);
//binds everything, and call glDraw*, its parameter is model matrix and u_r uniform
//it is also tested and works fine
sceneQuad->Draw(Scale(1.0f), 1.0f);
glEnable(GL_RASTERIZER_DISCARD);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilMask(0xFF);
maskQuad->Draw(); // it does not need matrix or u_r, because it uses different shader
glDisable(GL_RASTERIZER_DISCARD);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilMask(0x00);
glDisable(GL_DEPTH_TEST);
oulineQuad->Draw(Scale(1.1), 0.0f); //a bit scaled
}
}
颜色着色器:
#version 460 core
layout (location = 0) in vec2 a_position;
uniform mat4 u_model;
void main()
{
gl_Position = u_model * vec4(a_position, 0.0f, 1.0f);
}
//-------------------------------------------------------------------
#version 460 core
layout (location = 0) out vec4 f_color;
uniform float u_r;
void main()
{
f_color = vec4(u_r, 0.0f, 1.0f, 1.0f);
}
遮罩着色器,只是顶点程序:
#version 460 core
layout (location = 0) in vec2 a_position;
void main()
{
gl_Position = vec4(a_position, 0.0f, 1.0f);
}
我期望的是绘制紫色四边形,
然后再次绘制它但没有片段着色器,只绘制到模板缓冲区
然后在所有内容之上绘制蓝色四边形,但丢弃由模板缓冲区中的掩码绘制的像素。
它的作用是在不丢弃掩码像素的情况下绘制蓝色四边形。
如何解决?
来自"What actually does GL_RASTERIZE_DISCARD":
When enabled, primitives are discarded immediately before the rasterization stage, but after the optional transform feedback stage (see section 13.2)
鉴于您想要绘制到模板缓冲区,您仍然需要光栅化,而不是颜色缓冲区。
为此,您可以使用
glDrawBuffer(GL_NONE)
或
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE)
请参阅 this post 进行比较,但我认为任何一种方式都适合您的应用程序。
我想在 3 遍中使用模板缓冲区绘制轮廓。
- 普通绘图通过
- 轮廓掩码生成过程
- 轮廓图通过
第二遍不需要片段着色器工作,因为它只写入模板缓冲区,所以我使用 glEnable(GL_RASTERIZER_DISCARD);
完全防止接触片段着色器。
问题是没有生成掩码(这是我的想法,也许是其他原因),因此轮廓四边形片段不会被丢弃。它被绘制但在我想要概述的四边形之上。如果说得通。
int main()
{
//create window, gl context etc. etc...
Shader colorShader("colorShader.glsl");
Shader maskShader("maskShader.glsl");
//Creates geometry for quad, also creates vertex array, vertex buffer and adds data glBufferData.
//this code is tested and works, so it is not neccessery to show what it does internaly.
Quad sceneQuad(colorShader);
Quad maskQuad(maskShader);
Quad outlineQuad(colorShader);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
bool quit = false;
while(!quit) {
glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_RASTERIZER_DISCARD);
glStencilMask(0x00);
//binds everything, and call glDraw*, its parameter is model matrix and u_r uniform
//it is also tested and works fine
sceneQuad->Draw(Scale(1.0f), 1.0f);
glEnable(GL_RASTERIZER_DISCARD);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilMask(0xFF);
maskQuad->Draw(); // it does not need matrix or u_r, because it uses different shader
glDisable(GL_RASTERIZER_DISCARD);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilMask(0x00);
glDisable(GL_DEPTH_TEST);
oulineQuad->Draw(Scale(1.1), 0.0f); //a bit scaled
}
}
颜色着色器:
#version 460 core
layout (location = 0) in vec2 a_position;
uniform mat4 u_model;
void main()
{
gl_Position = u_model * vec4(a_position, 0.0f, 1.0f);
}
//-------------------------------------------------------------------
#version 460 core
layout (location = 0) out vec4 f_color;
uniform float u_r;
void main()
{
f_color = vec4(u_r, 0.0f, 1.0f, 1.0f);
}
遮罩着色器,只是顶点程序:
#version 460 core
layout (location = 0) in vec2 a_position;
void main()
{
gl_Position = vec4(a_position, 0.0f, 1.0f);
}
我期望的是绘制紫色四边形, 然后再次绘制它但没有片段着色器,只绘制到模板缓冲区 然后在所有内容之上绘制蓝色四边形,但丢弃由模板缓冲区中的掩码绘制的像素。
它的作用是在不丢弃掩码像素的情况下绘制蓝色四边形。
如何解决?
来自"What actually does GL_RASTERIZE_DISCARD":
When enabled, primitives are discarded immediately before the rasterization stage, but after the optional transform feedback stage (see section 13.2)
鉴于您想要绘制到模板缓冲区,您仍然需要光栅化,而不是颜色缓冲区。
为此,您可以使用
glDrawBuffer(GL_NONE)
或
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE)
请参阅 this post 进行比较,但我认为任何一种方式都适合您的应用程序。