Skip to content

Instantly share code, notes, and snippets.

@flexd
Created December 16, 2013 00:12
Show Gist options
  • Select an option

  • Save flexd/7980193 to your computer and use it in GitHub Desktop.

Select an option

Save flexd/7980193 to your computer and use it in GitHub Desktop.

Revisions

  1. flexd created this gist Dec 16, 2013.
    136 changes: 136 additions & 0 deletions ld28.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,136 @@
    library ld28;

    import 'dart:html';
    import 'dart:math' as Math;
    import 'dart:web_gl' as WebGL;
    import 'dart:typed_data';
    import 'package:vector_math/vector_math.dart';

    part 'shader.dart';

    WebGL.RenderingContext gl;

    class TextureLoader {


    static WebGL.Texture load(String url) {
    ImageElement img = new ImageElement();
    WebGL.Texture texture = gl.createTexture();
    img.onLoad.listen((e) {
    gl.bindTexture(WebGL.TEXTURE_2D, texture);
    gl.texImage2DImage(WebGL.TEXTURE_2D, 0, WebGL.RGBA, WebGL.RGBA, WebGL.UNSIGNED_BYTE, img);
    gl.texParameteri(WebGL.TEXTURE_2D, WebGL.TEXTURE_MIN_FILTER, WebGL.NEAREST);
    gl.texParameteri(WebGL.TEXTURE_2D, WebGL.TEXTURE_MAG_FILTER, WebGL.NEAREST);
    });
    img.src = url;
    }
    }
    class Quad {
    Shader shader;
    int posLocation;
    WebGL.UniformLocation objectTransformLocation, cameraTransformLocation, viewTransformLocation, textureTransformLocation;
    WebGL.UniformLocation colorLocation;
    Quad(this.shader) {
    posLocation = gl.getAttribLocation(shader.program, "a_pos");

    objectTransformLocation = gl.getUniformLocation(shader.program, "u_objectTransform");
    cameraTransformLocation = gl.getUniformLocation(shader.program, "u_cameraTransform");
    viewTransformLocation = gl.getUniformLocation(shader.program, "u_viewTransform");
    viewTransformLocation = gl.getUniformLocation(shader.program, "u_textureTransform");
    colorLocation = gl.getUniformLocation(shader.program, "u_color");

    Float32List vertexArray = new Float32List(4*3);
    vertexArray.setAll(0*3, [0.0, 0.0, 0.0]);
    vertexArray.setAll(1*3, [0.0, 1.0, 0.0]);
    vertexArray.setAll(2*3, [1.0, 1.0, 0.0]);
    vertexArray.setAll(3*3, [1.0, 0.0, 0.0]);

    Int16List indexArray = new Int16List(6);
    indexArray.setAll(0, [0, 1, 2, 0, 2, 3]);


    gl.useProgram(shader.program);
    gl.enableVertexAttribArray(posLocation);
    WebGL.Buffer vertexBuffer = gl.createBuffer();
    gl.bindBuffer(WebGL.ARRAY_BUFFER, vertexBuffer);
    gl.bufferDataTyped(WebGL.ARRAY_BUFFER, vertexArray, WebGL.STATIC_DRAW);
    gl.vertexAttribPointer(posLocation, 3, WebGL.FLOAT, false, 0, 0);

    WebGL.Buffer indexBuffer = gl.createBuffer();
    gl.bindBuffer(WebGL.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferDataTyped(WebGL.ELEMENT_ARRAY_BUFFER, indexArray, WebGL.STATIC_DRAW);
    gl.bindBuffer(WebGL.ELEMENT_ARRAY_BUFFER, indexBuffer);
    }

    void setCamera(Matrix4 viewMatrix, Matrix4 cameraMatrix) {
    gl.uniformMatrix4fv(viewTransformLocation, false, viewMatrix.storage);
    gl.uniformMatrix4fv(cameraTransformLocation, false, cameraMatrix.storage);
    }

    Matrix4 objectMatrix = new Matrix4.identity();
    Matrix4 textureMatrix = new Matrix4.identity();
    void render(int x, int y, int w, int h, int uo, int vo, Vector4 color) {
    double texWidth = 256.0;
    double texHeight = 256.0;

    objectMatrix.setIdentity();
    objectMatrix.translate(x*1.0, y*1.0, -1.0);
    objectMatrix.scale(w*1.0, h*1.0, 0.0);

    textureMatrix.setIdentity();
    textureMatrix.translate(uo*1.0, vo*1.0, -1.0);
    textureMatrix.scale(w*1.0/texWidth, h*1.0/texHeight, 0.0);

    gl.uniformMatrix4fv(objectTransformLocation, false, objectMatrix.storage);
    gl.uniformMatrix4fv(textureTransformLocation, false, textureMatrix.storage);

    gl.uniform4fv(colorLocation, color.storage);

    gl.drawElements(WebGL.TRIANGLES, 6, WebGL.UNSIGNED_SHORT, 0);
    }
    }

    class Game {
    CanvasElement canvas;
    Math.Random random;
    Quad quad;
    Matrix4 viewMatrix, cameraMatrix;

    WebGL.Texture sheetTexture;
    double fov = 90.0;

    void start() {
    random = new Math.Random();
    canvas = querySelector("#game_canvas");
    gl = canvas.getContext("webgl");
    if (gl==null) {
    gl = canvas.getContext("experimental-webgl");
    }
    quad = new Quad(quadShader);
    sheetTexture = TextureLoader.load("tex/sheet.png");
    if (gl!=null) {
    window.requestAnimationFrame(render);
    }

    }

    void render (double time) {
    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clear(WebGL.COLOR_BUFFER_BIT);

    viewMatrix = makePerspectiveMatrix(fov*Math.PI/180, canvas.width/canvas.height, 0.01, 100.0);
    double scale = 2.0/canvas.height;
    cameraMatrix = new Matrix4.identity().scale(scale, -scale, 1.0);
    quad.setCamera(viewMatrix, cameraMatrix);
    Vector4 whiteColor = new Vector4(1.0, 0.0, 1.0, 1.0);
    quad.render(0, 0, 24, 95, 0, 0, whiteColor);

    window.requestAnimationFrame(render);
    }

    }

    void main() {
    new Game().start();
    }
    70 changes: 70 additions & 0 deletions shader.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,70 @@
    part of ld28;

    class Shader {
    String vertexShaderCode, fragmentShaderCode;
    WebGL.Shader vertexShader, fragmentShader;
    WebGL.Program program;

    Shader (this.vertexShaderCode, this.fragmentShaderCode) {
    compile();
    }
    void compile() {
    vertexShader = gl.createShader(WebGL.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexShaderCode);
    gl.compileShader(vertexShader);

    if (!gl.getShaderParameter(vertexShader, WebGL.COMPILE_STATUS)) {
    throw gl.getShaderInfoLog(vertexShader);
    }

    fragmentShader = gl.createShader(WebGL.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragmentShaderCode);
    gl.compileShader(fragmentShader);

    if (!gl.getShaderParameter(fragmentShader, WebGL.COMPILE_STATUS)) {
    throw gl.getShaderInfoLog(fragmentShader);
    }

    program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    if (!gl.getProgramParameter(program, WebGL.LINK_STATUS)) {
    throw gl.getProgramInfoLog(program);
    }
    }
    }

    Shader quadShader = new Shader("""
    precision highp float;
    attribute vec3 a_pos;
    uniform mat4 u_objectTransform;
    uniform mat4 u_cameraTransform;
    uniform mat4 u_viewTransform;
    uniform mat4 u_textureTransform;
    varying vec2 v_texcoord;
    void main() {
    v_texcoord = (u_textureTransform*vec4(a_pos, 1.0)).xy;
    gl_Position = u_viewTransform*u_cameraTransform*u_objectTransform*vec4(a_pos, 1.0);
    }
    """,/*=============================================================================================*/"""
    precision highp float;
    varying vec2 v_texcoord;
    uniform sampler2D u_tex;
    uniform vec4 u_color;
    void main() {
    vec4 col = texture2D(u_tex, v_texcoord);
    if (col.a>0.0) {
    gl_FragColor = col*u_color;
    } else {
    discard;
    }
    }
    """);