LWJGL和纹理加载 - 似乎在每一帧都创建一个新对象

时间:2013-11-07 19:27:57

标签: textures lwjgl

所以我刚刚开始使用LWJGL,我正在尝试创建一个简单的2D平台游戏。我现在争论的问题是纹理加载。问题是,只要我在main方法的类中保留所有与纹理加载相关的方法,一切都工作得很好。

只要我将TextureHandler方法添加到loadTexture()方法中,只要我将其移到单独的班级drawTexture()中,它就无法工作。问题是,就我所知,它每帧都在不停地制作新物体。我已经谷歌了几个小时,但我不能找到解决方案。

主要课程:

public class Main {
    String playerPath = "res/PlayerNeutral.png";

    public void render() {
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
    }

    public void initGL() {
        try {
            Display.setDisplayMode(new DisplayMode(800, 600));
            Display.create();
            Display.setVSyncEnabled(true);
        }
        catch (LWJGLException e) {
            e.printStackTrace();

            System.exit(0);
        }

        // Initiating OpenGL
        GL11.glViewport(0, 0, 800, 600);
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glEnable(GL11.GL_TEXTURE_2D);

        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

        // Enables the Alpha Blending
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

        GL11.glMatrixMode(GL11.GL_MODELVIEW);

        GL11.glOrtho(0, 800, 0, 600, 1, -1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    }

    public void start() {
        initGL();

        TextureHandler.loadTexture(Player.playerText, playerPath);

        while (!Display.isCloseRequested()) {
            render();
            TextureHandler.drawTexture(Player.playerText, playerPath);          
            Display.update();
        }

        Display.destroy();      
    }

    public static void main(String[] args) {
        Main test = new Main();
        test.start();
    }

TextureHandler类:

public class TextureHandler {
    public static void textRelease(Texture text){
        text.release();
    }

    public static void loadTexture(Texture texture, String path){
        try {
            texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));

            System.out.println("Texture loaded: "+texture);
            System.out.println(">> Image width: "+texture.getImageWidth());
            System.out.println(">> Image height: "+texture.getImageHeight());
            System.out.println(">> Texture width: "+texture.getTextureWidth());
            System.out.println(">> Texture height: "+texture.getTextureHeight());
            System.out.println(">> Texture ID: "+texture.getTextureID());

            TextureImpl.unbind();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void drawTexture(Texture texture, String path) {
        try {
            texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));

            System.out.println("Texture loaded: "+texture);
            System.out.println(">> Image width: "+texture.getImageWidth());
            System.out.println(">> Image height: "+texture.getImageHeight());
            System.out.println(">> Texture width: "+texture.getTextureWidth());
            System.out.println(">> Texture height: "+texture.getTextureHeight());
            System.out.println(">> Texture ID: "+texture.getTextureID());
        } catch (IOException e) {
            e.printStackTrace();
        }

        Color.white.bind();
        texture.bind();

        GL11.glBegin(GL11.GL_QUADS);
            GL11.glTexCoord2f(0, 1);
            GL11.glVertex2f(100, 100);
            GL11.glTexCoord2f(1, 1);
            GL11.glVertex2f(100+texture.getTextureWidth(), 100);
            GL11.glTexCoord2f(1, 0);
            GL11.glVertex2f(100+texture.getTextureWidth(), 100+texture.getTextureHeight());
            GL11.glTexCoord2f(0, 0);
            GL11.glVertex2f(100, 100 + texture.getTextureHeight());
        GL11.glEnd();

        texture.release();
    }
}

玩家类:

public class Player {
    private int x;//x pos on screen
    private int y;//y pos on screen
    public static Texture playerText;

    // method for moving the player object around
    public void move() {
        if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT))
            x++;
        if (Keyboard.isKeyDown(Keyboard.KEY_LEFT))
            x--;
        if (Keyboard.isKeyDown(Keyboard.KEY_UP))
            y++;
        if (Keyboard.isKeyDown(Keyboard.KEY_DOWN))
            y--;
    }
}

1 个答案:

答案 0 :(得分:0)

这是因为在您的drawTexture()方法中,您可以执行以下操作。

try {
    texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));

    System.out.println("Texture loaded: "+texture);
    System.out.println(">> Image width: "+texture.getImageWidth());
    System.out.println(">> Image height: "+texture.getImageHeight());
    System.out.println(">> Texture width: "+texture.getTextureWidth());
    System.out.println(">> Texture height: "+texture.getTextureHeight());
    System.out.println(">> Texture ID: "+texture.getTextureID());
} catch (IOException e) {
    e.printStackTrace();
}

只需从drawTexture()方法中删除上述代码即可。

纹理仍然会被加载,因为在进入渲染循环之前,您已经通过调用loadTexture()方法执行了一次。

修改

  

我很确定我已经尝试过了。我确实想要记住我把它放在那里因为没有它就行不通,如果你愿意的话,可以“快速修复”。

正如你所说,我刚刚意识到了什么。您的loadTexture()方法已经过时了。这可能是因为你不知道你不能做那样的事情。

引用在Java中通过值传递。这意味着,当您通过方法传递变量时,该变量就是该方法的局部变量。因此,更改方法内部的变量不会更改原始变量。

实施例

我希望您能理解以下示例。如果要为变量分配新内容,则无法使用通过该方法传递的变量来执行此操作。您需要将其返回然后进行分配。

public class PassingVariables {
    public static void main(String[] args) {
        String s = "Hello World!";

        System.out.println(s); // Prints | Hello World!

        test1(s);

        System.out.println(s); // Prints | Hello World!

        s = test2(s);

        System.out.println(s); // Prints | Testing...

        s = test3(s);

        System.out.println(s); // Prints | Hello World!
    }

    private static String test1(String s) {
        System.out.println(s); // Prints | Hello World!

        s = "Testing...";

        System.out.println(s); // Prints | Testing...
    }

    private static String test2(String s) {
        System.out.println(s); // Prints | Hello World!

        return "Testing...";
    }

    private static String test3(String s) {
        System.out.println(s); // Prints | Testing...

        return "Hello World!";
    }
}

新代码

这是您的代码,我已经更改了一些内容,以便在我们考虑到上述内容时能够正常运行。

public static Texture loadTexture(String path) {
    Texture texture = null;

    try {
        texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));

        /* Removed all your println to spare some lines in the answer */

        TextureImpl.unbind();
    }
    catch (IOException e) {
        e.printStackTrace();
    }

    return texture;
}

public static void drawTexture(Texture texture) {
    Color.white.bind();
    texture.bind();

    GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(0, 1);
        GL11.glVertex2f(100, 100);
        GL11.glTexCoord2f(1, 1);
        GL11.glVertex2f(100+texture.getTextureWidth(), 100);
        GL11.glTexCoord2f(1, 0);
        GL11.glVertex2f(100+texture.getTextureWidth(), 100+texture.getTextureHeight());
        GL11.glTexCoord2f(0, 0);
        GL11.glVertex2f(100, 100 + texture.getTextureHeight());
    GL11.glEnd();

    /* 
     * I don't recognize the release() method, but if it deletes the texture
     * then remove if. If it simply unbinds the texture then keep it. If it
     * does remove it, then change it to something like unbind(), if such
     * method exist.
     */
    texture.release();
}

public void start() {
    initGL();

    Player.playerText = TextureHandler.loadTexture(playerPath);

    while (!Display.isCloseRequested()) {
        render();
        TextureHandler.drawTexture(Player.playerText, playerPath);          
        Display.update();
    }

    Display.destroy();      
}