我有一个问题是否有一个特殊的模式来分组模型在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中的慢速模型批处理渲染的更多相关文章

  1. android – LIBGDX输入 – 触摸屏幕的手指数

    我想知道如何让我的游戏触摸屏幕的手指总数.谢谢解决方法如果您使用InputProcessor进行基于事件的输入处理,只需在touchDown处递增计数器并在touchUp处递减计数器.如果您使用Gdx.input进行基于轮询的输入处理,请使用isTouched(int)调用来测试指针N是否已关闭.libGDX实现tracksatmost20pointers.我不认为任何硬件支持那么多(并且你的游戏

  2. android – libgdx如何检测键盘的存在

    在文本字段中书写时,我需要我的文本字段向上移动,以便在键盘弹出时让文本字段可见.libgdx是否有某种方法在键盘可见时返回true而在键盘关闭时返回false?解决方法以下代码将检测您何时按下文本字段,阻止其显示键盘,然后打开使用键盘上下移动的本机对话框.它将从原生对话框中获取输入,最后将其放回textField中:祝好运!

  3. android – LibGDX无法加载特定图像

    )因为在使用OSX上的Preview将我的spritesheet转换为8位深度后,我发现问题消失了.感谢P.T.有关升级LibGDX的建议,因为我收到以下错误消息:

  4. android-studio – 从Android Studio导出一个Libgdx游戏作为可执行文件夹

    好吧所以我用Libgdx制作了一个游戏,我打算将它作为一个Android应用程序但我想让我的朋友没有安卓手机试试看.该项目已经设置为桌面和Android,所以有没有办法将其导出为可执行的jar文件?

  5. Android:LibGDX 2D游戏内存消耗

    或者发布一些链接以了解解决此问题需要做些什么.一些更新Toady我在3.x模拟器上做了一些额外的测试>我使用1024*600采用的纹理运行游戏–80%加载资源上的应用程序崩溃>纹理为800*480–应用程序在100%加载时崩溃最后我在新的谷歌Nexus平板电脑上运行应用程序,该平板电脑使用与3.x平板电脑相同的纹理–约30Mb本机内存和~12Mbvm堆.现在我完全不了解正在发生的事情–相同的内存分配为纹理800*480和1280*800……id=16941幸运的Android3你有大堆选项这是我必须为我们

  6. android – 使用Libgdx集成Fabric

    我正在尝试将FabricSDK与我的Androidlibgdx应用程序集成.fabric.io提供的AndroidStudio插件不适用于我的Gradle构建文件(由Libgdxtool生成).该插件只是不触及它们.所以我尝试手动编辑它们.这是我的build.gradle文件:我没有触及android/build.gradle文件.SDK不在类路径中.解决方法我正在用这种方式将Fabric(Cra

  7. android – touchDragged如何在libgdx中运行?

    我目前正在学习libgdx游戏编程,现在我已经学会了如何使用touchDown但是我不知道如何使用touchDragged.计算机如何知道手指被拖动的方向解决方法电脑不知道.或者至少界面不会告诉你这些信息.它看起来像这样:它与touchDown几乎相同:发生touchDown事件后,只会触发touchDragged事件,直到触发touchUp事件.如果你想知道指针移动的方向,你必须通过计算最后一个接触点和当前接触点之间的差值(差值)来自己计算.这可能看起来像这样:

  8. android – 使用libgdx的SVG文件

    我打算创建平板电脑应用程序.我会要求一些指导.我有像thisone这样的SVG格式的图片.使用SVG很容易,您只需将填充参数更改为不同的颜色,但是据了解,使用libgdx没有简单/稳定的svg处理.我仍然想使用svg文件来创建/存储我的应用程序的图像.>你会推荐什么处理路径?

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

    可以在一个绘图调用中渲染一切吗?解决方法问题解决了!

  10. android – 如何在libgdx中创建加载屏幕?

    我有一个GameScreen类来渲染我的游戏.但在开始渲染游戏之前,需要阅读文件并进行初始化是耗时的.所以我需要显示/渲染另一个名为LoadingScreen的Screen类,以便花费一些时间并同时读取我的文件,并对我的GameScreen进行初始化过程,并且在初始化完成后,通过调用setScreen(gameScreen)来更改屏幕.我需要使用线程进行并发工作,现在的问题是如果我使用线程来读取文

随机推荐

  1. bluetooth-lowenergy – Altbeacon库无法在Android 5.0上运行

    昨天我在Nexus4上获得了Android5.0的更新,并且altbeacon库停止了检测信标.似乎在监视和测距时,didEnterRegion和didRangeBeaconsInRegion都没有被调用.即使RadiusNetworks的Locate应用程序现在表现不同,一旦检测到信标的值,它们就不再得到更新,并且通常看起来好像信标超出了范围.我注意到的一点是,现在在logcat中出现以下行“B

  2. android – react-native动态更改响应者

    我正在使用react-native进行Android开发.我有一个视图,如果用户长按,我想显示一个可以拖动的动画视图.我可以使用PanResponder实现这一点,它工作正常.但我想要做的是当用户长按时,用户应该能够继续相同的触摸/按下并拖动新显示的Animated.View.如果您熟悉Google云端硬盘应用,则它具有类似的功能.当用户长按列表中的任何项目时,它会显示可拖动的项目.用户可以直接拖

  3. android – 是否有可能通过使用与最初使用的证书不同的证书对其进行签名来发布更新的应用程序

    是否可以通过使用与最初使用的证书不同的证书进行签名来发布Android应用程序的更新?我知道当我们尝试将这样的构建上传到市场时,它通常会给出错误消息.但有没有任何出路,比如将其标记为主要版本,指定市场中的某个地方?解决方法不,你不能这样做.证书是一种工具,可确保您是首次上传应用程序的人.所以总是备份密钥库!

  4. 如何检测Android中是否存在麦克风?

    ..所以我想在让用户访问语音输入功能之前检测麦克风是否存在.如何检测设备上是否有麦克风.谢谢.解决方法AndroidAPI参考:hasSystemFeature

  5. Android – 调用GONE然后VISIBLE使视图显示在错误的位置

    我有两个视图,A和B,视图A在视图B上方.当我以编程方式将视图A设置为GONE时,它将消失,并且它正下方的视图将转到视图A的位置.但是,当我再次将相同的视图设置为VISIBLE时,它会在视图B上显示.我不希望这样.我希望视图B回到原来的位置,这是我认为会发生的事情.我怎样才能做到这一点?编辑–代码}这里是XML:解决方法您可以尝试将两个视图放在RelativeLayout中并相对于彼此设置它们的位置.

  6. android – 获得一首歌的流派

    我如何阅读与歌曲相关的流派?我可以读这首歌,但是如何抓住这首歌的流派,它存放在哪里?解决方法检查此代码:

  7. android – 使用textShadow折叠工具栏

    我有一个折叠工具栏的问题,在展开状态我想在文本下面有一个模糊的阴影,我使用这段代码:用:我可以更改textColor,它可以工作,但阴影不起作用.我为阴影尝试了很多不同的值.是否可以为折叠文本投射阴影?

  8. android – 重用arm共享库

    我已经建立了armarm共享库.我有兴趣重用一个函数.我想调用该函数并获得返回值.有可能做这样的事吗?我没有任何头文件.我试过这个Android.mk,我把libtest.so放在/jni和/libs/armeabi,/lib/armeabi中.此时我的cpp文件编译,但现在是什么?我从objdump知道它的名字编辑:我试图用这个android.mk从hello-jni示例中添加prebuild库:它工作,但libtest.so相同的代码显示以下错误(启动时)libtest.so存在于libhello-j

  9. android – 为NumberPicker捕获键盘’Done’

    我有一个AlertDialog只有一些文本,一个NumberPicker,一个OK和一个取消.(我知道,这个对话框还没有做它应该保留暂停和恢复状态的事情.)我想在软键盘或其他IME上执行“完成”操作来关闭对话框,就像按下了“OK”一样,因为只有一个小部件可以编辑.看起来处理IME“Done”的最佳方法通常是在TextView上使用setonEditorActionListener.但我没有任何Te

  10. android – 想要在调用WebChromeClient#onCreateWindow时知道目标URL

    当我点击一个带有target=“_blank”属性的超链接时,会调用WebChromeClient#onCreateWindow,但我找不到新的窗口将打开的新方法?主页url是我唯一能知道的东西?我想根据目标网址更改应用行为.任何帮助表示赞赏,谢谢!

返回
顶部