diff --git a/lib/kotludens/com/persesgames/game/Game.kt b/lib/kotludens/com/persesgames/game/Game.kt index 8cf6452..29053ed 100644 --- a/lib/kotludens/com/persesgames/game/Game.kt +++ b/lib/kotludens/com/persesgames/game/Game.kt @@ -14,7 +14,7 @@ */ class DefaultScreen: Screen() { - override fun update(time: Float) { + override fun update(time: Float, delta: Float) { } override fun render() { @@ -152,6 +152,10 @@ var currentTime = start var currentDelta = 0f + var fps = 0 + var fpsCount = 0 + var fpsCountTime = 0f + fun gl() = html.webgl fun resize() { @@ -176,10 +180,10 @@ textCanvas.width = view.width.toInt() textCanvas.height = view.height.toInt() - - html.canvas2d.fillStyle = "green" - html.canvas2d.font = "bold 36pt Arial" - html.canvas2d.fillText("Hello World!", 10.0, 40.0) +// +// html.canvas2d.fillStyle = "green" +// html.canvas2d.font = "bold 36pt Arial" +// html.canvas2d.fillText("Hello World!", 10.0, 40.0) gl().viewport(0, 0, view.width.toInt(), view.height.toInt()) canvas.setAttribute("style", "position: absolute; left: 0px; top: 0px; z-index: 5; width: ${view.windowWidth}px; height: ${view.windowHeight}px;" ) @@ -214,11 +218,29 @@ } else { resize(); + html.canvas2d.clearRect(0.0, 0.0, view.width.toDouble(), view.height.toDouble()); + + Game.gl().clearColor(0f, 0f, 0f, 1f) + Game.gl().clear(WebGLRenderingContext.COLOR_BUFFER_BIT) + + Game.gl().enable(WebGLRenderingContext.BLEND); + Game.gl().blendFunc(WebGLRenderingContext.SRC_ALPHA, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA); //ONE_MINUS_DST_ALPHA); + val time = Date().getTime() - currentDelta = (currentTime - time) / 1000f + currentDelta = (time - currentTime) / 1000f currentTime = time - currentScreen.update(currentDelta); + val timeInSeconds = (currentTime - start) / 1000f + + fpsCountTime += currentDelta + fpsCount++ + if (fpsCountTime > 1f) { + fps = fpsCount + fpsCountTime -= 1f + fpsCount = 0 + } + + currentScreen.update(timeInSeconds, currentDelta); currentScreen.render(); } diff --git a/lib/kotludens/com/persesgames/game/Game.kt b/lib/kotludens/com/persesgames/game/Game.kt index 8cf6452..29053ed 100644 --- a/lib/kotludens/com/persesgames/game/Game.kt +++ b/lib/kotludens/com/persesgames/game/Game.kt @@ -14,7 +14,7 @@ */ class DefaultScreen: Screen() { - override fun update(time: Float) { + override fun update(time: Float, delta: Float) { } override fun render() { @@ -152,6 +152,10 @@ var currentTime = start var currentDelta = 0f + var fps = 0 + var fpsCount = 0 + var fpsCountTime = 0f + fun gl() = html.webgl fun resize() { @@ -176,10 +180,10 @@ textCanvas.width = view.width.toInt() textCanvas.height = view.height.toInt() - - html.canvas2d.fillStyle = "green" - html.canvas2d.font = "bold 36pt Arial" - html.canvas2d.fillText("Hello World!", 10.0, 40.0) +// +// html.canvas2d.fillStyle = "green" +// html.canvas2d.font = "bold 36pt Arial" +// html.canvas2d.fillText("Hello World!", 10.0, 40.0) gl().viewport(0, 0, view.width.toInt(), view.height.toInt()) canvas.setAttribute("style", "position: absolute; left: 0px; top: 0px; z-index: 5; width: ${view.windowWidth}px; height: ${view.windowHeight}px;" ) @@ -214,11 +218,29 @@ } else { resize(); + html.canvas2d.clearRect(0.0, 0.0, view.width.toDouble(), view.height.toDouble()); + + Game.gl().clearColor(0f, 0f, 0f, 1f) + Game.gl().clear(WebGLRenderingContext.COLOR_BUFFER_BIT) + + Game.gl().enable(WebGLRenderingContext.BLEND); + Game.gl().blendFunc(WebGLRenderingContext.SRC_ALPHA, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA); //ONE_MINUS_DST_ALPHA); + val time = Date().getTime() - currentDelta = (currentTime - time) / 1000f + currentDelta = (time - currentTime) / 1000f currentTime = time - currentScreen.update(currentDelta); + val timeInSeconds = (currentTime - start) / 1000f + + fpsCountTime += currentDelta + fpsCount++ + if (fpsCountTime > 1f) { + fps = fpsCount + fpsCountTime -= 1f + fpsCount = 0 + } + + currentScreen.update(timeInSeconds, currentDelta); currentScreen.render(); } diff --git a/lib/kotludens/com/persesgames/game/Screen.kt b/lib/kotludens/com/persesgames/game/Screen.kt index 4c0967c..42ddeca 100644 --- a/lib/kotludens/com/persesgames/game/Screen.kt +++ b/lib/kotludens/com/persesgames/game/Screen.kt @@ -13,7 +13,7 @@ } - abstract fun update(time: Float) + abstract fun update(time: Float, delta: Float) abstract fun render() diff --git a/lib/kotludens/com/persesgames/game/Game.kt b/lib/kotludens/com/persesgames/game/Game.kt index 8cf6452..29053ed 100644 --- a/lib/kotludens/com/persesgames/game/Game.kt +++ b/lib/kotludens/com/persesgames/game/Game.kt @@ -14,7 +14,7 @@ */ class DefaultScreen: Screen() { - override fun update(time: Float) { + override fun update(time: Float, delta: Float) { } override fun render() { @@ -152,6 +152,10 @@ var currentTime = start var currentDelta = 0f + var fps = 0 + var fpsCount = 0 + var fpsCountTime = 0f + fun gl() = html.webgl fun resize() { @@ -176,10 +180,10 @@ textCanvas.width = view.width.toInt() textCanvas.height = view.height.toInt() - - html.canvas2d.fillStyle = "green" - html.canvas2d.font = "bold 36pt Arial" - html.canvas2d.fillText("Hello World!", 10.0, 40.0) +// +// html.canvas2d.fillStyle = "green" +// html.canvas2d.font = "bold 36pt Arial" +// html.canvas2d.fillText("Hello World!", 10.0, 40.0) gl().viewport(0, 0, view.width.toInt(), view.height.toInt()) canvas.setAttribute("style", "position: absolute; left: 0px; top: 0px; z-index: 5; width: ${view.windowWidth}px; height: ${view.windowHeight}px;" ) @@ -214,11 +218,29 @@ } else { resize(); + html.canvas2d.clearRect(0.0, 0.0, view.width.toDouble(), view.height.toDouble()); + + Game.gl().clearColor(0f, 0f, 0f, 1f) + Game.gl().clear(WebGLRenderingContext.COLOR_BUFFER_BIT) + + Game.gl().enable(WebGLRenderingContext.BLEND); + Game.gl().blendFunc(WebGLRenderingContext.SRC_ALPHA, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA); //ONE_MINUS_DST_ALPHA); + val time = Date().getTime() - currentDelta = (currentTime - time) / 1000f + currentDelta = (time - currentTime) / 1000f currentTime = time - currentScreen.update(currentDelta); + val timeInSeconds = (currentTime - start) / 1000f + + fpsCountTime += currentDelta + fpsCount++ + if (fpsCountTime > 1f) { + fps = fpsCount + fpsCountTime -= 1f + fpsCount = 0 + } + + currentScreen.update(timeInSeconds, currentDelta); currentScreen.render(); } diff --git a/lib/kotludens/com/persesgames/game/Screen.kt b/lib/kotludens/com/persesgames/game/Screen.kt index 4c0967c..42ddeca 100644 --- a/lib/kotludens/com/persesgames/game/Screen.kt +++ b/lib/kotludens/com/persesgames/game/Screen.kt @@ -13,7 +13,7 @@ } - abstract fun update(time: Float) + abstract fun update(time: Float, delta: Float) abstract fun render() diff --git a/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt b/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt index cca9749..cab8cb3 100644 --- a/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt +++ b/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt @@ -20,32 +20,44 @@ ) { val webgl = shaderProgram.webgl //val data: Array = Array(4096, { 0f }) - val data: Float32Array = Float32Array(4096) + val data: Float32Array var currentIndex: Int = 0 val attribBuffer: WebGLBuffer var counter = 0 + var userdata: T? = null init { + data = Float32Array(4096 - (4096 % shaderProgram.drawLength)) + attribBuffer = webgl.createBuffer() ?: throw IllegalStateException("Unable to create webgl buffer!") webgl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, attribBuffer); } fun queue(vararg vertices: Float) { - data.set(vertices.toTypedArray(), currentIndex) - currentIndex += vertices.size + queue(vertices.toTypedArray()) } fun queue(vertices: Array) { data.set(vertices, currentIndex) currentIndex += vertices.size + + if (currentIndex == data.length) { + val ud = userdata + if (ud != null) { + render(ud) + } else { + println("Skipped draw call, to many values and userdata is not set!") + currentIndex = 0 + } + } } fun render(userdata: T) { counter++ if (currentIndex > 0) { - if (counter % 100 == 0) { +/* if (counter % 100 == 0) { println("currentIndex=$currentIndex blockSize=${shaderProgram.verticesBlockSize} drawLength=${shaderProgram.drawLength} drawing=${(currentIndex / shaderProgram.verticesBlockSize).toInt()}") - } + }*/ if (currentIndex % shaderProgram.verticesBlockSize != 0) { throw IllegalStateException("Number of vertices not a multiple of the attribute block size!") } diff --git a/lib/kotludens/com/persesgames/game/Game.kt b/lib/kotludens/com/persesgames/game/Game.kt index 8cf6452..29053ed 100644 --- a/lib/kotludens/com/persesgames/game/Game.kt +++ b/lib/kotludens/com/persesgames/game/Game.kt @@ -14,7 +14,7 @@ */ class DefaultScreen: Screen() { - override fun update(time: Float) { + override fun update(time: Float, delta: Float) { } override fun render() { @@ -152,6 +152,10 @@ var currentTime = start var currentDelta = 0f + var fps = 0 + var fpsCount = 0 + var fpsCountTime = 0f + fun gl() = html.webgl fun resize() { @@ -176,10 +180,10 @@ textCanvas.width = view.width.toInt() textCanvas.height = view.height.toInt() - - html.canvas2d.fillStyle = "green" - html.canvas2d.font = "bold 36pt Arial" - html.canvas2d.fillText("Hello World!", 10.0, 40.0) +// +// html.canvas2d.fillStyle = "green" +// html.canvas2d.font = "bold 36pt Arial" +// html.canvas2d.fillText("Hello World!", 10.0, 40.0) gl().viewport(0, 0, view.width.toInt(), view.height.toInt()) canvas.setAttribute("style", "position: absolute; left: 0px; top: 0px; z-index: 5; width: ${view.windowWidth}px; height: ${view.windowHeight}px;" ) @@ -214,11 +218,29 @@ } else { resize(); + html.canvas2d.clearRect(0.0, 0.0, view.width.toDouble(), view.height.toDouble()); + + Game.gl().clearColor(0f, 0f, 0f, 1f) + Game.gl().clear(WebGLRenderingContext.COLOR_BUFFER_BIT) + + Game.gl().enable(WebGLRenderingContext.BLEND); + Game.gl().blendFunc(WebGLRenderingContext.SRC_ALPHA, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA); //ONE_MINUS_DST_ALPHA); + val time = Date().getTime() - currentDelta = (currentTime - time) / 1000f + currentDelta = (time - currentTime) / 1000f currentTime = time - currentScreen.update(currentDelta); + val timeInSeconds = (currentTime - start) / 1000f + + fpsCountTime += currentDelta + fpsCount++ + if (fpsCountTime > 1f) { + fps = fpsCount + fpsCountTime -= 1f + fpsCount = 0 + } + + currentScreen.update(timeInSeconds, currentDelta); currentScreen.render(); } diff --git a/lib/kotludens/com/persesgames/game/Screen.kt b/lib/kotludens/com/persesgames/game/Screen.kt index 4c0967c..42ddeca 100644 --- a/lib/kotludens/com/persesgames/game/Screen.kt +++ b/lib/kotludens/com/persesgames/game/Screen.kt @@ -13,7 +13,7 @@ } - abstract fun update(time: Float) + abstract fun update(time: Float, delta: Float) abstract fun render() diff --git a/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt b/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt index cca9749..cab8cb3 100644 --- a/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt +++ b/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt @@ -20,32 +20,44 @@ ) { val webgl = shaderProgram.webgl //val data: Array = Array(4096, { 0f }) - val data: Float32Array = Float32Array(4096) + val data: Float32Array var currentIndex: Int = 0 val attribBuffer: WebGLBuffer var counter = 0 + var userdata: T? = null init { + data = Float32Array(4096 - (4096 % shaderProgram.drawLength)) + attribBuffer = webgl.createBuffer() ?: throw IllegalStateException("Unable to create webgl buffer!") webgl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, attribBuffer); } fun queue(vararg vertices: Float) { - data.set(vertices.toTypedArray(), currentIndex) - currentIndex += vertices.size + queue(vertices.toTypedArray()) } fun queue(vertices: Array) { data.set(vertices, currentIndex) currentIndex += vertices.size + + if (currentIndex == data.length) { + val ud = userdata + if (ud != null) { + render(ud) + } else { + println("Skipped draw call, to many values and userdata is not set!") + currentIndex = 0 + } + } } fun render(userdata: T) { counter++ if (currentIndex > 0) { - if (counter % 100 == 0) { +/* if (counter % 100 == 0) { println("currentIndex=$currentIndex blockSize=${shaderProgram.verticesBlockSize} drawLength=${shaderProgram.drawLength} drawing=${(currentIndex / shaderProgram.verticesBlockSize).toInt()}") - } + }*/ if (currentIndex % shaderProgram.verticesBlockSize != 0) { throw IllegalStateException("Number of vertices not a multiple of the attribute block size!") } diff --git a/lib/kotludens/com/persesgames/text/Texts.kt b/lib/kotludens/com/persesgames/text/Texts.kt new file mode 100644 index 0000000..5263af4 --- /dev/null +++ b/lib/kotludens/com/persesgames/text/Texts.kt @@ -0,0 +1,16 @@ +package com.persesgames.text + +import com.persesgames.game.Game + +/** + * Created by rnentjes on 16-5-16. + */ + +object Texts { + + fun drawText(x: Float, y: Float, message: String, font: String = "bold 24pt Arial", fillStyle: String = "white") { + Game.html.canvas2d.fillStyle = fillStyle + Game.html.canvas2d.font = font + Game.html.canvas2d.fillText(message, x.toDouble(), y.toDouble()) + } +} \ No newline at end of file diff --git a/lib/kotludens/com/persesgames/game/Game.kt b/lib/kotludens/com/persesgames/game/Game.kt index 8cf6452..29053ed 100644 --- a/lib/kotludens/com/persesgames/game/Game.kt +++ b/lib/kotludens/com/persesgames/game/Game.kt @@ -14,7 +14,7 @@ */ class DefaultScreen: Screen() { - override fun update(time: Float) { + override fun update(time: Float, delta: Float) { } override fun render() { @@ -152,6 +152,10 @@ var currentTime = start var currentDelta = 0f + var fps = 0 + var fpsCount = 0 + var fpsCountTime = 0f + fun gl() = html.webgl fun resize() { @@ -176,10 +180,10 @@ textCanvas.width = view.width.toInt() textCanvas.height = view.height.toInt() - - html.canvas2d.fillStyle = "green" - html.canvas2d.font = "bold 36pt Arial" - html.canvas2d.fillText("Hello World!", 10.0, 40.0) +// +// html.canvas2d.fillStyle = "green" +// html.canvas2d.font = "bold 36pt Arial" +// html.canvas2d.fillText("Hello World!", 10.0, 40.0) gl().viewport(0, 0, view.width.toInt(), view.height.toInt()) canvas.setAttribute("style", "position: absolute; left: 0px; top: 0px; z-index: 5; width: ${view.windowWidth}px; height: ${view.windowHeight}px;" ) @@ -214,11 +218,29 @@ } else { resize(); + html.canvas2d.clearRect(0.0, 0.0, view.width.toDouble(), view.height.toDouble()); + + Game.gl().clearColor(0f, 0f, 0f, 1f) + Game.gl().clear(WebGLRenderingContext.COLOR_BUFFER_BIT) + + Game.gl().enable(WebGLRenderingContext.BLEND); + Game.gl().blendFunc(WebGLRenderingContext.SRC_ALPHA, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA); //ONE_MINUS_DST_ALPHA); + val time = Date().getTime() - currentDelta = (currentTime - time) / 1000f + currentDelta = (time - currentTime) / 1000f currentTime = time - currentScreen.update(currentDelta); + val timeInSeconds = (currentTime - start) / 1000f + + fpsCountTime += currentDelta + fpsCount++ + if (fpsCountTime > 1f) { + fps = fpsCount + fpsCountTime -= 1f + fpsCount = 0 + } + + currentScreen.update(timeInSeconds, currentDelta); currentScreen.render(); } diff --git a/lib/kotludens/com/persesgames/game/Screen.kt b/lib/kotludens/com/persesgames/game/Screen.kt index 4c0967c..42ddeca 100644 --- a/lib/kotludens/com/persesgames/game/Screen.kt +++ b/lib/kotludens/com/persesgames/game/Screen.kt @@ -13,7 +13,7 @@ } - abstract fun update(time: Float) + abstract fun update(time: Float, delta: Float) abstract fun render() diff --git a/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt b/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt index cca9749..cab8cb3 100644 --- a/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt +++ b/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt @@ -20,32 +20,44 @@ ) { val webgl = shaderProgram.webgl //val data: Array = Array(4096, { 0f }) - val data: Float32Array = Float32Array(4096) + val data: Float32Array var currentIndex: Int = 0 val attribBuffer: WebGLBuffer var counter = 0 + var userdata: T? = null init { + data = Float32Array(4096 - (4096 % shaderProgram.drawLength)) + attribBuffer = webgl.createBuffer() ?: throw IllegalStateException("Unable to create webgl buffer!") webgl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, attribBuffer); } fun queue(vararg vertices: Float) { - data.set(vertices.toTypedArray(), currentIndex) - currentIndex += vertices.size + queue(vertices.toTypedArray()) } fun queue(vertices: Array) { data.set(vertices, currentIndex) currentIndex += vertices.size + + if (currentIndex == data.length) { + val ud = userdata + if (ud != null) { + render(ud) + } else { + println("Skipped draw call, to many values and userdata is not set!") + currentIndex = 0 + } + } } fun render(userdata: T) { counter++ if (currentIndex > 0) { - if (counter % 100 == 0) { +/* if (counter % 100 == 0) { println("currentIndex=$currentIndex blockSize=${shaderProgram.verticesBlockSize} drawLength=${shaderProgram.drawLength} drawing=${(currentIndex / shaderProgram.verticesBlockSize).toInt()}") - } + }*/ if (currentIndex % shaderProgram.verticesBlockSize != 0) { throw IllegalStateException("Number of vertices not a multiple of the attribute block size!") } diff --git a/lib/kotludens/com/persesgames/text/Texts.kt b/lib/kotludens/com/persesgames/text/Texts.kt new file mode 100644 index 0000000..5263af4 --- /dev/null +++ b/lib/kotludens/com/persesgames/text/Texts.kt @@ -0,0 +1,16 @@ +package com.persesgames.text + +import com.persesgames.game.Game + +/** + * Created by rnentjes on 16-5-16. + */ + +object Texts { + + fun drawText(x: Float, y: Float, message: String, font: String = "bold 24pt Arial", fillStyle: String = "white") { + Game.html.canvas2d.fillStyle = fillStyle + Game.html.canvas2d.font = font + Game.html.canvas2d.fillText(message, x.toDouble(), y.toDouble()) + } +} \ No newline at end of file diff --git a/lib/kotludens/com/persesgames/texture/Textures.kt b/lib/kotludens/com/persesgames/texture/Textures.kt index 517c930..2fe4ee2 100644 --- a/lib/kotludens/com/persesgames/texture/Textures.kt +++ b/lib/kotludens/com/persesgames/texture/Textures.kt @@ -19,6 +19,7 @@ private val vertexShaderSource = """ attribute vec2 a_position; + attribute vec2 a_boundingBox; attribute vec2 a_texCoord; uniform mat4 u_projectionView; @@ -28,7 +29,7 @@ void main(void) { v_textCoord = a_texCoord; - gl_Position = u_projectionView * vec4(a_position, -1, 1.0); + gl_Position = u_projectionView * vec4(a_position + a_boundingBox, -1, 1.0); } """ @@ -49,27 +50,36 @@ val texture: WebGLTexture ) -class Texture(val glTexture: WebGLTexture, val shaderProgram: ShaderProgram) { +class Texture( + val glTexture: WebGLTexture, + val shaderProgram: ShaderProgram, + val width: Int, + val height: Int +) { val shaderProgramMesh: ShaderProgramMesh + val left = -width / 2f + val right = width / 2f + val bottom = -height / 2f + val top = height / 2f init { shaderProgramMesh = ShaderProgramMesh(shaderProgram) } fun queueDraw(x: Float, y: Float) { - shaderProgramMesh.queue( -100f, -100f, 0f, 0f); - shaderProgramMesh.queue( -100f, 100f, 0f, 1f); - shaderProgramMesh.queue( 100f, 100f, 1f, 1f); - - shaderProgramMesh.queue( 100f, 100f, 1f, 1f); - shaderProgramMesh.queue( 100f, -100f, 1f, 0f); - shaderProgramMesh.queue( -100f, -100f, 0f, 0f); + shaderProgramMesh.queue( x, y, left, bottom, 0f, 0f); + shaderProgramMesh.queue( x, y, left, top, 0f, 1f); + shaderProgramMesh.queue( x, y, right, top, 1f, 1f); + shaderProgramMesh.queue( x, y, right, top, 1f, 1f); + shaderProgramMesh.queue( x, y, right, bottom, 1f, 0f); + shaderProgramMesh.queue( x, y, left, bottom, 0f, 0f); } fun render(userdata: TextureData) { Game.gl().activeTexture(WebGLRenderingContext.TEXTURE0) Game.gl().bindTexture(WebGLRenderingContext.TEXTURE_2D, glTexture); + shaderProgramMesh.userdata = userdata shaderProgramMesh.render(userdata) } } @@ -82,18 +92,16 @@ init { val setter = { program: ShaderProgram, data: TextureData -> - program.webgl.activeTexture(WebGLRenderingContext.TEXTURE0); - program.webgl.bindTexture(WebGLRenderingContext.TEXTURE_2D, data.texture); + //program.webgl.activeTexture(WebGLRenderingContext.TEXTURE0); + //program.webgl.bindTexture(WebGLRenderingContext.TEXTURE_2D, data.texture); program.setUniform1i("u_sampler", 0) - val matrix = Matrix4() - matrix.setPerspectiveProjection(120f, 1f, 0.1f, 100f) - matrix.setOrthographicProjection(-1000f, 1000f, -1000f, 1000f, -0.1f, -100f) program.setUniformMatrix4fv("u_projectionView", Game.view.vMatrix.getFloat32Array()) } val vainfo = arrayOf( VertextAttributeInfo("a_position", 2), + VertextAttributeInfo("a_boundingBox", 2), VertextAttributeInfo("a_texCoord", 2) ) @@ -114,7 +122,7 @@ val image = document.createElement("img") as HTMLImageElement image.onload = { textureLoaded(webGlTexture, image) - textures.put(name, Texture(webGlTexture, shaderProgram)) + textures.put(name, Texture(webGlTexture, shaderProgram, image.width, image.height)) loaded++ println("loaded texture $loaded/$startedLoading ${ready()}") } diff --git a/lib/kotludens/com/persesgames/game/Game.kt b/lib/kotludens/com/persesgames/game/Game.kt index 8cf6452..29053ed 100644 --- a/lib/kotludens/com/persesgames/game/Game.kt +++ b/lib/kotludens/com/persesgames/game/Game.kt @@ -14,7 +14,7 @@ */ class DefaultScreen: Screen() { - override fun update(time: Float) { + override fun update(time: Float, delta: Float) { } override fun render() { @@ -152,6 +152,10 @@ var currentTime = start var currentDelta = 0f + var fps = 0 + var fpsCount = 0 + var fpsCountTime = 0f + fun gl() = html.webgl fun resize() { @@ -176,10 +180,10 @@ textCanvas.width = view.width.toInt() textCanvas.height = view.height.toInt() - - html.canvas2d.fillStyle = "green" - html.canvas2d.font = "bold 36pt Arial" - html.canvas2d.fillText("Hello World!", 10.0, 40.0) +// +// html.canvas2d.fillStyle = "green" +// html.canvas2d.font = "bold 36pt Arial" +// html.canvas2d.fillText("Hello World!", 10.0, 40.0) gl().viewport(0, 0, view.width.toInt(), view.height.toInt()) canvas.setAttribute("style", "position: absolute; left: 0px; top: 0px; z-index: 5; width: ${view.windowWidth}px; height: ${view.windowHeight}px;" ) @@ -214,11 +218,29 @@ } else { resize(); + html.canvas2d.clearRect(0.0, 0.0, view.width.toDouble(), view.height.toDouble()); + + Game.gl().clearColor(0f, 0f, 0f, 1f) + Game.gl().clear(WebGLRenderingContext.COLOR_BUFFER_BIT) + + Game.gl().enable(WebGLRenderingContext.BLEND); + Game.gl().blendFunc(WebGLRenderingContext.SRC_ALPHA, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA); //ONE_MINUS_DST_ALPHA); + val time = Date().getTime() - currentDelta = (currentTime - time) / 1000f + currentDelta = (time - currentTime) / 1000f currentTime = time - currentScreen.update(currentDelta); + val timeInSeconds = (currentTime - start) / 1000f + + fpsCountTime += currentDelta + fpsCount++ + if (fpsCountTime > 1f) { + fps = fpsCount + fpsCountTime -= 1f + fpsCount = 0 + } + + currentScreen.update(timeInSeconds, currentDelta); currentScreen.render(); } diff --git a/lib/kotludens/com/persesgames/game/Screen.kt b/lib/kotludens/com/persesgames/game/Screen.kt index 4c0967c..42ddeca 100644 --- a/lib/kotludens/com/persesgames/game/Screen.kt +++ b/lib/kotludens/com/persesgames/game/Screen.kt @@ -13,7 +13,7 @@ } - abstract fun update(time: Float) + abstract fun update(time: Float, delta: Float) abstract fun render() diff --git a/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt b/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt index cca9749..cab8cb3 100644 --- a/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt +++ b/lib/kotludens/com/persesgames/shader/ShaderProgramMesh.kt @@ -20,32 +20,44 @@ ) { val webgl = shaderProgram.webgl //val data: Array = Array(4096, { 0f }) - val data: Float32Array = Float32Array(4096) + val data: Float32Array var currentIndex: Int = 0 val attribBuffer: WebGLBuffer var counter = 0 + var userdata: T? = null init { + data = Float32Array(4096 - (4096 % shaderProgram.drawLength)) + attribBuffer = webgl.createBuffer() ?: throw IllegalStateException("Unable to create webgl buffer!") webgl.bindBuffer(WebGLRenderingContext.ARRAY_BUFFER, attribBuffer); } fun queue(vararg vertices: Float) { - data.set(vertices.toTypedArray(), currentIndex) - currentIndex += vertices.size + queue(vertices.toTypedArray()) } fun queue(vertices: Array) { data.set(vertices, currentIndex) currentIndex += vertices.size + + if (currentIndex == data.length) { + val ud = userdata + if (ud != null) { + render(ud) + } else { + println("Skipped draw call, to many values and userdata is not set!") + currentIndex = 0 + } + } } fun render(userdata: T) { counter++ if (currentIndex > 0) { - if (counter % 100 == 0) { +/* if (counter % 100 == 0) { println("currentIndex=$currentIndex blockSize=${shaderProgram.verticesBlockSize} drawLength=${shaderProgram.drawLength} drawing=${(currentIndex / shaderProgram.verticesBlockSize).toInt()}") - } + }*/ if (currentIndex % shaderProgram.verticesBlockSize != 0) { throw IllegalStateException("Number of vertices not a multiple of the attribute block size!") } diff --git a/lib/kotludens/com/persesgames/text/Texts.kt b/lib/kotludens/com/persesgames/text/Texts.kt new file mode 100644 index 0000000..5263af4 --- /dev/null +++ b/lib/kotludens/com/persesgames/text/Texts.kt @@ -0,0 +1,16 @@ +package com.persesgames.text + +import com.persesgames.game.Game + +/** + * Created by rnentjes on 16-5-16. + */ + +object Texts { + + fun drawText(x: Float, y: Float, message: String, font: String = "bold 24pt Arial", fillStyle: String = "white") { + Game.html.canvas2d.fillStyle = fillStyle + Game.html.canvas2d.font = font + Game.html.canvas2d.fillText(message, x.toDouble(), y.toDouble()) + } +} \ No newline at end of file diff --git a/lib/kotludens/com/persesgames/texture/Textures.kt b/lib/kotludens/com/persesgames/texture/Textures.kt index 517c930..2fe4ee2 100644 --- a/lib/kotludens/com/persesgames/texture/Textures.kt +++ b/lib/kotludens/com/persesgames/texture/Textures.kt @@ -19,6 +19,7 @@ private val vertexShaderSource = """ attribute vec2 a_position; + attribute vec2 a_boundingBox; attribute vec2 a_texCoord; uniform mat4 u_projectionView; @@ -28,7 +29,7 @@ void main(void) { v_textCoord = a_texCoord; - gl_Position = u_projectionView * vec4(a_position, -1, 1.0); + gl_Position = u_projectionView * vec4(a_position + a_boundingBox, -1, 1.0); } """ @@ -49,27 +50,36 @@ val texture: WebGLTexture ) -class Texture(val glTexture: WebGLTexture, val shaderProgram: ShaderProgram) { +class Texture( + val glTexture: WebGLTexture, + val shaderProgram: ShaderProgram, + val width: Int, + val height: Int +) { val shaderProgramMesh: ShaderProgramMesh + val left = -width / 2f + val right = width / 2f + val bottom = -height / 2f + val top = height / 2f init { shaderProgramMesh = ShaderProgramMesh(shaderProgram) } fun queueDraw(x: Float, y: Float) { - shaderProgramMesh.queue( -100f, -100f, 0f, 0f); - shaderProgramMesh.queue( -100f, 100f, 0f, 1f); - shaderProgramMesh.queue( 100f, 100f, 1f, 1f); - - shaderProgramMesh.queue( 100f, 100f, 1f, 1f); - shaderProgramMesh.queue( 100f, -100f, 1f, 0f); - shaderProgramMesh.queue( -100f, -100f, 0f, 0f); + shaderProgramMesh.queue( x, y, left, bottom, 0f, 0f); + shaderProgramMesh.queue( x, y, left, top, 0f, 1f); + shaderProgramMesh.queue( x, y, right, top, 1f, 1f); + shaderProgramMesh.queue( x, y, right, top, 1f, 1f); + shaderProgramMesh.queue( x, y, right, bottom, 1f, 0f); + shaderProgramMesh.queue( x, y, left, bottom, 0f, 0f); } fun render(userdata: TextureData) { Game.gl().activeTexture(WebGLRenderingContext.TEXTURE0) Game.gl().bindTexture(WebGLRenderingContext.TEXTURE_2D, glTexture); + shaderProgramMesh.userdata = userdata shaderProgramMesh.render(userdata) } } @@ -82,18 +92,16 @@ init { val setter = { program: ShaderProgram, data: TextureData -> - program.webgl.activeTexture(WebGLRenderingContext.TEXTURE0); - program.webgl.bindTexture(WebGLRenderingContext.TEXTURE_2D, data.texture); + //program.webgl.activeTexture(WebGLRenderingContext.TEXTURE0); + //program.webgl.bindTexture(WebGLRenderingContext.TEXTURE_2D, data.texture); program.setUniform1i("u_sampler", 0) - val matrix = Matrix4() - matrix.setPerspectiveProjection(120f, 1f, 0.1f, 100f) - matrix.setOrthographicProjection(-1000f, 1000f, -1000f, 1000f, -0.1f, -100f) program.setUniformMatrix4fv("u_projectionView", Game.view.vMatrix.getFloat32Array()) } val vainfo = arrayOf( VertextAttributeInfo("a_position", 2), + VertextAttributeInfo("a_boundingBox", 2), VertextAttributeInfo("a_texCoord", 2) ) @@ -114,7 +122,7 @@ val image = document.createElement("img") as HTMLImageElement image.onload = { textureLoaded(webGlTexture, image) - textures.put(name, Texture(webGlTexture, shaderProgram)) + textures.put(name, Texture(webGlTexture, shaderProgram, image.width, image.height)) loaded++ println("loaded texture $loaded/$startedLoading ${ready()}") } diff --git a/src/com/persesgames/shooter/Shooter.kt b/src/com/persesgames/shooter/Shooter.kt index 2ade959..2b2dbba 100644 --- a/src/com/persesgames/shooter/Shooter.kt +++ b/src/com/persesgames/shooter/Shooter.kt @@ -4,6 +4,7 @@ import com.persesgames.game.Screen import com.persesgames.sprite.Sprite import com.persesgames.sprite.SpriteBatch +import com.persesgames.text.Texts import com.persesgames.texture.Textures import org.khronos.webgl.WebGLRenderingContext @@ -16,31 +17,39 @@ var x = 1f var y = 1f var sprite = Sprite("SHIP") + val random = Math.random() override fun loadResources() { Textures.load("SHIP", "images/ship2.png") } - override fun update(time: Float) { - x = 100f + Math.sin(time.toDouble()).toFloat() * 50f - y = 100f + Math.cos(time.toDouble()).toFloat() * 50f + override fun update(time: Float, delta: Float) { + x = Math.sin(time.toDouble()).toFloat() * 150f + y = Math.cos(time.toDouble()).toFloat() * 150f } override fun render() { - Game.gl().clearColor(0f, 0.5f, 1f, 1f) - Game.gl().clear(WebGLRenderingContext.COLOR_BUFFER_BIT) + for (index in 0..2500) { + val x = Math.random() * 1000f - 500f + val y = Math.random() * 1000f - 500f - Game.gl().enable(WebGLRenderingContext.BLEND); - Game.gl().blendFunc(WebGLRenderingContext.SRC_ALPHA, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA); //ONE_MINUS_DST_ALPHA); + sprites.draw(sprite, x.toFloat(), y.toFloat()); + } sprites.draw(sprite, x, y); + sprites.draw(sprite, -x, y); + sprites.draw(sprite, x, -y); + sprites.draw(sprite, -x, -y); + sprites.render() + + Texts.drawText(10f, 40f, "Hello! FPS ${Game.fps}", font = "bold 36pt Arial") } } class GameScreen: Screen() { - override fun update(time: Float) { + override fun update(time: Float, delta: Float) { } override fun render() {