初始化
-
获取 webGL
const canvas = document.getElementById("webgl") as HTMLCanvasElement; const gl = canvas.getContext("webgl"); if (!gl) return alert("浏览器不支持webgl"); gl.canvas.width = canvas.clientWidth; gl.canvas.height = canvas.clientHeight;
-
定义着色器(顶点着色器、片段着色器)
const vsSource = ` attribute vec4 aVertexPosition; void main() { gl_Position = aVertexPosition; } `; // 顶点着色器数据源 const fsSource = ` precision mediump float; void main() { gl_FragColor = vec4(1, 0, 0.5, 1); } `; // 片段着色器数据源 const vertexShader = gl.createShader(gl.VERTEX_SHADER); // 创建顶点着色器对象 gl.shaderSource(vertexShader, vsSource); // 提供数据源 gl.compileShader(vertexShader); // 编译着色器 const vertexSuccess = gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS); // 获取着色器编译状态 const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); // 创建顶点着色器对象 gl.shaderSource(fragmentShader, fsSource); // 提供数据源 gl.compileShader(fragmentShader); // 编译着色器 const fragmentSuccess = gl.getShaderParameter( fragmentShader, gl.COMPILE_STATUS ); // 获取着色器编译状态
-
定义着色程序
const program = gl.createProgram(); gl.attachShader(program, vertexShader); // 绑定顶点着色器 gl.attachShader(program, fragmentShader); // 绑定片段着色器 gl.linkProgram(program); const programSuccess = gl.getProgramParameter(program, gl.LINK_STATUS);
-
获取属性位置
const positionAttributeLocation = gl.getAttribLocation( program, "aVertexPosition" ); const positionBuffer = gl.createBuffer(); // 创建缓冲区 gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); // 绑定位置信息缓冲 // 三个二维点坐标 const positions = [0, 0, 0, 0.5, 0.7, 0]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
渲染
WebGL 重置画布尺寸
- 画布包括两个尺寸
- drawingbuffer 的尺寸, 这个表示画布中有多少个像素
- 画布显示的尺寸,一半由 css 决定
-
设置画布的 drawingbuffer 尺寸方法
- html 方法设置
<canvas id="c" width="400" height="300"></canvas>
- js 方法
<canvas id="c"></canvas> <script> var canvas = document.querySelector("#c"); canvas.width = 400; canvas.height = 300; function resize(canvas) { // 获取浏览器中画布的显示尺寸 var displayWidth = canvas.clientWidth; var displayHeight = canvas.clientHeight; // 检尺寸是否相同 if (canvas.width != displayWidth || canvas.height != displayHeight) { // 设置为相同的尺寸 canvas.width = displayWidth; canvas.height = displayHeight; } } </script>
-
设置画布尺寸后,调整视域 (gl.viewport)
function drawScene() { resize(gl.canvas); gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); }
-
高清显示(HD-DPI)或者苹果叫它“Retina Display”的特性
function resize(gl) { var realToCSSPixels = window.devicePixelRatio; // 获取浏览器显示的画布的CSS像素值 // 然后计算出设备像素设置drawingbuffer var displayWidth = Math.floor(gl.canvas.clientWidth * realToCSSPixels); var displayHeight = Math.floor(gl.canvas.clientHeight * realToCSSPixels); // 检查画布尺寸是否相同 if ( gl.canvas.width !== displayWidth || gl.canvas.height !== displayHeight ) { // 设置为相同的尺寸 gl.canvas.width = displayWidth; gl.canvas.height = displayHeight; } }