【问题标题】:i want to make obj parsing in android我想在android中进行obj解析
【发布时间】:2020-10-25 15:26:41
【问题描述】:

你好,我是安卓开发者!!

这是我的 OBJ 文件加载器

我是用 opengles 做的

我正在尝试完全制作 obj loader

但结果是纹理混乱

我认为问题在于顶点位置归一化问题

然后最终我的纹理结果程序搞砸了

我很失望

如何在android中制作纹理

有什么问题?

the result is messed up

这个 obj 加载器类

     [1]: https://i.stack.imgur.com/bOsFv.png







   for (String line : object) {
                    if (line.startsWith("v") && !line.contains("t") && !line.contains("n")) {
                        String[] data = line.split("\\s+");
                        for (int i = 0; i < data.length; i++) {
                            if (!data[i].contains("v")) {
                                vertice[vstep++] = Float.parseFloat(data[i]);
    
                                if (max < Float.parseFloat(data[i]))
                                    max = Float.parseFloat(data[i]);
                            }
                        }
    
    
                    }
                }
                vstep = 0;
                for (String line : object) {
    
                    if (line.startsWith("v") && !line.contains("t") && !line.contains("n")) {
                        String[] data = line.split("\\s+");
                        for (int i = 0; i < data.length; i++) {
                            if (!data[i].contains("v"))
                                vertice[vstep++] = Float.parseFloat(data[i]) / max;
                        }
    
    
                    }
                }
    
                for (String line : object) {
    
                    if (line.startsWith("vt")) {
                        String[] data = line.split("\\s+");
                        temptexcoord[tstep][0] = Float.parseFloat(data[1]);
                      step][1] = 1 - Float.parseFloat(data[2]);
                        tstep++;
    
                    }
                }
    
                int count = 0;
                int tcount = 0;
                for (String line : object) {
    
    
                    if (line.startsWith("f")) {
    
                        String[] data = line.split("\\s+");
    
    
                        String[] info;
    
                        int step = 0;
                        if (data.length == 4) {
                            info = data[1].split("/");
                            face[count++] = (short) (Short.parseShort(info[0]) - (short) 1);
    
                            info = data[2].split("/");
                            face[count++] = (short) (Short.parseShort(info[0]) - (short) 1);
    
                            info = data[3].split("/");
                            face[count++] = (short) (Short.parseShort(info[0]) - (short) 1);
                        }
    
                      
      
    
    
    
    
     if (data.length == 5) {
                            //first triangle
                            info = data[1].split("/");
                            face[count++] = (short) (Short.parseShort(info[0]) - (short) 1);
    
    
                            info = data[2].split("/");
                            face[count++] = (short) (Short.parseShort(info[0]) - (short) 1);
    
    
                            info = data[3].split("/");
                            face[count++] = (short) (Short.parseShort(info[0]) - (short) 1);
    
                            //second triangle
                            info = data[1].split("/");
                            face[count++] = (short) (Short.parseShort(info[0]) - (short) 1);
    
    
                            info = data[3].split("/");
                            face[count++] = (short) (Short.parseShort(info[0]) - (short) 1);
    
    
                            info = data[4].split("/");
                            face[count++] = (short) (Short.parseShort(info[0]) - (short) 1);
    
                        }
    
                    }
    
                }
                for (String line : object) {
    
    
                    if (line.startsWith("f")) {
    
                        String[] data = line.split("\\s+");
    
    
                        String[] info;
    
                        int step = 0;
                        if (data.length == 4) {
                            info = data[1].split("/");
                            step = Integer.parseInt(info[1]) - 1;
                            texcoord[tcount++] = temptexcoord[step][0];
                            texcoord[tcount++] = temptexcoord[step][1];
    
                            info = data[2].split("/");
                            step = Integer.parseInt(info[1]) - 1;
                            texcoord[tcount++] = temptexcoord[step][0];
                            texcoord[tcount++] = temptexcoord[step][1];
    
                            info = data[3].split("/");
                            step = Integer.parseInt(info[1]) - 1;
                            texcoord[tcount++] = temptexcoord[step][0];
                            texcoord[tcount++] = temptexcoord[step][1];
                        }
    
                        if (data.length == 5) {
                            //first triangle
                            info = data[1].split("/");
                            step = Integer.parseInt(info[1]) - 1;
                            texcoord[tcount++] = temptexcoord[step][0];
                            texcoord[tcount++] = temptexcoord[step][1];
    
    
                            info = data[2].split("/");
                            step = Integer.parseInt(info[1]) - 1;
                            texcoord[tcount++] = temptexcoord[step][0];
                            texcoord[tcount++] = temptexcoord[step][1];
    
    
                            info = data[3].split("/");
                            step = Integer.parseInt(info[1]) - 1;
                            texcoord[tcount++] = temptexcoord[step][0];
                            texcoord[tcount++] = temptexcoord[step][1];
    
                            //second triangle
                            info = data[1].split("/");
                            step = Integer.parseInt(info[1]) - 1;
                            texcoord[tcount++] = temptexcoord[step][0];
                            texcoord[tcount++] = temptexcoord[step][1];
    
    
                            info = data[3].split("/");
                            step = Integer.parseInt(info[1]) - 1;
                            texcoord[tcount++] = temptexcoord[step][0];
                            texcoord[tcount++] = temptexcoord[step][1];
    
    
                            info = data[4].split("/");
                            step = Integer.parseInt(info[1]) - 1;
                            texcoord[tcount++] = temptexcoord[step][0];
                            texcoord[tcount++] = temptexcoord[step][1];
    
                        }
    
                    }//if end
    
                }
            }
    
        }

