【问题标题】:Rotating with glRotatef causes warping使用 glRotatef 旋转会导致翘曲
【发布时间】: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);   

}

不完全确定去哪里尝试解决这个问题,我自己对其他显然没有这个问题的人的研究只是导致了脱发。如果需要更多代码或更多图片,请相信我,我会竭诚为您提供帮助。

【问题讨论】:

    标签: opengl lwjgl glrotate


    【解决方案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' 用于两者,因为我希望矩形在任一方向上都是正方形,并将其设置为宽度和高度的相同变量使其更简单。
      猜你喜欢
      • 2012-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-28
      • 1970-01-01
      • 1970-01-01
      • 2016-04-09
      • 1970-01-01
      相关资源
      最近更新 更多