如何使用正交项目将 3d 渲染图像(透视项目)绘制回另一个视口。同时使用多个视口和 OpenGL [关闭]
Posted
技术标签:
【中文标题】如何使用正交项目将 3d 渲染图像(透视项目)绘制回另一个视口。同时使用多个视口和 OpenGL [关闭]【英文标题】:How to draw a 3d rendered Image (perspective proj) back to another viewport with orthogonal proj. simultaniously using multiple Viewports and OpenGL [closed] 【发布时间】:2013-12-16 03:28:15 【问题描述】:我的问题是我想拍摄 3d 场景的快照,操纵该快照并将其绘制回场景的另一个视口,
我刚刚使用 glReadPixel 方法读取图像。 现在我想使用现代 OpenGL 将该图像拉回到指定的视口。
我阅读了有关 FrameBufferObject (fbo) 和 PixelBufferObject (pbo) 以及将 FrameBufferObject 内容写回 gl2DTexture 并将其作为简单纹理传递给 FragementShader 的解决方案。
这种方式是否正确,或者任何人都可以提供一个简单的示例来说明如何使用现代 OpenGL 而不是已弃用的 glDrawPixel
方法将图像渲染回场景?
【问题讨论】:
这是一般的过程,虽然我不知道为什么在这个例子中你需要一个 FBO。当您想在屏幕外或纹理中绘制时,FBO 很有用,这不是您描述的这两件事。单独的 PBO 就绰绰有余了,术语“CPU 内存”在 OpenGL 中通常称为“客户端内存”;了解这一点可能会帮助您更好地理解实现这一点必须阅读的一些文档。 好吧,也许问题描述得不够充分。我有一个具有不同视口的应用程序。一个视口显示某种模拟,我只想将快照作为这个 3d 模拟的 2d 图像并对其进行操作并在另一个视口中显示结果。都是同时的。也许我的标题不正确。 您真的要在 CPU 上执行此操作吗?这是着色器的主要候选者,在这种情况下,FBO 将是您需要的唯一工具(除了着色器)。 是的,你的权利。我知道的性能问题。但起初我想看看它是否以这种方式工作,因为我想对图像执行的操作目前只是作为 c 代码可用。我知道我必须实现一个特殊的着色器。这是一个学术问题。 这个问题太宽泛了? OP 解释了他在做什么,提到了他尝试了什么,并询问了该怎么做。这是一个非常合理的问题,@AndonM.Coleman 和我都能够毫无困难地帮助他。 【参考方案1】:你想要做的整个过程看起来像这样
创建带有颜色和深度附件的 FBO。绑定吧。
渲染你的场景
将其颜色附件中的内容复制到客户端内存中,以对其执行所需的操作。*
将图像复制回 OpenGL 纹理(最好保持相同)。
绑定默认帧缓冲(0)
使用您的图像作为纹理贴图渲染全屏四边形。 (可能使用不同的着色器或切换着色器功能)。
您可能有的问题:
我必须渲染一个全屏四边形吗? 是的。您不能绕过顶点着色器。所以在某个地方只需要在 VBO 中用纹理坐标制作四个顶点,yada yada。
我的顶点着色器处理投影事物,我该如何处理那个四边形?您可以创建一个子例程来切换您在顶点着色器中处理顶点的方式。一种可以用于常规 3D 渲染(即从模型空间转换到世界/视图/屏幕空间),一种可以只是沿未修改的顶点发送的通道。您只需要在 (-1,-1) 到 (1,1) 的正方形的四个角上找到顶点。将它们发送到您的片段着色器,它会做您想做的事情。如果您不想使用子例程,您可以选择将所有矩阵设置为恒等式。
*如果你能找到一种在着色器中进行纹理操作的方法,我强烈推荐它。 GPU 就是为此构建的。
【讨论】:
不,我已经编写了能够为视口分配不同投影的东西,所以这应该没问题 但是我有一个问题。 Scissor 和 Viewport 之间有什么区别,以及在帧缓冲区中已经绘制了多个视口时调用 ReadPixels 会发生什么。这是我的问题 您可以使用glBlitFramebuffer (...)
来避免绘制全屏四边形。但这听起来可能很奇怪(因为 glBlitFramebuffer (...)
被设计为只做一件事),绘制全屏四边形往往比使用 glBlitFramebuffer (...)
将帧缓冲区数据从读取缓冲区复制到绘制缓冲区更快:)
啊,好吧,我已经在“SuperBible”中读到过这个,但它似乎无法解决我的问题。不过我会再看看。
至您的第二个可能的问题。你是完全正确的。我也有这个问题,我还考虑了一个不同的着色器,它只是忽略了视图投影。谢谢。在我看来,你是一个纯粹的专家。期待向您提出更多问题。以上是关于如何使用正交项目将 3d 渲染图像(透视项目)绘制回另一个视口。同时使用多个视口和 OpenGL [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 中的 OpenGL 中将坐标从 3D 透视投影映射到 2D 正交投影
Unity3D正交视图与透视视图 ( 正交视图概念 | 透视视图概念 | 观察点 | 正交视图作用 | 摄像机广角设定 | 透视畸变效果 )