3

私は数年前からプログラミングを行っており、Java LWJGL を試してみたかったのですが、Slick-Util ライブラリの使用を勧められたので、すべてをセットアップしました。いくつかのプロジェクトに取り組んできましたが、この問題に遭遇したことはありません。 . しかし、openGL にテクスチャをバインドするときに、同じ間違ったテクスチャが毎回バインドされるという問題が発生しました。私は最初に、一連のクラスなどを含むプロジェクトでこの問題に遭遇し、問題を 1 つの jar ファイルに凝縮しようとしました。

コードを示す前に、サンプル ファイルがどのように機能するかを説明したいと思います。基本的に、私のプロジェクトには 4 つの PNG があります。res/textures/character/texturesHere に含まれています。PNG の名前は、char_d.png、char_u.png、char_l.png、char_r.png のようになります。4つすべてを確認しましたが、4つすべてがキャラクターの方向のテクスチャが異なるはずです. これは、プロジェクトのリソースに問題がないことを証明するためです。これは、「メイン」クラス ファイルに凝縮された問題全体です。

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

私が気づいたことの 1 つは、initTextures() メソッド内で、最後にロードされたテクスチャを変更すると、バインドしたすべてのテクスチャが initTextures() でロードされた最後のテクスチャをレンダリングすることになることです。

この例では、Texture char_left をバインドしますが、代わりに char_right を使用します。これは、initTextures() メソッドで最後に読み込まれたものだからです。initTextures() メソッドに最後にロードされたテクスチャを変更すると、代わりにそのテクスチャがレンダリングされ、バインドするように指示したテクスチャが再び無視されるため、これを証明できます。私が言ったように、私はすべての PNG を複数回チェックしましたが、それらはすべて見栄えがよく、キャラクターが正しい方向を向いていることを示しています。私の loadTextureFrom(String path) メソッドは、他のテクスチャ ローダーと同じです。本当にそれについて特別なことは何もありません。私は実際に Java LWJGL / Slick-Util の 2D プロジェクトの 90% でこの正確な方法を使用していますが、最近この問題に遭遇し始めました。私は言葉を失っており、これまでこの問題に遭遇したことはありません。どんな助けでも大歓迎です。:)

編集1:

重要なテストを行ったところです。initTextures() メソッド内にそれらをロードした後、4 つのテクスチャすべての 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); を実行します。あなたのループの前に。この種の問題を引き起こす可能性のあるもう 1 つのことは、ループ内で 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 行は、ミップマップ/フィルタリング/それが呼ばれるものを無効にするためのものです。

于 2015-02-24T17:59:24.860 に答える