OpenGL中图片尺寸和上屏尺寸不一致的变形问题解决

一、尺寸不一致问题:

图片加载到OpenGL纹理,再将纹理进行上屏的时候,可能会出现图片尺寸和屏幕尺寸不一致,导致图片绘制到屏幕时出现变形的问题:

二、根本原因:

原始图片的纹理尺寸(Texture),和用于绘制上屏的渲染缓冲区(RBO,画布)尺寸不一致。
而OpenGL内部对图像顶点坐标运算都是归一化的运算(-1.0 ~ 1.0),并且默认绘制的时候都是填满整个渲染缓冲区

三、解决办法:

根据原始图片尺寸和画布的尺寸,计算在绘制时的新的顶点坐标。

计算过程:

我们假设:
原始图片的宽高分别是ab
上屏的渲染缓冲区的宽高分别是:wh
OpenGL中图片尺寸和上屏尺寸不一致的变形问题解决_第1张图片

1.我们先讨论图片宽高比 大于> 屏幕宽高比的情况:(a/b > w/h)

OpenGL中图片尺寸和上屏尺寸不一致的变形问题解决_第2张图片
如上图,把图片居中到屏幕中央,不变形的情况。
此时,图片的宽 = 屏幕的宽w
按照不变形的情况,图片的高也要做一样比例的缩放,此时图片的高 = wb/a(图中蓝色虚线的部分)
OpenGL中图片尺寸和上屏尺寸不一致的变形问题解决_第3张图片
如上如,OpenGL的顶点坐标系是在屏幕中央。
对于上图这种情况,x坐标不变,y坐标需要缩小到某个值。如何计算y需要缩小到什么数值?
我们考虑最极端的情况:
原来占满屏幕的情况下,y最大值为 h/2 (半个屏幕,因为原点在中央)(绿线 + 一段红线的长度)
缩放之后,y最大值变为 wb/2a(绿线的长度)
因此,y的变化系数就是 (wb/2a)÷(h/2) = wb/ha

2.对于图片宽高比 小于< 屏幕宽高比的情况:(a/b < w/h)

推导过程与上述类似,y不变,x值的变化系数是ha/wb(跟上面y的系数互为倒数),有兴趣的同学可以自行推导

四、结论:

1.图片宽高比 > 屏幕宽高比(a/b > w/h)时:
顶点坐标变换:(x,y) >>>>> (x,y × wb/ha)
2.图片宽高比 < 屏幕宽高比(a/b < w/h)时:
顶点坐标变换:(x,y) >>>>> (x × ha/wb,y)

五、OpenGL实现:

在OpenGL中,对坐标的变换都在顶点着色器进行。
按上述结论,可以在顶点着色器中,对顶点的x值和y值分别计算,把计算后的坐标赋值给gl_Position

可以在外部计算宽高比值,也可以在着色器里计算比值

  • 在外部计算宽高比值的例子:
//c++代码部分
float xRatio = ha / wb;
float yRatio = wb / ha;
program->setUniform2f("correctFactor", xRatio, yRatio);
//顶点着色器
attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 texcoordOut;
uniform vec2 correctFactor;

void main()
{
    texcoordOut = a_texCoord;
    vec2 position = a_position * correctFactor;
	gl_Position = vec4(clamp(position, 0.0, 1.0), 0.0, 1.0);
}

缩放之后的效果:

你可能感兴趣的:(OpenGL,图像算法,图像处理,图形渲染,OpenGLES,OpenGL)