[SOLVED] Help with interleaved VBO setup

Started by kaphula, January 14, 2020, 20:38:58

Previous topic - Next topic

kaphula

Hello,

I don't know why, but I can't seem to get interleaved VBO setup working no matter what I try. When I setup the VBO in packed form by splitting the VAO in different VBOs, everything works fine.

Here's my code for setting up the the VAO and VBO for interleaved. The vertexData parameter will contain all of the data in interleaved form, like PPPTTNNNPPTTNNN... where single letter is a float value and P=position, T=texture_coordinate and N=normal Are there any visible errors? VBO() is just a data class containing relevant information to VBO and it calls glGenBuffers() automatically to create the id. The code is written in Kotlin.

fun createInterleaved(vertexData: FloatArray, indices: IntArray) {
        vaoId = GL30.glGenVertexArrays()
        GL30.glBindVertexArray(vaoId)

        var interleavedBuffer: FloatBuffer? = null
        var indicesBuffer: IntBuffer? = null

        try {
            // Interleaved VBO
            var vbo = VBO()
            vboIdMap.put(OpenGLDataType.CombinedAll, vbo)
            interleavedBuffer = MemoryUtil.memAllocFloat(vertexData.size)
            interleavedBuffer.put(vertexData).flip()
            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.id)
            GL15.glBufferData(GL15.GL_ARRAY_BUFFER, interleavedBuffer!!, GL15.GL_STATIC_DRAW)

            val vertexSize = 8 * Float.BYTES
            GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, vertexSize, 0)
            GL20.glEnableVertexAttribArray(0)

            GL20.glVertexAttribPointer(1, 2, GL11.GL_FLOAT, false, vertexSize, Float.BYTES * 3L)
            GL20.glEnableVertexAttribArray(1)

            GL20.glVertexAttribPointer(2, 3, GL11.GL_FLOAT, false, vertexSize, Float.BYTES * 5L)
            GL20.glEnableVertexAttribArray(2)

            // Index VBO
            vbo = VBO()
            vboIdMap.put(OpenGLDataType.Index, vbo)
            indicesBuffer = MemoryUtil.memAllocInt(indices.size)
            indicesBuffer.put(indices).flip()
            GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vbo.id)
            GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer!!, GL15.GL_STATIC_DRAW)

            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0)
            GL30.glBindVertexArray(0)
        }
        finally {
            freeBuffers(interleavedBuffer, indicesBuffer)
        }

    }



For comparison, here's the packed version that does work:
   fun createPacked(positions: FloatArray, textCoords: FloatArray, normals: FloatArray, indices: IntArray) {
        var posBuffer: FloatBuffer? = null
        // var colourBuffer: FloatBuffer? = null
        var indicesBuffer: IntBuffer? = null
        var textCoordsBuffer: FloatBuffer? = null
        var vecNormalsBuffer: FloatBuffer? = null
        try {
            vertexCount = indices.size
            vaoId = GL30.glGenVertexArrays()
            GL30.glBindVertexArray(vaoId)

            // Position VBO
            var vbo = VBO(layoutNum = 0, index = 0, size = 3)
            vboIdMap.put(OpenGLDataType.Position, vbo)
            posBuffer = MemoryUtil.memAllocFloat(positions.size)
            posBuffer.put(positions).flip()
            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.id)
            GL15.glBufferData(GL15.GL_ARRAY_BUFFER, posBuffer, GL15.GL_STATIC_DRAW)
            GL20.glEnableVertexAttribArray(vbo.layoutNum)
            GL20.glVertexAttribPointer(vbo.index, vbo.size, GL11.GL_FLOAT, false, 0, 0)

            // Texture coordinates VBO
            vbo = VBO(layoutNum = 1, index = 1, size = 2)
            vboIdMap.put(OpenGLDataType.TextureUV, vbo)
            textCoordsBuffer = MemoryUtil.memAllocFloat(textCoords.size)
            textCoordsBuffer.put(textCoords).flip()
            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.id)
            GL15.glBufferData(GL15.GL_ARRAY_BUFFER, textCoordsBuffer, GL15.GL_STATIC_DRAW)
            GL20.glEnableVertexAttribArray(vbo.layoutNum)
            GL20.glVertexAttribPointer(vbo.index, vbo.size, GL11.GL_FLOAT, false, 0, 0)

            // Vertex normals VBO
            vbo = VBO(layoutNum = 2, index = 2, size = 3)
            vboIdMap.put(OpenGLDataType.Normals, vbo)
            vecNormalsBuffer = MemoryUtil.memAllocFloat(normals.size)
            if (vecNormalsBuffer.capacity() > 0) {
                vecNormalsBuffer.put(normals).flip()
            } else { // Create empty structure
                vecNormalsBuffer = MemoryUtil.memAllocFloat(positions.size)
            }
            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.id)
            GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vecNormalsBuffer!!, GL15.GL_STATIC_DRAW)
            GL20.glEnableVertexAttribArray(vbo.layoutNum)
            GL20.glVertexAttribPointer(vbo.index, vbo.size, GL11.GL_FLOAT, false, 0, 0)

            // Index VBO
            vbo = VBO()
            vboIdMap.put(OpenGLDataType.Index, vbo)
            indicesBuffer = MemoryUtil.memAllocInt(indices.size)
            indicesBuffer.put(indices).flip()
            GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vbo.id)
            GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW)

            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0)
            GL30.glBindVertexArray(0)
        } finally {
            freeBuffers(posBuffer, textCoordsBuffer, vecNormalsBuffer, indicesBuffer)
        }
    }


VBO data class:

data class VBO(val layoutNum: Int=0, val index: Int = 0, val size: Int = 0, val id: Int = GL15.glGenBuffers())


EDIT:

The code was otherwise correct, but I forgot to update the number of vertices to be drawn at glDrawElements() call. Whoops!