java - 在 Libgdx 中加载 Obj 文件不适用于 Android

标签 java android file-io opengl-es libgdx

以下代码显示了一个缓慢旋转并开始显示的环面:

package com.objloader.example;

import ...
public class ObjLoaderProg implements ApplicationListener{
    String torus;
    Mesh model;
    private PerspectiveCamera camera;
    @Override
    public void create() {
        InputStream stream=null;
        try {
            stream = new FileInputStream(Gdx.files.internal("data/torus.obj").path());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        model = ObjLoader.loadObj(stream, true);
        Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
        Gdx.gl10.glTranslatef(0.0f,0.0f,-3.0f);
    }

    @Override
    public void dispose() {
    }

    @Override
    public void pause() {
    }

    protected int lastTouchX;
    protected int lastTouchY;
    protected float rotateZ=0.01f;
    protected float increment=0.01f;

    @Override
    public void render() {
        Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        camera.update();
        camera.apply(Gdx.gl10);
        Gdx.gl10.glTranslatef(0.0f,0.0f,-3.0f);
        Gdx.gl10.glRotatef(rotateZ, rotateZ, 5.0f, rotateZ);
        model.render(GL10.GL_TRIANGLES);

         if (Gdx.input.justTouched()) {
              lastTouchX = Gdx.input.getX();
              lastTouchY = Gdx.input.getY();
            } else if (Gdx.input.isTouched()) {
              camera.rotate(0.2f * (lastTouchX - Gdx.input.getX()), 0, 1.0f, 0);
              camera.rotate(0.2f * (lastTouchY - Gdx.input.getY()), 1.0f, 0, 0);

              lastTouchX = Gdx.input.getX();
              lastTouchY = Gdx.input.getY();
            }
         rotateZ+=increment;
         System.out.println(""+rotateZ);
    }

    @Override
    public void resize(int arg0, int arg1) {
        float aspectRatio = (float) arg0 / (float) arg1;
        camera = new PerspectiveCamera(67, 2f * aspectRatio, 2f);
        camera.near=0.1f;
        camera.translate(0, 0, 0);
    }

    @Override
    public void resume() {
    }
}

它呈现一个保存在数据文件夹中的环面对象,通过在屏幕上单击并拖动,用户可以旋转相机。

这在桌面上运行良好,但是当我尝试在 android 上运行它时,我在以下位置收到 NullPointerException:

model.render(GL10.GL_TRIANGLES);

我试过将 torus.obj 放在 assets 和 assets/data 中。我正在使用 libgdx 0.9.2。

最佳答案

我假设您指的是 model.render(GL10.GL_TRIANGLES);。我相信你有两个问题。首先,model 为空,因为您正在捕获 FileNotFoundException 并忽略它。我建议您现在不要捕获 FileNotFoundException,让它崩溃,然后查看堆栈跟踪。这将使您更好地了解失败的原因。请注意,e.printStackTrace() 对于在 android 上进行调试没有用,请尝试使用 gdx 日志。

第二个问题是我怀疑路径/流实际上去错了地方。不要创建 FileInputStream,而是使用 FileHandle.read() 函数。它返回一个 java.io.InputStream,您可以将其传递给 ObjLoader.loadObj()。

in = Gdx.files.internal("data/torus.obj").read();
model ObjLoader.loadObj(in);
in.close();

这与您的代码之间的区别在于 libgdx 的 android 后端中的 FileHandle.read() 使用 android AssetManager打开与程序 bundle 在一起的文件。

最后,将torus.obj文件复制到/assets/data/torus.obj。

旁白:如果指定行号,请提供完整文件,否则该行将关闭。您提供的代码的第 52 行是:lastTouchY = Gdx.input.getY();。请注意代码开头的“导入...”。这些导入会影响行号。

关于java - 在 Libgdx 中加载 Obj 文件不适用于 Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7536307/

相关文章:

java - 如何通过 JMX 连接到远程 Docker 容器

java - 困难的公式

android - 切换到前置摄像头和后置摄像头 Android SurfaceView

android - 如何在状态栏的特定位置添加通知/正在进行的事件图标?

java.io.FileNotFoundException : File is not a normal file. 露天

java - onResume() 是在 Android 的 onRequestPermissionsResult() 之后调用的吗?

java - 我们可以使用 @RequestParam ="CodeTxt"获取 id ("custCode"吗?

android - 如何在特定事件中通知用户?

c# - System.IO.ReadAllxxx/WriteAllxxx 方法的性能

安卓文件拷贝