<commit_before><!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
  <meta name="viewport" content="initial-scale=1,user-scalable=no,maximum-scale=1"/>
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="phet-sim-level" content="production">
  <title>Simulation Test WebGL</title>

  <!-- jQuery and LoDash are dependencies -->
  <script src="../../assert/js/assert.js"></script>
  <script src="../../sherpa/jquery-2.1.0.min.js"></script>
  <script src="../../sherpa/lodash-2.4.1.min.js"></script>
  <script src="../../sherpa/has.js"></script>
  <script src="../../sherpa/stats-r12.js"></script>

  <!-- Parse query parameters, so we can easily subset the tests.-->
  <script src="../../phetcommon/js/util/query-parameters.js"></script>

  <script type="text/javascript">
    window.assertions.enableAssert();
  </script>

  <!-- Our code, in either the concatenated 'with comments' version or the minified version -->
  <script data-main="../js/config.js" src="../../sherpa/require-2.1.11.js"></script>

</head>

<body>
<canvas id="canvas" style="position: absolute;top:0px; left:0px"></canvas>

<script>

  var stats = new Stats();
  stats.setMode( 0 ); // 0: fps, 1: ms

  // align top-left
  stats.domElement.style.position = 'absolute';
  stats.domElement.style.left = '0px';
  stats.domElement.style.top = '0px';

  document.body.appendChild( stats.domElement );

  var main = function() {

    var canvas = document.getElementById( "canvas" );

    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    // Code inspired by http://www.webglacademy.com/#1
    var gl;
    try {
      gl = canvas.getContext( "experimental-webgl", {antialias: true} ); // TODO: {antialias:true?}
    }
    catch( e ) {
      return false;
    }

    var vertexShaderSource = [
      'attribute vec2 aPosition;',
      'attribute vec4 aVertexColor;',
      'varying vec4 vColor;',
      'void main(void) { ',//pre-built function
      '  gl_Position = vec4(aPosition, 0., 1.); ',//0. is the z, and 1 is w
      '  vColor = aVertexColor;',
      '}'
    ].join( '\n' );

    var fragmentShaderSource = [
      'precision mediump float;',
      'varying vec4 vColor;',
      'void main(void) {',
      '  gl_FragColor = vColor;',
      '}'].join( '\n' );

    var toShader = function( source, type, typeString ) {
      var shader = gl.createShader( type );
      gl.shaderSource( shader, source );
      gl.compileShader( shader );
      if ( !gl.getShaderParameter( shader, gl.COMPILE_STATUS ) ) {
        console.log( "ERROR IN " + typeString + " SHADER : " + gl.getShaderInfoLog( shader ) );
        return false;
      }
      return shader;
    };

    var vertexShader = toShader( vertexShaderSource, gl.VERTEX_SHADER, "VERTEX" );
    var fragmentShader = toShader( fragmentShaderSource, gl.FRAGMENT_SHADER, "FRAGMENT" );

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

    gl.linkProgram( shaderProgram );

    var positionAttribLocation = gl.getAttribLocation( shaderProgram, 'aPosition' );
    var colorAttributeLocation = gl.getAttribLocation( shaderProgram, 'aVertexColor' );

    gl.enableVertexAttribArray( positionAttribLocation );
    gl.enableVertexAttribArray( colorAttributeLocation );

    gl.useProgram( shaderProgram );

    var vertexArray = [];

    var numMovingTriangles = 5000;
    for ( var i = 0; i < numMovingTriangles; i++ ) {
      var x = Math.random() * 2 - 1;
      var y = Math.random() * 2 - 1;
      vertexArray.push( x, y );
      vertexArray.push( x, y + 0.1 );
      vertexArray.push( x + 0.1, y );
    }

    var originalArray = [];
    for ( var i = 0; i < vertexArray.length; i++ ) {
      var element = vertexArray[i];
      originalArray.push( element );
    }

    var vertexBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( vertexArray ), gl.STATIC_DRAW );

    var colors = [];
    var colorChoices = [
      [1, 0, 0, 1],
      [0, 1, 0, 1],
      [0, 0, 1, 1]
    ];
    for ( i = 0; i < numMovingTriangles; i++ ) {
      var color = colorChoices[i % colorChoices.length];
      for ( var k = 0; k < 3; k++ ) {
        for ( var m = 0; m < color.length; m++ ) {
          colors.push( color[m] );
        }
      }
    }

    // Set up different colors for each triangle
    var vertexColorBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vertexColorBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( colors ), gl.STATIC_DRAW );

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

    var animate = function() {
      window.requestAnimationFrame( animate );

      stats.begin();

      gl.viewport( 0.0, 0.0, canvas.width, canvas.height );
      gl.clear( gl.COLOR_BUFFER_BIT );

      gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );

      // Update the vertex locations
      //see http://stackoverflow.com/questions/5497722/how-can-i-animate-an-object-in-webgl-modify-specific-vertices-not-full-transfor
      gl.bufferSubData( gl.ARRAY_BUFFER, 0, new Float32Array( vertexArray ) );
      gl.vertexAttribPointer( positionAttribLocation, 2, gl.FLOAT, false, 0, 0 );

      // Send the colors to the GPU
      gl.bindBuffer( gl.ARRAY_BUFFER, vertexColorBuffer );
      gl.vertexAttribPointer( colorAttributeLocation, 4, gl.FLOAT, false, 0, 0 );

      // Show one oscillation per second so it is easy to count time
      var x = 0.2 * Math.cos( Date.now() / 1000 * 2 * Math.PI );
      for ( var i = 0; i < numMovingTriangles; i++ ) {
        vertexArray[0 + i * 6] = originalArray[0 + i * 6] + x;
        vertexArray[2 + i * 6] = originalArray[2 + i * 6] + x;
        vertexArray[4 + i * 6] = originalArray[4 + i * 6] + x;
      }

      gl.drawArrays( gl.TRIANGLES, 0, vertexArray.length / 2 );
      gl.flush();<commit_msg>Abstracted out TrianglesGeometry for managing vertices<commit_after><!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
  <meta name="viewport" content="initial-scale=1,user-scalable=no,maximum-scale=1"/>
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="phet-sim-level" content="production">
  <title>Simulation Test WebGL</title>

  <!-- jQuery and LoDash are dependencies -->
  <script src="../../assert/js/assert.js"></script>
  <script src="../../sherpa/jquery-2.1.0.min.js"></script>
  <script src="../../sherpa/lodash-2.4.1.min.js"></script>
  <script src="../../sherpa/has.js"></script>
  <script src="../../sherpa/stats-r12.js"></script>

  <!-- Parse query parameters, so we can easily subset the tests.-->
  <script src="../../phetcommon/js/util/query-parameters.js"></script>

  <script type="text/javascript">
    window.assertions.enableAssert();
  </script>

  <!-- Our code, in either the concatenated 'with comments' version or the minified version -->
  <script data-main="../js/config.js" src="../../sherpa/require-2.1.11.js"></script>

