使用 glRotatef 旋转会导致翘曲
Posted
技术标签:
【中文标题】使用 glRotatef 旋转会导致翘曲【英文标题】:Rotating with glRotatef causes warping 【发布时间】:2016-11-03 11:19:44 【问题描述】:我正在尝试将玩家的图像旋转到他们指向的位置。从技术上讲,这很好用。将图像变换到中心后沿Z轴旋转,然后再变换回来,没问题。
但是,当它被渲染时,当角度指向窗口的较宽部分时,图像会被挤压,就好像它试图按比例对图像进行归一化一样。如果我将分辨率设置为正方形(1080x1080、1440x1440 等),那么它可以正常工作,但任何不是正方形的矩形分辨率都会使其播放器图像变形。
我最初在尝试让环境围绕播放器的 x/y 坐标旋转时遇到了同样的问题,但是通过将 glViewport 设置为正方形来解决这个问题。
glViewport(0,0,width,width);
Warped when rotated 90 degrees
Normal when not rotated.
这些效果分别镜像 270 度和 180 度,并在所有其他角度逐渐相互转换。
Player.render() 的代码
glPushMatrix();
glTranslatef(
x/Main.width*2,
y/Main.height*2,
0);
glRotatef((float)angle,0f,0f,1f);
glTranslatef(
-x/Main.width*2,
-y/Main.height*2,
0);
drawTexture(t,x-w/2,y-w/2,w,w); //t = texture, w = width in pixels for texture to be mapped to
glPopMatrix();
还有drawTexture方法:
public static void drawTexture(Texture in,float x, float y,float w, float h)
//Main.width and Main.height are the window window width and height.
float nx = x*2/Main.width;
float ny = y*2/Main.height;
float nw = w*2/Main.width;
float nh = h*2/Main.height;
in.bind(0);
glTexEnvf(GL_TEXTURE_2D,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glDepthMask(false);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0f,1.0f,1.0f,1.0f);
glBegin(GL_QUADS);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glTexCoord2f(0, 1);
glVertex2f(nx,ny);
glTexCoord2f(1, 1);
glVertex2f(nx+nw,ny);
glTexCoord2f(1, 0);
glVertex2f(nx+nw,ny+nh);
glTexCoord2f(0, 0);
glVertex2f(nx,ny+nh);
glEnd();
glDisable(GL_BLEND);
glDepthMask(true);
不完全确定去哪里尝试解决这个问题,我自己对其他显然没有这个问题的人的研究只是导致了脱发。如果需要更多代码或更多图片,请相信我,我会竭诚为您提供帮助。
【问题讨论】:
【参考方案1】:在一个可爱的早上 5:30,我想通了。
修复了播放器渲染的代码
glPushMatrix();
glTranslatef(
x/Main.width*2,
y/Main.height*2,
0);
glScalef(1f,(float)Main.width/Main.height,1f);
glRotatef((float)angle,0f,0f,1f);
glScalef(1f,(float)Main.height/Main.width,1f);
glTranslatef(
-x/Main.width*2,
-y/Main.height*2,
0);
drawTexture(t,x-w/2,y-w/2,w,w);
glPopMatrix();
(注意围绕旋转添加的缩放函数)。 必须添加这些,因为我在每一帧的开头添加了另一个缩放功能,它可以缩放所有内容以在所有分辨率下看起来都正常:
glScalef(1f,(float)Main.height/Main.width,1f);
因为否则它会将 300 像素的宽度视为 169 像素的高度,由于 LWJGL 采用比例浮点参数的方式(在两个方向上为 -1f 到 +1f,这个缩放函数将其更改为 -1f 到 +1f高度,宽度为 -1.78f 到 +1.78f,宽高比为 16:9。这使得纹理贴图在旋转时变得很奇怪,所以如果我按相反的比例缩放它以使其达到 1:1,旋转,然后按比例缩小以达到比例,那么一切都很好。
希望我的解释是可以理解的。 第一次玩这个,所以生活和学习。
【讨论】:
【参考方案2】:我相信你调用 drawTexture 以高度为宽度。
【讨论】:
drawTexture(t,x-w/2,y-w/2,w,w);这是你的代码。最后一个参数是高度,但似乎是宽度。 不知道 w 是什么,但发现它很奇怪,因为您的算法适用于正方形分辨率,并且您传递的参数与宽度和高度相同。 如果我想任意拉伸纹理以获得视觉效果,或者纹理不是方形的,我会使用它。纹理是正方形的,drawTexture 的宽度和高度只是指定了我希望纹理映射到的矩形。所以我可以拥有相同的纹理,并在飞行中在任一方向上使其变小或变大。 'w' 用于两者,因为我希望矩形在任一方向上都是正方形,并将其设置为宽度和高度的相同变量使其更简单。以上是关于使用 glRotatef 旋转会导致翘曲的主要内容,如果未能解决你的问题,请参考以下文章
API 调用期间的 Android 屏幕旋转会产生 kotlinx.coroutines.JobCancellationException