[android]在 libgdx 缓慢呈现器

标签: Android
发布时间: 2014/2/6 2:30:25
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我有一个问题是否有一种特殊的方式进行分组中 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, 0, -y);
        mModelBatch.render(instance);
     }

  }

  mModelBatch.end(); 

I've got about 12 FPS on my phone (Sony Xperia mini pro).

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

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。与此同时,使另一个测试我创造在搅拌机中同一地图因为它是在先前的程序。下一个我 groupped 一切都只是一个对象 (无需任何额外的版本)。这种方式,我创建了一个大对象的大小几乎 1 MB,它可以从搅拌机的截图上看到:)。

enter image description here

我改变了它绘制只有这一个大对象的一种方法中的测试程序:

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

下一件事的就是我在我的手机 (索尼 XPeria Mini Pro-和以前相同) 上发起程序和 iPod 5 g 和我过了......60 FPS !enter image description here

谁可以帮我吗?请吗?

解决方法 1:

问题解决了 !我 ver 低端移动设备上实现 60 FPS。游戏运行 smootly。我找到了如何将多个网格合并到一个网格,以便可以使用 VBO mechanizms。LibGDX 造成无法使用的网格复制方法与多个网格中有一个 bug。改变后,地图被划分在小部门。每个部门包括具有相同的 z 轴值的网格上下面的图像中可以看出:enter image description here

VBO 机制是非常 limitated,所以不多的顶点可以画在一次性这就是为什么各部门都要相当小。新呈现器不得不编写,以处理呈现正确。渲染器的部分动态合并网格 (没有任何单独的工具,像 eg。 搅拌机)。

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), vertices, vertexSize, offset, numComponents, vertexOffset, numVertices);
        vertexOffset += numVertices;
        vertexSizeOffset += baseSize;
    }

    Mesh result = new Mesh(true, vertexOffset, 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, numVertices, indices == null ? 0 : indices.length, attrs);
    result.setVertices(vertices, 0, numVertices * newVertexSize);
    result.setIndices(indices);
    return result;
}

这可以是对人们试图在 libGDX 中编写他们自己的 3D 游戏非常有用。没有这个机制就不大可能比几个模型的多个并发写任何东西。

官方微信
官方QQ群
31647020