适用于 Android 的 OpenGL ES 工具

2024-02-27

在哪里可以找到用于在 OpenGL ES 中设计复杂对象的所有工具?

像正方形、立方体、球体等


只需对对象进行建模并将其导出为 OBJ 文件,然后即可将 OBJ 文件加载到场景中。

这是我编写的用于加载 OBJ 文件的代码,我将它们从 Maya 导出。 请注意,这更像是实验代码,因此它并不干净,但我对其进行了测试并且工作正常。

Vector3D 类保存 X、Y 和 Z 变量,Face 类保存 UVW、顶点和顶点法线的 ArrayList。

而且你必须通过调用 glDrawElements 顺便说一句来绘制你的对象。 希望这会有所帮助 =)

public class Model {

    // Constants
    private static final int FLOAT_SIZE_BYTES = 4;
    private static final int SHORT_SIZE_BYTES = 2;

    private FloatBuffer _vb;
    private FloatBuffer _nb;
    private ShortBuffer _ib;
    private FloatBuffer _tcb;

    private short[] indices;

    private float[] tempV;
    private float[] tempVt;
    private float[] tempVn;

    private ArrayList<Vector3D> vertices;
    private ArrayList<Vector3D> vertexTexture;
    private ArrayList<Vector3D> vertexNormal;
    private ArrayList<Face> faces;
    private int vertexCount;

    private ArrayList<GroupObject> groupObjects;

    //Android Stuff!
    private Context context;
    private int modelID;

    public Model(int modelID, Context activity)
    {
        this.vertices = new ArrayList<Vector3D>();
        this.vertexTexture = new ArrayList<Vector3D>();
        this.vertexNormal = new ArrayList<Vector3D>();
        this.faces = new ArrayList<Face>();

        this.groupObjects = new ArrayList<GroupObject>();

        this.modelID = modelID;
        this.context = activity;

        loadFile();
    }

