0

私は運がなければこの問題を解決しようとしました。メイン クラス、オブジェクト クラス、スプライト クラス、イメージ ローダー クラスの 4 つのクラスがあります。

イメージローダーを使用して、ここにある方法を使用してpngをロードしようとしています: http://www.java-gaming.org/topics/bufferedimage-to-lwjgl-texture/25516/msg/220280/view.html #msg220280を使用して ByteBuffer に変換し、OpenGL にバインドします。

画像は、独自の別のリソース フォルダーにあります。描画する必要があるのはこれです: ( http://i.imgur.com/j8GBU4c.png ) (32x32)、しかし、私が見ているのは、画像の寸法を持つ白いボックスですが、実際のテクスチャではありません.

誰かがこれを修正するためにどこに行くことができるかについて何か考えを持っているなら、私はそれを感謝します. 私は OpenGL が初めてで、実際のコードがどのように機能するかを学ぶために外部ライブラリの使用を避けたいと考えています。ありがとう。

更新しました!

フォローしている人には、Vallentin から提供された提案を実装しましたが、クワッドは画像の最初のピクセルの色を取得しています。CS hereが提供する画像ローダーの実装を試みました。しかし今、私はこのエラーを受け取っています:

javax.imageio.IIOException: Error reading PNG image data
at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1291)
at com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1560)
at pImageLoader.loadBIn(pImageLoader.java:60)
at Monkeybars.main(Monkeybars.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

Caused by: javax.imageio.IIOException: Destination type from ImageReadParam does not match!
at javax.imageio.ImageReader.getDestination(ImageReader.java:2862)
at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1263)
... 8 more

Exception in thread "main" java.lang.NullPointerException
at pImageLoader.loadpSprite(pImageLoader.java:75)
at Monkeybars.main(Monkeybars.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at     sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

Java 6を使用して、Windows 7でIntelliJ 12を使用しています。ロードしようとしている画像は上にリンクされています。誰かにアイデアがあれば、私は提案を受け付けています。

メインブロック:

   public static void main(String[] args){
    System.out.println("Sup!");
    int width = 800 ;
    int height = 600;
    try{
        Display.setDisplayMode(new DisplayMode(width,height));
        Display.setTitle("The Playground");
        Display.create();
    }catch (LWJGLException e){
        e.printStackTrace();
        Display.destroy();
        System.exit(1);
    }


    //Initialize OpenGL
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GL11.glOrtho(0, width, height, 0f, 1f, -1f);

    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    GL11.glLoadIdentity();
    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glDisable(GL11.GL_DEPTH_TEST);
    GL11.glEnable(GL11.GL_BLEND);



    pObject MrRedSquare = new pObject(300f,300f,pImageLoader.loadpSprite(pImageLoader.loadBIn("test.png")));

    while(!Display.isCloseRequested()){

        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
        MrRedSquare.drawMe();
        Display.sync(60);
        Display.update();
    }
}
}

テクスチャ ローダー、新しいメソッド。

public static BufferedImage loadBIn(String filepath){

    BufferedImage image;
    // get the reader
    ImageReader ir = ImageIO.getImageReadersByFormatName("png").next();

    // get the default param
    ImageReadParam p = ir.getDefaultReadParam();
    p.setDestinationType(
            // define the image type to return if supported
            ImageTypeSpecifier.createInterleaved(
                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
                    new int[] {0, 1, 2, 3},    // <-- the order of the color bands to return so the bytes are in the desired order
                    DataBuffer.TYPE_BYTE,
                    true, false)
    );

    try{
        InputStream stream = pImageLoader.class.getClassLoader().getResourceAsStream(filepath);
        ImageInputStream imageStream = ImageIO.createImageInputStream(stream);
        ir.setInput(imageStream);
        image = ir.read(0, p);
    }catch(Exception e){
        System.out.print("IMAGELOADER CANNOT OBTAIN ASSET");
        e.printStackTrace();
        return null;

    }
    return image;

}

アーカイブ目的で保持されている古いコード

主要:

public static void main(String[] args){
    System.out.println("Sup!");
    try{
        Display.setDisplayMode(new DisplayMode(800,600));
        Display.setTitle("The Playground");
        Display.create();
    }catch (LWJGLException e){
        e.printStackTrace();
        Display.destroy();
        System.exit(1);
    }


    //Initialize OpenGL
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GL11.glOrtho(0, 800, 0, 600, 1, -1);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);


    pObject MrRedSquare = new pObject(300,300,pImageLoader.loadpSprite(pImageLoader.loadBI("square.png")));

    while(!Display.isCloseRequested()){
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        MrRedSquare.drawMe();
        Display.sync(60);
        Display.update();
    }
}

オブジェクト (描画コード):

    public void drawMe(){

    // store the current model matrix
    GL11.glPushMatrix();

    // bind to the appropriate texture for this sprite
    texture.bind();

    // translate to the right location and prepare to draw
    GL11.glTranslatef(x, y, 0);

    // draw a quad textured to match the sprite
    GL11.glBegin(GL11.GL_QUADS);
    {
        GL11.glTexCoord2f(0, 0);
        GL11.glVertex2f(0, 0);

        GL11.glTexCoord2f(0, texture.getHeight());
        GL11.glVertex2f(0, height);

        GL11.glTexCoord2f(texture.getWidth(), texture.getHeight());
        GL11.glVertex2f(width,height);

        GL11.glTexCoord2f(texture.getWidth(), 0);
        GL11.glVertex2f(width,0);
    }
    GL11.glEnd();

    // restore the model view matrix to prevent contamination
    GL11.glPopMatrix();

} 

