package me.eater.threedom.gl.dom import me.eater.threedom.dom.IDocument import me.eater.threedom.dom.Node import me.eater.threedom.gl.ShaderProgram import me.eater.threedom.gl.vertex.VertexArrayObject import me.eater.threedom.utils.joml.toFloat import org.joml.Matrix3d import org.joml.Matrix4d import org.lwjgl.opengl.GL30.* open class TriMesh(document: IDocument?) : Node(document), GLRenderNode { var mesh: VertexArrayObject? = null var program: ShaderProgram? = null private set var programConfig: (ShaderProgram.(TriMesh) -> Unit)? = null private set fun use(program: T, block: T.(TriMesh) -> Unit) { this.program = program @kotlin.Suppress("UNCHECKED_CAST") this.programConfig = block as ShaderProgram.(TriMesh) -> Unit } fun use(program: T) { this.program = program this.programConfig = null } override fun cloneSelf(): TriMesh { return TriMesh(document).also { it.mesh = mesh it.program = program it.programConfig = programConfig } } override fun render(renderer: ICamera<*>) { val mesh = mesh ?: return val program = program ?: return program.enable() programConfig?.let { program.it(this) } program.camera(renderer) program.model = absolute.toFloat() program.normalModel = model.invert(Matrix4d()).transpose().get3x3(Matrix3d()).toFloat() glBindVertexArray(mesh.id) glDrawArrays(GL_TRIANGLES, 0, mesh.size) } }