3

我已经编程了几年,想尝试 Java LWJGL,人们建议使用 Slick-Util 库,所以我设置了所有这些,等等。我一直在从事几个项目,从未遇到过这个问题. 但是,我遇到了一个问题,即在将纹理绑定到 openGL 时,每次都会绑定相同的错误纹理。我首先在一个包含一堆类等的项目中遇到了这个问题,并选择尝试将问题压缩到一个 jar 文件中。

所以在我展示代码之前,我想解释一下示例文件是如何工作的。基本上,我的项目中有四个 PNG。它们包含在 res/textures/character/texturesHere 中。PNG 的名称包括:char_d.png、char_u.png、char_l.png、char_r.png。我已经检查了所有四个,并且所有四个都具有角色方向的不同纹理,因为它应该是。这是为了证明项目的资源不是问题。这是浓缩成“主”类文件的整个问题。

package main_p;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.*;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;

import static org.lwjgl.opengl.GL11.*;

public class Main
{

    public final int srcWidth = 1280;
    public final int srcHeight = 720;

    public float x = 150;
    public float y = 150;
    public float w = 40;
    public float h = 40;

    public Texture char_down;
    public Texture char_right;
    public Texture char_left;
    public Texture char_up;

    public Main()
    {
        try
        {
            Display.setTitle("Escape Alpha v0.0.1");
            Display.setDisplayMode(new DisplayMode(srcWidth, srcHeight));
            Display.create();
        }
        catch (LWJGLException e)
        {
            e.printStackTrace();
        }

        initGL();
        initTextures();
        loop();
    }

    public void loop()
    {
        glClear(GL_COLOR_BUFFER_BIT);

        while (!Display.isCloseRequested())
        {
            glBegin(GL_QUADS);

                char_left.bind();
                glTexCoord2f(0, 0);
                glVertex2f(x, y);
                glTexCoord2f(1, 0);
                glVertex2f(x + w, y);
                glTexCoord2f(1, 1);
                glVertex2f(x + w, y + h);
                glTexCoord2f(0, 1);
                glVertex2f(x, y + h);

            glEnd();

            Display.update();
            Display.sync(60);
        }

        Display.destroy();
    }

    public void initGL()
    {
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0, srcWidth, srcHeight, 0, 1, -1);
        glMatrixMode(GL_MODELVIEW);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    }

    public void initTextures()
    {
        char_down = loadTextureFrom("character/char_d.png");
        char_up = loadTextureFrom("character/char_u.png");
        char_left = loadTextureFrom("character/char_l.png");
        char_right = loadTextureFrom("character/char_r.png");
    }

    public Texture loadTextureFrom(String path)
    {
        try
        {
            return TextureLoader.getTexture("PNG", new FileInputStream(new File("res/textures/" + path)));
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        return null;
    }

    public static void write(Object ob)
    {
        System.out.println(ob);
    }

    public static void main(String[] args)
    {
        new Main();
    }
}

我注意到的一件事是,在 initTextures() 方法中,如果我更改最后加载的纹理,我绑定的任何纹理最终都会渲染 initTextures() 中加载的最后一个纹理

在这个例子中,我绑定了 Texture char_left,但它使用了 char_right,因为它是我的 initTextures() 方法中最后加载的一个。我可以证明这一点,因为如果我更改在我的 initTextures() 方法中最后加载的纹理,它最终会渲染那个纹理,再次忽略我告诉它绑定的纹理。就像我说的那样,我已经多次检查了我所有的 PNG,它们看起来都很好,并且显示角色面向正确的方向。我的 loadTextureFrom(String path) 方法与任何其他纹理加载器一样。真的没什么特别的。实际上,我在 90% 的 Java LWJGL / Slick-Util 2D 项目中都使用了这种精确的方法,而且我最近才开始遇到这个问题。我不知所措,以前从未遇到过这个问题。任何帮助是极大的赞赏。:)

编辑1:

我刚刚做了一个重要的测试。在 initTextures() 方法中加载它们之后,我检查了所有四个纹理的 HashCode。

public void initTextures()
{
    char_left = loadTextureFrom("character/char_l.png");
    char_right = loadTextureFrom("character/char_r.png");
    char_down = loadTextureFrom("character/char_d.png");
    char_up = loadTextureFrom("character/char_u.png");

    write(System.identityHashCode(char_left));
    write(System.identityHashCode(char_right));
    write(System.identityHashCode(char_down));
    write(System.identityHashCode(char_up));
}

它返回了这个:

1364345882
1878339755
1246651385
1619367563

我认为这确实证明了 initTextures() 方法不是问题。再次感谢任何帮助!这种 100% 让我无法在任何项目上做更多的工作:/谢谢!:)

4

3 回答 3

1

我知道这是一篇旧帖子,但我不希望任何看到此内容的人无话可说。基本上,纹理绑定调用必须超出“glBegin”。这就是问题所在。您不能在 glBegin 调用中绑定纹理。如果你不这样做,gl 只会绑定最后加载的纹理。

于 2015-12-10T23:51:31.590 回答
0

我不知道这是否真的有帮助,但你的循环方法有问题。基本上你没有清除你的屏幕。你做 glClear(GL_COLOR_BUFFER_BIT); 在你的循环之前。可能导致此类问题的另一件事是您实际上必须在循环中启用和禁用 GL_BLEND。也几乎忘记了您没有glEnable(GL_TEXTURE_2D);在 initGl() 方法中启用。

public void loop()
{
    while (!Display.isCloseRequested())
    {
        glClear(GL_COLOR_BUFFER_BIT);

        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glBegin(GL_QUADS);

            char_left.bind();
            glTexCoord2f(0, 0);
            glVertex2f(x, y);
            glTexCoord2f(1, 0);
            glVertex2f(x + w, y);
            glTexCoord2f(1, 1);
            glVertex2f(x + w, y + h);
            glTexCoord2f(0, 1);
            glVertex2f(x, y + h);

        glEnd();

        glDisable(GL_BLEND);

        Display.update();
        Display.sync(60);
    }

    Display.destroy();
}
于 2013-05-13T16:32:18.047 回答
0

嗯试试这个,看看它是否有效。我在我的 2d 游戏中使用它,它在那里工作。

package game.utils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.lwjgl.opengl.GL11;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.util.ResourceLoader;

public class TextureLoader {
    private static Map<URL, Texture> texMap = new HashMap<>();

    public static void bindTexture(URL tex) {
        try {
            Texture texture = texMap.get(tex);
            if (texture == null) {
                texture = loadTexture(tex);
            }
            texture.bind();
            GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
            GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
        } catch (IOException e) {
            // TODO Auto-generated catch block.
            e.printStackTrace();
        }
    }

    public static void bindTexture(String tex) {
        try {
            bindTexture(ResourceLoader.getResource(tex));
        } catch (Exception e) {
            bindTexture("res/other/white.png");
        }
    }

    private static Texture loadTexture(URL tex) throws FileNotFoundException, IOException {
        System.out.printf("Loading texture %s (%s)%n", texMap.size(), tex.getFile());
        Texture texture = org.newdawn.slick.opengl.TextureLoader.getTexture("PNG", tex.openStream());
        texMap.put(tex, texture);
        return texture;
    }
}

您可以将“res/other/white.png”更改为您丢失的纹理文件。glTexParameterf 行也用于禁用 mipmap/filtering/无论它被称为什么。

于 2015-02-24T17:59:24.860 回答