Last active
August 29, 2015 13:57
-
-
Save g-pechorin/9440780 to your computer and use it in GitHub Desktop.
An example of libGDX and GLSL ES with correct(ish) maths
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
package com.peterlavalle.demo | |
import com.badlogic.gdx._ | |
import com.badlogic.gdx.backends.lwjgl.LwjglApplication | |
import com.badlogic.gdx.graphics.glutils.ShaderProgram | |
import com.badlogic.gdx.math.{Vector3, Matrix4} | |
import com.badlogic.gdx.graphics.{PerspectiveCamera, GL20, VertexAttribute, Mesh} | |
import java.util | |
/** | |
* Created by peter on 06/03/14. | |
*/ | |
object GistDesktop extends App with InputProcessor with ApplicationListener { | |
new LwjglApplication(this, "Why Happen!?", 1024, 768, true) | |
lazy val shader = | |
new ShaderProgram( | |
""" | |
|attribute vec4 a_position; | |
| | |
|uniform mat4 u_projection; | |
|uniform mat4 u_view; | |
|uniform mat4 u_model; | |
| | |
|void main() | |
|{ | |
| gl_Position = u_projection * u_view * u_model * a_position; | |
|} | |
""".stripMargin, | |
""" | |
|void main() | |
|{ | |
| gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); | |
|} | |
""".stripMargin) | |
lazy val model = new Matrix4() | |
lazy val mesh = { | |
val mesh = | |
new Mesh(true, 4, 4, VertexAttribute.Position()) | |
mesh setIndices Array[Short](0, 1, 2, 3) | |
mesh setVertices Array[Float]( | |
-0.5f, -0.5f, -.25f, | |
+0.5f, -0.5f, -.25f, | |
-0.5f, +0.5f, -.25f, | |
+0.5f, +0.5f, -.25f | |
) | |
mesh | |
} | |
lazy val camera = new PerspectiveCamera(90, 1, 1) | |
override def resize(width: Int, height: Int) { | |
camera.near = 0.1f | |
camera.far = 1024f * 1024f | |
camera.viewportWidth = width.toFloat / Math.max(width, height).toFloat | |
camera.viewportHeight = height.toFloat / Math.max(width, height).toFloat | |
camera.update(true) | |
} | |
/** | |
* Wouldn't it be cool if Scala supported some sort of syntactical sugar (well ... semantic sugar) that created lazy or eager fields from method variables? | |
* | |
* ... just saying ... | |
*/ | |
private val render$move = new Vector3() | |
override def render() { | |
Gdx.gl20.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT) | |
shader begin() | |
shader setUniformMatrix("u_projection", camera.projection) | |
shader setUniformMatrix("u_view", camera.view) | |
shader setUniformMatrix("u_model", model) | |
mesh.render(shader, GL20.GL_TRIANGLE_STRIP) | |
shader end() | |
// translate the camera | |
camera | |
.position | |
.add( | |
impulses | |
.filterKeys(keyCodes.contains) | |
.foldLeft(render$move.set(0, 0, 0))((move, impulse) => move.add(impulse._2)) | |
.scl(Gdx.graphics.getDeltaTime) | |
.mul(camera.view.setTranslation(Vector3.Zero).inv())) | |
camera.update(false) | |
} | |
override def pause() { | |
} | |
override def resume() { | |
} | |
def dispose() { | |
shader.dispose() | |
mesh.dispose() | |
} | |
val keyCodes = new util.HashSet[Int]() | |
val impulses = Map( | |
Input.Keys.W -> new Vector3(0, 0, -1), | |
Input.Keys.A -> new Vector3(-1, 0, 0), | |
Input.Keys.Q -> new Vector3(0, +1, 0), | |
Input.Keys.S -> new Vector3(0, 0, +1), | |
Input.Keys.D -> new Vector3(+1, 0, 0), | |
Input.Keys.Z -> new Vector3(0, -1, 0)) | |
override def keyDown(keyCode: Int) = | |
keyCodes.add(keyCode) | |
override def keyUp(keyCode: Int) = | |
keyCodes.remove(keyCode) | |
var tilt = 0.0f | |
var turn = 0.0f | |
val edge = 45.0f | |
override def touchDragged(screenX: Int, screenY: Int, pointer: Int) = { | |
turn += Gdx.input.getDeltaX(pointer) | |
tilt = Math.max(-edge, Math.min(+edge, tilt + Gdx.input.getDeltaY(pointer))) | |
camera.direction.set(0, 0, -1) | |
camera.up.set(0, 1, 0) | |
camera.rotate(tilt, 1, 0, 0) | |
camera.rotate(turn, 0, 1, 0) | |
true | |
} | |
override def scrolled(amount: Int) = | |
false | |
override def mouseMoved(screenX: Int, screenY: Int) = | |
false | |
override def touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int) = | |
false | |
override def touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int) = | |
false | |
override def keyTyped(character: Char) = | |
false | |
override def create() { | |
Gdx.input.setInputProcessor(this) | |
Gdx.graphics.setVSync(true) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment