You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
1.9 KiB
Kotlin
79 lines
1.9 KiB
Kotlin
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 <T : VertexData> VertexBuffer<T>.invoke(prop: KProperty1<T, *>) =
|
|
bind(this, prop)
|
|
|
|
fun <T : VertexData> bind(vertexBuffer: VertexBuffer<T>, prop: KProperty1<T, *>) {
|
|
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)
|
|
}
|
|
}
|