1

我已经将搅拌机中的模型导出到 .obj 文件。我设法创建了一个非常简单的类,可以将顶点和索引加载到数组中。我的问题是我也想要纹理坐标(vt)和法线(vn)。因此,例如,我需要 4 个顶点 * 6 个面才能让一个简单的立方体能够使用纹理,但我的 .obj 文件中只有 8 个,而且我不知道如何处理索引vt 因为我只能有一个用于索引的数组/缓冲区,但我在 .obj 文件中得到了两个不同的 v/vt。

是否有任何加载器只返回顶点、纹理、法线和一个索引数组的数组或类似数组?或者如何写一个例子?到目前为止,我只在完整的 3d 引擎中找到了加载器,这不是我想要的。

4

2 回答 2

1

4 个顶点 * 6 个面超出了您的需要。实际上它不会有效率。您拥有的导出顶点已使用索引进行了优化。使用 Opengl-es,您可以指向从哪里获取顶点(数组),然后使用它们在另一个数组中的索引绘制顶点。结果你得到 8 个顶点而不是可能的 24 个顶点,你需要更少的内存来存储。所以效率是 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 回答