WebGL基础(一)

1、H5里引入了canvas画布标签,canvas提供了一些简单的绘图函数,用来绘制点、线面、矩形,canvas的使用如下:

  

以上定义了一个宽高各为400的画布,下面绘制一个简单的矩形

function main() {  
  // Retrieve  element
 //获取canvas 元素
  var canvas = document.getElementById('example');  
  if (!canvas) { 
    console.log('Failed to retrieve the  element');
    return false; 
  } 

  // 获取二维图形上下文
  var ctx = canvas.getContext('2d');

  // 绘制蓝色矩形
  ctx.fillStyle = 'rgba(0, 0, 255, 1.0)'; //设置填充颜色(r,g,b,a:透明度)
  ctx.fillRect(120, 10, 150, 150);        // 填充颜色填充矩形(前两个参数为左上顶点坐标,后两个为矩形的宽和高)
}

由于canvas 支持二三维绘图,但是它不提供绘图方法,而是由一种上下文的机制进行绘图canvas.getContext(),函数参数指定类型,是二维还是三维。
2、WebGL绘制上下文

function main() {
  // Retrieve  element
  var canvas = document.getElementById('webgl');

  // Get the rendering context for WebGL
  var gl = getWebGLContext(canvas);
  if (!gl) {
    console.log('Failed to get the rendering context for WebGL');
    return;
  }

  // 设置清空颜色
  gl.clearColor(0.0, 0.0, 0.0, 1.0);

  // 清空画布
  gl.clear(gl.COLOR_BUFFER_BIT);
}

WebGL使用getWebGLContext(canvas)获取上下文,那么程序最后为什么会清除颜色呢?这是因为一旦指定了颜色,颜色就会贮存在WebGL中,为了不影响下一次的使用,所以要清除颜色,清除缓冲缓冲种类有以下几种:

参数 名称
gl.COLOR_BUFFER_BIT 颜色缓存
gl.DEPTH_BUFFER_BIT 指定深度缓存
gl.STENCIL_BUFFER_BIT 指定模板缓存

3、着色器
着色器是以字符串的形式嵌入到JS中去,主要分为两种:
1、顶点着色器。描述点的特性(位置、颜色)
2、片元着色器。进行逐片元处理过程,可理解为像素。
画点程序如下:

// 顶点着色程序
var VSHADER_SOURCE = 
  'void main() {\n' +
  '  gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n' + // Set the vertex coordinates of the point
  '  gl_PointSize = 10.0;\n' +                    // Set the point size
  '}\n';

// 片元着色程序
var FSHADER_SOURCE =
  'void main() {\n' +
  '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' + // Set the point color
  '}\n';

function main() {
  // Retrieve  element
  var canvas = document.getElementById('webgl');

  // Get the rendering context for WebGL
  var gl = getWebGLContext(canvas);
  if (!gl) {
    console.log('Failed to get the rendering context for WebGL');
    return;
  }

  // Initialize shaders
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log('Failed to intialize shaders.');
    return;
  }

  // Specify the color for clearing 
  gl.clearColor(0.0, 0.0, 0.0, 1.0);

  // Clear 
  gl.clear(gl.COLOR_BUFFER_BIT);

  // Draw a point
  gl.drawArrays(gl.POINTS, 0, 1);
}

着色器程序使用类似于Cde OpenGL ES着色器语言,处理流程如下;

WebGL基础(一)_第1张图片
Paste_Image.png

3、将位置信息从JS中传给顶点着色器,有两种方法:attribute和uniform变量,attribute传输的是那些与顶点相关的数据,uniform传输的是对于所有顶点都相同的数据。

// HelloPint2.js (c) 2012 matsuda
// Vertex shader program
var VSHADER_SOURCE = 
  'attribute vec4 a_Position;\n' + // attribute variable
  'void main() {\n' +
  '  gl_Position = a_Position;\n' +
  '  gl_PointSize = 10.0;\n' +
  '}\n'; 

// Fragment shader program
var FSHADER_SOURCE = 
  'void main() {\n' +
  '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
  '}\n';

