我试图找出在绘制纹理部分时掩盖纹理部分的最佳方法。我的问题在于我似乎已经运行了我们的 alpha 蒙版!
我们正在使用 openGL 绘制自定义构建的 2D 游戏引擎。游戏由精灵和简单的块纹理构成。
我想要的结果是这样的:
- 一个角色精灵被绘制在适当的位置(使用它的 alpha 颜色不仅仅是一个盒子)
- 一个物品被绘制到玩家手中(也使用它的 alpha 颜色绘制到场景中而不是一个盒子)
- 该项目应出现在角色手臂/手的后面,但在身体的其余部分上方。
目前我能弄清楚如何做到这一点的唯一方法是按顺序绘制它们(身体、物品、手臂),但我想避免这种情况,以使艺术资产更容易处理。我的想法解决方案是绘制角色,然后使用 alpha 蒙版绘制项目,该蒙版遮挡应该在手臂“下方”的纹理区域。
我见过的其他解决方案是这样的,其中使用了 glBlendFuncSeparate() 函数。我试图避免引入扩展,因为我当前版本的 OpenGL 不支持它。并不是说我反对这个想法,但是仅仅为了绘制一个 alpha 蒙版,它似乎有点像把柄?
我完全承认这对我来说是一个学习过程,我以此为借口来真正了解 OpenGL 的处理方式。关于我应该去哪里让它正确绘制的任何建议?固定管道中的 OpenGL 有没有办法获取纹理,在其上应用 alpha 蒙版,然后将其绘制到缓冲区中?我应该屈服并将我的角色分成其模型的几个部分吗?
[更新:2012 年 8 月 12 日]
尝试添加 Tim 建议的代码,但我似乎遇到了问题。当我启用模板缓冲区时,一切都被封锁了,不仅仅是我想要的。这是我的测试示例代码。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// 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);
// Draw our blocking poly
glBegin(GL_POLYGON);
glVertex2f( 50, 50 );
glVertex2f( 50, 50+128 );
glVertex2f( 50+128, 50+128 );
glEnd();
glStencilFunc(GL_GREATER, 0, -1);
glEnable(GL_STENCIL_TEST);
// Re enable drawing of colors
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
// Enable use of textures
glEnable(GL_TEXTURE_2D);
// 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();
// Swap buffers and display!
SDL_GL_SwapBuffers();
为了清楚起见,这也是我设置这个系统的初始化代码。
当代码在 stencil disabled的情况下运行时,我得到这个:
当我使用 glEnable(GL_STENCIL_TEST) 时,我得到了这个:
我尝试过各种选项,但我看不出我的模板缓冲区阻塞一切的明确原因。
[更新#2 8/12/12]
我们得到了一些工作代码,谢谢蒂姆!这是我最终运行正常工作的内容。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Disable writing to any of the color fields
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glStencilOp(GL_INCR, GL_INCR, GL_INCR);
glEnable(GL_STENCIL_TEST);
// Draw our blocking poly
glBegin(GL_POLYGON);
glVertex2f( 50, 50 );
glVertex2f( 50, 50+128 );
glVertex2f( 50+128, 50+128 );
glEnd();
glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// Re enable drawing of colors
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
// Enable use of textures
glEnable(GL_TEXTURE_2D);
// 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();