0

So, my code works fine, all is good except one thing. I have 2 methods that setup the same VBO. one is a simple loop that builds the VBO, the seconds does the same thing but the VBO is built from object properties.

Both use the same render call etc. THE odd thing is, method one gives double the FPS! They both make 27000 objects.

FAST METHOD

public CubeVBOVBA(int generatedCubeFactor) {
        mActualCubeFactor = generatedCubeFactor;

        final float[] cubePositionData = new float[108 * generatedCubeFactor * generatedCubeFactor * generatedCubeFactor];
        int cubePositionDataOffset = 0;

        final int segments = 1; //generatedCubeFactor + (generatedCubeFactor - 1);

        final float minPosition = -1.0f;
        final float maxPosition = 1.0f;
        final float positionRange = maxPosition - minPosition;
        final float space = 1.0f;

        int c = 0;

        for (int x = 0; x < generatedCubeFactor; x++) {
            for (int y = 0; y < generatedCubeFactor; y++) {
                for (int z = 0; z < generatedCubeFactor; z++) {

                    final float x1 = minPosition + ((positionRange / segments) * (x * space));
                    final float x2 = minPosition + ((positionRange / segments) * ((x * space) + 1));
                    final float y1 = minPosition + ((positionRange / segments) * (y * space));
                    final float y2 = minPosition + ((positionRange / segments) * ((y * space) + 1));
                    final float z1 = minPosition + ((positionRange / segments) * (z * space));
                    final float z2 = minPosition + ((positionRange / segments) * ((z * space) + 1));

                    // Define points for a cube.
                    // X, Y, Z
                    final float[] p1p = {x1, y2, z2};
                    final float[] p2p = {x2, y2, z2};
                    final float[] p3p = {x1, y1, z2};
                    final float[] p4p = {x2, y1, z2};
                    final float[] p5p = {x1, y2, z1};
                    final float[] p6p = {x2, y2, z1};
                    final float[] p7p = {x1, y1, z1};
                    final float[] p8p = {x2, y1, z1};

                    final float[] thisCubePositionData = ShapeBuilder.generateCubeData(p1p, p2p, p3p, p4p, p5p, p6p, p7p, p8p,
                            p1p.length);

                    System.arraycopy(thisCubePositionData, 0, cubePositionData, cubePositionDataOffset, thisCubePositionData.length);
                    cubePositionDataOffset += thisCubePositionData.length;
                }
            }
        }

        FloatBuffer[] floatBuffers = getBuffers(cubePositionData, cubeNormalData, textureCoordinateData, generatedCubeFactor * generatedCubeFactor * generatedCubeFactor);

        FloatBuffer cubePositionsBuffer = floatBuffers[0];
        FloatBuffer cubeNormalsBuffer = floatBuffers[1];
        FloatBuffer cubeTextureCoordinatesBuffer = floatBuffers[2];

        // Second, copy these buffers into OpenGL's memory. After, we don't need to keep the client-side buffers around.
        final int buffers[] = new int[3];
        GLES20.glGenBuffers(3, buffers, 0);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, cubePositionsBuffer.capacity() * BYTES_PER_FLOAT, cubePositionsBuffer, GLES20.GL_STATIC_DRAW);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[1]);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, cubeNormalsBuffer.capacity() * BYTES_PER_FLOAT, cubeNormalsBuffer, GLES20.GL_STATIC_DRAW);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[2]);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, cubeTextureCoordinatesBuffer.capacity() * BYTES_PER_FLOAT, cubeTextureCoordinatesBuffer,
                GLES20.GL_STATIC_DRAW);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

        mCubePositionsBufferIdx = buffers[0];
        mCubeNormalsBufferIdx = buffers[1];
        mCubeTexCoordsBufferIdx = buffers[2];

        cubePositionsBuffer.limit(0);
        cubePositionsBuffer = null;
        cubeNormalsBuffer.limit(0);
        cubeNormalsBuffer = null;
        cubeTextureCoordinatesBuffer.limit(0);
        cubeTextureCoordinatesBuffer = null;
    }

Second method

public CubeVBOVBA(List<Vector3> cubeList) {

        final float[] cubePositionData = new float[108 * cubeList.size()];
        int cubePositionDataOffset = 0;

        for (Vector3 placeMarker : cubeList) {

            final float x1 = placeMarker.x - 1;
            final float x2 = placeMarker.x + 1;
            final float y1 = placeMarker.y - 1;
            final float y2 = placeMarker.y + 1;
            final float z1 = placeMarker.z - 1;
            final float z2 = placeMarker.z + 1;

            final float[] p1p = {x1, y2, z2};
            final float[] p2p = {x2, y2, z2};
            final float[] p3p = {x1, y1, z2};
            final float[] p4p = {x2, y1, z2};
            final float[] p5p = {x1, y2, z1};
            final float[] p6p = {x2, y2, z1};
            final float[] p7p = {x1, y1, z1};
            final float[] p8p = {x2, y1, z1};

            final float[] thisCubePositionData = ShapeBuilder.generateCubeData(p1p, p2p, p3p, p4p, p5p, p6p, p7p, p8p,
                    p1p.length);

            System.arraycopy(thisCubePositionData, 0, cubePositionData, cubePositionDataOffset, thisCubePositionData.length);
            cubePositionDataOffset += thisCubePositionData.length;

        }

        FloatBuffer[] floatBuffers = getBuffers(cubePositionData, cubeNormalData, textureCoordinateData, cubeList.size());

        FloatBuffer cubePositionsBuffer = floatBuffers[0];
        FloatBuffer cubeNormalsBuffer = floatBuffers[1];
        FloatBuffer cubeTextureCoordinatesBuffer = floatBuffers[2];

        // Second, copy these buffers into OpenGL's memory. After, we don't need to keep the client-side buffers around.
        final int buffers[] = new int[3];
        GLES20.glGenBuffers(3, buffers, 0);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, cubePositionsBuffer.capacity() * BYTES_PER_FLOAT, cubePositionsBuffer, GLES20.GL_STATIC_DRAW);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[1]);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, cubeNormalsBuffer.capacity() * BYTES_PER_FLOAT, cubeNormalsBuffer, GLES20.GL_STATIC_DRAW);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[2]);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, cubeTextureCoordinatesBuffer.capacity() * BYTES_PER_FLOAT, cubeTextureCoordinatesBuffer,
                GLES20.GL_STATIC_DRAW);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

        mCubePositionsBufferIdx = buffers[0];
        mCubeNormalsBufferIdx = buffers[1];
        mCubeTexCoordsBufferIdx = buffers[2];

        cubePositionsBuffer.limit(0);
        cubePositionsBuffer = null;
        cubeNormalsBuffer.limit(0);
        cubeNormalsBuffer = null;
        cubeTextureCoordinatesBuffer.limit(0);
        cubeTextureCoordinatesBuffer = null;
    }

public void createText() {

        cubeList2 = new CopyOnWriteArrayList<Vector3>();

        int c = 0;
        for (int i = 0; i < 30; i++) {
            for (int j = 0; j < 30; j++) {
                for (int k = 0; k < 30; k++) {

                    c ++;

                    Vector3 v = new Vector3(i, j, k);
                    cubeList2.add(v);


                }
            }
        }
Burf2000
  • 5,001
  • 14
  • 58
  • 117
  • So are you saying you create the exact same VBOs - yet the other one renders twice the speed? – harism Oct 25 '14 at 20:35
  • Yup, bonkers aint it. I am thinking maybe VBO's are not flexible enough for something like Minecraft – Burf2000 Oct 25 '14 at 20:41
  • Just to confirm the hopefully obvious: I figure you're only calling `CubeVBOVBA()` once, during setup? – Reto Koradi Oct 25 '14 at 22:30
  • Yeah you had me thinking then but yes it's the called when the object is created and if called twice would run out of memory. Thanks – Burf2000 Oct 26 '14 at 07:32

0 Answers0