Assignment 4

Friday!

New time for Wednesday Lecture

1. Initialize WebGL

2. Shaders

3. Create Geometry

4. Connect Shader with Geometry

5. Draw!

1 Frame

multiple Frames

animate()

1 Rectangle

multiple Rectangles

createRectangle()

createRectangle()

change Offsets!

multiple Rectangles

<html>
  <head>
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
    <title>Default WebGL!</title>
    <style>
      html, body { 
        background-color:#000;
        margin: 0;
        padding: 0;
        height: 100%;
        overflow: hidden !important;  
      }

      #c {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <script type="text/javascript" src="https://cs460.org/js/glmatrix.js"></script>
  
  <script id="vertexshader" type="glsl">
    attribute vec3 position;

    uniform vec3 offset;

    void main(void) {
    
      gl_PointSize = 10.;

      vec3 final_position = position;
      final_position.x += offset.x;
      final_position.y += offset.y;
      final_position.z += offset.z;

      gl_Position = vec4( final_position, 1.);
    
    }
  </script>
  
  <script id="fragmentshader" type="glsl">
    precision mediump float;

    uniform vec4 color;

    void main(void) {

      //gl_FragColor = vec4(1., 1., 1., 1.);
      gl_FragColor = color;

    }
  </script>

  <script>

    // VARIABLE DECLARATIONS

    window.onload = function() {
      

      //************************************************************//
      //
      // INITIALIZE WEBGL
      //
      c = document.getElementById( 'c' ); // grab canvas to JS
      c.width = window.innerWidth;
      c.height = window.innerHeight;

      gl = c.getContext( 'webgl' );
      gl.viewport(0, 0, c.width, c.height);

      //************************************************************//
      //
      // SHADERS
      //

      // compile vertex shader
      v_shader = gl.createShader( gl.VERTEX_SHADER );

      gl.shaderSource( v_shader, document.getElementById('vertexshader').innerText );
      gl.compileShader( v_shader );

      if(!gl.getShaderParameter( v_shader, gl.COMPILE_STATUS )) {

        // shader compilation failed
        console.log( gl.getShaderInfoLog( v_shader ) );

      }


      // compile fragment shader
      f_shader = gl.createShader( gl.FRAGMENT_SHADER );

      gl.shaderSource( f_shader, document.getElementById('fragmentshader').innerText );
      gl.compileShader( f_shader );

      if(!gl.getShaderParameter( f_shader, gl.COMPILE_STATUS )) {

        // shader compilation failed
        console.log( gl.getShaderInfoLog( f_shader ) );

      }

      // attach and link the shaders
      shaderprogram = gl.createProgram();
      gl.attachShader( shaderprogram, v_shader );
      gl.attachShader( shaderprogram, f_shader );

      gl.linkProgram( shaderprogram );

      gl.useProgram( shaderprogram );


      console.log('after compilation');


      rectangles = [];
      rectangles.push( createRectangle(new Float32Array([0., 0., 0.]), new Float32Array([1., 1., 1., 1.])) ); // 
      
      rectangles.push( createRectangle(new Float32Array([.2, .2, 0.]), new Float32Array([1., 0., 0., 1.])) );
      
      rectangles.push( createRectangle(new Float32Array([-.2, -.2, 0.]), new Float32Array([1., 1., 0., 1.])) );



      //************************************************************//
      //
      // CONNECT SHADER WITH GEOMETRY
      //
    
      gl.clearColor( 0., 0., 0., 0. );
      gl.clear( gl.COLOR_BUFFER_BIT );

      for( var r =0; r<rectangles.length; r++) {

        var current_buffers = rectangles[r];

        var current_v_buffer = current_buffers[0];
        var current_i_buffer = current_buffers[1];
        var current_offset = current_buffers[2];
        var current_color = current_buffers[3];

        // vertex shader connection
        gl.bindBuffer( gl.ARRAY_BUFFER, current_v_buffer );

        gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, current_i_buffer );

        a_position = gl.getAttribLocation( shaderprogram, 'position' );

        gl.vertexAttribPointer( a_position, 3, gl.FLOAT, false, 0, 0);

        gl.enableVertexAttribArray( a_position );

        u_offset = gl.getUniformLocation( shaderprogram, 'offset' );

        gl.uniform3fv( u_offset, current_offset); // this one matches the vec3 uniform in the vertex shader

        // fragment shader connection
        u_color = gl.getUniformLocation( shaderprogram, 'color' );

        gl.uniform4fv( u_color, current_color); // R G B A color, passed in as a float vector4
          // this matches our vec4 uniform in the shader





        //************************************************************//
        //
        // DRAW!
        //


        // gl.drawArrays( gl.TRIANGLES, 0, vertices.length / 3 );
        gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0); // INDEXED GEOMETRY

      }

    };

    function createRectangle(offset, color) {

      //************************************************************//
      //
      // CREATE GEOMETRY
      //
      vertices = new Float32Array( [
                                     -0.5,  0.5, 0.0, // V0
                                     -0.5, -0.5, 0.0, // V1, V4
                                      0.5,  0.5, 0.0, // V2, V3

                                      // 0.5,  0.5, 0.0, // V3
                                     // -0.5, -0.5, 0.0, // V4
                                      0.5, -0.5, 0.0  // V5
                                    ] );

      v_buffer = gl.createBuffer(); // create
      gl.bindBuffer( gl.ARRAY_BUFFER, v_buffer ); // bind
      gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW ); // put data in
      gl.bindBuffer( gl.ARRAY_BUFFER, null ); // unbind

      // now use indices
      indices = new Uint8Array( [ 0, 1, 2, // Triangle 1
                                  2, 1, 3] ); // Triangle 2

      i_buffer = gl.createBuffer(); // create
      gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, i_buffer ); //bind
      gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW ); // put data in
      gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, null ); // unbind

      return [v_buffer, i_buffer, offset, color];

    };


  </script>
  <body>
    <canvas id="c"></canvas>
  </body>
