Java Code Examples for com.jme3.scene.VertexBuffer#isUpdateNeeded()

The following examples show how to use com.jme3.scene.VertexBuffer#isUpdateNeeded() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: GLRenderer.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
public void updateVertexArray(Mesh mesh, VertexBuffer instanceData) {
    int id = mesh.getId();
    if (id == -1) {
        IntBuffer temp = intBuf1;
        gl3.glGenVertexArrays(temp);
        id = temp.get(0);
        mesh.setId(id);
    }

    if (context.boundVertexArray != id) {
        gl3.glBindVertexArray(id);
        context.boundVertexArray = id;
    }

    VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
    if (interleavedData != null && interleavedData.isUpdateNeeded()) {
        updateBufferData(interleavedData);
    }

    if (instanceData != null) {
        setVertexAttrib(instanceData, null);
    }

    for (VertexBuffer vb : mesh.getBufferList().getArray()) {
        if (vb.getBufferType() == Type.InterleavedData
                || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
                || vb.getBufferType() == Type.Index) {
            continue;
        }

        if (vb.getStride() == 0) {
            // not interleaved
            setVertexAttrib(vb);
        } else {
            // interleaved
            setVertexAttrib(vb, interleavedData);
        }
    }
}
 
Example 2
Source File: JoglRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private void renderMeshVBO(Mesh mesh, int lod, int count) {
    VertexBuffer indices = null;
    VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
    if (interleavedData != null && interleavedData.isUpdateNeeded()) {
        updateBufferData(interleavedData);
    }
    IntMap<VertexBuffer> buffers = mesh.getBuffers();
    if (mesh.getNumLodLevels() > 0) {
        indices = mesh.getLodLevel(lod);
    } else {
        indices = buffers.get(Type.Index.ordinal());
    }
    for (Entry<VertexBuffer> entry : buffers) {
        VertexBuffer vb = entry.getValue();

        if (vb.getBufferType() == Type.InterleavedData
                || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
                || vb.getBufferType() == Type.Index) {
            continue;
        }

        if (vb.getStride() == 0) {
            // not interleaved
            setVertexAttribVBO(vb, null);
        } else {
            // interleaved
            setVertexAttribVBO(vb, interleavedData);
        }
    }

    if (indices != null) {
        drawTriangleListVBO(indices, mesh, count);
    } else {
        gl.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount());
    }
    clearVertexAttribs();
    clearTextureUnits();
}
 
Example 3
Source File: LwjglRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public void updateVertexArray(Mesh mesh) {
    int id = mesh.getId();
    if (id == -1) {
        IntBuffer temp = intBuf1;
        ARBVertexArrayObject.glGenVertexArrays(temp);
        id = temp.get(0);
        mesh.setId(id);
    }

    if (context.boundVertexArray != id) {
        ARBVertexArrayObject.glBindVertexArray(id);
        context.boundVertexArray = id;
    }

    VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
    if (interleavedData != null && interleavedData.isUpdateNeeded()) {
        updateBufferData(interleavedData);
    }

    IntMap<VertexBuffer> buffers = mesh.getBuffers();
    for (Entry<VertexBuffer> entry : buffers) {
        VertexBuffer vb = entry.getValue();

        if (vb.getBufferType() == Type.InterleavedData
                || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
                || vb.getBufferType() == Type.Index) {
            continue;
        }

        if (vb.getStride() == 0) {
            // not interleaved
            setVertexAttrib(vb);
        } else {
            // interleaved
            setVertexAttrib(vb, interleavedData);
        }
    }
}
 
