java.nio.BufferOverflowException or indeces ignoring
I've suddenly faced to
Exception in thread "main" java.nio.BufferOverflowException
at java.base/java.nio.Buffer.nextPutIndex(Buffer.java:730)
at java.base/java.nio.DirectByteBuffer.putFloat(DirectByteBuffer.java:916)
at de.fabmax.kool.util.MixedBufferImpl.putFloat32(Buffer.kt:289)
at de.fabmax.kool.util.MixedBuffer$DefaultImpls.putFloat32(Buffer.kt:169)
at de.fabmax.kool.util.MixedBufferImpl.putFloat32(Buffer.kt:190)
at de.fabmax.kool.pipeline.Uniform2fv.putToBuffer(Uniform.kt:106)
at de.fabmax.kool.pipeline.BufferLayout.putToBuffer(BufferLayout.kt:22)
at de.fabmax.kool.platform.gl.MappedUbo.setUniform(MappedUniform.kt:50)
at de.fabmax.kool.platform.gl.CompiledShader$ShaderInstance.bindInstance(CompiledShader.kt:280)
at de.fabmax.kool.platform.gl.CompiledShader.bindInstance(CompiledShader.kt:134)
at de.fabmax.kool.platform.gl.ShaderManager.setupShader(ShaderManager.kt:23)
at de.fabmax.kool.platform.gl.QueueRendererGl.renderQueue(QueueRendererGl.kt:64)
at de.fabmax.kool.platform.gl.GlRenderBackend.drawFrame(GlRenderBackend.kt:116)
at de.fabmax.kool.platform.Lwjgl3Context.run(Lwjgl3Context.kt:124)
at App.<init>(App.kt:35)
at MainKt.main(main.kt:5)
at MainKt.main(main.kt)
and looks like here https://github.com/fabmax/kool/blob/f7e6d2e9bc8f9b936a0f1f120d08af67c8b4ad43/kool-core/src/jvmMain/kotlin/de/fabmax/kool/platform/gl/CompiledShader.kt#L83
private fun setupUboLayout(desc: UniformBuffer, blockIndex: Int) {
val blockSize = glGetActiveUniformBlocki(prog, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE)
val indices = IntArray(desc.uniforms.size)
val offsets = IntArray(desc.uniforms.size)
MemoryStack.stackPush().use { stack ->
val uniformNames = desc.uniforms.map {
if (it.length > 1) { MemoryUtil.memASCII("${it.name}[0]") } else { MemoryUtil.memASCII(it.name) }
}.toTypedArray()
val namePointers = stack.pointers(*uniformNames)
glGetUniformIndices(prog, namePointers, indices)
glGetActiveUniformsiv(prog, indices, GL_UNIFORM_OFFSET, offsets)
}
glUniformBlockBinding(prog, blockIndex, desc.binding)
uboLayouts[desc.name] = ExternalBufferLayout(desc.uniforms, offsets, blockSize)
}
(and in WebGL version too) indiced only used by gl call, and offsets is still in indices order? For example, if we have
indices = {int[2]@3664} [1, 0]
0 = 1
1 = 0
and offsets like
offsets = {int[2]@3665} [0, 64]
0 = 0
1 = 64
and uniforms like
desc.uniforms = {ArrayList@4006} size = 2
0 = {UniformMat4f@4008} uMvpMat
value = {Mat4f@4013} de.fabmax.kool.math.Mat4f@24b52d3e
name = "uMvpMat"
size = 64
length = 1
isArray {boolean}
1 = {Uniform2fv@4009} roots
value = {MutableVec2f[3]@4012}
name = "roots"
size = 48
length = 3
isArray {boolean}
it would brake??? Or i'm missing something? Please, help! :+1:
The problem is the Vec2 array uniform. When the Uniform2fv puts the values to the buffer it expects the buffer to be in Std140 layout, meaning that the individual Vec2f values are padded with 8 additional 0-bytes. However, apparently OpenGL expects the values to be tightly packed, therefore the created buffer is too small to take the values including padding, resulting in the BufferOverflow.
I should probably fix that... Until then, as a workaround, you should be able to use a Vec4 array uniform and only use the xy values of the Vec4s.
Not thoroughly tested, but I pushed a commit, which should fix that