在 libgdx 中批量处理多维数据集时遇到问题 [英] Trouble batching cubes in libgdx

查看:26
本文介绍了在 libgdx 中批量处理多维数据集时遇到问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试开发一个游戏,我在屏幕上渲染多达 300 个立方体.在为每个多维数据集创建新的模型实例时,modelBatch 的性能很糟糕.据我所知,没有 3d 批处理可以将所有立方体批处理到一个绘制调用中.所以我拼命地试图以某种方式批量处理它们.

这个问题和这个有直接关系:.

我还想澄清一下,我没有使用任何自定义着色器.仅使用 ModelBatch.begin() 和 .end() 方法,无需额外的 openGl 调用.

解决方案

我看到了几个问题:

  1. 您已关闭混合和/或您的着色器未设置 alpha 值

  2. 你没有剔除背面.

因此,当您创建新材料时,不要仅使用 new Material(),而是使用:

新材料(IntAttribute.createCullFace(GL20.GL_FRONT),//由于某些原因,libgdx ModelBuilder 做了反向缠绕的boxes,所以cull FRONTnew BlendingAttribute(1f),//不透明,因为乘以顶点颜色new DepthTestAttribute(false),//不想要深度遮罩或后方立方体可能无法显示ColorAttribute.createDiffuse(Color.WHITE)//白色自乘顶点颜色);

您还需要按距相机的距离对立方体进行排序,以使它们的 alpha 正确分层.这是一个支持排序的更新 Cube 类.它必须能够独立于顶点数组跟踪颜色,以防其索引发生变化:

公共类Cube实现Comparable{私有整数索引;int vertexFloatSize;int posOffset;int norOffset;boolean hasColor;int colOffset;私有 Vector3 位置 = new Vector3();私有 Matrix4 rotationTransform = new Matrix4().idt();公共浮动半宽、半高、半深;私有布尔transformDirty = false;private boolean colorDirty = false;私有颜色颜色=新颜色();浮动凸轮DistSquared;静态最终 Vector3 CORNER000 = new Vector3();静态最终 Vector3 CORNER010 = new Vector3();静态最终 Vector3 CORNER100 = new Vector3();静态最终 Vector3 CORNER110 = new Vector3();静态最终 Vector3 CORNER001 = new Vector3();静态最终 Vector3 CORNER011 = new Vector3();静态最终 Vector3 CORNER101 = new Vector3();静态最终 Vector3 CORNER111 = new Vector3();静态最终 Vector3[] FACE0 = {CORNER000, CORNER100, CORNER110, CORNER010};静态最终 Vector3[] FACE1 = {CORNER101, CORNER001, CORNER011, CORNER111};静态最终 Vector3[] FACE2 = {CORNER000, CORNER010, CORNER011, CORNER001};静态最终 Vector3[] FACE3 = {CORNER101, CORNER111, CORNER110, CORNER100};静态最终 Vector3[] FACE4 = {CORNER101, CORNER100, CORNER000, CORNER001};静态最终 Vector3[] FACE5 = {CORNER110, CORNER111, CORNER011, CORNER010};静态最终 Vector3[][] 面部 = {FACE0,FACE1,FACE2,FACE3,FACE4,FACE5};静态最终 Vector3 NORMAL0 = new Vector3();静态最终 Vector3 NORMAL1 = new Vector3();静态最终 Vector3 NORMAL2 = new Vector3();静态最终 Vector3 NORMAL3 = new Vector3();静态最终 Vector3 NORMAL4 = new Vector3();静态最终 Vector3 NORMAL5 = new Vector3();静态最终 Vector3[] NORMALS = {NORMAL0, NORMAL1, NORMAL2, NORMAL3, NORMAL4, NORMAL5};公共立方体(浮动 x,浮动 y,浮动 z,浮动宽度,浮动高度,浮动深度,整数索引,VertexAttributes vertexAttributes, float[] meshVertices){位置.set(x,y,z);this.halfWidth = 宽度/2;this.halfHeight = 高度/2;this.halfDepth = 深度/2;this.index = 索引;vertexFloatSize = vertexAttributes.vertexSize/4;//每个浮点数 4 个字节posOffset = getVertexAttribute(Usage.Position, vertexAttributes).offset/4;norOffset = getVertexAttribute(Usage.Normal, vertexAttributes).offset/4;VertexAttribute colorAttribute = getVertexAttribute(Usage.Color, vertexAttributes);hasColor = colorAttribute!=null;如果(有颜色){colOffset = colorAttribute.offset/4;this.setColor(Color.WHITE, meshVertices);}transformDirty = 真;}公共无效updateCameraDistance(相机凸轮){camDistSquared = cam.position.dst2(position);}/*** 在移动和/或旋转后调用它.*/公共无效更新(浮动[]meshVertices){如果(转换脏){transformDirty = 假;CORNER000.set(-halfWidth,-halfHeight,-halfDepth).rot(rotationTransform).add(position);CORNER010.set(-halfWidth,halfHeight,-halfDepth).rot(rotationTransform).add(position);CORNER100.set(halfWidth,-halfHeight,-halfDepth).rot(rotationTransform).add(position);CORNER110.set(halfWidth,halfHeight,-halfDepth).rot(rotationTransform).add(position);CORNER001.set(-halfWidth,-halfHeight,halfDepth).rot(rotationTransform).add(position);CORNER011.set(-halfWidth,halfHeight,halfDepth).rot(rotationTransform).add(position);CORNER101.set(halfWidth,-halfHeight,halfDepth).rot(rotationTransform).add(position);CORNER111.set(halfWidth,halfHeight,halfDepth).rot(rotationTransform).add(position);NORMAL0.set(0,0,-1).rot(rotationTransform);NORMAL1.set(0,0,1).rot(rotationTransform);NORMAL2.set(-1,0,0).rot(rotationTransform);NORMAL3.set(1,0,0).rot(rotationTransform);NORMAL4.set(0,-1,0).rot(rotationTransform);NORMAL5.set(0,1,0).rot(rotationTransform);for (int faceIndex= 0; faceIndex<6; faceIndex++){int baseVertexIndex = (index*24 + faceIndex*4)*vertexFloatSize;//每个立方体24个唯一顶点,每个面4个唯一顶点for (int cornerIndex=0;cornerIndex<4;cornerIndex++){int vertexIndex = baseVertexIndex + cornerIndex*vertexFloatSize + posOffset;meshVertices[vertexIndex] = FACES[faceIndex][cornerIndex].x;meshVertices[++vertexIndex] = FACES[faceIndex][cornerIndex].y;meshVertices[++vertexIndex] = FACES[faceIndex][cornerIndex].z;vertexIndex = baseVertexIndex + cornerIndex*vertexFloatSize + norOffset;meshVertices[vertexIndex] = NORMALS[faceIndex].x;meshVertices[++vertexIndex] = NORMALS[faceIndex].y;meshVertices[++vertexIndex] = NORMALS[faceIndex].z;}}}如果(颜色脏){colorDirty = 假;for (int faceIndex= 0; faceIndex<6; faceIndex++){int baseVertexIndex = (index*24 + faceIndex*4)*vertexFloatSize;//每个立方体24个唯一顶点,每个面4个唯一顶点for (int cornerIndex=0;cornerIndex<4;cornerIndex++){int vertexIndex = baseVertexIndex + cornerIndex*vertexFloatSize + colOffset;meshVertices[vertexIndex] = color.r;meshVertices[++vertexIndex] = color.g;meshVertices[++vertexIndex] = color.b;meshVertices[++vertexIndex] = color.a;}}}}公共立方体 setColor(颜色颜色,浮动 [] 网格顶点){如果(有颜色){this.color.set(颜色);颜色脏 = 真;}返回这个;}public void setIndex(int index){如果 (this.index != index){transformDirty = 真;颜色脏 = 真;this.index = 索引;}}公共立方体翻译(浮动 x,浮动 y,浮动 z){位置.添加(x,y,z);transformDirty = 真;返回这个;}公共立方体translateTo(浮动x,浮动y,浮动z){位置.set(x,y,z);transformDirty = 真;返回这个;}公共立方体旋转(浮动轴X,浮动轴Y,浮动轴Z,浮动度){rotationTransform.rotate(axisX,axisY,axisZ,degrees);transformDirty = 真;返回这个;}公共立方体旋转(浮动轴X,浮动轴Y,浮动轴Z,浮动度){旋转变换.idt();rotationTransform.rotate(axisX,axisY,axisZ,degrees);transformDirty = 真;返回这个;}public VertexAttribute getVertexAttribute(int 用法,VertexAttributes 属性){int len = attributes.size();for (int i = 0; i other.camDistSquared)返回-1;返回 camDistSquared

你会这样排序:

for (Cube cube : mBatchedCubes){立方体.updateCameraDistance(相机);}mBatchedCubes.sort();整数索引 = 0;对于(立方体立方体:mBatchedCubes){立方体.setIndex(索引++);}

I am trying to develop a game where I am rendering up to 300 cubes on screen. The performance of modelBatch when creating new modelInstance for each cube is terrible. There is no 3d batch that batches all the cubes to one draw call as far as I know. So I am desperately trying to batch them somehow.

This question is directly related to this one: LibGDX 3D increase perfomance

The answer posted batches all the cubes successfully but when environment is added to get some lighting it appears that the cubes have missing sides or something else is wrong with them.

Heres a picture:

Here is my cube class (pretty much copied from answer above)

public class Cube {

  int index;
  int vertexFloatSize;
  int posOffset;
  int norOffset;
  boolean hasColor;
  int colOffset;
  private Vector3 position = new Vector3();
  private Matrix4 rotationTransform = new Matrix4().idt();

  private Color color = new Color();
  public float halfWidth, halfHeight, halfDepth;
  private boolean transformDirty = false;
  private boolean colorDirty = false;

  static final Vector3 CORNER000 = new Vector3();
  static final Vector3 CORNER010 = new Vector3();
  static final Vector3 CORNER100 = new Vector3();
  static final Vector3 CORNER110 = new Vector3();
  static final Vector3 CORNER001 = new Vector3();
  static final Vector3 CORNER011 = new Vector3();
  static final Vector3 CORNER101 = new Vector3();
  static final Vector3 CORNER111 = new Vector3();

  static final Vector3[] FACE0 = {CORNER000, CORNER100, CORNER110, CORNER010};
  static final Vector3[] FACE1 = {CORNER101, CORNER001, CORNER011, CORNER111};
  static final Vector3[] FACE2 = {CORNER000, CORNER010, CORNER011, CORNER001};
  static final Vector3[] FACE3 = {CORNER101, CORNER111, CORNER110, CORNER100};
  static final Vector3[] FACE4 = {CORNER101, CORNER100, CORNER000, CORNER001};
  static final Vector3[] FACE5 = {CORNER110, CORNER111, CORNER011, CORNER010};
  static final Vector3[][] FACES = {FACE0, FACE1, FACE2, FACE3, FACE4, FACE5};

  static final Vector3 NORMAL0 = new Vector3();
  static final Vector3 NORMAL1 = new Vector3();
  static final Vector3 NORMAL2 = new Vector3();
  static final Vector3 NORMAL3 = new Vector3();
  static final Vector3 NORMAL4 = new Vector3();
  static final Vector3 NORMAL5 = new Vector3();
  static final Vector3[] NORMALS = {NORMAL0, NORMAL1, NORMAL2, NORMAL3, NORMAL4, NORMAL5};

  float[] meshVertices;

  public Cube(float x, float y, float z, float width, float height, float depth, int index, 
        VertexAttributes vertexAttributes, float[] meshVertices){

      position.set(x,y,z);
      this.halfWidth = width/2;
      this.halfHeight = height/2;
      this.halfDepth = depth/2;
      this.index = index;
      this.meshVertices = meshVertices;

      NORMAL0.set(0,0,-1);
      NORMAL1.set(0,0,1);
      NORMAL2.set(-1,0,0);
      NORMAL3.set(1,0,0);
      NORMAL4.set(0,-1,0);
      NORMAL5.set(0,1,0);

      vertexFloatSize = vertexAttributes.vertexSize/4; //4 bytes per float
      posOffset = getVertexAttribute(Usage.Position, vertexAttributes).offset/4;
      norOffset = getVertexAttribute(Usage.Normal, vertexAttributes).offset/4;

      VertexAttribute colorAttribute = getVertexAttribute(Usage.Color, vertexAttributes);
      hasColor = colorAttribute!=null;
      if (hasColor){
          colOffset = colorAttribute.offset/4;
          this.setColor(Color.WHITE);
      }
      transformDirty = true;

  }

  public void setDimensions(float x, float y , float z){

      this.halfWidth = x/2;
      this.halfHeight = y/2;
      this.halfDepth = z/2;

  }

  public void setIndex(int index){

      this.index = index;
      transformDirty = true;
      colorDirty = true;

  }

  /**
   * Call this after moving and/or rotating.
   */
  public void update(){

      if (colorDirty && hasColor){
          for (int faceIndex= 0; faceIndex<6; faceIndex++){
              int baseVertexIndex = (index*24 + faceIndex*4)*vertexFloatSize;//24 unique vertices per cube, 4 unique vertices per face
              for (int cornerIndex=0; cornerIndex<4; cornerIndex++){
                  int vertexIndex = baseVertexIndex + cornerIndex*vertexFloatSize + colOffset;
                  meshVertices[vertexIndex] = color.r;
                  meshVertices[++vertexIndex] = color.g;
                  meshVertices[++vertexIndex] = color.b;
                  meshVertices[++vertexIndex] = color.a;
              }
          }
          colorDirty = false;
      }


      if (!transformDirty){
          return;
      }

      transformDirty = false;

      CORNER000.set(-halfWidth,-halfHeight,-halfDepth).rot(rotationTransform).add(position);
      CORNER010.set(-halfWidth,halfHeight,-halfDepth).rot(rotationTransform).add(position);
      CORNER100.set(halfWidth,-halfHeight,-halfDepth).rot(rotationTransform).add(position);
      CORNER110.set(halfWidth,halfHeight,-halfDepth).rot(rotationTransform).add(position);
      CORNER001.set(-halfWidth,-halfHeight,halfDepth).rot(rotationTransform).add(position);
      CORNER011.set(-halfWidth,halfHeight,halfDepth).rot(rotationTransform).add(position);
      CORNER101.set(halfWidth,-halfHeight,halfDepth).rot(rotationTransform).add(position);
    CORNER111.set(halfWidth,halfHeight,halfDepth).rot(rotationTransform).add(position);

      NORMAL0.set(0,0,-1).rot(rotationTransform);
      NORMAL1.set(0,0,1).rot(rotationTransform);
      NORMAL2.set(-1,0,0).rot(rotationTransform);
      NORMAL3.set(1,0,0).rot(rotationTransform);
      NORMAL4.set(0,-1,0).rot(rotationTransform);
      NORMAL5.set(0,1,0).rot(rotationTransform);

      for (int faceIndex= 0; faceIndex<6; faceIndex++){
          int baseVertexIndex = (index*24 + faceIndex*4)*vertexFloatSize;//24 unique vertices per cube, 4 unique vertices per face
          for (int cornerIndex=0; cornerIndex<4; cornerIndex++){
              int vertexIndex = baseVertexIndex + cornerIndex*vertexFloatSize + posOffset;
              meshVertices[vertexIndex] = FACES[faceIndex][cornerIndex].x;
              meshVertices[++vertexIndex] = FACES[faceIndex][cornerIndex].y;
              meshVertices[++vertexIndex] = FACES[faceIndex][cornerIndex].z;

              vertexIndex = baseVertexIndex + cornerIndex*vertexFloatSize + norOffset;
              meshVertices[vertexIndex] = NORMALS[faceIndex].x;
              meshVertices[++vertexIndex] = NORMALS[faceIndex].y;
              meshVertices[++vertexIndex] = NORMALS[faceIndex].z;
          }
      }
  }

  public Cube setColor(Color color){

      if (hasColor){
          this.color.set(color);
          colorDirty = true;
      }
      return this;
  }

  public void setAlpha(float alpha) {

       if (hasColor){

           this.color.set(this.color.r, this.color.g, this.color.b, alpha);
           colorDirty = true;

       }
  }

  public Cube translate(float x, float y, float z){
      position.add(x,y,z);
      transformDirty = true;
      return this;
  }

  public Cube setPosition(float x, float y, float z){
      position.set(x,y,z);
      transformDirty = true;
      return this;
  }

public Cube setPosition(Vector3 position1) {

       position.set(position1);
       transformDirty = true;
       return this;

  }

  public VertexAttribute getVertexAttribute (int usage, VertexAttributes attributes) {
      int len = attributes.size();
      for (int i = 0; i < len; i++)
          if (attributes.get(i).usage == usage) return attributes.get(i);

      return null;
  }



  public Vector3 getPosition() {

      return this.position;
  }

}

And here is a test case that i created to test the cubes.

public class TestCase {

    ModelInstance mBatchedCubesModelInstance;
    Mesh mBatchedCubesMesh;
    float[] mBatchedCubesVertices;
    Array<Cube> mBatchedCubes;

    TestCase(){

            int width = 5;
            int height = 5;
            int length = 5;
            int numCubes = width*height*length;

            ModelBuilder mb = new ModelBuilder();
            mb.begin();
            MeshPartBuilder mpb = mb.part("cubes", GL20.GL_TRIANGLES, (Usage.Position | Usage.Normal | Usage.Color), new Material());
            for (int i=0; i<numCubes; i++){
                mpb.box(1, 1, 1);
            }
            Model model = mb.end();
            mBatchedCubesModelInstance = new ModelInstance(model);

            mBatchedCubesMesh = model.meshes.get(0);
            VertexAttributes vertexAttributes = mBatchedCubesMesh.getVertexAttributes();
            int vertexFloatSize = vertexAttributes .vertexSize / 4; //4 bytes per float
            mBatchedCubesVertices = new float[numCubes * 24 * vertexFloatSize]; //24 unique vertices per cube
            mBatchedCubesMesh.getVertices(mBatchedCubesVertices);

            mBatchedCubes = new Array<Cube>(numCubes);
            int cubeNum = 0;
            for (int x = 0; x < width; x++) {
                    for (int y = 0; y < height; y++) {
                            for (int z = 0; z < length; z++) {
                                    mBatchedCubes.add(new Cube((x-(width/2f))*1.5f, -((y-(height/2f)) * 1.5f), -(z-(length/2f))*1.5f, 1,1,1, cubeNum++, vertexAttributes, mBatchedCubesVertices ).setColor(Colors.getMixedColor()));
                            }
                    }
            }

    }

    public void render(ModelBatch batch, Environment environment){

            for (Cube cube : mBatchedCubes){ //must update any changed cubes.
                cube.update();
            }
            mBatchedCubesMesh.setVertices(mBatchedCubesVertices); //apply changes to mesh

            if(environment!=null) batch.render(mBatchedCubesModelInstance,environment);
            else batch.render(this.mBatchedCubesModelInstance);

    }

}

The cubes don't even move in my game so I don't even need the transformation. I just need to set the colors (including alpha channel) every frame. The batched mesh should work with libgdx shadow mapping also (I hope it automatically works when you have a properly batched modelInstance).

Could anyone tell me what is wrong with my code and why some faces don't show up. I understand I might be asking much so I will put a bounty on this question (50 points) after two days.

EDIT: After the answer from Tenfour04 things got a lot better. Alpha channel seems to work, strange face problem seems to have disappeared. However When I applied the changes to my real game I noticed that sometimes flour draws on top of in game terrain. I updated the test to illustrate the problem by adding big plane in the middle of cubes. Made a video: https://www.youtube.com/watch?v=LQhSMJfuyZY.

I would also like to clarify that I am not using any custom shader. Using only ModelBatch.begin() and .end() methods with no additional openGl calls.

解决方案

I see a couple problems:

  1. You have blending off and/or your shader isn't setting the alpha value

  2. You aren't culling back faces.

So when you create your new material, instead of just using new Material(), use:

new Material(
    IntAttribute.createCullFace(GL20.GL_FRONT),//For some reason, libgdx ModelBuilder makes boxes with faces wound in reverse, so cull FRONT
    new BlendingAttribute(1f), //opaque since multiplied by vertex color
    new DepthTestAttribute(false), //don't want depth mask or rear cubes might not show through
    ColorAttribute.createDiffuse(Color.WHITE) //white since multiplied by vertex color
    );

You will also need to sort the cubes by distance from camera to get their alphas to layer correctly. Here's an updated Cube class that supports sorting. It has to be able to track color independently from the vertices array in case its index changes:

public class Cube implements Comparable<Cube>{

    private int index;
    int vertexFloatSize;
    int posOffset;
    int norOffset;
    boolean hasColor;
    int colOffset;
    private Vector3 position = new Vector3();
    private Matrix4 rotationTransform = new Matrix4().idt();
    public float halfWidth, halfHeight, halfDepth;
    private boolean transformDirty = false;
    private boolean colorDirty = false;
    private Color color = new Color();
    float camDistSquared;

    static final Vector3 CORNER000 = new Vector3();
    static final Vector3 CORNER010 = new Vector3();
    static final Vector3 CORNER100 = new Vector3();
    static final Vector3 CORNER110 = new Vector3();
    static final Vector3 CORNER001 = new Vector3();
    static final Vector3 CORNER011 = new Vector3();
    static final Vector3 CORNER101 = new Vector3();
    static final Vector3 CORNER111 = new Vector3();

    static final Vector3[] FACE0 = {CORNER000, CORNER100, CORNER110, CORNER010};
    static final Vector3[] FACE1 = {CORNER101, CORNER001, CORNER011, CORNER111};
    static final Vector3[] FACE2 = {CORNER000, CORNER010, CORNER011, CORNER001};
    static final Vector3[] FACE3 = {CORNER101, CORNER111, CORNER110, CORNER100};
    static final Vector3[] FACE4 = {CORNER101, CORNER100, CORNER000, CORNER001};
    static final Vector3[] FACE5 = {CORNER110, CORNER111, CORNER011, CORNER010};
    static final Vector3[][] FACES = {FACE0, FACE1, FACE2, FACE3, FACE4, FACE5};

    static final Vector3 NORMAL0 = new Vector3();
    static final Vector3 NORMAL1 = new Vector3();
    static final Vector3 NORMAL2 = new Vector3();
    static final Vector3 NORMAL3 = new Vector3();
    static final Vector3 NORMAL4 = new Vector3();
    static final Vector3 NORMAL5 = new Vector3();
    static final Vector3[] NORMALS = {NORMAL0, NORMAL1, NORMAL2, NORMAL3, NORMAL4, NORMAL5};

    public Cube(float x, float y, float z, float width, float height, float depth, int index, 
        VertexAttributes vertexAttributes, float[] meshVertices){
    position.set(x,y,z);
    this.halfWidth = width/2;
    this.halfHeight = height/2;
    this.halfDepth = depth/2;
    this.index = index;


    vertexFloatSize = vertexAttributes.vertexSize/4; //4 bytes per float
    posOffset = getVertexAttribute(Usage.Position, vertexAttributes).offset/4;
    norOffset = getVertexAttribute(Usage.Normal, vertexAttributes).offset/4;

    VertexAttribute colorAttribute = getVertexAttribute(Usage.Color, vertexAttributes);
    hasColor = colorAttribute!=null;
    if (hasColor){
        colOffset = colorAttribute.offset/4;
        this.setColor(Color.WHITE, meshVertices);
    }
    transformDirty = true;
    }

    public void updateCameraDistance(Camera cam){
    camDistSquared = cam.position.dst2(position);
    }

    /**
     * Call this after moving and/or rotating.
     */
    public void update(float[] meshVertices){

    if (transformDirty){
        transformDirty = false;

        CORNER000.set(-halfWidth,-halfHeight,-halfDepth).rot(rotationTransform).add(position);
        CORNER010.set(-halfWidth,halfHeight,-halfDepth).rot(rotationTransform).add(position);
        CORNER100.set(halfWidth,-halfHeight,-halfDepth).rot(rotationTransform).add(position);
        CORNER110.set(halfWidth,halfHeight,-halfDepth).rot(rotationTransform).add(position);
        CORNER001.set(-halfWidth,-halfHeight,halfDepth).rot(rotationTransform).add(position);
        CORNER011.set(-halfWidth,halfHeight,halfDepth).rot(rotationTransform).add(position);
        CORNER101.set(halfWidth,-halfHeight,halfDepth).rot(rotationTransform).add(position);
        CORNER111.set(halfWidth,halfHeight,halfDepth).rot(rotationTransform).add(position);

        NORMAL0.set(0,0,-1).rot(rotationTransform);
        NORMAL1.set(0,0,1).rot(rotationTransform);
        NORMAL2.set(-1,0,0).rot(rotationTransform);
        NORMAL3.set(1,0,0).rot(rotationTransform);
        NORMAL4.set(0,-1,0).rot(rotationTransform);
        NORMAL5.set(0,1,0).rot(rotationTransform);

        for (int faceIndex= 0; faceIndex<6; faceIndex++){
        int baseVertexIndex = (index*24 + faceIndex*4)*vertexFloatSize;//24 unique vertices per cube, 4 unique vertices per face
        for (int cornerIndex=0; cornerIndex<4; cornerIndex++){
            int vertexIndex = baseVertexIndex + cornerIndex*vertexFloatSize + posOffset;
            meshVertices[vertexIndex] = FACES[faceIndex][cornerIndex].x;
            meshVertices[++vertexIndex] = FACES[faceIndex][cornerIndex].y;
            meshVertices[++vertexIndex] = FACES[faceIndex][cornerIndex].z;

            vertexIndex = baseVertexIndex + cornerIndex*vertexFloatSize + norOffset;
            meshVertices[vertexIndex] = NORMALS[faceIndex].x;
            meshVertices[++vertexIndex] = NORMALS[faceIndex].y;
            meshVertices[++vertexIndex] = NORMALS[faceIndex].z;
        }
        }
    }

    if (colorDirty){
        colorDirty = false;

        for (int faceIndex= 0; faceIndex<6; faceIndex++){
        int baseVertexIndex = (index*24 + faceIndex*4)*vertexFloatSize;//24 unique vertices per cube, 4 unique vertices per face
        for (int cornerIndex=0; cornerIndex<4; cornerIndex++){
            int vertexIndex = baseVertexIndex + cornerIndex*vertexFloatSize + colOffset;
            meshVertices[vertexIndex] = color.r;
            meshVertices[++vertexIndex] = color.g;
            meshVertices[++vertexIndex] = color.b;
            meshVertices[++vertexIndex] = color.a;
        }
        }
    }
    }

    public Cube setColor(Color color, float[] meshVertices){
    if (hasColor){
        this.color.set(color);
        colorDirty = true;

    }
    return this;
    }

    public void setIndex(int index){
    if (this.index != index){
        transformDirty = true;
        colorDirty = true;
        this.index = index;
    }
    }

    public Cube translate(float x, float y, float z){
    position.add(x,y,z);
    transformDirty = true;
    return this;
    }

    public Cube translateTo(float x, float y, float z){
    position.set(x,y,z);
    transformDirty = true;
    return this;
    }

    public Cube rotate(float axisX, float axisY, float axisZ, float degrees){
    rotationTransform.rotate(axisX, axisY, axisZ, degrees);
    transformDirty = true;
    return this;
    }

    public Cube rotateTo(float axisX, float axisY, float axisZ, float degrees){
    rotationTransform.idt();
    rotationTransform.rotate(axisX, axisY, axisZ, degrees);
    transformDirty = true;
    return this;
    }

    public VertexAttribute getVertexAttribute (int usage, VertexAttributes attributes) {
    int len = attributes.size();
    for (int i = 0; i < len; i++)
        if (attributes.get(i).usage == usage) return attributes.get(i);

    return null;
    }

    @Override
    public int compareTo(Cube other) {
    //the cube has a lower index than a cube that is closer to the camera
    if (camDistSquared>other.camDistSquared)
        return -1;
    return camDistSquared<other.camDistSquared ? 1 : 0;
    }
}

And you would sort it like this:

for (Cube cube : mBatchedCubes){
    cube.updateCameraDistance(camera);
}
mBatchedCubes.sort();
int index = 0;
for (Cube cube : mBatchedCubes){
    cube.setIndex(index++);
}

这篇关于在 libgdx 中批量处理多维数据集时遇到问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