4

現在開発中のゲームにいくつかの単純な 3D 機能を実装しようとしています。この目標を達成するためにLibGDX ゲーム エンジンを利用しています。これは OpenGL ES とうまく統合されているように見えBufferますが、Java で画像から単純なオブジェクトを作成する方法を理解できないことに起因する問題に遭遇しました。

問題

私の目標は、キューブを 3D 空間で回転させ、その上にテクスチャを配置することです。Buffer問題は、立方体をレンダリングして回転させることはできましたが、立方体をテクスチャリングするために実際に画像を にデコードする方法に関するチュートリアル、コード例、またはドキュメントを見つけることができないことです。Androidでこれを行う方法を示すかなりの数の例を見つけましたが、これBitmapFactory.decodeResource(<your_image here>)により、Android SDKでメソッドを使用する必要が制限されます。これは、コードを多くの人に移植できるようにしようとしているため、私にとってはオプションではありませんプラットフォーム。

このため、OpenGL ES にパッケージ化されている方法を利用するために、画像 (.bmpファイル) をにデコードする方法を何らかの形で見つけなければならないという結論に達しました。BufferGdx.gl10.glTexImage2D()

これまでに試したこと

私は解決策を見つけるために多くの選択肢を追求してきました。

  • LibGDX パッケージに付属するクラスにTexture.bind()組み込まれているメソッドを活用します。Texture
  • Java ImageIOパッケージを使用して画像をデコードしようとしています。
  • image4jライブラリなどの他のデコード ツールを使用する。

いくつかのコード

Cube をレンダリングするために使用しているコードの一部を次に示します。わかりやすくするために、OpenGL の「スイッチ フリッピング」の多くは省略されています。何か見落としがあると思われる場合は、コメントを投稿してください。別のクラスの別の部分にあるだけかどうかを確認します。

このコードはふるいにかけるのがかなり難しいことを知っているので、必要に応じてコメントするように最善を尽くしました.

このコードは私の現在の実装を表しており、以下の「デバッグ情報」セクションに関連するコードであることに注意してください。

public void draw(){

    // This is used to hold the OpenGL pointer to the texture      
    int[] textures = new int[1];

    // Tells the GPU to render the vertices in a clockwise manner   
    Gdx.gl10.glFrontFace(GL10.GL_CW);

    // Informs OpenGL of the location of the vertices
    Gdx.gl10.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);

    // Bind the texture pointer in OpenGL to the texture
    Gdx.gl10.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    // This is the function I found in LibGDX that I think I am supposed to use?
    mTexture.bind();

    // Some "switch-flipping" in OpenGL
    Gdx.gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
            GL10.GL_NEAREST);

    Gdx.gl10.glTexParameterf(GL10.GL_TEXTURE_2D,
            GL10.GL_TEXTURE_MAG_FILTER,
            GL10.GL_LINEAR);

    Gdx.gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
            GL10.GL_CLAMP_TO_EDGE);

    Gdx.gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
            GL10.GL_CLAMP_TO_EDGE);

    Gdx.gl10.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
            GL10.GL_REPLACE);

    // This tells OpenGL to assign my Texture to the 3D Image
    Gdx.gl10.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGB, 256, 256, 0, GL10.GL_RGB, GL10.GL_UNSIGNED_BYTE, mTexture);

    // Finally, this draws the objects to the screen
    Gdx.gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
}

私の質問

BufferJavaで画像を直接デコードするにはどうすればよいですか? これができない場合、LibGDX で 3D オブジェクトをテクスチャ化するにはどうすればよいですか? 他に相談すべきリソースはありますか?

デバッグ情報

最終更新: 2013 年 3 月 19 日午後 12 時 45 分 (EST)

これは、アプリケーションの現在のデバッグ プロセスに関連する情報です。この問題の進行に合わせて更新します。

  • 現時点では、アプリケーションを実行するとエラーが発生しますInvalid memory access of location 0x0 rip=0x11dc77564。おそらく、この実装は正しいものであり、他の場所で構文が欠落しているだけですか?
  • 現在、いくつかのフォーラムをふるいにかけた後に見つけたこの追加リソースを調査しています。
  • Meshここでは、オブジェクトが正しいルートであるように見えます。私はこの実装を追求し、結果を更新しようとします! LibGDX チームによって「非推奨」と見なされているため、以前はこれを見つけることができませんでした。そのため、これがすぐに置き換えられるかどうかはわかりません。

補足情報

私の質問に答える際に考慮すべき点は次のとおりです。

  • 私はLibGDX Game Engineを使用してこれを行っていることに注意してください。そのため、この問題に関して彼らのフォーラムにも投稿します。

  • BufferedImageさらに、 Image からa を取得する方法はたくさんあるようですが、そこBufferからa を抽出する方法はありませんBufferedImage。ここで明らかに明らかなことを見落としているだけですか?BufferedImage本当に必要なのはそれだけですか?

  • ビルド パスに Android SDK を含めるだけではなく、単純なBitmapFactory.decodeResource(<your_image_here>)方法を使用したいと思います。

  • 現在、互換性の理由から OpenGL ES 1.0 を使用してこれを実装しようとしています。

4

1 に答える 1

2

Mesh生の OpenGL テクスチャとバッファ API を避けて、LibgdxとTextureラッパーに固執する必要があると思います。それらは、OpenGL の詳細を隠しています。もちろん、OpenGL の詳細について知りたい場合は、これはあまり役に立ちません。(しかし、おそらく、Libgdx API で動作するようになり、そのソースを調べて、実際に何が起こっているかを確認できます)。

最初のステップは、 (を使用していない場合はMesh生のOpenGL 頂点リスト) に、各頂点の有効な (u, v) テクスチャ座標が含まれていることを確認します。これらの座標は、レンダリング時に「現在の」テクスチャを参照します。https://code.google.com/p/libgdx/wiki/MeshColorTexture#Textureを参照してください。 mVertexBufferMesh

まず、メッシュを定義して、各頂点にテクスチャ情報を含めます。

mesh = new Mesh(true, 3, 3, 
            new VertexAttribute(Usage.Position, 3, "a_position"),
            new VertexAttribute(Usage.ColorPacked, 4, "a_color"),
            new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords"));

(このメッシュにもカラー データがありますが、生のカラー データをブレンドしたくない場合は、"a_color" を使用してラインを省略できます。)

もう 1 つの準備ステップは、テクスチャ ファイルを Libgdx テクスチャにロードすることです。ファイルが標準の「資産」の場所にパッケージ化されていると仮定すると、相対パスでロードできるはずです。

Texture texture = new Texture("path/to/image.bmp");

Libgdx は通常、BMP、PNG、および JPEG ファイル形式を読み込んで解析できます。他の形式の場合は、Pixmap自分でオブジェクトを作成し、それをTexture.

次に、各頂点に (u,v) テクスチャ座標が関連付けられていることを確認します。

mesh.setVertices(new float[] { -0.5f, -0.5f, 0, Color.toFloatBits(255, 0, 0, 255), 0, 1,
                                0.5f, -0.5f, 0, Color.toFloatBits(0, 255, 0, 255), 1, 1
                                0, 0.5f, 0, Color.toFloatBits(0, 0, 255, 255), 0.5f, 0 });

上記の各行は、各頂点の「(x、y、z、rgba、u、v)」を定義します。(「rgba」は、1 つのフロートに押しつぶされた色全体です。)

この時点Meshで、Color情報とテクスチャ (u、v) 座標を使用して を定義しました。

2 番目のステップは、render呼び出し中にテクスチャをバインドすることです。そのため、(u, v) 座標にはMesh参照するものがあります。

texture.bind();
mesh.render(GL10.GL_TRIANGLES, 0, 3);

OpenGL テクスチャまたは頂点 API を直接使用する必要はありません。

于 2013-03-19T16:52:14.157 に答える