opengl es渲染屏幕部分到纹理

时间:2014-11-13 11:50:06

标签: android opengl-es

我正在使用FBO,我需要将屏幕的一部分渲染为纹理。我需要限制全屏渲染,所以我只得到一个渲染到纹理的屏幕的小窗口(然后我将模糊该部分并将其作为纹理渲染回屏幕)。

问题是我对视口,透视和视图矩阵的处理有点困惑。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

我假设您正在绘制一些场景,并且您希望仅将该屏幕的一部分渲染到FBO,其具有与您要重绘的部分成比例的大小。或者换句话说,FBO与您想要重绘的屏幕部分一样大。

创建适当大小的FBO(可能需要POT尺寸)后,您需要将视口设置为与要重绘的部分的大小相同,并且原点保持为(0,0)。接下来需要更改的是矩阵的投影部分,在大多数情况下是glOrthoglFrustum。这两个都有4个边框参数(左,右,上,下)。这些参数需要设置为您正在重绘的场景的哪个部分,这取决于两者,在主场景上如何设置边框参数以及在您的重绘矩形定义的坐标系中。例如,如果要重新绘制屏幕的左上角100x100部分并使用glOrtho和边框参数作为(0,0,viewWidth,viewHeight),则新边框参数只是(0,0,100,100)。但是,如果您使用类似(-1,-1,1,1)的内容,则需要根据您的屏幕(缓冲区)大小计算这些参数。

无论如何,您应该只通过更改这两种方法来管理它。完成绘制到FBO后,不要忘记重置它们。

编辑:协调系统转型

虽然这已经得到了很多回答,但这里有几次数学代码可以从一个坐标系转换到另一个坐标系。通常从原始场景中插入您的真实参数,这应该为您提供转换的边框参数,您应该将其插入到FBO平截头体中。

(我没有测试过,所以可能犯了错误)

    BorderParameters screenRect; // for instance (0, 0, 360, 480) (left, top, right, bottom)
    BorderParameters redrawRect; // for instance (0, 0, 36, 48) (left, top, right, bottom)
    BorderParameters frustumRect; // for instance (-1, ratio, 1, -ratio) (left, top, right, bottom)

    BorderParameters outputRect; // result (insert into ortho or frustum)

    outputRect.left = frustumRect.left + ((redrawRect.left-screenRect.left)/(screenRect.right-screenRect.left))*(frustumRect.right-frustumRect.left);
    // -1 + ((0-0)/(360-0))*(1+1) = -1
    outputRect.right = frustumRect.left + ((redrawRect.right-screenRect.left)/(screenRect.right-screenRect.left))*(frustumRect.right-frustumRect.left);
    // -1 + ((36-0)/(360-0))*(1+1) = -.8
    outputRect.bottom = frustumRect.top + ((redrawRect.bottom-screenRect.top)/(screenRect.bottom-screenRect.top))*(frustumRect.bottom-frustumRect.top);
    // ratio + ((48-0)/(480-0))*(-ratio-ratio) = ratio - .2*ratio = .8*ratio
    outputRect.top = frustumRect.top + ((redrawRect.top-screenRect.top)/(screenRect.bottom-screenRect.top))*(frustumRect.bottom-frustumRect.top);
    // ratio + ((0-0)/(480-0))*(-ratio-ratio) = ratio

我有点50%肯定这个整个程序现在我会想到它,但是,重绘部分可能会有轻微的偏移(如果它是一个很大的参数问题)。 无论如何,更常见的是将整个场景绘制到FBO,然后使用后期处理将其重绘到主缓冲区,而不是将所有元素重新绘制到一个小FBO,因为可能有很多元素要重绘到FBO。如果您希望屏幕上的许多小部分(例如10个)同时模糊,会发生什么情况,您是否会重绘整个场景11次以获得场景加上10个FBO?