WebGL绘制五角星(多边形)
1. 初始化WebGL context
/**
* Initialize the context of WebGL
*/
function initWebGL() {
const canvas = document.querySelector('#glcanvas');
const gl = canvas.getContext('webgl');
// If we don't have WebGL, print tip
if (!gl) {
console.log('%c%s', 'color: blue', 'Unable to initialize the WebGL, your browser or machine may not support it.');
return;
}
return gl;
}
2. 初始化WebGLShader着色器对象
/**
* Initialize the shader
*/
function initShader(gl, type, source) {
// Create the shader
const shader = gl.createShader(type);
// Send the source to shader
gl.shaderSource(shader, source);
// Compile the shader
gl.compileShader(shader);
// See if compiling shader falied, print tip
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.log('%c%s', 'color: blue', 'An error occurred compiling the shader: ' + gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
3. 初始化WebGLProgram对象
/**
* Initialize the shader program
*/
function initShaderProgram(gl, vsSource, fsSource) {
// Create the shader program
const shaderProgram = gl.createProgram();
// Get shaders
const vertexShader = initShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = initShader(gl, gl.FRAGMENT_SHADER, fsSource);
// Attach shaders to shader program
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
// Tell WebGL the shader program, that is we use to draw
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
console.log('%c%s', 'color: blue', 'An error occurred linking program: ' + gl.getProgramInfoLog(shaderProgram));
return null;
}
return shaderProgram;
}
4. 初始化保存顶点数据的WebGLBuffer对象(顶点位置数据作为参数传入)
/**
* Initialize the buffer
*/
function initBuffer(gl, verticePositions) {
// Create buffer
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticePositions), gl.STATIC_DRAW);
return positionBuffer;
}
5. 绘制图元
/**
* Draw the scene
*/
function drawScene(gl, programInfo) {
// Clear to black, fully opaque
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.useProgram(programInfo.shaderProgram);
gl.bindBuffer(gl.ARRAY_BUFFER, programInfo.positionBuffer);
gl.enableVertexAttribArray(programInfo.vertexPositionBound);
gl.vertexAttribPointer(
programInfo.vertexPositionBound,
3,
gl.FLOAT,
false,
0,
0
);
gl.drawArrays(gl.LINE_LOOP, 0, 10); // line
// gl.drawArrays(gl.TRIANGLE_FAN, 0, 10); // triangle
}
6. 入口函数
main();
/**
* Sample's entry
*/
function main() {
// Shader sources
const vertexShaderSource = `
attribute vec4 vertexPosition;
void main(void) {
gl_Position = vertexPosition;
}
`;
const fragmentShaderSource = `
void main(void) {
gl_FragColor = vec4(0.94, 0.61, 0.62, 1.0);
}
`;
const { PI, sin, cos, tan } = Math;
// Vertices positions
const verticesPositions = [
-0.3 * tan(36 / 180 * PI), 0.3, 0.0,
0.0, 1.0, 0.0,
0.3 * tan(36 / 180 * PI), 0.3, 0.0,
cos(18 / 180 * PI), sin(18 / 180 * PI), 0.0,
0.3 / cos(36 / 180 * PI) * cos(18 / 180 * PI), -0.3 / cos(36 / 180 * PI) * sin(18 / 180 * PI), 0.0,
cos(54 / 180 * PI), -sin(54 / 180 * PI), 0.0,
0.0, -0.3 / cos(36 / 180 * PI), 0.0,
-cos(54 / 180 * PI), -sin(54 / 180 * PI), 0.0,
-0.3 / cos(36 / 180 * PI) * cos(18 / 180 * PI), -0.3 / cos(36 / 180 * PI) * sin(18 / 180 * PI), 0.0,
-cos(18 / 180 * PI), sin(18 / 180 * PI), 0.0,
];
// Get context of WebGL
const gl = initWebGL();
// Collect info needed to use to draw
const shaderProgram = initShaderProgram(gl, vertexShaderSource, fragmentShaderSource);
const positionBuffer = initBuffer(gl, verticesPositions);
const vertexPositionBound = gl.getAttribLocation(shaderProgram, 'vertexPosition');
const programInfo = {
shaderProgram,
positionBuffer,
vertexPositionBound
}
// Draw scene
drawScene(gl, programInfo);
}
7. 总结
绘制图元的基本步骤1-6。想画出一个好看的五角星需要精心的计算,重拾了三角函数
…后面还会有矩阵计算
。今天好奇看了一下,WebGL
有113个函数,有的函数形参多达9个,没细数有多少个常量…多coding吧…