var squareRotation =0.0;main();//// Start here//functionmain(){const canvas = document.querySelector('#glcanvas');const gl = canvas.getContext('webgl');// If we don't have a GL context, give up nowif(!gl){alert('Unable to initialize WebGL. Your browser or machine may not support it.');return;}// Vertex shader programconst vsSource =`
attribute vec4 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
varying lowp vec4 vColor;
void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
vColor = aVertexColor;
}
`;// Fragment shader programconst fsSource =`
varying lowp vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
`;// Initialize a shader program; this is where all the lighting// for the vertices and so forth is established.const shaderProgram =initShaderProgram(gl, vsSource, fsSource);// Collect all the info needed to use the shader program.// Look up which attributes our shader program is using// for aVertexPosition, aVevrtexColor and also// look up uniform locations.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'),},};// Here's where we call the routine that builds all the// objects we'll be drawing.const buffers =initBuffers(gl);var then =0;// Draw the scene repeatedlyfunctionrender(now){
now *=0.001;// convert to secondsconst deltaTime = now - then;
then = now;drawScene(gl, programInfo, buffers, deltaTime);requestAnimationFrame(render);}requestAnimationFrame(render);}//// initBuffers//// Initialize the buffers we'll need. For this demo, we just// have one object -- a simple two-dimensional square.//functioninitBuffers(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 =[0,0.5,-0.5,-0.5,0.5,-0.5];// 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,newFloat32Array(positions), gl.STATIC_DRAW);// Now set up the colors for the verticesconst colors =[1.0,0.0,0.0,1.0,// red1.0,0.0,0.0,1.0,// red1.0,0.0,0.0,1.0,// red1.0,0.0,0.0,1.0,// red];const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER,newFloat32Array(colors), gl.STATIC_DRAW);return{
position: positionBuffer,
color: colorBuffer,};}//// Draw the scene.//functiondrawScene(gl, programInfo, buffers, deltaTime){
gl.clearColor(0.0,0.0,0.0,1.0);// Clear to black, fully opaque
gl.clearDepth(1.0);// Clear everything
gl.enable(gl.DEPTH_TEST);// Enable depth testing
gl.depthFunc(gl.LEQUAL);// Near things obscure far things// Clear the canvas before we start drawing on it.
gl.clear(gl.COLOR_BUFFER_BIT| gl.DEPTH_BUFFER_BIT);// Create a perspective matrix, a special matrix that is// used to simulate the distortion of perspective in a camera.// Our field of view is 45 degrees, with a width/height// ratio that matches the display size of the canvas// and we only want to see objects between 0.1 units// and 100 units away from the camera.const fieldOfView =45* Math.PI/180;// in radiansconst aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;const zNear =0.1;const zFar =100.0;const projectionMatrix = mat4.create();// note: glmatrix.js always has the first argument// as the destination to receive the result.
mat4.perspective(projectionMatrix,
fieldOfView,
aspect,
zNear,
zFar);// Set the drawing position to the "identity" point, which is// the center of the scene.const modelViewMatrix = mat4.create();// Now move the drawing position a bit to where we want to// start drawing the square.
mat4.translate(modelViewMatrix,// destination matrix
modelViewMatrix,// matrix to translate[-0.0,0.0,-6.0]);// amount to translate
mat4.rotate(modelViewMatrix,// destination matrix
modelViewMatrix,// matrix to rotate
squareRotation,// amount to rotate in radians[0,0,1]);// axis to rotate around// Tell WebGL how to pull out the positions from the position// buffer into the vertexPosition attribute{const numComponents =2;const type = gl.FLOAT;const normalize =false;const stride =0;const offset =0;
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
gl.vertexAttribPointer(
programInfo.attribLocations.vertexPosition,
numComponents,
type,
normalize,
stride,
offset);
gl.enableVertexAttribArray(
programInfo.attribLocations.vertexPosition);}// Tell WebGL how to pull out the colors from the color buffer// into the vertexColor attribute.{const numComponents =4;const type = gl.FLOAT;const normalize =false;const stride =0;const offset =0;
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.color);
gl.vertexAttribPointer(
programInfo.attribLocations.vertexColor,
numComponents,
type,
normalize,
stride,
offset);
gl.enableVertexAttribArray(
programInfo.attribLocations.vertexColor);}// Tell WebGL to use our program when drawing
gl.useProgram(programInfo.program);// Set the shader uniforms
gl.uniformMatrix4fv(
programInfo.uniformLocations.projectionMatrix,false,
projectionMatrix);
gl.uniformMatrix4fv(
programInfo.uniformLocations.modelViewMatrix,false,
modelViewMatrix);{const offset =0;const vertexCount =4;
gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount);}// Update the rotation for the next draw
squareRotation += deltaTime;}//// Initialize a shader program, so WebGL knows how to draw our data//functioninitShaderProgram(gl, vsSource, fsSource){const vertexShader =loadShader(gl, gl.VERTEX_SHADER, vsSource);const fragmentShader =loadShader(gl, gl.FRAGMENT_SHADER, fsSource);// Create the shader programconst shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);// If creating the shader program failed, alertif(!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)){alert('Unable to initialize the shader program: '+ gl.getProgramInfoLog(shaderProgram));returnnull;}return shaderProgram;}//// creates a shader of the given type, uploads the source and// compiles it.//functionloadShader(gl, type, source){const shader = gl.createShader(type);// Send the source to the shader object
gl.shaderSource(shader, source);// Compile the shader program
gl.compileShader(shader);// See if it compiled successfullyif(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)){alert('An error occurred compiling the shaders: '+ gl.getShaderInfoLog(shader));
gl.deleteShader(shader);returnnull;}return shader;}