</head>

<body>
<canvas id="canvas" style="position: absolute;top:0px; left:0px"></canvas>

<script>

  var stats = new Stats();
  stats.setMode( 0 ); // 0: fps, 1: ms

  // align top-left
  stats.domElement.style.position = 'absolute';
  stats.domElement.style.left = '0px';
  stats.domElement.style.top = '0px';

  document.body.appendChild( stats.domElement );

  var main = function() {

    var canvas = document.getElementById( "canvas" );

    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    // Code inspired by http://www.webglacademy.com/#1
    var gl;
    try {
      gl = canvas.getContext( "experimental-webgl", {antialias: true} ); // TODO: {antialias:true?}
    }
    catch( e ) {
      return false;
    }

    var vertexShaderSource = [
      'attribute vec2 aPosition;',
      'attribute vec4 aVertexColor;',
      'varying vec4 vColor;',
      'void main(void) { ',//pre-built function
      '  gl_Position = vec4(aPosition, 0., 1.); ',//0. is the z, and 1 is w
      '  vColor = aVertexColor;',
      '}'
    ].join( '\n' );

    var fragmentShaderSource = [
      'precision mediump float;',
      'varying vec4 vColor;',
      'void main(void) {',
      '  gl_FragColor = vColor;',
      '}'].join( '\n' );

    var toShader = function( source, type, typeString ) {
      var shader = gl.createShader( type );
      gl.shaderSource( shader, source );
      gl.compileShader( shader );
      if ( !gl.getShaderParameter( shader, gl.COMPILE_STATUS ) ) {
        console.log( "ERROR IN " + typeString + " SHADER : " + gl.getShaderInfoLog( shader ) );
        return false;
      }
      return shader;
    };

    var vertexShader = toShader( vertexShaderSource, gl.VERTEX_SHADER, "VERTEX" );
    var fragmentShader = toShader( fragmentShaderSource, gl.FRAGMENT_SHADER, "FRAGMENT" );

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

    gl.linkProgram( shaderProgram );

    var positionAttribLocation = gl.getAttribLocation( shaderProgram, 'aPosition' );
    var colorAttributeLocation = gl.getAttribLocation( shaderProgram, 'aVertexColor' );

    gl.enableVertexAttribArray( positionAttribLocation );
    gl.enableVertexAttribArray( colorAttributeLocation );

    gl.useProgram( shaderProgram );

    // Manages the indices within a single array, so that disjoint geometries can be represented easily here.
    // TODO: Compare this same idea to triangle strips
    var TrianglesGeometry = function() {
      var trianglesGeometry = this;
      this.vertexArray = [];
      this.colors = [];

      this.createRectangle = function( x, y, width, height, r, g, b, a ) {
        var index = this.vertexArray.length;
        trianglesGeometry.vertexArray.push(
            // Top left
            x, y,
            (x + width), y,
            x, y + height,

            // Bottom right
            (x + width), y + height,
            (x + width), y,
            x, y + height
        );

        // Add the same color for all vertices (solid fill rectangle).
        // TODO: some way to reduce this amount of elements!
        trianglesGeometry.colors.push(
            r, g, b, a,
            r, g, b, a,
            r, g, b, a,
            r, g, b, a,
            r, g, b, a,
            r, g, b, a
        );

        //Track the index so it can delete itself, update itself, etc.
        return {
          initialState: {x: x, y: y, width: width, height: height},
          index: index,
          setXWidth: function( x, width ) {
            trianglesGeometry.vertexArray[index] = x;
            trianglesGeometry.vertexArray[index + 2] = x + width;
            trianglesGeometry.vertexArray[index + 4] = x;
            trianglesGeometry.vertexArray[index + 6] = x + width;
            trianglesGeometry.vertexArray[index + 8] = x + width;
            trianglesGeometry.vertexArray[index + 10] = x;
          },
          setRect: function( x, y, width, height ) {

            trianglesGeometry.vertexArray[index] = x;
            trianglesGeometry.vertexArray[index + 1] = y;

            trianglesGeometry.vertexArray[index + 2] = x + width;
            trianglesGeometry.vertexArray[index + 3] = y;

            trianglesGeometry.vertexArray[index + 4] = x;
            trianglesGeometry.vertexArray[index + 5] = y + height;

            trianglesGeometry.vertexArray[index + 6] = x + width;
            trianglesGeometry.vertexArray[index + 7] = y + height;

            trianglesGeometry.vertexArray[index + 8] = x + width;
            trianglesGeometry.vertexArray[index + 9] = y;

            trianglesGeometry.vertexArray[index + 10] = x;
            trianglesGeometry.vertexArray[index + 11] = y + height;
          }
        };
      };
    };

    var trianglesGeometry = new TrianglesGeometry();
    var vertexArray = trianglesGeometry.vertexArray;
    var colors = trianglesGeometry.colors;

    var rectangles = [];

    var numRectangles = 2500;
    for ( var i = 0; i < numRectangles; i++ ) {
      var x = (Math.random() * 2 - 1) * 0.9;
      var y = (Math.random() * 2 - 1) * 0.9;
      rectangles.push( trianglesGeometry.createRectangle( x, y, 0.02, 0.02, x, y, 1, 1 ) );
    }

    var vertexBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( vertexArray ), gl.DYNAMIC_DRAW );

    // Set up different colors for each triangle
    var vertexColorBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vertexColorBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( colors ), gl.STATIC_DRAW );

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

    var animate = function() {
      window.requestAnimationFrame( animate );

      stats.begin();

      gl.viewport( 0.0, 0.0, canvas.width, canvas.height );
      gl.clear( gl.COLOR_BUFFER_BIT );

      gl.bindBuffer( gl.ARRAY_BUFFER, vertexBuffer );

      // Update the vertex locations
      //see http://stackoverflow.com/questions/5497722/how-can-i-animate-an-object-in-webgl-modify-specific-vertices-not-full-transfor
      gl.bufferSubData( gl.ARRAY_BUFFER, 0, new Float32Array( vertexArray ) );
      gl.vertexAttribPointer( positionAttribLocation, 2, gl.FLOAT, false, 0, 0 );

      // Send the colors to the GPU
      gl.bindBuffer( gl.ARRAY_BUFFER, vertexColorBuffer );
      gl.vertexAttribPointer( colorAttributeLocation, 4, gl.FLOAT, false, 0, 0 );

      // Show one oscillation per second so it is easy to count time
      var x = 0.2 * Math.cos( Date.now() / 1000 * 2 * Math.PI );
      for ( var i = 0; i < rectangles.length; i++ ) {
        var rectangle = rectangles[i];
        rectangle.setXWidth( rectangle.initialState.x + x, rectangle.initialState.width );
      }

      gl.drawArrays( gl.TRIANGLES, 0, vertexArray.length / 2 );
      gl.flush();
{'fraction_non_alphanumeric': 0.14557503206498504, 'fraction_numerical': 0.01638877012968505, 'mean_word_length': 2.62474173553719, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3809260', 'n_tokens_mistral': 4646, 'n_tokens_neox': 4373, 'n_words': 1091}