function main() {
  // Retrieve  element
  var canvas = document.getElementById('webgl');

  // Get the rendering context for WebGL
  var gl = getWebGLContext(canvas);
  if (!gl) {
    console.log('Failed to get the rendering context for WebGL');
    return;
  }

  // Initialize shaders
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log('Failed to intialize shaders.');
    return;
  }

  // 获取attribute变量的位置
  var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  if (a_Position < 0) {
    console.log('Failed to get the storage location of a_Position');
    return;
  }

  // 将顶点位置传输给着色器
  gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);

  // Specify the color for clearing 
  gl.clearColor(0.0, 0.0, 0.0, 1.0);

  // Clear 
  gl.clear(gl.COLOR_BUFFER_BIT);
    
  // Draw
  gl.drawArrays(gl.POINTS, 0, 1);
}

gl.vertexAttrib1f(localtion, v0);
gl.vertexAttrib2f(localtion, v0,v1);
gl.vertexAttrib3f(localtion, v0,v1,v2);
gl.vertexAttrib4f(localtion, v0,v1,v2,v3);
同理给变点的颜色一个例子如下:

// ColoredPoint.js (c) 2012 matsuda
// Vertex shader program
var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'void main() {\n' +
  '  gl_Position = a_Position;\n' +
  '  gl_PointSize = 10.0;\n' +
  '}\n';

// Fragment shader program
var FSHADER_SOURCE =
  'precision mediump float;\n' +
  'uniform vec4 u_FragColor;\n' +  // uniform変数
  'void main() {\n' +
  '  gl_FragColor = u_FragColor;\n' +
  '}\n';

function main() {
  // Retrieve  element
  var canvas = document.getElementById('webgl');

  // Get the rendering context for WebGL
  var gl = getWebGLContext(canvas);
  if (!gl) {
    console.log('Failed to get the rendering context for WebGL');
    return;
  }

  // Initialize shaders
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log('Failed to intialize shaders.');
    return;
  }

  // // Get the storage location of a_Position
  var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  if (a_Position < 0) {
    console.log('Failed to get the storage location of a_Position');
    return;
  }

  // Get the storage location of u_FragColor
  var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
  if (!u_FragColor) {
    console.log('Failed to get the storage location of u_FragColor');
    return;
  }

  // Register function (event handler) to be called on a mouse press
  canvas.onmousedown = function(ev){ click(ev, gl, canvas, a_Position, u_FragColor) };

  // Specify the color for clearing 
  gl.clearColor(0.0, 0.0, 0.0, 1.0);

  // Clear 
  gl.clear(gl.COLOR_BUFFER_BIT);
}

var g_points = [];  // The array for the position of a mouse press
var g_colors = [];  // The array to store the color of a point
function click(ev, gl, canvas, a_Position, u_FragColor) {
  var x = ev.clientX; // x coordinate of a mouse pointer
  var y = ev.clientY; // y coordinate of a mouse pointer
  var rect = ev.target.getBoundingClientRect();

  x = ((x - rect.left) - canvas.width/2)/(canvas.width/2);
  y = (canvas.height/2 - (y - rect.top))/(canvas.height/2);

  // Store the coordinates to g_points array
  g_points.push([x, y]);
  // Store the coordinates to g_points array
  if (x >= 0.0 && y >= 0.0) {      // First quadrant
    g_colors.push([1.0, 0.0, 0.0, 1.0]);  // Red
  } else if (x < 0.0 && y < 0.0) { // Third quadrant
    g_colors.push([0.0, 1.0, 0.0, 1.0]);  // Green
  } else {                         // Others
    g_colors.push([1.0, 1.0, 1.0, 1.0]);  // White
  }

  // Clear 
  gl.clear(gl.COLOR_BUFFER_BIT);

  var len = g_points.length;
  for(var i = 0; i < len; i++) {
    var xy = g_points[i];
    var rgba = g_colors[i];

    // Pass the position of a point to a_Position variable
    gl.vertexAttrib3f(a_Position, xy[0], xy[1], 0.0);
    // Pass the color of a point to u_FragColor variable
    gl.uniform4f(u_FragColor, rgba[0], rgba[1], rgba[2], rgba[3]);
    // Draw
    gl.drawArrays(gl.POINTS, 0, 1);
  }
}

使用了uniform4f函数,同时注册了一个onmousedown事件,具体看代码。

你可能感兴趣的:(WebGL基础(一))