package me.eater.threedom.gl.vertex import me.eater.threedom.gl.GL.stack import org.lwjgl.opengl.GL30.* import kotlin.math.min import kotlin.reflect.KProperty1 class VertexArrayObject() { var size: Int = 0 val id = run { val pId = stack.mallocInt(1) glGenVertexArrays(pId) pId.get(0) } constructor(block: VertexArrayObject.() -> Unit) : this() { block(this) } var pointerIndex: Int = 0 operator fun VertexBuffer.invoke(prop: KProperty1) = bind(this, prop) fun bind(vertexBuffer: VertexBuffer, prop: KProperty1) { if (vertexBuffer.items.isEmpty()) { return } size = if (pointerIndex == 0) { vertexBuffer.items.size } else { min(size, vertexBuffer.items.size) } val first = vertexBuffer.items.first() val item = first.getDataPoint(prop) ?: return var size = item.slots var length = item.length var repeat = 1 var i = 4 while (size > 4) { if ((size % i) == 0) { repeat = size / i size = i length /= i break } i-- } val stride = if (vertexBuffer.interleaved) { vertexBuffer.stride } else { item.length } var offset = first.getOffset(prop)!! if (!vertexBuffer.interleaved) { offset *= vertexBuffer.items.size } glBindVertexArray(id) glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.id) for (x in 0 until repeat) { val pointer = pointerIndex++ glVertexAttribPointer(pointer, size, item.type, false, stride, offset + (x * length).toLong()) glEnableVertexAttribArray(pointer) } glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0) } }