当前位置: 首页 > 知识库问答 >
问题:

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

厉成仁
2023-03-14

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

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

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

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

  • g
  • v
  • vt
  • vn
  • f

我尝试了libgdx,它工作正常,但对于我所需要的东西来说有点过头了。

我试过oObjLoaderhttps://github.com/seanrowens/oObjLoader没有LWJGL。解析似乎有效,但如何在简单场景中显示值?

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

我对不同的解决方案持开放态度,比如预转换文件,因为它只会在应用程序中出现这种情况。

谢谢!

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

共有2个答案

太叔富
2023-03-14

试试这个在Github上找到我的项目。https://github.com/WenlinMao/android-3d-model-viewer

这是一个OpenGL ES 2.0的演示,它是一个带有3D引擎的android应用程序,可以加载Wavefront OBJ, STL, DAE

这个应用程序的目的是学习和分享如何使用OpenGLES和Android绘图。由于这是我的第一个Android应用程序,很可能存在漏洞;但我会继续改进应用程序,增加更多功能。

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

谷梁晟
2023-03-14

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

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);
        }
    }
}
 类似资料:
  • 问题内容: 我正在制作一个Android应用程序,它必须通过Internet加载一些数据(只有一些数据- 并非全部)。因此,当数据正在加载且Internet连接速度很慢时,我想向用户显示“正在加载…”图标。 那我该怎么做呢?在后台加载数据时显示“正在加载…”图标,当数据完全加载后,隐藏该图标吗? 提前致谢! 问题答案: 使用异步任务来获取您的状态。

  • 问题内容: 在创建PDF文件的过程中单击按钮时如何显示进度条,在完成创建文件后如何隐藏进度条? 问题答案: 此代码将使用推荐的AsyncTask来完成您想做的事情! 现在使用以下命令在AsyncTask上方调用 从你的活动课

  • 使用三维软件导出.obj模型文件的时候,会同时导出一个材质文件.mtl, .obj和.stl文件包含的信息一样都是几何体顶点相关数据,材质文件.mtl包含的是模型的材质信息,比如颜色、贴图路径等。 加载.obj三维模型的时候,可以只加载.obj文件,然后借助three.js引擎自定义材质Material,也可以同时加载.obj和.mtl文件。 只加载obj文件 只加载obj文件,引入路径three

  • 我正在将url加载到WebView中: 但是,上面的代码是不工作的。如果有任何想法,请帮助。提前谢了。

  • 我正在尝试用android显示PPT文件。我从ApachePOI开始,bcoz我还没有找到任何免费的开源jar。我从将ppt幻灯片转换为图像开始,参考此链接将PowerPoint幻灯片导出为java。awt。图表2D 这是Java语言。我找不到Dimension、BuffereImage和Graphics2D类。我已经导入了poi-scratchpad-3.8-20120326。jar在我的构建路

  • 问题内容: 我有一个网页,该网页使用命令shell_exec运行python脚本。我想要一个加载微调器,在Python脚本运行时显示“请稍等此页面加载”消息,然后在执行完之后显示其余的回显HTML。 我找到了看似不错的解决方案,但是我对ajax还是陌生的,所以我不知道如何使用该解决方案。我试着做 但这没有用。我需要调用ajax来执行ajaxStart吗?我怎么称呼它?我应该用ajax代码包装she