首页 > 解决方案 > 是否可以在openGL(glViewport)中分离标准化设备坐标和窗口剪辑

问题描述

有没有办法将 NDC 转换为窗口,但单独指定剪切区域,使其与实际窗口大小匹配?

背景:我有一堆将 2D 地图呈现到窗口的 openGL 代码。这是很多复杂的代码,因为我同时使用 GPU 和 CPU 在地图上进行绘制,所以在这两个地方保持一致的坐标系很重要。为了简单起见,我使用 glViewport(0,0,mapSizeX, mapSizeY),现在地图坐标与帧缓冲区中的像素坐标很好地对应,这正是我所需要的。我可以使用 GLSL 绘制一些地图,调用 glReadPixels 并使用 CPU 在其上绘制,然后使用 glDrawPixels 将其发送回帧缓冲区,所有这些都使用相同的坐标系。最后我使用 GLSL 在上面画了一些最后的东西(我不想放大)。一切正常,除了...

窗口与地图的大小不同,glViewport 不只是设置转换。它还设置了剪辑。所以现在当我去画最后几个项目时,窗口比地图大,我在屏幕顶部附近画的东西会被剪掉。有解决方法吗?

标签: opengl2dclipping

解决方案


glViewport 不只是设置转换。它还设置了剪辑。

不,它只是设置了转换。当 NDC 到窗口空间的变换发生时,裁剪已经完成。那是在顶点处理之后立即发生的;您的顶点着色器(或您为转换顶点所做的任何事情)根据将顶点转换为剪辑空间的方式进行处理。

您应该使用视口来设置 NDC 框在窗口中的可见显示方式。您的 VS 需要处理到剪切区域的转换。所以它有效地决定了世界上有多少东西被放入到 NDC 盒子里。

基本上,您有地图空间(地图使用的坐标)和剪辑空间(顶点变换后的坐标)。并且您对实际要将地图的哪一部分绘制到窗口有一些概念。您需要转换您想要查看的地图区域,以使该区域的角出现在剪切框的角中(对于正交投影,这通常是 [-1, 1])。

在兼容性 OpenGL 中,这可能是通过使用glOrtho正交投影从您转换来定义的。在适当的顶点着色器中,您需要提供适当的正交矩阵。


推荐阅读