1
votes

Iv'e exported a model in blender to a .obj file. Iv'e managed to create a very simple class that loads vertices and indices to arrays. My problem is that i want the texture coordinates (vt) and normals (vn) as well. So for example, i would need 4 vertices * 6 faces for a simple cube to be able to use texture but i only get 8 in my .obj file, as well as i don't have a clue about how to handle the indices for vt since i can only have one array/buffer for indices but i get two different v/vt in .obj file.

Is there any loader out there that only returns arrays or similar for vertex, texture, normals, and one array of indices? Or examples of how to write one? Iv'e only found loaders in complete 3d engines so far and that is not what i want.

2

2 Answers

1
votes

4 vertices * 6 faces is more than you need. Actually it will be not efficient. Exported vertices that you've got are optimized with indexes. Using Opengl-es you can point from where to get vertices(array) and then draw a vertices using their indexes in another array. In result you get 8 vertices versus possible 24 vertices, you need less memory to store. So efficience is 16/24 *100%. Imagine that you'll have a model with 1000 vertices.

Index of vertex means that in another array with a proper offset GPU will get a vertex (size_of_vertex(3 floats)*index) and a proper offset for UV coords (size_of_UVcoord(2 floats)*index)

this code for opengl ES 2.0 but you can get an idea:

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

and sqTEx is a instance of 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;
        }



}
0
votes

Look a jPCT (or jPCT-AE), it's an exellent 3D library for Java (and/or Android). It supports 3ds/obj loading out of the box.