在前一篇WebGL的基础上修改了代码,使之符合WebGL2规范。
<html>
<head>
<!--
Date: 2018-3-16
Author: kagula
Prologue:
WebGL2的例子
Prologue:
Description:
網上太多WebGL資料,爲了避免混肴,我們在原本WebGL的基礎上瞭解WebGL2, 這裏還是用兩個三角形拼出一個彩色的正方形.
Original:
[1]https://my.oschina.net/thesadabc/blog/1592866
測試環境
[1]Chrome 65.0.3325.162
[2]nginx 1.12.2
-->
<title>第一个Webgl2程序</title>
<meta charset="utf-8">
<!-- gl-matrix version 2.4.0 from http://glmatrix.net/ -->
<script type="text/javascript" src="/gl-matrix-min.js"></script>
<script type="text/javascript" src="/kagula/webgl_helper.js"></script>
</head>
<body>
<canvas id="glCanvas" width="640" height="480"></canvas>
</body>
</html>
<script>
main();
//弄4个顶点, 4個顔色, 用来演示render流程!
function initBuffers(gl) {
// Create a buffer for the square's positions.
const positionBuffer = gl.createBuffer();
// Select the positionBuffer as the one to apply buffer
// operations to from here out.
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Now create an array of positions for the square.
const positions = [
1.0, 1.0,
-1.0, 1.0,
1.0, -1.0,
-1.0, -1.0,
];
// Now pass the list of positions into WebGL to build the
// shape. We do this by creating a Float32Array from the
// JavaScript array, then use it to fill the current buffer.
gl.bufferData(gl.ARRAY_BUFFER,
new Float32Array(positions),
gl.STATIC_DRAW);
//給每個頂點弄一個顔色
const colors = [
1.0, 1.0, 1.0, 1.0, // white
1.0, 0.0, 0.0, 1.0, // red
0.0, 1.0, 0.0, 1.0, // green
0.0, 0.0, 1.0, 1.0, // blue
];
const colorBuffer = gl.createBuffer();//创建gl缓存,但是不指定缓存类型.
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);//指定olorBuffer的类型为gl.ARRAY_BUFFER
//缓冲区对象中的数据只指定1次,但是常常使用。这种模式下,OpenGL会将数据放在能够快速渲染的地方。
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
return {
position: positionBuffer,
color: colorBuffer,
};
}
function main() {
//选择器的使用
//http://www.runoob.com/jsref/met-document-queryselector.html
const canvas = document.querySelector("#glCanvas");
// Initialize the GL context
//為了获取WebGL2上下文,getContext方法传入的参数是"webgl2",而不是"webgl".
const gl = canvas.getContext("webgl2");
// Only continue if WebGL is available and working
if (!gl) {
alert("Unable to initialize WebGL. Your browser or machine may not support it.");
return;
}
//OpenGL ES 3.0 不支持多维数组
//對傳入的數組大小有限制
console.log("gl.MAX_VERTEX_UNIFORM_VECTORS=" + gl.MAX_VERTEX_UNIFORM_VECTORS + ", gl.MAX_FRAGMENT_UNIFORM_VECTORS=" + gl.MAX_FRAGMENT_UNIFORM_VECTORS);
// Vertex shader program
//WebGL2的着色器语言支持原本WebGL1的GLSL 100 ,同时也支持GLSL 300 es
//要使用GLSL 300 es,需要在着色器代码中显示声明
//版本声明的代码需要在顶点着色器和片元着色器中同时指定, 版本声明的代码必须严格在第一行.
//在webgl 1.0中 attribute表示输入,varying表示輸入輸出.
//現在要改爲用/in out标记輸入,输出.
const vsSource = `#version 300 es
in vec4 aVertexPosition;
in vec4 aVertexColor;//从外部拿到颜色,不做任何处理,丢给vColor.
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
//从aVertexColor拿到的颜色直接给vColor,
//由vColor传给Fragment Shader.
out lowp vec4 vColor;
void main() {
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
vColor = aVertexColor;//什么都不做,只是为了把从外部得到的color传递给Fragment Shader.
}
`;
// Fragment shader, 相当于pixel shader
//varying被in代替
//在GLSL 100 中,我们通过给内置变量gl_FragColor赋值来设置片元的输出颜色
//而在GLSL 300 es中,需要自己定义一个输出颜色的变量,并在main函数中设置颜色值
const fsSource = `#version 300 es
precision highp float;//必須要為float類型指定精度
in lowp vec4 vColor;//从vertex shader得到的颜色放在这里。
out vec4 myOutputColor;
void main() {
myOutputColor = vColor;
}
`;
//装配shader到shaderProgram中去
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
//为了让外部的数据能统一传到shanderProgram中去,新建programInfo对象。
//vertexPosition => aVertexPosition位置
//projectionMatrix => uProjectionMatrix位置
//modelViewMatrix => uModelViewMatrix位置
//...
const programInfo = {
program: shaderProgram,
attribLocations: {
vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'),
},
uniformLocations: {
projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'),
modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'),
},
};
//initBuffers(gl)返回要render的vertex.
drawScene(gl, programInfo, initBuffers(gl));
}//main
</script>