1

Blender のモデルを .obj ファイルにエクスポートしました。頂点とインデックスを配列にロードする非常に単純なクラスを作成することができました。私の問題は、テクスチャ座標 (vt) と法線 (vn) も必要なことです。したがって、たとえば、単純な立方体でテクスチャを使用できるようにするには、4 つの頂点 * 6 つの面が必要ですが、.obj ファイルでは 8 つしか得られず、インデックスの処理方法についての手がかりもありません。 vt インデックス用の配列/バッファは 1 つしか持てないため、.obj ファイルで 2 つの異なる v/vt を取得します。

頂点、テクスチャ、法線、およびインデックスの 1 つの配列に対して配列または類似のもののみを返すローダーはありますか? または、書き方の例はありますか?これまでのところ、完全な 3D エンジンでのみローダーを見つけましたが、それは私が望んでいるものではありません。

4

2 に答える 2

1

4 つの頂点 * 6 つの面は必要以上です。実際、それは効率的ではありません。あなたが持っているエクスポートされた頂点は、インデックスで最適化されています。Opengl-es を使用すると、頂点 (配列) を取得する場所を指定し、別の配列のインデックスを使用して頂点を描画できます。結果として、可能な 24 個の頂点に対して 8 個の頂点が得られるため、保存に必要なメモリが少なくて済みます。したがって、効率は 16/24 *100% です。1000 個の頂点を持つモデルがあるとします。

頂点のインデックスは、適切なオフセットを持つ別の配列で、GPU が頂点 (size_of_vertex(3 floats)*index) と UV 座標の適切なオフセット (size_of_UVcoord(2 floats)*index) を取得することを意味します。

このコードはopengl ES 2.0用ですが、アイデアを得ることができます:

GLES20.glUseProgram(programTextured);

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
sqTex.getVertexBuffer().position(sqTex.VERT_OFFSET);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(programTextured, "aPosition") 3,                                    GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer());               GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aPosition"));

sqTex.getVertexBuffer().position(sqTex.TEXT_OFFSET);
GLES20.glVertexAttribPointer(
                                GLES20.glGetAttribLocation(programTextured, "aTextureCoord"), 2,
                                GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer());
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, sqTex.getIndexBuffer());

sqTEx は TexturedSquare のインスタンスです。

public class TexturedSquare {

        // private float[] vertices=new float[4];

        float vertices[] = { -1.0f, -1.0f, 0.0f,0.0f,0.0f, // 0, Top Left  //x,y,z,u,v
                        1.0f, -1.0f, 0.0f,0.0f,1.0f, // 1, Bottom Left
                        1.0f, 1.0f, 0.0f,1.0f,1.0f, // 2, Bottom Right
                        -1.0f, 1.0f, 0.0f,1.0f,0.0f, // 3, Top Right
        };

        public static int VERT_OFFSET=0;
        public static int TEXT_OFFSET=3;

        short[] indices = { 0, 1, 2, 2, 3, 0 };;

        // Our vertex buffer.
        private FloatBuffer vertexBuffer;

        // Our index buffer.
        private ShortBuffer indexBuffer;

        public TexturedSquare()
        {
                ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
                vbb.order(ByteOrder.nativeOrder());
                vertexBuffer = vbb.asFloatBuffer();
                vertexBuffer.put(vertices);
                vertexBuffer.position(0);

                // short is 2 bytes, therefore we multiply the number if
                // vertices with 2.
                ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
                ibb.order(ByteOrder.nativeOrder());
                indexBuffer = ibb.asShortBuffer();
                indexBuffer.put(indices);
                indexBuffer.position(0);

        }

        FloatBuffer getVertexBuffer(){
                return vertexBuffer;
        }

        ShortBuffer getIndexBuffer(){
                return indexBuffer;
        }



}
于 2011-05-05T03:32:23.793 に答える
0

jPCT (または jPCT-AE) を見てください。Java (および/または Android) 用の優れた 3D ライブラリです。すぐに使用できる 3ds/obj の読み込みをサポートしています。

于 2013-10-04T18:00:53.430 に答える