Java LWJGL玩家健康栏未正确定位

Java LWJGL玩家健康栏未正确定位,java,opengl,position,lwjgl,Java,Opengl,Position,Lwjgl,我正在用LWJGL和slick_util用Java制作一个游戏,最近我试图实现一个悬停在玩家头顶的健康栏。问题是,它没有正确定位。健康栏的左下角(从OpenGL开始绘制的位置)始终显示在播放器矩形的右上角,当播放器在x或y或两者中移动时,健康栏将以相同的方向远离播放器。我想这可能是GLTRANSTEF的问题,或者是我错过了一些愚蠢的东西 播放器的渲染方法: protected void render() { Draw.rect(x, y, 32, 32, tex); //Play

我正在用LWJGL和slick_util用Java制作一个游戏,最近我试图实现一个悬停在玩家头顶的健康栏。问题是,它没有正确定位。健康栏的左下角(从OpenGL开始绘制的位置)始终显示在播放器矩形的右上角,当播放器在x或y或两者中移动时,健康栏将以相同的方向远离播放器。我想这可能是GLTRANSTEF的问题,或者是我错过了一些愚蠢的东西

播放器的渲染方法:

protected void render() {
        Draw.rect(x, y, 32, 32, tex); //Player texture drawn
        Draw.rect(x, y + 33, 32, 15, 1, 0, 0); //Health bar drawn. x is the same as player's, but y is +33 because I want it to hover on top
    }
绘图类:

package rpgmain;
import static org.lwjgl.opengl.GL11.*;
import org.newdawn.slick.opengl.*;
/**
 *
 * @author Samsung
 */
public class Draw {

    public static void rect(float x, float y, float width, float height, Texture tex) {
        glEnable(GL_TEXTURE_2D);
        glTranslatef(x, y, 0);        
        glColor4f(1f, 1f, 1f, 1f);
        tex.bind();
        glBegin(GL_QUADS); //Specifies to the program where the drawing code begins. just to keep stuff neat. GL_QUADS specifies the type of shape you're going to be drawing.
        {
            //PNG format for images
            glTexCoord2f(0,1); glVertex2f(0, 0);  //Specify the vertices. 0, 0 is on BOTTOM LEFT CORNER OF SCREEN.
            glTexCoord2f(0,0); glVertex2f(0, height); //2f specifies the number of args we're taking(2) and the type (float)
            glTexCoord2f(1,0); glVertex2f(width, height); 
            glTexCoord2f(1,1); glVertex2f(width, 0);
        }
        glEnd();
        glDisable(GL_TEXTURE_2D);
    }

    public static void rect(float x, float y, float width, float height, float r, float g, float b) {
        glDisable(GL_TEXTURE_2D);
        glTranslatef(x, y, 0);
        glColor3f(r, g, b); 

        glBegin(GL_QUADS); //Specifies to the program where the drawing code begins. just to keep stuff neat. GL_QUADS specifies the type of shape you're going to be drawing.
        {                 
            glVertex2f(0, 0);  //Specify the vertices. 0, 0 is on BOTTOM LEFT CORNER OF SCREEN.
            glVertex2f(0, height); //2f specifies the number of args we're taking(2) and the type (float)
            glVertex2f(width, height);
            glVertex2f(width, 0); 
        }
        glEnd();
        glEnable(GL_TEXTURE_2D);
    }
}

我认为你的问题在于矩阵。调用glTranslatef时,您正在转换OpenGL ModelView矩阵。但是,由于OpenGL是一个基于状态的机器,因此此转换将保留以供进一步的绘图事件使用。第二个矩形将平移两次。您要做的是使用OpenGL矩阵堆栈。我将在此处重写其中一种绘图方法:

public static void rect(float x, float y, float width, float height, Texture tex) {
    glEnable(GL_TEXTURE_2D);
    glPushMatrix();
    glTranslatef(x, y, 0);        
    glColor4f(1f, 1f, 1f, 1f);
    tex.bind();
    glBegin(GL_QUADS);
    {
        glTexCoord2f(0,1); glVertex2f(0, 0);
        glTexCoord2f(0,0); glVertex2f(0, height);
        glTexCoord2f(1,0); glVertex2f(width, height); 
        glTexCoord2f(1,1); glVertex2f(width, 0);
    }
    glEnd();
    glPopMatrix();
    glDisable(GL_TEXTURE_2D);
}

行glPushMatrix()将向堆栈顶部添加一个新矩阵。从这一点开始的所有变换都将应用于新添加的矩阵。然后,当您调用glPopMatrix()时,该矩阵将被丢弃,堆栈将返回到其以前的状态。

:D工作得非常出色。虽然有效,但我还是想了解一件事。当我从我的游戏类中调用render方法时,该方法运行于每个游戏对象,并对其进行更新和渲染,我将glPushMatrix和glPopMatrix放在其中,并在它们之间调用特定游戏对象的渲染。通过在Draw方法中添加额外的Push和Pops,我是否向已经存在的父矩阵添加了新矩阵?或者我只是在主矩阵中添加一个新元素?提前感谢-REX,glPushMatrix()将OpenGL矩阵的当前状态保存到堆栈顶部。当前矩阵将不受影响,除非调用glLoadIdentity()会将矩阵恢复到上次调用glPushMatrix()时的状态。任何变换都将应用于该矩阵。调用glPopMatrix()时,将从堆栈顶部“弹出”一个矩阵,并成为当前矩阵。然后将矩阵恢复到上次调用glPopMatrix()时的状态。对glPopMatrix()的另一个调用将上升一个级别。