<html>
<head>
<meta charset="utf-8" />
<title>webgl</title>
<script type="text/javascript" src="lib/webgl-utils.js"></script>
<script type="text/javascript" src="lib/webgl-debug.js"></script>
<script type="text/javascript" src="lib/cuon-utils.js"></script>
</head>
<body onload="initWebGL()">
<canvas id="webgl" width="400" height="400"></canvas>
<script type="text/javascript">
/**
* 多边形和多点的区别主要有2点
* 1、不用指定点的大小 即 gl_PointSize 不用指定
* 2、绘制时参数不是 gl.POINTS 而已 例如 gl.TRIANGLES
* 绘制的类型有
* gl.POINTS 多点 gl.LINES 两两线段 gl.LINE_STRIP 线段 gl.LINE_LOOP 闭合线段
* gl.TRANGLES 三角形(012,345,678...) gl.TRIANGLE_STRIP 连续三角形(012,123,234...) gl.TRIANGLE_FAN 连续三角形(012,023,034...)
* WebGL 只能绘制三种图形:点 线 三角形,其他复杂图形都是基于它们来绘制的
*/
function initWebGL(){
// 获得canvas元素
var canvas = document.getElementById('webgl')
// 获取绘图上下文
var gl = getWebGLContext(canvas);
if(!gl){
throw new Error("浏览器不支持");
}else{
// 顶点着色器 坐标采用变量a_position赋值
// 注意 attribute 初始化应该在main函数外
var VSHADER_SOURCE =
'uniform mat4 u_rotate_matrix;\n' +
'uniform mat4 u_trans_matrix;\n' +
'uniform mat4 u_zoom_matrix;\n' +
'attribute vec4 a_position;\n' +
'void main() {\n' +
// 绘制图形pointsize可有可无,绘制点时必需
// 'gl_PointSize = 10.0;\n' +
// 矩阵转换
// 注意:<新坐标> = <矩阵> * <旧坐标>; 位置不能调换
'gl_Position = u_rotate_matrix * a_position;\n' +
'gl_Position = u_trans_matrix * gl_Position;\n' +
'gl_Position = u_zoom_matrix * gl_Position;\n' +
'}\n';
// 片元着色器 指定颜色
// 这里用uniform 变量设置颜色,
// 这里的precision mediump float; 表示精度限定,不能少,否则异常
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_fragColor;\n' +
'void main(){\n' +
'gl_FragColor = u_fragColor;\n' +
'}\n';
// 初始化着色器
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE )) {
throw new Error("着色器初始化异常");
};
// 利用缓冲对象一次性传输多个顶点数据
// 这里传入了8个坐标 4个点
var n = initVertexBuffers(gl, 'a_position', [-0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5], 2);
if(n < 0){
throw new Error("创建缓冲对象异常!");
}
// 设置颜色变量
setColorLocation(gl, 'u_fragColor', 0.0, 1.0, 1.0, 1.0);
// 设置矩阵变换
setMatrixRotateLocation(gl, 'u_rotate_matrix', 35.0);
setMatrixTransLocation(gl, 'u_trans_matrix', 0.25, 0.25, 0.0);
setMatrixZoomLocation(gl, 'u_zoom_matrix', 0.5, 0.5, 1.0);
// 设置背景色
gl.clearColor(0.5, 0.5, 0.5, 1);
// 初始化绘图区
gl.clear(gl.COLOR_BUFFER_BIT);
// 绘制图形
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
}
}
// 初始化顶点缓冲区
// target 表示webgl上下文 variableName为顶点位置变量名 array 为坐标数组 size为每个坐标占的数值个数
function initVertexBuffers(target, variableName, array, size){
// 初始化着色器后,获取变量的存储位置
var a_position = target.getAttribLocation(target.program, variableName);
// 地址小于0 表示变量不存在或者异常
if(a_position < 0){
throw new Error("获取顶点变量存储异常!");
}
// Float32Array 为类型化数组,只能存放一种类型的数据,不支持push()、pop()方法,只能new关键字创建
var vertices = new Float32Array(array);
var n = array.length/size;
// 1 、创建缓冲对象
var vertexBuffer = target.createBuffer();
if(!vertexBuffer){
return -1;
}
// 2、 缓冲对象绑定到目标 target.ARRAY_BUFFER 表示缓冲对象中包含定点的数据
target.bindBuffer(target.ARRAY_BUFFER, vertexBuffer);
// 3、 向目标写入数据
target.bufferData(target.ARRAY_BUFFER, vertices, target.STATIC_DRAW);
// 4、 将缓冲对象分配给变量
// 参数2 表示每个顶点包含2个数值
target.vertexAttribPointer(a_position, size, target.FLOAT, false, 0, 0);
///5、 连接变量与缓冲对象(使用了缓冲对象就不能用vertexAttrib3f方法显式的赋值了)
target.enableVertexAttribArray(a_position);
// 返回坐标数
return n;
}
// 设置颜色变量
// target 表示webgl上下文 variableName为平移变量名 r g b a 表示颜色
function setColorLocation(target, variableName, r, g, b, a){
// 获取颜色变量的地址
var u_fragColor = target.getUniformLocation(target.program, variableName);
// 与attribute变量不同 uniform变量不存在或异常时返回null
if (!u_fragColor) {
throw new Error("获取颜色变量存储异常!");
};
// 设置颜色变量
target.uniform4f(u_fragColor, r, g, b, a);
}
// 设置平移变量
// target 表示webgl上下文 variableName为平移变量名 x y z 为平移距离
function setTransLocation(target, variableName, x, y, z){
// 获取平移变量的地址
var u_translation = target.getUniformLocation(target.program, variableName);
// 与attribute变量不同 uniform变量不存在或异常时返回null
if (!u_translation) {
throw new Error("获取平移变量存储异常!");
};
// 设置平移变量 x 轴平移 0.25 y 轴 平移 0.25
// 这里四个参数表示齐次坐标,分别和原来的坐标相加,w要和之前的1.0相加,所以w坐标设置为0.0
target.uniform4f(u_translation, x, y, z, 0.0);
}
// 设置旋转变量
// target 表示webgl上下文 variableName为旋转变量名 angle为旋转角度
function setRotateLocation(target, variableName, angle){
// 获取变量地址
var location = target.getUniformLocation(target.program, variableName);
if(!location){
throw new Error("获取旋转变量存储位置异常!");
}
// 计算旋转角度
// 转换为弧度制
var radian = Math.PI * angle / 180.0;
var cosB = Math.cos(radian);
var sinB = Math.sin(radian);
// 传递变量值
target.uniform2f(location, cosB, sinB);
}
// 设置旋转矩阵变量
// target 表示webgl上下文 variableName为旋转变量名 angle为旋转角度
function setMatrixRotateLocation(target, variableName, angle){
// 获取变量地址
var location = target.getUniformLocation(target.program, variableName);
if(!location){
throw new Error("获取矩阵变量存储位置异常!");
}
// 计算旋转角度
// 转换为弧度制
var radian = Math.PI * angle / 180.0;
var cosB = Math.cos(radian);
var sinB = Math.sin(radian);
// WebGL与OpenGL一样是按列主序读取数组中的矩阵
var arr_matrix = new Float32Array([
cosB, sinB, 0.0, 0.0,
-sinB, cosB, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
]);
// 传递变量值
target.uniformMatrix4fv(location, false, arr_matrix);
}
// 设置平移矩阵变量
// target 表示webgl上下文 variableName为旋转变量名 x, y, z 为 平移距离
function setMatrixTransLocation(target, variableName, x, y, z){
// 获取变量地址
var location = target.getUniformLocation(target.program, variableName);
if(!location){
throw new Error("获取矩阵变量存储位置异常!");
}
// WebGL与OpenGL一样是按列主序读取数组中的矩阵
var arr_matrix = new Float32Array([
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, z, 1.0
]);
// 传递变量值
target.uni
评论1
最新资源