Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/234.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用OpenGL ES 2在Android中加载和显示.obj文件_Android_Opengl Es_Opengl Es 2.0 - Fatal编程技术网

如何使用OpenGL ES 2在Android中加载和显示.obj文件

如何使用OpenGL ES 2在Android中加载和显示.obj文件,android,opengl-es,opengl-es-2.0,Android,Opengl Es,Opengl Es 2.0,我正在尝试将一个.obj文件加载到我的Android应用程序中,并使用OpenGL 2显示它 您可以在此处找到该文件:编辑:我删除了该文件,您可以使用包含以下提到的值的任何.obj文件进行测试 关于stackoverflow有很多类似的问题,但我没有找到一个不需要大型库的简单解决方案 该文件仅包含以下值类型: g 五 vt 越南 f 我尝试了libgdx,它工作正常,但对于我所需要的东西来说有点过分了 我试过没有LWJGL的oObjLoader。解析似乎有效,但如何在简单场景中显示值 下一步

我正在尝试将一个.obj文件加载到我的Android应用程序中,并使用OpenGL 2显示它

您可以在此处找到该文件:编辑:我删除了该文件,您可以使用包含以下提到的值的任何.obj文件进行测试

关于stackoverflow有很多类似的问题,但我没有找到一个不需要大型库的简单解决方案

该文件仅包含以下值类型:

  • g
  • vt
  • 越南
  • f
我尝试了libgdx,它工作正常,但对于我所需要的东西来说有点过分了

我试过没有LWJGL的oObjLoader。解析似乎有效,但如何在简单场景中显示值

下一步是将图像作为纹理附加到对象。但现在,我很乐意按原样显示文件

我对不同的解决方案持开放态度,比如预转换文件,因为在应用程序中只有这个解决方案

谢谢

状态更新
基本的加载和显示工作,现在,如我自己的回答所示

我最后编写了一个新的解析器,它可以像这样用于构建浮动缓冲区,以便在渲染器中使用:

ObjLoader objLoader = new ObjLoader(context, "Mug.obj");

numFaces = objLoader.numFaces;

