如何在两个视口之间实现清晰的分离?
我有2个视口,一个占全屏长度,另一个需要小于或等于屏幕尺寸的四分之一(我希望它是一个地图).问题是它们一直在干扰,我可以在大视口中看到大视频内容.
这是display()我正在使用的功能:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,newWidth,newHeight);
gluPerspective(45,(float)newWidth/(float)newHeight,0.2,500);
//setup view
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camera.render(crntMode, radiusNew);
//ground
glColor3f(0.5,0.5,0.5);
draw_ground(50,50,2,2,-2);
...
...
...
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(newWidth / 2, newHeight / 2, newWidth / 2, newHeight / 2);
gluPerspective(45,(float)newWidth/(float)newHeight,0.2,500);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camera.render(mini_map, radiusNew);
//ground
glColor3f(0.5,0.5,0.5);
draw_ground(50,50,2,2,-2);
...
...
...
//swap buffers
glutSwapBuffers();
Run Code Online (Sandbox Code Playgroud)

两个视口摄像机都遵循这个角色,一个来自第三人称视角,另一个来自自上而下.可能更难看,但迷你地图视口的背景干扰了大型背景(大型背景几乎作为迷你地图的背景).有时大视口覆盖小视口.
Nic*_*las 10
视口不是迷你窗户.视口只不过是主窗口中进行渲染的位置.所有渲染仍然发生在同一帧缓冲区中.出现此问题是因为两个视口都使用相同的深度缓冲区.OpenGL不知道您希望较大场景中的深度影响较小场景中的渲染.这只是OpenGL的一个场景,一个帧缓冲.
有许多方法可以解决这个问题,所有方法都有不同的性能影响/ OpenGL要求:
使用渲染两个场景之间清除深度缓冲区glClear(GL_DEPTH_BUFFER_BIT);.这是最简单的,但在性能方面成本最高.我只是为了完整起见而在此列出; 你应该改为使用:
先画出你的大场景.然后将视口设置为较小的场景.关闭深度测试,但请glDepthMask继续.然后绘制一个屏幕对齐的四边形,其Z为-1,其中四边形的范围在X和Y中为[-1,1].矩阵应该是投影和模型视图矩阵的标识.这将有效地清除场景的一部分的深度.
在绘制四边形之后,不要忘记打开深度测试.如果需要,也不要忘记修复你的矩阵.这仅在您绘制到新视口的每个像素时才起作用(除非您将四边形的颜色设置为预期的背景颜色).
先画出你的大场景.然后使用glScissor将剪刀盒设置为较小的场景,并用于glEnable(GL_SCISSOR_TEST)启用剪裁.之后,清除深度缓冲区glClear(GL_DEPTH_BUFFER_BIT).然后禁用剪刀测试并渲染较小的场景.
这就像#2,除了你不必画一个屏幕对齐的四边形.glClear当剪刀测试启用时,尊重剪刀盒,因此它只会清除剪切区域.
我提供这个作为一种替代,而不是建议的机制,因为OpenGL实现可以得到glClear和glScissor行为是错误的.这应该是首选机制.
使用深度范围.这可能会影响您的场景质量,但它可能是最快的(注意:除非您有真正的理由,否则您不应该关心.也就是说,只有在分析显示性能有问题时才这样做).对于你的主场景,使用glDepthRange(0.1, 1.0); 对于你的小场景,请使用glDepthRange(0.0, 0.1).
这实际上意味着小场景的所有深度值都将位于大场景的所有深度值的前面.但是,这也意味着您的大型场景将具有较低的深度精度,因此z-fighting可能是明显的.
你可以随意移动0.1; 你可以将范围分成0.5,但我个人建议不要这样做.小场景不太重要,在较小的分辨率下,z-fighting不太重要.因此,您应该为最重要的场景提供更高的精度.
将小场景渲染到FBO并将其blit到屏幕.这是最简单的推理.只需创建一些渲染缓冲区,一个用于颜色,一个用于深度.将它们粘贴在帧缓冲对象中.在那里渲染你的小场景.然后使用glBlitFramebuffer它将其绘制到默认帧缓冲区中所需的位置.
还有其他方法,例如使用模板测试,但这些是您可以依赖的方法.