这个 opengles 渲染类

public class model {

    public float[] mModelMatrix = new float[16];

    private FloatBuffer vertexBuffer;
    private ShortBuffer indexBuffer;
    private FloatBuffer textureBuffer;
    static int COORDS_PER_VERTEX=3;
    private int vertexStride=COORDS_PER_VERTEX*4;

    static int COORDS_PER_TEXTURE=2;
    private int textureStride=COORDS_PER_TEXTURE*4;




    static public int colors;



    private int mProgram;

    private String vertexShadeCode=
            "uniform mat4 uMVPMatrix;"+
                    "attribute vec3 vPosition;" +
                    "attribute vec2 a_TexCoordinate;" +
                    "varying vec2 v_TexCoordinate;" +
                    "void main() {" +
                    "  v_TexCoordinate = a_TexCoordinate;" +
                    "  gl_Position = uMVPMatrix*vec4(vPosition,1.0);" +

                    "}";
    private String fragmentShadeCode= "precision highp float;" +
            "uniform vec4 vColor;" +
            "uniform sampler2D u_Texture;" +
            "varying vec2 v_TexCoordinate;" +
            "void main() {" +
            "vec4 texturecolor=texture2D(u_Texture, v_TexCoordinate);"+
            "  gl_FragColor =texturecolor;" +
            "}";

    private int mMVPMatrixHandle;

    private int mPositionHandle;
    private int mColorHandle;

    private int textureDataHandle;
    private int textureUniformHandle;
    private int textureCoordinateHandle;
    private float[] vertices;
    private short[] indices;
    float[] previewTexturCoordinateData;