Example 4
Source File: GdxRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
public void updateVertexArray(Mesh mesh) {
    logger.log(Level.INFO, "updateVertexArray({0})", mesh);
    int id = mesh.getId();
    /*
    if (id == -1){
    IntBuffer temp = intBuf1;
    //      ARBVertexArrayObject.glGenVertexArrays(temp);
    GLES20.glGenVertexArrays(temp);
    id = temp.get(0);
    mesh.setId(id);
    }
    
    if (context.boundVertexArray != id){
    //     ARBVertexArrayObject.glBindVertexArray(id);
    GLES20.glBindVertexArray(id);
    context.boundVertexArray = id;
    }
     */
    VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
    if (interleavedData != null && interleavedData.isUpdateNeeded()) {
        updateBufferData(interleavedData);
    }

    SafeArrayList<VertexBuffer> buffersList = mesh.getBufferList();
    for (int i = 0; i < buffersList.size(); i++) {
        VertexBuffer vb = buffersList.get(i);

        if (vb.getBufferType() == Type.InterleavedData
                || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
                || vb.getBufferType() == Type.Index) {
            continue;
        }

        if (vb.getStride() == 0) {
            // not interleaved
            setVertexAttrib(vb);
        } else {
            // interleaved
            setVertexAttrib(vb, interleavedData);
        }
    }
}
 
Example 5
Source File: GdxRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
private void renderMeshDefault(Mesh mesh, int lod, int count) {
        if (verboseLogging) {
            logger.log(Level.INFO, "renderMeshDefault({0}, {1}, {2})",
                    new Object[]{mesh, lod, count});
        }
        VertexBuffer indices = null;

        VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
        if (interleavedData != null && interleavedData.isUpdateNeeded()) {
            updateBufferData(interleavedData);
        }

        //IntMap<VertexBuffer> buffers = mesh.getBuffers();     ;
        if (mesh.getNumLodLevels() > 0) {
            indices = mesh.getLodLevel(lod);
        } else {
            indices = mesh.getBuffer(Type.Index);// buffers.get(Type.Index.ordinal());
        }
        SafeArrayList<VertexBuffer> buffersList = mesh.getBufferList();
        for (int i = 0; i < buffersList.size(); i++) {
            VertexBuffer vb = buffersList.get(i);

            if (vb.getBufferType() == Type.InterleavedData
                    || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
                    || vb.getBufferType() == Type.Index) {
                continue;
            }

            if (vb.getStride() == 0) {
                // not interleaved
                setVertexAttrib(vb);
            } else {
                // interleaved
                setVertexAttrib(vb, interleavedData);
            }
        }
        clearVertexAttribs();
//        clearTextureUnits();
        if (indices != null) {
            drawTriangleList(indices, mesh, count);
        } else {
//            throw new UnsupportedOperationException("Cannot render without index buffer");
            if (verboseLogging) {
                logger.log(Level.INFO, "GLES20.glDrawArrays({0}, 0, {1})",
                        new Object[]{convertElementMode(mesh.getMode()), mesh.getVertexCount()});
            }

            Gdx.gl20.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount());
        }
    }
 
Example 6
Source File: GdxRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
/**
 * setVertexAttrib_Array uses Vertex Array
 * @param vb
 * @param idb
 */