    private int loadFile()
    {
        InputStream inputStream = context.getResources().openRawResource(modelID);

        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));

        try {
            loadOBJ(in);
            Log.d("LOADING FILE", "FILE LOADED SUCESSFULLY====================");
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return 1;
    }

    private void loadOBJ(BufferedReader in) throws IOException
    {
        Log.d("LOADING FILE", "STARTING!====================");
        GroupObject defaultObject = new GroupObject();
        GroupObject currentObject = defaultObject;

        this.groupObjects.add(defaultObject);

        String Line;            // Stores ever line we read!
        String[] Blocks;        // Stores string fragments after the split!!
        String CommandBlock;    // Stores Command Blocks such as: v, vt, vn, g, etc...

        while((Line = in.readLine()) != null)
        {
            Blocks = Line.split(" ");
            CommandBlock = Blocks[0];

//          Log.d("COMMAND BLOCK" , "---------- " + CommandBlock + " ----------");

            if(CommandBlock.equals("g"))
            {
                if(Blocks[1] == "default")
                    currentObject = defaultObject;
                else
                {
                    GroupObject groupObject = new GroupObject();
                    groupObject.setObjectName(Blocks[1]);
                    currentObject = groupObject;
                    groupObjects.add(groupObject);
                }
            }

            if(CommandBlock.equals("v"))
            {
                Vector3D vertex = new Vector3D(Float.parseFloat(Blocks[1]), Float.parseFloat(Blocks[2]), Float.parseFloat(Blocks[3]));
                this.vertices.add(vertex);
//              Log.d("VERTEX DATA", " " + vertex.getX() + ", " + vertex.getY() + ", " + vertex.getZ());
            }

            if(CommandBlock.equals("vt"))
            {
                Vector3D vertexTex = new Vector3D(Float.parseFloat(Blocks[1]), Float.parseFloat(Blocks[2]), 0.0f);
                this.vertexTexture.add(vertexTex);
//              Log.d("TEXTURE DATA", " " + vertexTex.getX() + ", " + vertexTex.getY() + ", " + vertexTex.getZ());
            }

            if(CommandBlock.equals("vn"))
            {
                Vector3D vertexNorm = new Vector3D(Float.parseFloat(Blocks[1]), Float.parseFloat(Blocks[2]), Float.parseFloat(Blocks[3]));
                this.vertexNormal.add(vertexNorm);
//              Log.d("NORMAL DATA", " " + vertexNorm.getX() + ", " + vertexNorm.getY() + ", " + vertexNorm.getZ());
            }

            if(CommandBlock.equals("f"))
            {
                Face face = new Face();
                faces.add(face);

                String[] faceParams;

                for(int i = 1; i < Blocks.length ; i++)
                {               
                    faceParams = Blocks[i].split("/");

                    face.getVertices().add(this.vertices.get(Integer.parseInt(faceParams[0]) - 1));                 

                    if(faceParams[1] == ""){}
                    else
                    {
                        face.getUvws().add(this.vertexTexture.get(Integer.parseInt(faceParams[1]) - 1));
                        face.getNormals().add(this.vertexNormal.get(Integer.parseInt(faceParams[2]) - 1));
                    }
                }
            }
        }

//      fillInBuffers();
        fillInBuffersWithNormals();

        Log.d("OBJ OBJECT DATA", "V = " + vertices.size() + " VN = " + vertexTexture.size() + " VT = " + vertexNormal.size());

    }

    private void fillInBuffers() {

        int facesSize = faces.size();

        vertexCount = facesSize * 3;

        tempV = new float[facesSize * 3 * 3];
        tempVt = new float[facesSize * 2 * 3];
        indices = new short[facesSize * 3];

        for(int i = 0; i < facesSize; i++)
        {
            Face face = faces.get(i);
            tempV[i * 9]     = face.getVertices().get(0).getX();
            tempV[i * 9 + 1] = face.getVertices().get(0).getY();
            tempV[i * 9 + 2] = face.getVertices().get(0).getZ();
            tempV[i * 9 + 3] = face.getVertices().get(1).getX();
            tempV[i * 9 + 4] = face.getVertices().get(1).getY();
            tempV[i * 9 + 5] = face.getVertices().get(1).getZ();
            tempV[i * 9 + 6] = face.getVertices().get(2).getX();
            tempV[i * 9 + 7] = face.getVertices().get(2).getY();
            tempV[i * 9 + 8] = face.getVertices().get(2).getZ();
            tempVt[i * 6]     = face.getUvws().get(0).getX();
            tempVt[i * 6 + 1] = face.getUvws().get(0).getY();
            tempVt[i * 6 + 2] = face.getUvws().get(1).getX();
            tempVt[i * 6 + 3] = face.getUvws().get(1).getY();
            tempVt[i * 6 + 4] = face.getUvws().get(2).getX();
            tempVt[i * 6 + 5] = face.getUvws().get(2).getY();
            indices[i * 3]     = (short) (i * 3);
            indices[i * 3 + 1] = (short) (i * 3 + 1);
            indices[i * 3 + 2] = (short) (i * 3 + 2);
        }

        _vb = ByteBuffer.allocateDirect(tempV.length
                * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
        _vb.put(tempV);
        _vb.position(0);

        _tcb = ByteBuffer.allocateDirect(tempVt.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
        _tcb.put(tempVt);
        _tcb.position(0);

        _ib = ByteBuffer.allocateDirect(indices.length
                * SHORT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asShortBuffer();
        _ib.put(indices);
        _ib.position(0);
    }

    private void fillInBuffersWithNormals() {

        int facesSize = faces.size();

        vertexCount = facesSize * 3;

        tempV = new float[facesSize * 3 * 3];
        tempVt = new float[facesSize * 2 * 3];
        tempVn = new float[facesSize * 3 * 3];
        indices = new short[facesSize * 3];

        for(int i = 0; i < facesSize; i++)
        {
            Face face = faces.get(i);
            tempV[i * 9]     = face.getVertices().get(0).getX();
            tempV[i * 9 + 1] = face.getVertices().get(0).getY();
            tempV[i * 9 + 2] = face.getVertices().get(0).getZ();
            tempV[i * 9 + 3] = face.getVertices().get(1).getX();
            tempV[i * 9 + 4] = face.getVertices().get(1).getY();
            tempV[i * 9 + 5] = face.getVertices().get(1).getZ();
            tempV[i * 9 + 6] = face.getVertices().get(2).getX();
            tempV[i * 9 + 7] = face.getVertices().get(2).getY();
            tempV[i * 9 + 8] = face.getVertices().get(2).getZ();

            tempVn[i * 9]     = face.getNormals().get(0).getX();
            tempVn[i * 9 + 1] = face.getNormals().get(0).getY();
            tempVn[i * 9 + 2] = face.getNormals().get(0).getZ();
            tempVn[i * 9 + 3] = face.getNormals().get(1).getX();
            tempVn[i * 9 + 4] = face.getNormals().get(1).getY();
            tempVn[i * 9 + 5] = face.getNormals().get(1).getZ();
            tempVn[i * 9 + 6] = face.getNormals().get(2).getX();
            tempVn[i * 9 + 7] = face.getNormals().get(2).getY();
            tempVn[i * 9 + 8] = face.getNormals().get(2).getZ();

            tempVt[i * 6]     = face.getUvws().get(0).getX();
            tempVt[i * 6 + 1] = face.getUvws().get(0).getY();
            tempVt[i * 6 + 2] = face.getUvws().get(1).getX();
            tempVt[i * 6 + 3] = face.getUvws().get(1).getY();
            tempVt[i * 6 + 4] = face.getUvws().get(2).getX();
            tempVt[i * 6 + 5] = face.getUvws().get(2).getY();

            indices[i * 3]     = (short) (i * 3);
            indices[i * 3 + 1] = (short) (i * 3 + 1);
            indices[i * 3 + 2] = (short) (i * 3 + 2);
        }

        _vb = ByteBuffer.allocateDirect(tempV.length
                * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
        _vb.put(tempV);
        _vb.position(0);

        _tcb = ByteBuffer.allocateDirect(tempVt.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
        _tcb.put(tempVt);
        _tcb.position(0);

        _nb = ByteBuffer.allocateDirect(tempVn.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
        _nb.put(tempVn);
        _nb.position(0);

        _ib = ByteBuffer.allocateDirect(indices.length
                * SHORT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asShortBuffer();
        _ib.put(indices);
        _ib.position(0);
    }

    public FloatBuffer getVertices()
    {
        return _vb;
    }

    public FloatBuffer getTexCoords()
    {
        return _tcb;
    }

    public ShortBuffer getIndices()
    {
        return _ib;
    }

    public FloatBuffer getNormals() {
        return _nb;
    }
}

如果这回答了您的问题,请投票;)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

适用于 Android 的 OpenGL ES 工具 的相关文章

随机推荐

  • 如何使用 REST API 为领事附加手表?

    我使用 REST API 来访问领事 例如 这是我创建条目的方法 curl X PUT d localhost 8500 v1 kv example lt lt lt FooValue 我想添加watches当键值更改时通知我的服务的领事
  • 将函数发布到门户后,Azure 函数在函数列表中不可见

    我是Azure函数的新手 在函数发布到门户后发现这里 但它在函数列表中不可见 我附上了示例代码的快照和一个空的天蓝色列表 请帮忙 添加kudu ui 这里我找到了 wwwroot下唯一的host json Hi All 添加了kudu ui
  • 如何定义 Airflow 上 STFP Operator 的操作?

    class SFTPOperation object PUT put GET get operation SFTPOperation GET NameError name SFTPOperation is not defined 我在这里定
  • 维吉尼亚密码解密

    我正在尝试使用维吉尼亚密码进行加密和解密 这是一项更大任务的一部分 而维吉尼亚密码只扮演了一小部分 我从 bash 得到了这个加密脚本 可以正常工作 问题是我如何反向使用相同的代码来解密代码 usr local bin bash vigen
  • Java / Android 编程 - 循环失败

    我正在使用带有计时器的 while 循环 问题是计时器并不是在每个循环中都使用 仅在第一次使用 第一次之后 循环内包含的语句将在没有我设置的延迟的情况下执行 既然计时器包含在 while 循环内 这怎么可能呢 有什么解决办法吗 int co
  • 如何在 HTML 中将文本和图像并排放置?

    我希望文本和图像彼此相邻 但我希望图像位于屏幕的最左侧 而我希望文本位于屏幕的最右侧 这就是我目前所拥有的 img src website art png height 75 width 235 h3 font face Verdana T
  • 如何确定 Django 模型中的类实例是否是另一个模型的子类?

    我有一堂课叫BankAccount作为基类 我也有CheckingAccount and SavingsAccount继承自的类BankAccount BankAccount 不是一个抽象类 但我不从中创建对象 只创建继承类 然后 我执行如
  • 我不知道为什么这个画布是空的

    因此 我一直在研究如何用其他图像填充画布的几个示例 一旦我稍微重新排列代码 它们就会停止工作 我注意到画布上的一些行为与其他类型的 JavaScript 变量相比没有意义 我想知道发生了什么 例如 如果我做这样的事情
  • 在python中读取标头之间的文件

    我有一个大文本文件 其中的值由以 开头的标题分隔 如果条件与标头中的条件匹配 我想读取文件直到下一个标头 并跳过文件的其余部分 为了测试我正在尝试读取以下名为 test234 txt 的文本文件 abcdefgh 1fnrnf mrkfr
  • 我可以在 Play Framework 上的模板/视图中调用会话吗

    我是 Play Framework 2 0 的新手 我使用的是 Scala 并且有一个关于会话的问题 我有 Ruby on Rails 背景 因此我倾向于将在 Play Framework 中学到的所有内容都与 Ruby on Rails
  • 新的 Facebook API 3.0。和 ActionBarSherlock 兼容性

    我正在阅读 facebook Android API 3 0 文档 我不明白会话与后台活动有什么关系 在所有示例中 我都应该扩展 FacebookFragment 好吧 如果我的整个应用程序不扩展 SherlockFragment 那就太好
  • 将模块内的所有函数和类导入到 python 类中

    我正在尝试将子文件夹中的所有对象导入到 python 3 8 中的类中 并且正在努力寻找一种方法来执行此操作 我不想手动导入所有对象 因为要列出的文件太多 class Foo from bar import one two three 当我
  • Once_flag 可以移动吗?

    这是怎么回事 标准没有提到once flag的可移动性 我希望应用与 std mutex 相同的参数 至少对于 gcc 4 8 版 来说 移动似乎被禁用了 如果某个编译器允许移动 那么最终可能会得到不可移植的代码 概要是 30 4 thre
  • ASP.NET MVC 3 Razor 性能

    重要更新 请参阅底部的更新 5 asp net mvc 3 中没有性能问题 这是基准问题 我在 asp net mvc2 3 aspx 和 3 razor 中制作了一个简单的 hello world 项目并对它们进行了基准测试 我看到的是
  • 如何在 Windows 上安装 OpenJPEG 并将其与 Pillow 一起使用?

    我想使用Python Pillow库将16位灰度数组保存在jp2 JPEG 2000 格式 我在尝试在 Windows 计算机上安装所需的 OpenJPEG 库时遇到了困难 这文档 https github com uclouvain op
  • 调用非托管函数,该函数采用指向指针参数的指针

    我正在尝试从我的 Net Core 应用程序调用 C 中的函数 深入了解一下 C 函数来自libmpv 渲染 h https github com mpv player mpv blob master libmpv render h函数的头
  • 如何为给定的 JavaScript 生成调用图? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我见过 https stackoverflow com questions 1385335 how to generate funct
  • 显示名称而不是电子邮件的电子邮件标题的格式是什么?

    我正在尝试创建一个 php 脚本 该脚本将使用 mySQL 数据库为我处理邮件列表 并且我已经准备好了大部分内容 不幸的是 我似乎无法让标题正常工作 而且我不确定问题是什么 headers From email protected cdn
  • Julia 中的 ifelse 和三元运算符有什么区别?

    假设我有这样的代码 cond true a cond 1 2 b ifelse cond 1 2 两种操作有什么区别 在你写的例子中 没有任何有效的区别 但是 如果这两个分支比简单的整数字面更复杂 则存在差异 julia gt f prin
  • 适用于 Android 的 OpenGL ES 工具

    在哪里可以找到用于在 OpenGL ES 中设计复杂对象的所有工具 像正方形 立方体 球体等 只需对对象进行建模并将其导出为 OBJ 文件 然后即可将 OBJ 文件加载到场景中 这是我编写的用于加载 OBJ 文件的代码 我将它们从 Maya