KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/client/render/ConfiguredShaderProgram.kt
2022-09-11 17:55:47 +07:00

100 lines
3.0 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package ru.dbotthepony.kstarbound.client.render
import org.lwjgl.opengl.GL46.*
import ru.dbotthepony.kstarbound.client.gl.program.GLShaderProgram
import ru.dbotthepony.kstarbound.client.gl.VertexArrayObject
import ru.dbotthepony.kstarbound.client.gl.checkForGLError
import ru.dbotthepony.kstarbound.client.gl.vertex.AbstractVertexBuilder
import ru.dbotthepony.kvector.api.IFloatMatrix
import ru.dbotthepony.kvector.matrix.Matrix4fStack
/**
* Служит для быстрой настройки состояния для будущей отрисовки
*
* Установка текстурных блоков, программы, самих текстур и загрузка юниформ должна осуществляться тут
*
* Класс обязан быть наследован для осмысленных результатов
*
* Ожидается, что состояние будет выставлено ПОЛНОСТЬЮ, т.е. НИКАКОЙ предыдущий код НЕ МОЖЕТ повлиять на результат выполнения
* шейдерной программы, которая связанна с этим объектом (за исключением не вызова [setTransform] внешним кодом)
*/
open class ConfiguredShaderProgram(
val program: GLShaderProgram,
) {
private val transformLocation = program["_transform"]
open fun setTransform(value: IFloatMatrix<*>) {
transformLocation?.set(value)
}
/**
* Вызывается перед началом отрисовки
*/
open fun setup() {
program.use()
}
}
/**
* Запечённый статичный меш, позволяет быстро отрисовать меш со всеми параметрами
* с заданной матрицей трансформации
*/
class ConfiguredStaticMesh(
val programState: ConfiguredShaderProgram,
val indexCount: Int,
val vao: VertexArrayObject,
val elementIndexType: Int,
) : AutoCloseable {
private var onClose = {}
constructor(programState: ConfiguredShaderProgram, builder: AbstractVertexBuilder<*>) : this(
programState,
builder.indexCount,
programState.program.state.newVAO(),
builder.elementIndexType,
) {
val vbo = programState.program.state.newVBO()
val ebo = programState.program.state.newEBO()
onClose = {
vbo.close()
ebo.close()
}
vao.bind()
vbo.bind()
ebo.bind()
builder.upload(vbo, ebo, GL_STATIC_DRAW)
builder.attributes.apply(vao, true)
vao.unbind()
vbo.unbind()
ebo.unbind()
}
fun render(transform: IFloatMatrix<*>? = null) {
check(isValid) { "$this is no longer valid" }
programState.setup()
if (transform != null) {
programState.setTransform(transform)
}
vao.bind()
glDrawElements(GL_TRIANGLES, indexCount, elementIndexType, 0L)
checkForGLError()
}
fun renderStacked(transform: Matrix4fStack) = render(transform.last)
var isValid = true
private set
override fun close() {
vao.close()
onClose.invoke()
isValid = false
}
}