public void setVertexAttrib_Array(VertexBuffer vb, VertexBuffer idb) {
    if (verboseLogging) {
        logger.log(Level.INFO, "setVertexAttrib_Array({0}, {1})", new Object[]{vb, idb});
    }

    if (vb.getBufferType() == Type.Index) {
        throw new IllegalArgumentException("Index buffers not allowed to be set to vertex attrib");
    }

    // Get shader
    int programId = context.boundShaderProgram;
    if (programId > 0) {
        VertexBuffer[] attribs = context.boundAttribs;

        Attribute attrib = boundShader.getAttribute(vb.getBufferType());
        int loc = attrib.getLocation();
        if (loc == -1) {
            //throw new IllegalArgumentException("Location is invalid for attrib: [" + vb.getBufferType().name() + "]");
            if (verboseLogging) {
                logger.log(Level.WARNING, "attribute is invalid in shader: [{0}]", vb.getBufferType().name());
            }
            return;
        } else if (loc == -2) {
            String attributeName = "in" + vb.getBufferType().name();

            if (verboseLogging) {
                logger.log(Level.INFO, "GLES20.glGetAttribLocation({0}, {1})", new Object[]{programId, attributeName});
            }

            loc = Gdx.gl20.glGetAttribLocation(programId, attributeName);
            if (loc < 0) {
                attrib.setLocation(-1);
                if (verboseLogging) {
                    logger.log(Level.WARNING, "attribute is invalid in shader: [{0}]", vb.getBufferType().name());
                }
                return; // not available in shader.
            } else {
                attrib.setLocation(loc);
            }

        }  // if (loc == -2)

        if ((attribs[loc] != vb) || vb.isUpdateNeeded()) {
            System.err.println("isUpdateNeeded "+vb.isUpdateNeeded());
            vb.clearUpdateNeeded();
            // NOTE: Use data from interleaved buffer if specified
            VertexBuffer avb = idb != null ? idb : vb;
            avb.getData().clear();
            avb.getData().position(vb.getOffset());

            if (verboseLogging) {
                logger.log(Level.INFO,
                        "GLES20.glVertexAttribPointer("
                                + "location={0}, "
                                + "numComponents={1}, "
                                + "format={2}, "
                                + "isNormalized={3}, "
                                + "stride={4}, "
                                + "data.capacity={5})",
                        new Object[]{loc, vb.getNumComponents(),
                                vb.getFormat(),
                                vb.isNormalized(),
                                vb.getStride(),
                                avb.getData().capacity()});
            }


            // Upload attribute data

            Gdx.gl20.glVertexAttribPointer(loc,
                    vb.getNumComponents(),
                    convertFormat(vb.getFormat()),
                    vb.isNormalized(),
                    vb.getStride(),
                    convBuffer(avb.getData()));
            checkGLError();

            Gdx.gl20.glEnableVertexAttribArray(loc);

            attribs[loc] = vb;
        } // if (attribs[loc] != vb)
    } else {
        throw new IllegalStateException("Cannot render mesh without shader bound");
    }
}
 
Example 7
Source File: JoglRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
private void setVertexAttribVBO(VertexBuffer vb, VertexBuffer idb) {
    int arrayType = convertArrayType(vb.getBufferType());
    if (arrayType == -1) {
        return; // unsupported
    }
    if (vb.isUpdateNeeded() && idb == null) {
        updateBufferData(vb);
    }

    int bufId = idb != null ? idb.getId() : vb.getId();
    if (context.boundArrayVBO != bufId) {
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, bufId);
        context.boundArrayVBO = bufId;
    }

    gl.glEnableClientState(arrayType);
    context.boundAttribs[vb.getBufferType().ordinal()] = vb;

    if (vb.getBufferType() == Type.Normal) {
        // normalize if requested
        if (vb.isNormalized() && !context.normalizeEnabled) {
            gl.glEnable(gl.GL_NORMALIZE);
            context.normalizeEnabled = true;
        } else if (!vb.isNormalized() && context.normalizeEnabled) {
            gl.glDisable(gl.GL_NORMALIZE);
            context.normalizeEnabled = false;
        }
    }

    int comps = vb.getNumComponents();
    int type = convertVertexFormat(vb.getFormat());

    switch (vb.getBufferType()) {
        case Position:
            gl.glVertexPointer(comps, type, vb.getStride(), vb.getOffset());
            break;
        case Normal:
            gl.glNormalPointer(type, vb.getStride(), vb.getOffset());
            break;
        case Color:
            gl.glColorPointer(comps, type, vb.getStride(), vb.getOffset());
            break;
        case TexCoord:
            gl.glTexCoordPointer(comps, type, vb.getStride(), vb.getOffset());
            break;
    }
}
 
