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

文章讲述了在使用OpenGL加载图片到纹理并显示到屏幕上时,由于图片和屏幕尺寸不一致导致的变形问题。根本原因是纹理和渲染缓冲区尺寸不同。解决方法是根据原始图片和屏幕的宽高比计算新的顶点坐标,确保不变形。在顶点着色器中进行坐标变换,通过设置比例因子来调整x和y坐标。
摘要由CSDN通过智能技术生成

一、尺寸不一致问题:

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

二、根本原因:

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

三、解决办法:

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

计算过程:

我们假设:
原始图片的宽高分别是ab
上屏的渲染缓冲区的宽高分别是:wh
在这里插入图片描述

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

在这里插入图片描述
如上图,把图片居中到屏幕中央,不变形的情况。
此时,图片的宽 = 屏幕的宽w
按照不变形的情况,图片的高也要做一样比例的缩放,此时图片的高 = wb/a(图中蓝色虚线的部分)
在这里插入图片描述
如上如,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);
}

缩放之后的效果:
在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值