Android – 在libGDX中的慢速模型批处理渲染

Android – 在libGDX中的慢速模型批处理渲染,第1张

概述我有一个问题是否有一个特殊的模式来分组模型在libGDX.我创建了一个实现ApplicationListener的简单类,显示了我的问题.我正在使用libGDX的夜间版本. 我读了两个使用相同纹理的不同的模型.该应用程序分别呈现每种类型的250种型号.这是渲染代码的一部分如何: mModelBatch.begin(camera); for(int y=0; y<50; y++) { 我有一个问题是否有一个特殊的模式来分组模型在libGDX.我创建了一个实现ApplicationListener的简单类,显示了我的问题.我正在使用libGDX的夜间版本.

我读了两个使用相同纹理的不同的模型.该应用程序分别呈现每种类型的250种型号.这是渲染代码的一部分如何:

mModelBatch.begin(camera);  for(int y=0; y<50; y++)  {     for(int x=-5; x<5; x++)     {        Modelinstance instance;        if(x%2 == 0) instance = modelinstance1;        else instance = modelinstance2;        instance.transform.setToTranslation(x,-y);        mModelBatch.render(instance);     }  }  mModelBatch.end();

我试图找到一个很好的解决方案,所以我写了另一个测试代码:

public voID getRenderables(Array<Renderable> renderables,Pool<Renderable> pool){  for(int y=0; y<50; y++)  {     for(int x=-5; x<5; x++)     {        Modelinstance instance;        if(x%2 == 0) instance = modelinstance1;        else instance = modelinstance2;        instance.transform.setToTranslation(x,y%3,-y);        Renderable renderable = pool.obtain();        renderable = instance.getRenderable(renderable);        renderables.add(renderable);     }  }

}

我使用它,如下所示:

mModelBatch.begin(camera);      mModelBatch.render(testRenderProvIDer);mModelBatch.end();

但是它仍然给了我13 FPS.
同时做另一个测试,我在混合器中创建与之前程序中相同的地图.接下来,我将所有内容分组在一个对象中(没有任何其他版本).这样我就创建了一个大小接近1MB的BIG对象,可以从Blender的屏幕截图中看到.

我改变了测试程序,只能画出一个BIG对象:

mModelBatch.begin(camera);      modelinstance1.transform.setToTranslation(0,0);      mModelBatch.render(modelinstance1);mModelBatch.end();

我做的下一件事是我在手机上启动了程序(Sony XPeria Mini Pro – 与之前相同)和iPod 5g,我已经… 60 FPS!

可以在一个绘图调用中渲染一切吗?

解决方法 问题解决了!我在一个低端移动设备上实现了60个FPS.游戏运行平稳.我发现如何将多个Meshes合并成一个网格,以便可以使用VBO机制. libGDX中有一个错误,导致网格复制方法无法使用多个网格.变更后,地图划分为小部分.每个扇区由具有相同z轴值的网格构成,如下图所示:

VBO机制是非常有限的,因此不能一次绘制多个顶点,这就是为什么这些部门必须相当小.
必须编写新的渲染器才能正确处理渲染.并且渲染器的部分动态地合并网格(没有任何单独的工具,例如blender).

public static Mesh mergeMeshes(AbstractList<Mesh> meshes,AbstractList<Matrix4> transformations){    if(meshes.size() == 0) return null;    int vertexArrayTotalSize = 0;    int indexArrayTotalSize = 0;    VertexAttributes va = meshes.get(0).getVertexAttributes();    int vaA[] = new int [va.size()];    for(int i=0; i<va.size(); i++)    {        vaA[i] = va.get(i).usage;    }    for(int i=0; i<meshes.size(); i++)    {        Mesh mesh = meshes.get(i);        if(mesh.getVertexAttributes().size() != va.size())         {            meshes.set(i,copyMesh(mesh,true,false,vaA));        }        vertexArrayTotalSize += mesh.getNumVertices() * mesh.getVertexSize() / 4;        indexArrayTotalSize += mesh.getNumIndices();    }    final float vertices[] = new float[vertexArrayTotalSize];    final short indices[] = new short[indexArrayTotalSize];    int indexOffset = 0;    int vertexOffset = 0;    int vertexSizeOffset = 0;    int vertexSize = 0;    for(int i=0; i<meshes.size(); i++)    {        Mesh mesh = meshes.get(i);        int numIndices = mesh.getNumIndices();        int numVertices = mesh.getNumVertices();        vertexSize = mesh.getVertexSize() / 4;        int baseSize = numVertices * vertexSize;        VertexAttribute posAttr = mesh.getVertexAttribute(Usage.position);        int offset = posAttr.offset / 4;        int numComponents = posAttr.numComponents;        { //uzupelnianIE tablicy indeksow            mesh.getIndices(indices,indexOffset);            for(int c = indexOffset; c < (indexOffset + numIndices); c++)            {                indices[c] += vertexOffset;            }            indexOffset += numIndices;        }        mesh.getVertices(0,baseSize,vertices,vertexSizeOffset);        Mesh.transform(transformations.get(i),vertexSize,offset,numComponents,vertexOffset,numVertices);        vertexOffset += numVertices;        vertexSizeOffset += baseSize;    }    Mesh result = new Mesh(true,indices.length,meshes.get(0).getVertexAttributes());    result.setVertices(vertices);    result.setIndices(indices);    return result;}     public static Mesh copyMesh(Mesh meshTocopy,boolean isstatic,boolean removeDuplicates,final int[] usage) {    // Todo move this to a copy constructor?    // Todo duplicate the buffers without double copying the data if possible.    // Todo perhaps move this code to JNI if it turns out being too slow.    final int vertexSize = meshTocopy.getVertexSize() / 4;    int numVertices = meshTocopy.getNumVertices();    float[] vertices = new float[numVertices * vertexSize];    meshTocopy.getVertices(0,vertices.length,vertices);    short[] checks = null;    VertexAttribute[] attrs = null;    int newVertexSize = 0;    if (usage != null) {        int size = 0;        int as = 0;        for (int i = 0; i < usage.length; i++)            if (meshTocopy.getVertexAttribute(usage[i]) != null) {                size += meshTocopy.getVertexAttribute(usage[i]).numComponents;                as++;            }        if (size > 0) {            attrs = new VertexAttribute[as];            checks = new short[size];            int IDx = -1;            int ai = -1;            for (int i = 0; i < usage.length; i++) {                VertexAttribute a = meshTocopy.getVertexAttribute(usage[i]);                if (a == null)                    continue;                for (int j = 0; j < a.numComponents; j++)                    checks[++IDx] = (short)(a.offset/4 + j);                attrs[++ai] = new VertexAttribute(a.usage,a.numComponents,a.alias);                newVertexSize += a.numComponents;            }        }    }    if (checks == null) {        checks = new short[vertexSize];        for (short i = 0; i < vertexSize; i++)            checks[i] = i;        newVertexSize = vertexSize;    }    int numIndices = meshTocopy.getNumIndices();    short[] indices = null;     if (numIndices > 0) {        indices = new short[numIndices];        meshTocopy.getIndices(indices);        if (removeDuplicates || newVertexSize != vertexSize) {            float[] tmp = new float[vertices.length];            int size = 0;            for (int i = 0; i < numIndices; i++) {                final int IDx1 = indices[i] * vertexSize;                short newIndex = -1;                if (removeDuplicates) {                    for (short j = 0; j < size && newIndex < 0; j++) {                        final int IDx2 = j*newVertexSize;                        boolean found = true;                        for (int k = 0; k < checks.length && found; k++) {                            if (tmp[IDx2+k] != vertices[IDx1+checks[k]])                                found = false;                        }                        if (found)                            newIndex = j;                    }                }                if (newIndex > 0)                    indices[i] = newIndex;                else {                    final int IDx = size * newVertexSize;                    for (int j = 0; j < checks.length; j++)                        tmp[IDx+j] = vertices[IDx1+checks[j]];                    indices[i] = (short)size;                    size++;                }            }            vertices = tmp;            numVertices = size;        }    }    Mesh result;    if (attrs == null)        result = new Mesh(isstatic,numVertices,indices == null ? 0 : indices.length,meshTocopy.getVertexAttributes());    else        result = new Mesh(isstatic,attrs);    result.setVertices(vertices,numVertices * newVertexSize);    result.setIndices(indices);    return result;}

这对于尝试在libGDX中编写自己的3D游戏的人来说可能非常有用.没有这种机制,写出比几种型号更多的编辑是不可能的.

总结

以上是内存溢出为你收集整理的Android – 在libGDX中的慢速模型批处理渲染全部内容,希望文章能够帮你解决Android – 在libGDX中的慢速模型批处理渲染所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1133745.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存