如何将模板缓冲区与 alpha 掩码一起使用
How to use a stencil buffer with an alpha mask
我正在尝试使用带有 alpha 蒙版的模板缓冲区来防止绘制部分纹理。
初始化代码
if(SDL_Init(SDL_INIT_EVERYTHING) < 0) {
fprintf(stderr,"%s:%dn SDL_Init call failed.n",__FILE__,__LINE__);
return false;
}
// Request use of the stencil buffer
SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 1 );
if((Surf_Display = SDL_SetVideoMode(WWIDTH, WHEIGHT, 32, SDL_GL_DOUBLEBUFFER | SDL_OPENGL | SDL_RESIZABLE)) == NULL) {
fprintf(stderr,"%s:%dn SDL_SetVideoMode call failed.n",__FILE__,__LINE__);
return false;
}
// Init GLDebug system
GLDebug::Init();
// Init GL system
glClearColor(0, 0, 0, 1);
glClearDepth(1.0f);
glViewport(0, 0, WWIDTH, WHEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WWIDTH, WHEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
glLoadIdentity();
源
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Enable use of textures
glEnable(GL_TEXTURE_2D);
// Disable writing to any of the color fields
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glStencilFunc(GL_ALWAYS, 0,0);
glEnable(GL_ALPHA_TEST);
glEnable(GL_STENCIL_TEST);
glBindTexture(GL_TEXTURE_2D,(&StencilTex)[0]);
// Draw our stencil buffer texture
glBegin(GL_POLYGON);
glTexCoord2d( 0, 0 ); glVertex2f( 50, 50 );
glTexCoord2d( 0, 1 ); glVertex2f( 50, 50+128 );
glTexCoord2d( 1, 1 ); glVertex2f( 50+128, 50+128 );
glTexCoord2d( 1, 0 ); glVertex2f( 50+128, 50 );
glEnd();
glDisable(GL_ALPHA_TEST);
// Re enable drawing of colors
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glStencilFunc(GL_GREATER, 0, -1);
// Bind desired texture for drawing
glBindTexture(GL_TEXTURE_2D,(&texture)[0]);
// Draw the box with colors (this should be masked off)
glBegin(GL_QUADS);
glTexCoord2d( 0, 0 ); glVertex2f( 50, 50 );
glTexCoord2d( 0, 1 ); glVertex2f( 50, 50+128 );
glTexCoord2d( 1, 1 ); glVertex2f( 50+128, 50+128 );
glTexCoord2d( 1, 0 ); glVertex2f( 50+128, 50 );
glEnd();
glDisable(GL_STENCIL_TEST);
// Swap buffers and display!
SDL_GL_SwapBuffers();
我将摆脱蒂姆发布的这个问题的参考。我的设置适用于像素的原始绘制,但我无法 A) 制作此过程应该如何工作的正面或反面或 B) 让它从 alpha 纹理工作。我得到的只是一个黑屏,或者完整的纹理。
有人愿意把它分解成合理的步骤吗?我对glStencilOp和glStencilFunc选项的工作原理有一个模糊的理解,但它们与使用alpha测试和模板测试的关系让我感到困惑。我们如何决定仅保留纹理中的 alpha 层?
要查看:
- 我有一个想要绘制到场景中的纹理,但我需要屏蔽非常特定的区域。
- 无法在运行时修改对象的 alpha 纹理来实现此效果。 我
- 正在使用固定管道,我计划稍后学习如何使用 VBO。
- 给定的代码会导致在调用第二个纹理时不绘制任何内容。
[编辑 0]
接受的解决方案有效!这是符合我期望的最终代码。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// // Enable use of textures
glEnable(GL_TEXTURE_2D);
// Disable writing to any of the color fields
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glAlphaFunc(GL_GREATER, 0.05);
glStencilFunc(GL_ALWAYS, 0,0);
glEnable(GL_STENCIL_TEST);
glEnable(GL_ALPHA_TEST);
glBindTexture(GL_TEXTURE_2D,(&StencilTex)[0]);
// Draw our blocking poly
glBegin(GL_POLYGON);
glTexCoord2d( 0, 0 ); glVertex2f( 50, 50 );
glTexCoord2d( 0, 1 ); glVertex2f( 50, 50+128 );
glTexCoord2d( 1, 1 ); glVertex2f( 50+128, 50+128 );
glTexCoord2d( 1, 0 ); glVertex2f( 50+128, 50 );
glEnd();
glDisable(GL_ALPHA_TEST);
// Re enable drawing of colors
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glStencilFunc(GL_LESS, 0, -1);
// Bind desired texture for drawing
glBindTexture(GL_TEXTURE_2D,(&texture)[0]);
// Draw the box with colors
glBegin(GL_QUADS);
glTexCoord2d( 0, 0 ); glVertex2f( 50, 50 );
glTexCoord2d( 0, 1 ); glVertex2f( 50, 50+128 );
glTexCoord2d( 1, 1 ); glVertex2f( 50+128, 50+128 );
glTexCoord2d( 1, 0 ); glVertex2f( 50+128, 50 );
glEnd();
glDisable(GL_STENCIL_TEST);
// Swap buffers and display!
SDL_GL_SwapBuffers();
我看到您已启用 alpha 测试,但我没有看到任何设置 alpha 函数的调用(glAlphaFunc
)?
如果未设置 alpha 函数,则 alpha 测试始终通过。您必须告诉状态机要丢弃哪些像素。
通常我会将其设置为:
glAlphaFunc(GL_GREATER, 0.05); //reject any pixels with alpha less than 0.05
很抱歉,如果您没有从我之前的回答中清楚地理解,但如果您对模板功能的工作原理感到困惑,您可以随时glStencilFunc
glStencilOp
查阅他们的参考页面。
相关文章:
- 位移操作和位掩码未检测到重复字符
- OpenCV - 带有掩码的absdiff
- 生成前缀位掩码
- 如何从__m64值的 lsb 创建 8 位掩码?
- 如何对无符号长 int 进行位掩码?
- 删除K的背景掩码-意味着Python或C++中的集群/
- 如何在C++中优雅地处理位掩码
- 将uint64_t位掩码转换为 std::布尔数组
- 使输入二进制掩码适应 ITK 网格生成器
- 如何从 getifaddr 读取子网掩码
- 优化从子位掩码生成父位掩码
- 基于模式创建位掩码作为 constexpr
- 使用二进制掩码 C++ ITK 获取感兴趣区域
- C++中的运行时位复制(位掩码)
- 根据 IP 和掩码C++打印所有 IP
- C++设置"blank"或重置 ifstrean (ios) 的异常掩码
- OpenCV 检测带有掩码的斑点
- OPENCV:如何创建多边形形状的掩码
- 如何将模板缓冲区与 alpha 掩码一起使用
- 在Blackberry 10 Cascades中,有一种方法可以使用图像掩码或alpha通道更改Blackberry C