OpenGL渲染部分屏幕到纹理

时间:2014-06-19 15:33:39

标签: opengl screenshot render-to-texture projection-matrix

我正在尝试将屏幕的一个小区域渲染为离屏纹理。这是我的应用程序中的屏幕截图功能的一部分,用户在屏幕上选择一个区域并将其保存到图像中。虽然屏幕上的区域可能是250x250px,但保存的图像可能会像1000x1000px那样大得多。

我理解使用FBO渲染纹理的过程。在定义剪辑场景的投影矩阵以便只渲染屏幕截图区域时,我大多陷入困境。

2 个答案:

答案 0 :(得分:1)

我相信你可以在不改变投影矩阵的情况下做到这一点。毕竟,如果你想一想,你真的不想改变预测。您想要更改投影几何体的哪个部分映射到渲染表面。投影后的坐标系是NDC(标准化设备坐标)。控制NDC如何映射到渲染表面的变换是视口变换。您可以通过参数glViewport()控制视口转换。

如果将视口尺寸设置为渲染曲面的大小,则将NDC范围[-1.0,1.0]映射到渲染曲面。要将NDC范围的子范围渲染到曲面,需要相应地放大指定的视口大小。假设将原始图像的1/4映射到曲面的宽度,将视口宽度设置为曲面宽度的4倍。

要将标准NDC范围的子范围映射到曲面,还需要调整视口的原点。在这种情况下,视口原点值变为负值。继续上一个示例,要从图像中间开始映射1/4或原始图像,视口原点的x值将是表面宽度的-2倍。

以下是我提出的视口需要调整的方法。使用以下定义:

winWidth: width of original window
winHeight: height of original window
xMin: minimum x-value of zoomed region in original window coordinates
xMax: maximum x-value of zoomed region in original window coordinates
yMin: minimum y-value of zoomed region in original window coordinates
yMax: maximum y-value of zoomed region in original window coordinates
fboWidth: width of FBO you use for rendering zoomed region
fboHeight: height of FBO you use for rendering zoomed region

为避免失真,您可能需要保持宽高比:

fboWidth / fboHeight = (xMax - xMin) / (yMax - yMin)

在以下所有情况中,大多数操作(特别是分区)必须以浮点执行。如果原始变量是整数,请记住使用类型转换,并将结果舍入为整数以获得最终结果。

xZoom = winWidth / (xMax - xMin);
yZoom = winHeight / (yMax - yMin);
vpWidth = xZoom * fboWidth;
vpHeight = yZoom * fboHeight;
xVp = -(xMin / (xMax - xMin)) * fboWidth;
yVp = -(yMin / (yMax - yMin)) * fboHeight;
glViewport(xVp, yVp, vpWidth, vpHeight);

答案 1 :(得分:0)

您可能希望了解gluPickMatrix的工作原理并使用现代OpenGL方法复制其功能。您可以在Mesa3D的实现中找到gluPickMatrix源代码。

虽然gluPickMatrix的初衷是用于选择模式渲染,但它也可以用于你想要做的事情。