1

I'm trying to rotate the image of a player to where they are pointing. Technically, this works fine. It rotates the image along the Z axis after transforming to the center, and then transforms back, no problem.

However, when this is rendered, as the angle points towards the wide sections of the window, the image gets squished, as if it was trying to normalize the image proportionally. If I set the resolution to a square (1080x1080, 1440x1440, etc) then it works fine, but any rectangle resolution that isn't a square will have it's player image warped.

I originally had this same problem when trying to get the environment to rotate about the x/y coordinates of the player, but this was solved with setting glViewport to a square.

glViewport(0,0,width,width);

Warped when rotated 90 degrees

Normal when not rotated.

these effects mirror for 270 degrees and 180 degrees respectively, and gradually go between each other for all other angles.

Code for 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();

And the drawTexture method:

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);   

}

Not exactly sure where to go to try and resolve this issue, my own research into others that apparently have not had this problem has just resulted in hair loss. If more code is needed or more images, trust me I'll be at my knees for assistance.

2 Answers2

1

And at a lovely 5:30 in the morning, I figured it out.

Fixed code for the player rendering turned out to be

    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();

(note the addition of the scaling functions around the rotations). Those had to be added because I added another scale function at the beginning of each frame that scaled everything to look normal at all resolutions:

        glScalef(1f,(float)Main.height/Main.width,1f);

because otherwise it would treat 300 pixels of width as 169 pixels in height, due to the way that LWJGL takes proportional float arguments (-1f to +1f in both directions, this scaling function changes that to -1f to +1f in height, and -1.78f to +1.78f in width at a 16:9 aspect ratio. This made the texture map weirdly when it was rotated, so if I scale it by the opposite factor to get it to 1:1, rotate, then scale back to get to scaled ratios then all is well.

Hopefully my explanation is understandable enough. First time playing around with this, so live and learn.

-1

I believe you call drawTexture with hight as width.

  • drawTexture(t,x-w/2,y-w/2,w,w); It's your code. The last argument is the height but appears to be the width. – Johan Jönsson Nov 03 '16 at 14:59
  • Not knowing what w is thou, but finds it strange as your algorithm works with square resolution and you pass the same parameter as width and height. – Johan Jönsson Nov 03 '16 at 15:01
  • I use it in case I want to arbitrarily stretch a texture for visual effects, or if the texture isn't square. The texture is square, the drawTexture width and height just specifies the rectangle that I want the texture to map to. so I can have the same texture and make it smaller or bigger in either direction on the fly. 'w' is used in both because I want the rectangle to be square in either direction, and setting it to the same variable for width and height makes it simpler. – user7109452 Nov 04 '16 at 00:21