OpenGL ES 1.0 - 渲染不正确

时间:2016-09-07 13:00:10

标签: android opengl-es

我正在加载.obj文件并在android模拟器中呈现它。虽然第三方.obj观众正确显示模型(open3mod),但当我在Android模拟器上启动它时,它看起来很奇怪。你能解释一下为什么enulator模型中的reders不正确吗?

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import java.util.Hashtable;
import java.util.ArrayList;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.nio.FloatBuffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class MyGLSurfaceView extends GLSurfaceView implements GLSurfaceView.Renderer
{
    private Context context;
    private Hashtable<String, ArrayList<Float>> obj;

    public MyGLSurfaceView(Context context)
    {
        super(context);
        setRenderer(this);
        this.context = context;
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config)
    {
        obj = new Hashtable<String, ArrayList<Float>>();

        try
        {
            BufferedReader reader = new BufferedReader(
              new InputStreamReader(context.getAssets().open("calculator.obj")));

            ArrayList<Float> vertex = new ArrayList<Float>();

            String name = null;
            String line = null;
            while ((line = reader.readLine()) != null)
            {
                if (line.startsWith("v "))
                {
                    String[] parts = line.substring(2).trim().split("\\s+");

                    vertex.add(Float.valueOf(Float.valueOf(parts[0]).floatValue() / 2f)); // scale to smaller twice
                    vertex.add(Float.valueOf(Float.valueOf(parts[1]).floatValue() / 2f)); // scale to smaller twice
                    vertex.add(Float.valueOf(Float.valueOf(parts[2]).floatValue() / 2f)); // scale to smaller twice
                }

                if (line.startsWith("f "))
                {
                    String[] parts = line.substring(2).trim().split("\\s+");

                    obj.get(name).add(vertex.get(Integer.valueOf(parts[0]).intValue() - 1));
                    obj.get(name).add(vertex.get(Integer.valueOf(parts[1]).intValue() - 1));
                    obj.get(name).add(vertex.get(Integer.valueOf(parts[2]).intValue() - 1));
                }

                if (line.startsWith("g "))
                {
                    name = line.substring(2).trim();

                    obj.put(name, new ArrayList<Float>());
               }
            }

            reader.close();
        }
        catch (Exception e)
        {
            System.exit(0);
        }
    }

    public void onSurfaceChanged(GL10 gl, int width, int height)
    {
        gl.glViewport(0, 0, width, height);
    }

    public void onDrawFrame(GL10 gl)
    {
        gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        gl.glClearDepthf(1.0f);

        int i;

        ByteBuffer fByteBuffer = ByteBuffer.allocateDirect(obj.get("calculator").size() * 4);
        fByteBuffer.order(ByteOrder.nativeOrder());
        FloatBuffer faces = fByteBuffer.asFloatBuffer();
        for (i = 0; i < obj.get("calculator").size(); i++)
          faces.put(obj.get("calculator").get(i).floatValue());            
        faces.position(0);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, faces);

        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, faces.capacity() / 3);
    }
}

1 个答案:

答案 0 :(得分:0)

Obj文件是一种索引几何格式(面部元素线的开头是&#34; f&#34;是编码 - 它们告诉你顶点数组中的哪些顶点构成每个三角形)。

您当前的代码正在解码索引值,但在渲染时完全忽略它们。您需要使用glDrawElements,使用索引缓冲区选择哪些顶点对哪些三角形有贡献。

编辑我错过了你在加载时手动重新打包顶点数据的事实。您不需要这样做 - API本身支持索引渲染(并且由于共享顶点仅处理一次,因此效率更高。)