<!DOCTYPE html>
<html>
  <head>
    <style type="text/css" media="screen">
      canvas {
        margin: 20px;
        width: 200px;
        height: 200px;
        padding: 0 20px;
        border: 2px solid black;
        -webkit-box-reflect: below 20px;
        outline: 10px solid transparent; /* affects layer sizes */
      }
    
    </style>
    <script id="vertexShader" type="x-shader/x-vertex">
      attribute vec4 vPosition;

      void main() {
         gl_Position = vPosition;
      }
    </script>

    <script id="fragmentShader" type="x-shader/x-fragment">
      void main() {
          gl_FragColor = vec4(0.0, 0.5, 0.0, 1.0);
      }
    </script>
    <script>
    var gl = null;

    function draw()
    {
        var vertices = [ 0.0, 0.8, 0.0,
                        -0.8, -0.8, 0.0,
                         0.8, -0.8, 0.0 ]; 
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); // Load the vertex data
        gl.enableVertexAttribArray(0); 
        gl.drawArrays(gl.TRIANGLES, 0, 3); 
        gl.flush();
    }

    function getFragmentShader()
    {
        var shaderNode = document.getElementById("fragmentShader"); // fragmentShader has been defined at the top
        var shaderSource = getShaderSource(shaderNode);

        var shader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(shader, shaderSource);
        gl.compileShader(shader);

        return shader;
    }

    function getShaderSource(shaderNode)
    {
        var shaderSource = "";
        var node = shaderNode.firstChild;
        while (node) {
            if (node.nodeType == 3) // Node.TEXT_NODE
                shaderSource += node.textContent;
            node = node.nextSibling;
        }

        return shaderSource;
    }

    function getVertexShader()
    {
        var shaderNode = document.getElementById("vertexShader");
        var shaderSource = getShaderSource(shaderNode);

        var shader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(shader, shaderSource);
        gl.compileShader(shader);

        return shader;
    }

    function initialize()
    {
        var theCanvas = document.getElementById("canvas");
        gl = theCanvas.getContext("experimental-webgl");

        var vertexShader = getVertexShader();
        var fragmentShader = getFragmentShader();

        var shaderProgram = gl.createProgram();
        gl.attachShader(shaderProgram, vertexShader);
        gl.attachShader(shaderProgram, fragmentShader);
        gl.bindAttribLocation(shaderProgram, 0, "vPosition"); // vPosition has been defined at the top
        gl.linkProgram(shaderProgram);

        gl.useProgram(shaderProgram);

         var buffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    }

    function drawCanvas()
    {
      initialize();
      draw();
    }
    </script>
  </head>
  <body onload="drawCanvas()">
   
    <p>You should see a green triangle and its reflection.</p>
    <canvas id="canvas" style="left: 20px" width="200" height="200"></canvas>

  </body>
</html>
