Example: ex2

Your browser doesn't appear to support the <canvas> element.

Code

import ../src/webgl, dom

var gl: WebGLRenderingContext;
var viewportWidth:int
var viewportHeight:int

#########
proc identity4 (a:auto):auto =
    {. emit: "`a`[0]=1;`a`[1]=0;`a`[2]=0;`a`[3]=0;`a`[4]=0;`a`[5]=1;`a`[6]=0;`a`[7]=0;`a`[8]=0;`a`[9]=0;`a`[10]=1;`a`[11]=0;`a`[12]=0;`a`[13]=0;`a`[14]=0;`a`[15]=1;`result`=`a`" .}

proc translate4 (a,b,c:auto):auto =
    {. emit: "var d=`b`[0],e=`b`[1];`b`=`b`[2];if(!`c`||`a`==`c`){`a`[12]=`a`[0]*d+`a`[4]*e+`a`[8]*`b`+`a`[12];`a`[13]=`a`[1]*d+`a`[5]*e+`a`[9]*`b`+`a`[13];`a`[14]=`a`[2]*d+`a`[6]*e+`a`[10]*`b`+`a`[14];`a`[15]=`a`[3]*d+`a`[7]*e+`a`[11]*`b`+`a`[15];return `a`}var g=`a`[0],f=`a`[1],h=`a`[2],i=`a`[3],j=`a`[4],k=`a`[5],l=`a`[6],o=`a`[7],m=`a`[8],n=`a`[9],p=`a`[10],r=`a`[11];`c`[0]=g;`c`[1]=f;`c`[2]=h;`c`[3]=i;`c`[4]=j;`c`[5]=k;`c`[6]=l;`c`[7]=o;`c`[8]=m;`c`[9]=n;`c`[10]=p;`c`[11]=r;`c`[12]=g*d+j*e+m*`b`+`a`[12];`c`[13]=f*d+k*e+n*`b`+`a`[13];`c`[14]=h*d+l*e+p*`b`+`a`[14];`c`[15]=i*d+o*e+r*`b`+`a`[15];`result` = `c`;" .}
proc perspective4 (a,b,c,d,e:auto):auto =
    {. emit : "function frustum(a,b,c,d,e,g,f){var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f;};`a`=`c`*Math.tan(`a`*Math.PI/360);`b`=`a`*`b`;`result` = frustum(-`b`,`b`,-`a`,`a`,`c`,`d`,`e`);" .}

#######

proc initGL(canvas:Canvas) = 
    
    gl = canvas.getContext("webgl")
    if gl.isNil: gl = canvas.getContext("experimental-webgl")
    viewportWidth = canvas.width;
    viewportHeight = canvas.height;
    
    #if (gl==nil): 
        #alert("Could not initialise WebGL, sorry :-(");
    
proc getShader(gl:WebGLRenderingContext, id:cstring,stype:cstring):WebGLShader =
    var shaderScript = document.getElementById(id);
    if (shaderScript==nil) :
        return
    
    var str : cstring = shaderScript.firstChild.nodeValue;
    #[while (k!=nil) :
        if (k.nodeType == TextNode) :
            str &= k.nodeValue.cstring;
            {. emit : "console.log(`stype`+`k`);" .}
        k = k.nextSibling;
    {. emit : "console.log(`stype`+`str`);" .}]#

    if (stype == "x-shader/x-fragment") :
        result = gl.createShader(seFRAGMENT_SHADER)
    elif (stype == "x-shader/x-vertex"): 
        result = gl.createShader(seVERTEX_SHADER);
    else :
        return;

    gl.shaderSource(result, str);
    gl.compileShader(result);

    {. emit: "if (!`gl`.getShaderParameter(`result`, `gl`.COMPILE_STATUS)){alert(`stype`+' '+`gl`.getShaderInfoLog(`result`));return null;};" .}

var shaderProgram: WebGLProgram
var vertexPositionAttribute:uint
var pMatrixUniform:WebGLUniformLocation
var mvMatrixUniform:WebGLUniformLocation

proc initShaders() =
    var fragmentShader = getShader(gl, "shader-fs","x-shader/x-fragment");
    var vertexShader = getShader(gl, "shader-vs","x-shader/x-vertex");

    shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);

    gl.useProgram(shaderProgram);

    vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
    gl.enableVertexAttribArray(vertexPositionAttribute);
    pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
    mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");



var mvMatrix = newSeq[float](16) # 4x4, so 16 elements
var pMatrix = newSeq[float](16)

proc setMatrixUniforms() =
    gl.uniformMatrix4fv(pMatrixUniform, false, pMatrix);
    gl.uniformMatrix4fv(mvMatrixUniform, false, mvMatrix);

var triangleVertexPositionBuffer:WebGLBuffer
var squareVertexPositionBuffer:WebGLBuffer
var tin : tuple[itemSize,numItems:int]
var vin : tuple[itemSize,numItems:int]

proc initBuffers() =
    triangleVertexPositionBuffer = gl.createBuffer();
    gl.bindBuffer(beARRAY_BUFFER, triangleVertexPositionBuffer);
    var vertices = @[
            0.0,  1.0,  0.0,
        -1.0, -1.0,  0.0,
            1.0, -1.0,  0.0
    ];
    gl.bufferData(beARRAY_BUFFER, vertices, beSTATIC_DRAW);
    tin.itemSize = 3;
    tin.numItems = 3;

    squareVertexPositionBuffer = gl.createBuffer();
    gl.bindBuffer(beARRAY_BUFFER, squareVertexPositionBuffer);
    var vertices2 = @[
            1.0,  1.0,  0.0,
        -1.0,  1.0,  0.0,
            1.0, -1.0,  0.0,
        -1.0, -1.0,  0.0
    ];
    gl.bufferData(beARRAY_BUFFER, vertices2, beSTATIC_DRAW);
    vin.itemSize = 3;
    vin.numItems = 4;



proc drawScene() =
    gl.viewport(0, 0, viewportWidth, viewportHeight);
    gl.clear(bbCOLOR.uint or bbDEPTH.uint);

    perspective4(45, viewportWidth / viewportHeight, 0.1, 100.0, pMatrix);
        
    identity4(mvMatrix);

    traslate4(mvMatrix, @[-1.5, 0.0, -7.0], mvMatrix);

    gl.bindBuffer(beARRAY_BUFFER, triangleVertexPositionBuffer);
    gl.vertexAttribPointer(vertexPositionAttribute, tin.itemSize, dtFLOAT, false, 0, 0);
    setMatrixUniforms();
    gl.drawArrays(pmTRIANGLES, 0, tin.numItems);


    traslate4(mvMatrix, @[3.0, 0.0, 0.0], mvMatrix);
    gl.bindBuffer(beARRAY_BUFFER, squareVertexPositionBuffer);
    gl.vertexAttribPointer(vertexPositionAttribute, vin.itemSize, dtFLOAT, false, 0, 0);
    setMatrixUniforms();
    gl.drawArrays(pmTRIANGLE_STRIP, 0, vin.numItems);




dom.window.onload = proc (e: dom.Event) =
    var canvas = dom.document.getElementById("glcanvas").Canvas;
    initGL(canvas);
    initShaders();
    initBuffers();

    gl.clearColor(0.0, 0.0, 0.0, 1.0);

    drawScene();