Example 8
Source File: OGLESShaderRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
public void updateVertexArray(Mesh mesh) {
    logger.log(Level.INFO, "updateVertexArray({0})", mesh);
    int id = mesh.getId();
    /*
    if (id == -1){
    IntBuffer temp = intBuf1;
    //      ARBVertexArrayObject.glGenVertexArrays(temp);
    GLES20.glGenVertexArrays(temp);
    id = temp.get(0);
    mesh.setId(id);
    }
    
    if (context.boundVertexArray != id){
    //     ARBVertexArrayObject.glBindVertexArray(id);
    GLES20.glBindVertexArray(id);
    context.boundVertexArray = id;
    }
     */
    VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
    if (interleavedData != null && interleavedData.isUpdateNeeded()) {
        updateBufferData(interleavedData);
    }

    SafeArrayList<VertexBuffer> buffersList = mesh.getBufferList();
    for (int i = 0; i < buffersList.size(); i++) {
        VertexBuffer vb = buffersList.get(i);

        if (vb.getBufferType() == Type.InterleavedData
                || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
                || vb.getBufferType() == Type.Index) {
            continue;
        }

        if (vb.getStride() == 0) {
            // not interleaved
            setVertexAttrib(vb);
        } else {
            // interleaved
            setVertexAttrib(vb, interleavedData);
        }
    }
}
 
Example 9
Source File: OGLESShaderRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
private void renderMeshDefault(Mesh mesh, int lod, int count) {
        if (verboseLogging) {
            logger.log(Level.INFO, "renderMeshDefault({0}, {1}, {2})",
                    new Object[]{mesh, lod, count});
        }
        VertexBuffer indices = null;

        VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
        if (interleavedData != null && interleavedData.isUpdateNeeded()) {
            updateBufferData(interleavedData);
        }

        //IntMap<VertexBuffer> buffers = mesh.getBuffers();     ;
        if (mesh.getNumLodLevels() > 0) {
            indices = mesh.getLodLevel(lod);
        } else {
            indices = mesh.getBuffer(Type.Index);// buffers.get(Type.Index.ordinal());
        }
        SafeArrayList<VertexBuffer> buffersList = mesh.getBufferList();
        for (int i = 0; i < buffersList.size(); i++) {
            VertexBuffer vb = buffersList.get(i);

            if (vb.getBufferType() == Type.InterleavedData
                    || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
                    || vb.getBufferType() == Type.Index) {
                continue;
            }

            if (vb.getStride() == 0) {
                // not interleaved
                setVertexAttrib(vb);
            } else {
                // interleaved
                setVertexAttrib(vb, interleavedData);
            }
        }
        clearVertexAttribs();
//        clearTextureUnits();
        if (indices != null) {
            drawTriangleList(indices, mesh, count);
        } else {
//            throw new UnsupportedOperationException("Cannot render without index buffer");
            if (verboseLogging) {
                logger.log(Level.INFO, "GLES20.glDrawArrays({0}, 0, {1})",
                        new Object[]{convertElementMode(mesh.getMode()), mesh.getVertexCount()});
            }

            GLES20.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount());
        }
    }
 
Example 10
Source File: OGLESShaderRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
/**
 * setVertexAttrib_Array uses Vertex Array
 * @param vb
 * @param idb
 */