テクスチャ:

public class pSprite {

protected ByteBuffer spriteData;
protected BufferedImage spriteImage;
protected int id;

protected int width;
protected int height;

//---------------------------------------------------------------------------------------
//Constructors:

pSprite(BufferedImage sI, ByteBuffer s, int i){
    spriteImage = sI;
    spriteData = s;
    id = i;

    width = spriteImage.getWidth();
    height = spriteImage.getHeight();
}
//---------------------------------------------------------------------------------------
//Methods:
public void bind(){
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
} 

イメージローダー:

public class pImageLoader {

public static BufferedImage loadBI(String filepath){
    BufferedImage image;
    try{
        InputStream input = pImageLoader.class.getResourceAsStream(filepath);
        image = ImageIO.read(input);
    }catch (Exception e){
        System.out.print("IMAGELOADER: Cannot obtain asset.");
        e.printStackTrace();
        return null;
    }
    return image;
}

public static pSprite loadpSprite(BufferedImage image){

    //http://www.java-gaming.org/topics/bufferedimage-to-lwjgl-texture/25516/msg/220280/view.html#msg220280

    int pixels[] = new int[image.getWidth() * image.getHeight()];
    image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
    ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4); // <-- 4 for RGBA, 3 for RGB

    for(int y = 0; y < image.getHeight(); y++){
        for(int x = 0; x < image.getWidth(); x++){
            int pixel = pixels[y * image.getWidth() + x];
            buffer.put((byte) ((pixel >> 16) & 0xFF));     // Red component
            buffer.put((byte) ((pixel >> 8) & 0xFF));      // Green component
            buffer.put((byte) (pixel & 0xFF));               // Blue component
            buffer.put((byte) ((pixel >> 24) & 0xFF));    // Alpha component. Only for RGBA
        }
    }

    buffer.flip();

    int textureID = glGenTextures(); //Generate texture ID
    glBindTexture(GL_TEXTURE_2D, textureID);

    // Setup wrap mode
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);

    //Setup texture scaling filtering
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    //Send texel data to OpenGL
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    return new pSprite(image, buffer, textureID);
    }
}
4

3 に答える 3

2

あなたのコードには多くの問題があります。私が見つけた最も重要な問題は次のとおりです。

1)あなたの問題は、32ビット画像(つまりRGBA)を使用していないが、24ビット画像(つまりRGB)を使用しているという事実から始まります。

したがって、画像タイプを指定するために使用したコードは間違っています。以下を使用する必要があります。

p.setDestinationType(
    // define the image type to return if supported
    ImageTypeSpecifier.createInterleaved(
                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
                    new int[] {0, 1, 2}, // <-- you are expecting 3 color bands since your image is RGB 
                    DataBuffer.TYPE_BYTE,
                    false,   //<-- this is alpha, your image doesn't have any
                    false)
);

2)画像変換プロセスのコメントの指示に従って、ByteBufferサイズのを使用することになっていますwidth * height * 3。一般的に、これは真実です。ただし、LWJGL ではそれができないようです (長方形の寸法を強制しますか?) ので、この値をそのままにして4、アルファを次のように変更する必要があります。

buffer.put((byte) 0xFF);    // alpha always 1.0 i.e. opaque

これにより、画像が正しく読み込まれます。元のコードの追加の問題 ( の使用を忘れたこと以外glEnable(GL_TEXTURE_2D)) は、ブレンド関数を設定していなかったことです (ところで、これを一度設定すれば、すべてのフレームで設定する必要はありません)。そのため、32 ビット テクスチャを使用した場合でも、透明な領域は黒く表示されます。

3) 3 つ目の問題は、使用するテクスチャ座標を指定するときに、テクスチャglTexCoord2f(texture.getWidth(), texture.getHeight());座標が から[0, 1]. これが機能する唯一の方法は、 のテクスチャ パラメータを設定した場合で GL_TEXTURE_WRAP_SGL_TEXTURE_WRAP_T両方ともGL_REPEAT(デフォルト) を使用します。ただし、に設定していGL_CLAMP_TO_EDGEます。したがって1、最終的な画像よりも大きなテクスチャ値を指定すると、画像の境界線の色になります。

したがって、以下のようにコードを変更する必要があります。

GL11.glBegin(GL11.GL_QUADS);
{
    GL11.glTexCoord2f(0, 0);   // <--
    GL11.glVertex2f(0, 0);

    GL11.glTexCoord2f(0, 1);   // <--
    GL11.glVertex2f(0, height);

    GL11.glTexCoord2f(1, 1);   // <--
    GL11.glVertex2f(width, height);

    GL11.glTexCoord2f(1, 0);   // <--
    GL11.glVertex2f(width,0);
}

私のアドバイスは、テクスチャを試しているときは、大きな単純な画像を使用して、何が起こっているか (正しいアルファ、上下逆など) を確認できるようにすることです。 「機能しない」以外のテクスチャの問題を特定します。

それが役立つことを願っています

于 2013-08-18T08:12:31.960 に答える
0

glEnable(GL_TEXTURE_2D);テクスチャ/マテリアルを使用して OpenGL をレンダリングできるようにすることで、OpenGL を初期化する場所にそれを配置する必要があるようです。

有効にしない場合、説明したように、顔は真っ白にレンダリングされます。

于 2013-08-16T06:21:10.257 に答える