2019-01-04 20:47:26 +02:00

82 lines
2.4 KiB
Scala

package ocelot.desktop.graphics
import ocelot.desktop.geometry.Transform2D
import ocelot.desktop.util.{Resource, ResourceManager}
import org.apache.logging.log4j.scala.Logging
import org.lwjgl.opengl.GL20
import scala.io.Source
class ShaderProgram(name: String) extends Logging with Resource {
logger.info(s"Loading shader program ($name)")
val fragmentShader: Int = createShader(Source.fromResource(s"ocelot/desktop/shader/$name.frag", getClass.getClassLoader), GL20.GL_FRAGMENT_SHADER, "fragment")
val vertexShader: Int = createShader(Source.fromResource(s"ocelot/desktop/shader/$name.vert", getClass.getClassLoader), GL20.GL_VERTEX_SHADER, "vertex")
val shaderProgram: Int = GL20.glCreateProgram()
GL20.glAttachShader(shaderProgram, vertexShader)
GL20.glAttachShader(shaderProgram, fragmentShader)
GL20.glLinkProgram(shaderProgram)
{
val success = Array(0)
GL20.glGetProgramiv(shaderProgram, GL20.GL_LINK_STATUS, success)
if (success.head == 0) {
val info = GL20.glGetProgramInfoLog(shaderProgram)
logger.error(s"Failed to link shader program ($name)\n$info")
throw new RuntimeException("Shader linkage failed")
}
}
ResourceManager.registerResource(this)
def freeResource(): Unit = {
logger.debug(s"Destroyed shader program ($name)")
GL20.glDeleteProgram(shaderProgram)
GL20.glDeleteShader(vertexShader)
GL20.glDeleteShader(fragmentShader)
}
def bind(): Unit = {
GL20.glUseProgram(shaderProgram)
}
def set(name: String, transform: Transform2D): Unit = {
bind()
val array = transform.array ++ Array(0f, 0f, 1f)
GL20.glUniformMatrix3fv(getLocation(name), true, array)
}
def set(name: String, v: Int): Unit = {
bind()
GL20.glUniform1i(getLocation(name), v)
}
private def getLocation(name: String): Int = {
GL20.glGetUniformLocation(shaderProgram, name)
}
private def createShader(source: Source, ty: Int, s: String): Int = {
val shader = GL20.glCreateShader(ty)
GL20.glShaderSource(shader, source.mkString)
GL20.glCompileShader(shader)
val success = Array(0)
GL20.glGetShaderiv(shader, GL20.GL_COMPILE_STATUS, success)
if (success.head == 0) {
val info = GL20.glGetShaderInfoLog(shader)
logger.error(s"Failed to compile shader ($s)\n$info")
throw new RuntimeException("Shader compilation failed")
}
source.close()
shader
}
}