glClear()不服从剪刀区域

时间:2014-06-23 14:33:00

标签: c++ windows opengl

我在任意已打开的Windows 7窗口(例如Windows记事本窗口)中使用双缓冲绘制Open GL内容(直接Win32 - 不使用GLUT,FreeGLUT,GLFW等)。我有窗口句柄,可以按预期绘制我想要的内容,但我看到glClear()函数的奇怪行为。

据我了解,glClear()函数应仅影响屏幕上由glScissor()函数定义的区域内的像素。我用glScissor()定义了剪刀区域,然后使用glEnable(GL_SCISSOR_TEST)启用了剪刀功能。 glClearColor设置为白色(0,0,0,1)。我正在使用glClear()命令清除颜色和深度缓冲区。

执行SwapBuffers()命令以便在屏幕上渲染时,我所选择的清晰颜色的白色按照我的要求绘制在剪刀区域内,但窗口的其余部分 OUTSIDE 剪刀区域涂成黑色,而不是像我预期的那样保持这些像素不受影响。

如图所示,剪刀区域(白色)和对象(3D立方体)被正确绘制,但记事本窗口的其余部分像素被设置为黑色,之前在该记事本窗口中绘制的任何内容都被覆盖

glClearColor(1.0f, 1.0f, 1.0f, 1.0f);               // white background
glViewport(0, 0, 300, 300);
glScissor(0, 0, 250, 400);
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//... draw cube inside glBegin()/glEnd()...
SwapBuffers(hDC);

1 个答案:

答案 0 :(得分:5)

如果我的说明正确无误,glClear按预期工作。

你不能假设只是因为你在屏幕上看到某些东西,它也存在于后台缓冲区中。您看到的记事本窗口的内容是缓冲区,或者是前缀缓冲区的副本,它被blit到DWM自己的秘密渲染缓冲区中(取决于您是否有合成)。或者,其他东西,一个GDI缓冲区,它被blit到DWM的缓冲区,或者其他。最有可能是后者,因为它使用GDI进行渲染。

当你翻转缓冲区时,后面的缓冲区显示在该regin屏幕上的任何内容上,你得到的是一个全黑的缓冲区(实际上是未初始化的,但可能是驱动程序非常善良,以便将内存归零)除了您清除白色的区域 这正是您应该期望的 - 您的glClear只影响了一个子区域,其余部分未定义,恰好是零(黑色)。

在内部,如果没有启用合成您可以在屏幕上看到的内容可以从大多数图形卡上的前缓冲区复制到后台缓冲区,这样您就可以看到原始内容记事本窗口的内容,如果您希望这样。然而,你将永远不会在你的后台缓冲区中神奇地拥有GDI窗口的内容(这也不适用于DWM,它也不能保证工作,它只能在大部分时间内完全适用)

如果你想要窗口的原始内容,那么干净的解决方案是从DC到内存的BitBlt,创建一个纹理,并将一个纹理绘制(或blit)到后面的缓冲区。