1、opengl、webgl、threejs、opengl es2.0之间的关系?
WebGL标准来自OpenGL ES 2.0,OpenGL ES 2.0的标准来自纯可编程管线技术,把原来很多API给裁剪掉了。
OpenGL ES 2.0:OpenGL是针对PC端的桌面的,OpenGL ES是针对嵌入式移动设备,在OpenGL的基础上裁剪了一些固定管线技术与使用起来很慢的API,采用了可编程管线的技术。
2、查询WebGl相关API的网址?
https://www.khronos.org/webgl/

3、使用齐次坐标的好处?
其一是区分向量和点,向量加0,点加1;
其二是易于进行仿射变化(平移、缩放、旋转)
4、尝试编写第一个WebGL程序?了解在显卡上是如何完成绘制一个三角形
4.1 顶点着色器与片元着色器
(1)在顶点着色器上定义一个attribute类型的三维变量v3Position,用来存储需要绘制的顶点的三维坐标,在main函数中加1.0参数为表示成齐次坐标的形式,赋值给内置变量gl_Position.
(2)在片元着色器里,定义一个四维变量表示rgba的值,赋值给内置变量gl_FragColor,这里填充的颜色是对三角形内的元素进行填充的颜色。片元即像素,对像素进行着色。
<!--
这里的代码是在显卡上执行的,现在都还只是一些字符串,需要在后面进行编译、连接
定义一个attribute类型的三维变量(顶点的xyz坐标)
在main函数中,转成4维的赋值给内置变量gl_Position
-->
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 v3Position;
void main(void) {
gl_Position = vec4(v3Position, 1.0);
}
</script>
<!-- 2、片元着色器:给绘制结果填充颜色 -->
<script id="shader-fs" type="x-shader/x-fragment">
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
</script>
4.2 程序具体执行流程描述
(1)定义一个canvas画布,id是mycanvas。资源加载完之后,会调用Init()函数进行初始化操作。
<body onload="Init()">
<canvas id="mycanvas" style="border:1px solid red;" width="600" height="450"></canvas>
</body>
(2)Init函数的内部
具体解释可以看代码的内部注释。
大致的流程是:
1)先获取界面上的mycanvas对象,调用getContext函数创建webgl上下文对象,设置坐标原点位置与窗口大小。
2)在前面有写到的顶点着色器与片元着色器的代码,其实相当于是一些字符串,需要在Init函数的内部做创建对象等一系列操作。
3)创建。创建顶点着。色器对象与片元着色器对象,创建调用的函数是createShader(),传入参数是需要创建的Shader类型。
4)填充。新创建的着色器对象需要指定它的源代码(用上面定义的着色器字符串填充),调用的方法是shaderSource(),参数包括新创建的着色器对象与定义一个获取着色器字符串的函数。
5)编译。对这两个填充完毕的对象进行编译,编译的结果是生成在显卡上执行的汇编代码。调用的函数是compileShader(),参数是需要编译的对象。
6)编译出错处理。
7)创建程序.exe对象。调用createProgram()函数生成一个program程序对象。
8)生成exe可执行代码。将program对象与着色器的汇编对象代码关联,形成exe可执行代码。调用attachShader()函数,传入的参数是program对象与shader对象进行关联。
9)链接。调用linkProgram()进行链接,形成真正意义上的程序。
10)使用。使用可执行程序,useProgram()。
11)传入真正的三角形数据,进行绘制。
12)声明三角形的顶点坐标位置数组,以屏幕中心为原点
13)显卡中创建一个缓冲区对象,并绑定为数组缓存类型,把jsArrayData中的数据传到显存中。调用函数createBuffer()创建缓冲区,bindBuffer()函数绑定缓冲区类型,bufferData()函数传入真实数据。
14)调用clearColor()设置缓冲区的背景颜色与透明度,clear()函数真正将颜色缓冲区设置成上面设置的颜色。
15)通过bindAttribLocation()函数,给shader-vs里的attribute类型的v3Position变量赋值,后面可以通过给v3PositionIndex赋值从而给v3Position赋值。
16)启用v3PositionIndex变量。调用enableVertexAttribArray()函数,将已经与shader的变量绑定的变量启动。
17)调用drawArrays()将三角形画出来,参数是从第几个元素开始,绘制几个。
function Init() {
var canvas = document.getElementById('mycanvas');
//创建opengl上下文,返回一个opengl对象
webgl = canvas.getContext("webgl");
//
webgl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight);
//2.1 创建顶点着色器、片元着色器对象
vertexShaderObject = webgl.createShader(webgl.VERTEX_SHADER);
fragmentShaderObject = webgl.createShader(webgl.FRAGMENT_SHADER);
//2.2 给这两个对象填充东西
webgl.shaderSource(vertexShaderObject, getShaderSource("shader-vs"));
webgl.shaderSource(fragmentShaderObject, getShaderSource("shader-fs"));
//2.3 编译这两个对象,编译的结果是生成显卡可执行的汇编代码
webgl.compileShader(vertexShaderObject);
webgl.compileShader(fragmentShaderObject);
//2.4 编译有错
if (!webgl.getShaderParameter(vertexShaderObject, webgl.COMPILE_STATUS)) {
alert("error,vectorshader");
console.log(webgl.getShaderInfoLog(vertexShaderObject));
return;
}
if (!webgl.getShaderParameter(fragmentShaderObject, webgl.COMPILE_STATUS)) {
alert("error,FRAGshader");
console.log(webgl.getShaderInfoLog(fragmentShaderObject));
return;
}
//2.5 创建一个程序.exe
programObject = webgl.createProgram();
//2.6 program与shader链接起来形成可执行代码
webgl.attachShader(programObject, vertexShaderObject);
webgl.attachShader(programObject, fragmentShaderObject);
//2.7 webgl绑定顶点数据,给shader-vs里的attribute类型的v3Position变量赋值
// 通过给v3PositionIndex赋值从而给v3Position赋值
webgl.bindAttribLocation(programObject, v3PositionIndex, 'v3Position');
//2.8 链接 成为真正意义上的程序
webgl.linkProgram(programObject);
//2.9 使用可执行程序
webgl.useProgram(programObject);
//3.1 声明三角形的顶点坐标位置数组,以屏幕中心为原点
var jsArrayData = [
0.0,
1.0,
0.0, -1.0, -1.0,
0.0,
1.0, -1.0,
0.0
]
//3.2 在显卡中创建一个缓冲区对象,并绑定为数组缓存类型,把jsArrayData中的数据传到显存中
triangleBuffer = webgl.createBuffer();
webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData), webgl.STATIC_DRAW);
//相当于画刷颜色用float,其他颜色用123/255表示
webgl.clearColor(0.0, 0.0, 0.0, 1.0);
//将画布设置成上述颜色,帧缓冲区就是相当于一张二维图片
//此处是颜色缓冲区
webgl.clear(webgl.COLOR_BUFFER_BIT);
//4.1 使用triangleBuffer缓冲区
webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);
//4.2 启用v3PositionIndex变量
webgl.enableVertexAttribArray(v3PositionIndex);
//4.3 给该变量赋具体的值,返回指针指向jsArrayData数组。
// 给什么变量,赋值维数,赋值类型,是否规格化,变量之间的间隔字节数,从缓冲区第几个元素开始取值
webgl.vertexAttribPointer(v3PositionIndex, 3, webgl.FLOAT, false, 0, 0);
//4.4 从第几个元素开始,绘制几个
webgl.drawArrays(webgl.TRIANGLES, 0, 3);
}