public void setVertexAttrib_Array(VertexBuffer vb, VertexBuffer idb) {
    if (verboseLogging) {
        logger.log(Level.INFO, "setVertexAttrib_Array({0}, {1})", new Object[]{vb, idb});
    }

    if (vb.getBufferType() == VertexBuffer.Type.Index) {
        throw new IllegalArgumentException("Index buffers not allowed to be set to vertex attrib");
    }

    // Get shader
    int programId = context.boundShaderProgram;
    if (programId > 0) {
        VertexBuffer[] attribs = context.boundAttribs;

        Attribute attrib = boundShader.getAttribute(vb.getBufferType());
        int loc = attrib.getLocation();
        if (loc == -1) {
            //throw new IllegalArgumentException("Location is invalid for attrib: [" + vb.getBufferType().name() + "]");
            if (verboseLogging) {
                logger.log(Level.WARNING, "attribute is invalid in shader: [{0}]", vb.getBufferType().name());
            }
            return;
        } else if (loc == -2) {
            String attributeName = "in" + vb.getBufferType().name();

            if (verboseLogging) {
                logger.log(Level.INFO, "GLES20.glGetAttribLocation({0}, {1})", new Object[]{programId, attributeName});
            }

            loc = GLES20.glGetAttribLocation(programId, attributeName);
            if (loc < 0) {
                attrib.setLocation(-1);
                if (verboseLogging) {
                    logger.log(Level.WARNING, "attribute is invalid in shader: [{0}]", vb.getBufferType().name());
                }
                return; // not available in shader.
            } else {
                attrib.setLocation(loc);
            }

        }  // if (loc == -2)

        if ((attribs[loc] != vb) || vb.isUpdateNeeded()) {
            // NOTE: Use data from interleaved buffer if specified
            VertexBuffer avb = idb != null ? idb : vb;
            avb.getData().clear();
            avb.getData().position(vb.getOffset());

            if (verboseLogging) {
                logger.log(Level.INFO,
                        "GLES20.glVertexAttribPointer("
                        + "location={0}, "
                        + "numComponents={1}, "
                        + "format={2}, "
                        + "isNormalized={3}, "
                        + "stride={4}, "
                        + "data.capacity={5})",
                        new Object[]{loc, vb.getNumComponents(),
                            vb.getFormat(),
                            vb.isNormalized(),
                            vb.getStride(),
                            avb.getData().capacity()});
            }


            // Upload attribute data
            GLES20.glVertexAttribPointer(loc,
                    vb.getNumComponents(),
                    convertFormat(vb.getFormat()),
                    vb.isNormalized(),
                    vb.getStride(),
                    avb.getData());
            checkGLError();

            GLES20.glEnableVertexAttribArray(loc);

            attribs[loc] = vb;
        } // if (attribs[loc] != vb)
    } else {
        throw new IllegalStateException("Cannot render mesh without shader bound");
    }
}
 
Example 11
Source File: AbstractRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
protected void renderMeshDefault(Mesh mesh, int lod, int count) {
    VertexBuffer indices = null;
    VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
    if (interleavedData != null && interleavedData.isUpdateNeeded()) {
        updateBufferData(interleavedData);
    }
    IntMap<VertexBuffer> buffers = mesh.getBuffers();
    if (mesh.getNumLodLevels() > 0) {
        indices = mesh.getLodLevel(lod);
    }
    else {
        indices = buffers.get(Type.Index.ordinal());
    }
    for (Entry<VertexBuffer> entry : buffers) {
        VertexBuffer vb = entry.getValue();

        if (vb.getBufferType() == Type.InterleavedData || vb.getUsage() == Usage.CpuOnly
                || vb.getBufferType() == Type.Index) {
            continue;
        }

        /*if (vb.getBufferType() == Type.Index) {
            indices = vb;
        }
        else {*/
        if (vb.getStride() == 0) {
            // not interleaved
            setVertexAttrib(vb);
        }
        else {
            // interleaved
            setVertexAttrib(vb, interleavedData);
        }
        /*}*/
    }

    if (indices != null) {
        drawTriangleList(indices, mesh, count);
    }
    else {
        drawArrays(mesh);
    }
    clearVertexAttribs();
    clearTextureUnits();
}
 