// Initialize the buffers.
positions = ByteBuffer.allocateDirect(objLoader.positions.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
positions.put(objLoader.positions).position(0);

normals = ByteBuffer.allocateDirect(objLoader.normals.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
normals.put(objLoader.normals).position(0);

textureCoordinates = ByteBuffer.allocateDirect(objLoader.textureCoordinates.length * mBytesPerFloat)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
textureCoordinates.put(objLoader.textureCoordinates).position(0);
下面是解析器:

public final class ObjLoader {

    public final int numFaces;

    public final float[] normals;
    public final float[] textureCoordinates;
    public final float[] positions;

    public ObjLoader(Context context, String file) {

        Vector<Float> vertices = new Vector<>();
        Vector<Float> normals = new Vector<>();
        Vector<Float> textures = new Vector<>();
        Vector<String> faces = new Vector<>();

        BufferedReader reader = null;
        try {
            InputStreamReader in = new InputStreamReader(context.getAssets().open(file));
            reader = new BufferedReader(in);

            // read file until EOF
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split(" ");
                switch (parts[0]) {
                    case "v":
                        // vertices
                        vertices.add(Float.valueOf(parts[1]));
                        vertices.add(Float.valueOf(parts[2]));
                        vertices.add(Float.valueOf(parts[3]));
                        break;
                    case "vt":
                        // textures
                        textures.add(Float.valueOf(parts[1]));
                        textures.add(Float.valueOf(parts[2]));
                        break;
                    case "vn":
                        // normals
                        normals.add(Float.valueOf(parts[1]));
                        normals.add(Float.valueOf(parts[2]));
                        normals.add(Float.valueOf(parts[3]));
                        break;
                    case "f":
                        // faces: vertex/texture/normal
                        faces.add(parts[1]);
                        faces.add(parts[2]);
                        faces.add(parts[3]);
                        break;
                }
            }
        } catch (IOException e) {
            // cannot load or read file
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    //log the exception
                }
            }
        }

        numFaces = faces.size();
        this.normals = new float[numFaces * 3];
        textureCoordinates = new float[numFaces * 2];
        positions = new float[numFaces * 3];
        int positionIndex = 0;
        int normalIndex = 0;
        int textureIndex = 0;
        for (String face : faces) {
            String[] parts = face.split("/");

            int index = 3 * (Short.valueOf(parts[0]) - 1);
            positions[positionIndex++] = vertices.get(index++);
            positions[positionIndex++] = vertices.get(index++);
            positions[positionIndex++] = vertices.get(index);

            index = 2 * (Short.valueOf(parts[1]) - 1);
            textureCoordinates[normalIndex++] = textures.get(index++);
            // NOTE: Bitmap gets y-inverted
            textureCoordinates[normalIndex++] = 1 - textures.get(index);

            index = 3 * (Short.valueOf(parts[2]) - 1);
            this.normals[textureIndex++] = normals.get(index++);
            this.normals[textureIndex++] = normals.get(index++);
            this.normals[textureIndex++] = normals.get(index);
        }
    }
}
public final class ObjLoader{
公共最终国际货币基金会;
公共最终浮动[]正常值;
公共最终浮动坐标;
公开最终浮动[]职位;
公共对象加载程序(上下文,字符串文件){
向量顶点=新向量();
向量法线=新向量();
向量纹理=新向量();
向量面=新向量();
BufferedReader reader=null;
试一试{
InputStreamReader in=新建InputStreamReader(context.getAssets().open(file));
读卡器=新的缓冲读卡器(in);
//读取文件直到EOF
弦线;
而((line=reader.readLine())!=null){
String[]parts=line.split(“”);
开关(部件[0]){
案例“v”:
//顶点
顶点.add(Float.valueOf(parts[1]);
顶点.add(Float.valueOf(parts[2]);
顶点.add(Float.valueOf(parts[3]);
打破
案例“vt”:
//质地
纹理.add(Float.valueOf(parts[1]);
纹理.add(Float.valueOf(parts[2]);
打破
案例“vn”:
//常态
法线.add(Float.valueOf(parts[1]);
法线.add(Float.valueOf(parts[2]);
法线.add(Float.valueOf(parts[3]);
打破
案例“f”:
//面:顶点/纹理/法线
添加(零件[1]);
添加(零件[2]);
添加(零件[3]);
打破
}
}
}捕获(IOE异常){
//无法加载或读取文件
}最后{
if(读卡器!=null){
试一试{
reader.close();
}捕获(IOE异常){
//记录异常
}
}
}
numface=faces.size();
this.normals=新浮点[numface*3];
纹理坐标=新浮点[numface*2];
位置=新浮动[numface*3];
int positionIndex=0;
int normalIndex=0;
int-textureIndex=0;
用于(字符串面:面){
String[]parts=face.split(“/”);
int index=3*(缩写为valueOf(parts[0])-1);
positions[positionIndex++]=顶点.get(index++);
positions[positionIndex++]=顶点.get(index++);
位置[positionIndex++]=顶点。获取(索引);
索引=2*(简称为(第[1]部分)的值-1);
textureCoordinates[normalIndex++]=textures.get(index++);
//注意:位图得到y反转
textureCoordinates[normalIndex++]=1-textures.get(index);
索引=3*(简称为(第[2]部分)的值-1);
this.normals[textureIndex++]=normals.get(index++);
this.normals[textureIndex++]=normals.get(index++);
this.normals[textureIndex++]=normals.get(索引);
}
}
}

试试这个在Github上找到我的项目。

这是OpenGLES2.0的一个演示。它是一个android应用程序,带有3D引擎,可以加载波前OBJ、STL、DAE和glTF文件。该应用程序基于andresoviedo的项目,该项目可在此处找到,并具有加载和呈现glTF格式的附加功能

本应用程序的目的是学习和分享如何使用OpenGLES和Android进行绘图。因为这是我的第一个android应用程序,所以很可能存在bug;但我会继续改进应用程序并添加更多功能


这个项目是开源的,包含可以解决您的问题的类

感谢@Björn Kechel非常优雅的实现。 我只想添加一个可能导致不良结果的案例。 因为一个面可以有3个以上的顶点,所以我们应该能够处理4个顶点,如下所示

由于您使用的是Android,您的问题很可能针对OpenGL ES 2而不是OpenGL 2。如果是这种情况,我建议更新问题并相应地标记它。嗨,我能得到你的整个ObjLoader文件吗?我有一些问题。非常感谢。我对opengles非常陌生。你能指导我渲染缓冲区吗?多亏了你的代码,我才能够创建缓冲区,但未能重新编写。嗨,你能告诉我如何使用