</html>

createRectangle()

return [ v_buffer, i_buffer, color, offset ];

a =

var current_v_buffer = a[0];
var current_i_buffer = a[1];
var current_color = a[2];
var current_offset = a[3];

createRectangle()

return [ v_buffer, i_buffer, color, offset ];

a =

objects = [];

objects.push( a );
objects.push( b );

createRectangle()

b =

return [ v_buffer, i_buffer, color, offset ];

[ a, b ]

[ a, b ]

[ [ v_buffer, i_buffer, color, offset ], [ v_buffer, i_buffer, color, offset ] ]

objects =

objects =

function animate() {
  
  //
  // all kinds of stuff
  //
  
  
  requestAnimationFrame( animate );
  
}

[ a, b ]

[ [ v_buffer, i_buffer, color, offset ], [ v_buffer, i_buffer, color, offset ] ]

objects =

objects =

function animate() {
  
  for(var o = 0; o < objects.length; o++) {
  
    var current_object = objects[o];
    
  }
  
  requestAnimationFrame( animate );
  
}

[ [ v_buffer, i_buffer, color, offset ], [ v_buffer, i_buffer, color, offset ] ]

objects =

function animate() {
  
  for(var o = 0; o < objects.length; o++) {
  
    var current_object = objects[o];
    
    var current_v_buffer = current_object[0];
    var current_i_buffer = current_object[1];
    var current_color = current_object[2];
    var current_offset = current_object[3];
    
    // pass data to shader
    
    gl.drawElements( gl.TRIANGLES ... )
    
  }
  
  requestAnimationFrame( animate );
  
}

Transformation

Transformations

Translate

Rotate

Scale

Lecture 12

By Daniel Haehn

Lecture 12

Slides for CS460 Computer Graphics at UMass Boston. See https://cs460.org!

  • 461