Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android – 在libGDX中的慢速模型批处理渲染大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个问题是否有一个特殊的模式来分组模型在libGDX.我创建了一个实现ApplicationListener的简单类,显示了我的问题.我正在使用libGDX的夜间版本.

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

@H_289_4@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);
     }
  }

}

我使用它,如下所示:

@H_289_4@mModelBatch.begin(camera); mModelBatch.render(testRenderProvider); mModelBatch.end();

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

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

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

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

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

@L_772_17@

问题解决了!我在一个低端移动设备上实现了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 vertexArray@R_592_10586@lSize = 0;
    int indexArray@R_592_10586@lSize = 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));
        }

        vertexArray@R_592_10586@lSize += mesh.getNumVertices() * mesh.getVertexSize() / 4;
        indexArray@R_592_10586@lSize += mesh.getNumInDices();
    }

    final float vertices[] = new float[vertexArray@R_592_10586@lSize];
    final short inDices[] = new short[indexArray@R_592_10586@lSize];

    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中的慢速模型批处理渲染所遇到的程序开发问题。

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。