Skip to content

Instantly share code, notes, and snippets.

@basicxman
Created December 9, 2012 02:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save basicxman/4243082 to your computer and use it in GitHub Desktop.
Save basicxman/4243082 to your computer and use it in GitHub Desktop.
class WebGL
getWebGLContext: (id) ->
elm = document.getElementById(id)
ctx = elm.getContext("webgl") || elm.getContext("experimental-webgl")
getShader: (id) ->
shaderScript = document.getElementById(id)
theSource = shaderScript.textContent
if shaderScript.type == "x-shader/x-fragment"
shader = @gl.createShader(@gl.FRAGMENT_SHADER)
else
shader = @gl.createShader(@gl.VERTEX_SHADER)
@gl.shaderSource(shader, theSource)
@gl.compileShader(shader)
if not @gl.getShaderParameter(shader, @gl.COMPILE_STATUS)
console.log @gl.getShaderInfoLog(shader)
return
return shader
createProgram: (shaders...) ->
program = @gl.createProgram()
for shader in shaders
@gl.attachShader(program, shader)
@gl.linkProgram(program)
if not @gl.getProgramParameter(program, @gl.LINK_STATUS)
return
return program
class Game extends WebGL
constructor: ->
@stats = new Stats
document.getElementById("stats").appendChild(@stats.getDomElement())
@bg = document.getElementById("bg").getContext("2d")
@fg = document.getElementById("fg").getContext("2d")
@gl = this.getWebGLContext("game")
@gW = document.getElementById("game").getAttribute("width")
@gH = document.getElementById("game").getAttribute("height")
@spriteMap = new Image
@spriteMap.onload = => this.initGraphics()
@spriteMap.src = "mario_sprite_map.png"
initGraphics: ->
@textureProgram = this.createProgram(this.getShader("2d-texture-vertex-shader"), this.getShader("2d-texture-fragment-shader"))
@gl.useProgram(@textureProgram)
@shader = {
vertexPosition : @gl.getAttribLocation(@textureProgram, "aVertexPosition")
, texturePosition : @gl.getAttribLocation(@textureProgram, "aTexturePosition")
, windowResolution : @gl.getUniformLocation(@textureProgram, "uWindowResolution")
, textureResolution : @gl.getUniformLocation(@textureProgram, "uTextureResolution")
, texture : @gl.getUniformLocation(@textureProgram, "uTexture")
}
@gl.enableVertexAttribArray(@shader.vertexPosition)
@gl.enableVertexAttribArray(@shader.texturePosition)
@gl.uniform2f(@shader.windowResolution, @gW, @gH)
@gl.uniform2f(@shader.textureResolution, @spriteMap.width, @spriteMap.height)
@spriteMapTexture = @gl.createTexture()
@gl.bindTexture(@gl.TEXTURE_2D, @spriteMapTexture)
@gl.texImage2D(@gl.TEXTURE_2D, 0, @gl.RGBA, @gl.RGBA, @gl.UNSIGNED_BYTE, @spriteMap)
@gl.texParameteri(@gl.TEXTURE_2D, @gl.TEXTURE_WRAP_S, @gl.CLAMP_TO_EDGE)
@gl.texParameteri(@gl.TEXTURE_2D, @gl.TEXTURE_WRAP_T, @gl.CLAMP_TO_EDGE)
@gl.texParameteri(@gl.TEXTURE_2D, @gl.TEXTURE_MAG_FILTER, @gl.LINEAR)
@gl.texParameteri(@gl.TEXTURE_2D, @gl.TEXTURE_MIN_FILTER, @gl.LINEAR)
@gl.bindTexture(@gl.TEXTURE_2D, null)
@gl.activeTexture(@gl.TEXTURE0)
@gl.bindTexture(@gl.TEXTURE_2D, @spriteMapTexture)
@gl.uniform1i(@shader.texture, 0)
this.draw()
gridPositionToCoords: (x, y) ->
x1 = x * 16
y1 = y * 16
x2 = x1 + 16
y2 = y1 + 16
return [
x1, y1
, x2, y1
, x1, y2
, x2, y2
]
draw: ->
@coords = []
@textureCoords = []
for x in [0..10]
@coords = @coords.concat(this.gridPositionToCoords(x, 0))
@textureCoords = @textureCoords.concat(this.gridPositionToCoords(5, 0))
vertexBuf = @gl.createBuffer()
@gl.bindBuffer(@gl.ARRAY_BUFFER, vertexBuf)
@gl.vertexAttribPointer(@shader.vertexPosition, 2, @gl.FLOAT, false, 0, 0)
@gl.bufferData(@gl.ARRAY_BUFFER, new Float32Array(@coords), @gl.STATIC_DRAW)
textureBuf = @gl.createBuffer()
@gl.bindBuffer(@gl.ARRAY_BUFFER, textureBuf)
@gl.vertexAttribPointer(@shader.texturePosition, 2, @gl.FLOAT, false, 0, 0)
@gl.bufferData(@gl.ARRAY_BUFFER, new Float32Array(@textureCoords), @gl.STATIC_DRAW)
@gl.drawArrays(@gl.TRIANGLE_STRIP, 0, @coords.length / 2)
game = new Game
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sprite Map Testing</title>
<link rel="stylesheet" type="text/css" href="game.css" />
</head>
<body>
<div id="c">
<canvas id="bg" width="800" height="600"></canvas>
<canvas id="game" width="800" height="600"></canvas>
<canvas id="fg" width="800" height="600">Your browser does not support this game.</canvas>
<div id="stats"></div>
</div>
<script type="x-shader/x-vertex" id="2d-texture-vertex-shader">
attribute vec2 aVertexPosition;
attribute vec2 aTexturePosition;
uniform vec2 uWindowResolution;
varying vec2 vTexturePosition;
void main() {
vec2 clipSpace = (aVertexPosition / uWindowResolution) * 2.0 - 1.0;
clipSpace = clipSpace * vec2(1.0, -1.0);
gl_Position = vec4(clipSpace, 0.0, 1.0);
vTexturePosition = aTexturePosition;
}
</script>
<script type="x-shader/x-fragment" id="2d-texture-fragment-shader">
precision mediump float;
uniform sampler2D uTexture;
uniform vec2 uTextureResolution;
varying vec2 vTexturePosition;
void main() {
gl_FragColor = texture2D(uTexture, vTexturePosition / uTextureResolution);
}
</script>
<script type="text/javascript" src="Stats.js"></script>
<script type="text/javascript" src="requestAnimFrame.js"></script>
<script type="text/javascript" src="webgl-debug.js"></script>
<script type="text/javascript" src="game.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment