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!