Example 12
Source File: AbstractRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
protected void renderMeshVBO(Mesh mesh, int lod, int count) {
    VertexBuffer indices = null;
    VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
    if (interleavedData != null && interleavedData.isUpdateNeeded()) {
        updateBufferData(interleavedData);
    }
    IntMap<VertexBuffer> buffers = mesh.getBuffers();
    if (mesh.getNumLodLevels() > 0) {
        indices = mesh.getLodLevel(lod);
    }
    else {
        indices = buffers.get(Type.Index.ordinal());
    }
    for (Entry<VertexBuffer> entry : buffers) {
        VertexBuffer vb = entry.getValue();

        if (vb.getBufferType() == Type.InterleavedData || vb.getUsage() == Usage.CpuOnly // ignore
                                                                                         // cpu-only
                                                                                         // buffers
                || vb.getBufferType() == Type.Index) {
            continue;
        }

        if (vb.getStride() == 0) {
            // not interleaved
            setVertexAttribVBO(vb, null);
        }
        else {
            // interleaved
            setVertexAttribVBO(vb, interleavedData);
        }
    }

    if (indices != null) {
        drawTriangleListVBO(indices, mesh, count);
    }
    else {
        drawArrays(mesh);
    }
    clearVertexAttribs();
    clearTextureUnits();
}
 
Example 13
Source File: JoglRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@Override
protected void setVertexAttribVBO(VertexBuffer vb, VertexBuffer idb) {
    GL gl = GLContext.getCurrentGL();
    int arrayType = convertArrayType(vb.getBufferType());
    if (arrayType == -1) {
        return; // unsupported
    }

    if (vb.isUpdateNeeded() && idb == null) {
        updateBufferData(vb);
    }

    int bufId = idb != null ? idb.getId() : vb.getId();
    if (context.boundArrayVBO != bufId) {
        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, bufId);
        context.boundArrayVBO = bufId;
    }

    gl.getGL2().glEnableClientState(arrayType);
    context.boundAttribs[vb.getBufferType().ordinal()] = vb;

    if (vb.getBufferType() == Type.Normal) {
        // normalize if requested
        if (vb.isNormalized() && !context.normalizeEnabled) {
            gl.glEnable(GLLightingFunc.GL_NORMALIZE);
            context.normalizeEnabled = true;
        }
        else if (!vb.isNormalized() && context.normalizeEnabled) {
            gl.glDisable(GLLightingFunc.GL_NORMALIZE);
            context.normalizeEnabled = false;
        }
    }

    int comps = vb.getNumComponents();
    int type = convertVertexFormat(vb.getFormat());

    switch (vb.getBufferType()) {
        case Position:
            gl.getGL2().glVertexPointer(comps, type, vb.getStride(), vb.getOffset());
            break;
        case Normal:
            gl.getGL2().glNormalPointer(type, vb.getStride(), vb.getOffset());
            break;
        case Color:
            gl.getGL2().glColorPointer(comps, type, vb.getStride(), vb.getOffset());
            break;
        case TexCoord:
            gl.getGL2().glTexCoordPointer(comps, type, vb.getStride(), vb.getOffset());
            break;
    }
}
 
Example 14
Source File: LwjglRenderer.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
private void renderMeshDefault(Mesh mesh, int lod, int count) {
    VertexBuffer indices = null;

    VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData);
    if (interleavedData != null && interleavedData.isUpdateNeeded()) {
        updateBufferData(interleavedData);
    }

    //IntMap<VertexBuffer> buffers = mesh.getBuffers();
    SafeArrayList<VertexBuffer> buffersList = mesh.getBufferList();

    if (mesh.getNumLodLevels() > 0) {
        indices = mesh.getLodLevel(lod);
    } else {
        indices = mesh.getBuffer(Type.Index);
    }
    //for (Entry<VertexBuffer> entry : buffers) {
    //     VertexBuffer vb = entry.getValue();
    for (int i = 0; i < buffersList.size(); i++){
        VertexBuffer vb = buffersList.get(i);

        if (vb.getBufferType() == Type.InterleavedData
                || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
                || vb.getBufferType() == Type.Index) {
            continue;
        }

        if (vb.getStride() == 0) {
            // not interleaved
            setVertexAttrib(vb);
        } else {
            // interleaved
            setVertexAttrib(vb, interleavedData);
        }
    }

    if (indices != null) {
        drawTriangleList(indices, mesh, count);
    } else {
        drawTriangleArray(mesh.getMode(), count, mesh.getVertexCount());
    }
    clearVertexAttribs();
    clearTextureUnits();
}