-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Big refactor - try to break things up
- Loading branch information
Showing
5 changed files
with
172 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
class LightSource( | ||
var pos: Array<Float>, | ||
var ambientColor: Array<Float>, | ||
var diffuseColor: Array<Float>, | ||
var specularColor: Array<Float>) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import com.tanelso2.glmatrix.Mat3 | ||
import com.tanelso2.glmatrix.Mat4 | ||
import org.khronos.webgl.Float32Array | ||
import org.khronos.webgl.WebGLProgram | ||
import org.khronos.webgl.WebGLRenderingContext | ||
import org.khronos.webgl.WebGLUniformLocation | ||
|
||
class ShaderProgram(private val webgl: WebGLRenderingContext) { | ||
val program: WebGLProgram = | ||
webgl.createProgram() ?: throw IllegalStateException("Failed to create shader program") | ||
|
||
fun useProgram() { | ||
webgl.useProgram(program) | ||
} | ||
|
||
fun compile(vertexShaderSource: String, fragmentShaderSource: String) { | ||
val vertexShader = webgl.getVertexShader(vertexShaderSource) | ||
val fragmentShader = webgl.getFragmentShader(fragmentShaderSource) | ||
webgl.attachShader(program, vertexShader) | ||
webgl.attachShader(program, fragmentShader) | ||
webgl.linkProgram(program) | ||
useProgram() | ||
} | ||
|
||
fun setupAttribute(name: String, array: Float32Array) { | ||
val attribute = webgl.getAttribLocation(program, name) | ||
webgl.enableVertexAttribArray(attribute) | ||
val buffer = webgl.createBuffer() | ||
webgl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, buffer) | ||
webgl.bufferData(WebGLRenderingContext.ARRAY_BUFFER, array, WebGLRenderingContext.STATIC_DRAW) | ||
webgl.vertexAttribPointer(attribute, 3, WebGLRenderingContext.FLOAT, false, 0, 0) | ||
} | ||
|
||
fun getUniformLocation(name: String) : WebGLUniformLocation = | ||
webgl.getUniformLocation(program, name) | ||
?: throw IllegalArgumentException("Could not find uniform named '$name'") | ||
|
||
fun setupUniformMat4(name: String, value: Mat4, transpose: Boolean = false) { | ||
webgl.uniformMatrix4fv(getUniformLocation(name), transpose, value.array) | ||
} | ||
|
||
fun setupUniformMat3(name: String, value: Mat3, transpose: Boolean = false) { | ||
webgl.uniformMatrix3fv(getUniformLocation(name), transpose, value.array) | ||
} | ||
|
||
fun setupUniformFloat(name: String, value: Float) { | ||
webgl.uniform1f(getUniformLocation(name), value) | ||
} | ||
|
||
fun setupUniformVec3Float(name: String, value: Array<Float>) { | ||
webgl.uniform3fv(getUniformLocation(name), value) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import com.tanelso2.glmatrix.Mat3 | ||
import com.tanelso2.glmatrix.Mat4 | ||
import com.tanelso2.glmatrix.Vec3 | ||
import org.khronos.webgl.WebGLRenderingContext | ||
import kotlin.math.PI | ||
|
||
class TeapotObj(private val webgl: WebGLRenderingContext, private val objFileSource: String, private val shaderProgram: ShaderProgram) { | ||
private val objLoader = ObjLoader(objFileSource) | ||
private val faces = objLoader.getFaces() | ||
private val vertices = objLoader.getVertices() | ||
private val vertexNormals = objLoader.getVertexNormals() | ||
private val numFaces = objLoader.getNumFaces() | ||
|
||
private val faceIndexBuffer = webgl.createBuffer() | ||
private val pMatrix = Mat4.perspective(PI / 3, 16.0 / 9.0, 0.1, 60.0) | ||
private val vMatrix = Mat4.lookAt(Vec3(20, 20, 20), Vec3(0, 0, 0), Vec3(0, 0, 1)) | ||
|
||
private fun setupFaceBuffer() { | ||
webgl.bindBuffer(WebGLRenderingContext.ELEMENT_ARRAY_BUFFER, faceIndexBuffer) | ||
webgl.bufferData(WebGLRenderingContext.ELEMENT_ARRAY_BUFFER, faces, WebGLRenderingContext.STATIC_DRAW) | ||
} | ||
|
||
private fun setupAttributes() { | ||
shaderProgram.apply { | ||
setupAttribute("aVertexPosition", vertices) | ||
setupAttribute("aVertexNormal", vertexNormals) | ||
} | ||
} | ||
|
||
private fun setupMatrices(scaleFactor: Double, rotation: Double) { | ||
val mMatrix = Mat4() | ||
mMatrix.scale(scaleFactor) | ||
mMatrix.rotateX(PI / 2) | ||
mMatrix.rotateY(rotation) | ||
|
||
val nMatrix = Mat3.fromMat4(vMatrix * mMatrix) | ||
nMatrix.transpose() | ||
nMatrix.invert() | ||
|
||
shaderProgram.apply { | ||
setupUniformMat3("uNMatrix", nMatrix) | ||
setupUniformMat4("uPMatrix", pMatrix) | ||
setupUniformMat4("uVMatrix", vMatrix) | ||
setupUniformMat4("uMMatrix", mMatrix) | ||
} | ||
} | ||
|
||
private fun setupLight(light: LightSource) { | ||
shaderProgram.apply { | ||
setupUniformVec3Float("uLightPos", light.pos) | ||
setupUniformVec3Float("uAmbientColor", light.ambientColor) | ||
setupUniformVec3Float("uDiffuseColor", light.diffuseColor) | ||
setupUniformVec3Float("uSpecularColor", light.specularColor) | ||
} | ||
} | ||
|
||
fun draw(scaleFactor: Double, rotation: Double, shininess: Double, light: LightSource) { | ||
shaderProgram.useProgram() | ||
setupAttributes() | ||
setupFaceBuffer() | ||
setupMatrices(scaleFactor, rotation) | ||
setupShininess(shininess) | ||
setupLight(light) | ||
webgl.drawElements(WebGLRenderingContext.TRIANGLES, numFaces * 3, WebGLRenderingContext.UNSIGNED_SHORT, 0) | ||
} | ||
|
||
private fun setupShininess(shininess: Double) { | ||
shaderProgram.setupUniformFloat("shininess", shininess.toFloat()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import org.khronos.webgl.WebGLRenderingContext as GL | ||
import org.khronos.webgl.WebGLShader | ||
|
||
fun GL.getShader(source: String, shaderType: Int): WebGLShader { | ||
val shader = this.createShader(shaderType) | ||
this.shaderSource(shader, source) | ||
this.compileShader(shader) | ||
if(!(this.getShaderParameter(shader, GL.COMPILE_STATUS) as Boolean)) { | ||
println(this.getShaderInfoLog(shader)) | ||
} | ||
return shader ?: throw IllegalStateException("Shader is null!") | ||
} | ||
|
||
fun GL.getFragmentShader(source: String): WebGLShader = this.getShader(source, GL.FRAGMENT_SHADER) | ||
fun GL.getVertexShader(source: String): WebGLShader = this.getShader(source, GL.VERTEX_SHADER) |