    public model(Context context)
    {
        int Imgwidth,ImgHeight;
        textureDataHandle = loadTexture(context, R.drawable.dog);
        Objectloader obj=new Objectloader(R.raw.dog,context);


        vertices=obj.vertice;
        indices=obj.face;
        previewTexturCoordinateData=obj.texcoord;

        Matrix.setIdentityM(mModelMatrix, 0);

        ByteBuffer bf=ByteBuffer.allocateDirect(vertices.length*4);
        bf.order(ByteOrder.nativeOrder());
        vertexBuffer=bf.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        indexBuffer= ByteBuffer.allocateDirect(indices.length *2).order(ByteOrder.nativeOrder()).asShortBuffer();
        indexBuffer.put(indices).position(0);

        ByteBuffer texCoordinates = ByteBuffer.allocateDirect(previewTexturCoordinateData.length * 4);
        texCoordinates.order(ByteOrder.nativeOrder());
        textureBuffer = texCoordinates.asFloatBuffer();
        textureBuffer.put(previewTexturCoordinateData);
        textureBuffer.position(0);


        int vertexShader=MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
                vertexShadeCode);
        int fragmentshade=MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
                fragmentShadeCode);



        mProgram=GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram,vertexShader);
        GLES20.glAttachShader(mProgram,fragmentshade);
        GLES20.glLinkProgram(mProgram);

    }
    private int loadTexture(Context context,int ResourceID)
    {
        final int[] textureHandle = new int[1];

        GLES20.glGenTextures(1, textureHandle, 0);

        if (textureHandle[0] != 0)
        {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inScaled = false;   // No pre-scaling


            // Read in the resource
            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),ResourceID,options);


            // Bind to the texture in OpenGL
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);

            // Set filtering
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);

            // Load the bitmap into the bound texture.
            GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap,0);
            // Recycle the bitmap, since its data has been loaded into OpenGL.
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);

            bitmap.recycle();

        }

        if (textureHandle[0] == 0)
        {
            throw new RuntimeException("Error loading texture.");
        }

        return textureHandle[0];
    }
  




 public void draw(float[] mMVPMatrix)
    {
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        GLES20.glUseProgram(mProgram);
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false,
            vertexStride, vertexBuffer);



    textureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate");
    GLES20.glEnableVertexAttribArray(textureCoordinateHandle);
    GLES20.glVertexAttribPointer(textureCoordinateHandle,COORDS_PER_TEXTURE, GLES20.GL_FLOAT, false,
                textureStride, textureBuffer);


        textureUniformHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture");
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureDataHandle);
        GLES20.glUniform1i(textureUniformHandle, 0);



        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    // GLES20.GL_TRIANGLES : 삼각형채우기,
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT,indexBuffer);
  // GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,indices.length);
   GLES20.glFlush();



        GLES20.glDisableVertexAttribArray(mPositionHandle);





  }





}

【问题讨论】:

    标签: android parsing opengl-es textures loader


    【解决方案1】:

    here (ThinMatrix) 描述的 Java 上的 obj-parser 对我来说效果很好。源代码为herehere。当您应用此解析器时,您可以获得对象的数据,例如:

    InputStream input = context.getAssets().open("objects/suzanne.obj");
    OBJFileLoader loader = new OBJFileLoader();
    ModelData model = loader.loadOBJ(input);
    
    float[] vertices = model.getVertices();
    int[] indices = model.getIndices();
    float[] normals = model.getNormals();
    float[] textureCoordinates = model.getTextureCoordinates();
    

    并获取数据的缓冲区对象,例如:

    FloatBuffer bufferVertices = ByteBuffer.allocateDirect(vertices.length * 4)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    bufferVertices.put(vertices).position(0);
    
    IntBuffer bufferIndices = ByteBuffer.allocateDirect(indices.length * 4)
            .order(ByteOrder.nativeOrder()).asIntBuffer();
    bufferIndices.put(indices).position(0);
    
    ByteBuffer bnormal = ByteBuffer.allocateDirect(normals.length * 4);
    bnormal.order(ByteOrder.nativeOrder());
    FloatBuffer bufferNormals = bnormal.asFloatBuffer();
    bufferNormals.position(0);
    
    FloatBuffer bufferTextureCoordinates = ByteBuffer
            .allocateDirect(textureCoordinates.length * 4)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    bufferTextureCoordinates.put(textureCoordinates).position(0);
    

    【讨论】:

      猜你喜欢
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多