1、H5里引入了canvas画布标签,canvas提供了一些简单的绘图函数,用来绘制点、线面、矩形,canvas的使用如下:
<canvas id="webgl" width="400" height="400">
以上定义了一个宽高各为400的画布,下面绘制一个简单的矩形
function main() {
// Retrieve <canvas> element
//获取canvas 元素
var canvas = document.getElementById('example');
if (!canvas) {
console.log('Failed to retrieve the <canvas> 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 <canvas> 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 <canvas> 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 <canvas>
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// Clear <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw a point
gl.drawArrays(gl.POINTS, 0, 1);
}
着色器程序使用类似于Cde OpenGL ES着色器语言,处理流程如下;
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 <canvas> 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 <canvas>
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// Clear <canvas>
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 <canvas> 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 <canvas>
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// Clear <canvas>
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 <canvas>
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事件,具体看代码。