2023-06-13 17:58:27 +03:00

74 lines
1.7 KiB
Scala

package ocelot.desktop.graphics.buffer
import ocelot.desktop.util.{Logging, Resource}
import org.lwjgl.BufferUtils
import org.lwjgl.opengl.GL15
import java.nio.ByteBuffer
class Buffer[T <: BufferPut] extends Logging with Resource {
val target: Int = GL15.GL_ARRAY_BUFFER
val buffer: Int = GL15.glGenBuffers()
var capacity: Int = _
var stride: Int = _
override def freeResource(): Unit = {
super.freeResource()
GL15.glDeleteBuffers(buffer)
logger.debug(s"Destroyed buffer (ID: $buffer) of ${capacity * stride} bytes")
}
def this(elements: Seq[T]) = {
this()
createStatic(elements)
}
def write(offset: Int, buf: ByteBuffer): Unit = {
bind()
GL15.glBufferSubData(target, offset * stride, buf)
}
def resize(newCap: Int): Unit = {
createDynamic(this.stride, newCap)
}
protected def createDynamic(stride: Int, cap: Int): Unit = {
bind()
GL15.glBufferData(target, stride * cap, GL15.GL_DYNAMIC_DRAW)
this.stride = stride
capacity = cap
}
protected def createStatic(elements: Seq[T]): Unit = {
assert(elements.nonEmpty, "Zero size immutable buffer")
extractMeta(elements.head)
bind()
val buf = storeElements(elements)
GL15.glBufferData(target, buf, GL15.GL_STATIC_DRAW)
capacity = elements.length
}
private def storeElements(elements: Seq[T]): ByteBuffer = {
val data = BufferUtils.createByteBuffer(elements.length * elements.head.stride)
for (element <- elements) {
element.put(data)
}
data.flip
data
}
protected def extractMeta(head: T): Unit = {
stride = head.stride
}
def bind(): Unit = {
GL15.glBindBuffer(target, buffer)
}
}