This JavaScript program demonstrates how to draw a circle composed of points in WebGL.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>XoaX.net's WebGL</title> </head> <style> canvas { border: 1px solid black; width: 800px; height: 600px } </style> <body> <canvas id="idCanvas"></canvas> <script type="text/javascript" src="DrawACircleOfDots.js"></script> </body> </html>
'use strict'; // Vertex Shader const ksVertexShader = ` attribute float faPointIndex; uniform float fPointCount; uniform vec2 daCanvasSize; #define TWOPI radians(360.0) void main() { float fFraction = faPointIndex/fPointCount; float fAngle = TWOPI*fFraction; float dRadius = 0.90; vec2 daPosition = vec2(cos(fAngle), sin(fAngle)) * dRadius; float fAspectRatio = daCanvasSize.y / daCanvasSize.x; vec2 daScale = vec2(fAspectRatio, 1); gl_Position = vec4(daPosition * daScale, 0, 1); gl_PointSize = 5.0; } `; // Fragment Shader const ksFragmentShader = ` precision mediump float; void main() { gl_FragColor = vec4(1, .5, 0.0, 1); } `; const kgqGL = document.querySelector('#idCanvas').getContext('webgl'); // Compile and link the program function CreateTheProgram() { const saShaderType = ['VERTEX_SHADER', 'FRAGMENT_SHADER']; const saShaderCode = [ksVertexShader, ksFragmentShader]; var qaCompiledShaders = []; // Compile the shaders for (var i = 0; i < 2; ++i) { // This is the equivalent of kgqGL.VERTEX_SHADER or kgqGL.FRAGMENT_SHADER const kqShader = kgqGL.createShader(kgqGL[saShaderType[i]]); kgqGL.shaderSource(kqShader, saShaderCode[i]); kgqGL.compileShader(kqShader); const bCompiled = kgqGL.getShaderParameter(kqShader, kgqGL.COMPILE_STATUS); if (!bCompiled) { const ksErrorLog = kgqGL.getShaderInfoLog(kqShader); console.log('There was an error compiling \'' + kqShader + '\':' + ksErrorLog + `\n` + shaderSource.split('\n').map((l,i) => `${i + 1}: ${l}`).join('\n')); kgqGL.deleteShader(kqShader); return null; } qaCompiledShaders[i] = kqShader; } // Link the program const kqProgram = kgqGL.createProgram(); kgqGL.attachShader(kqProgram, qaCompiledShaders[0]); kgqGL.attachShader(kqProgram, qaCompiledShaders[1]); kgqGL.linkProgram(kqProgram); const kbLinked = kgqGL.getProgramParameter(kqProgram, kgqGL.LINK_STATUS); if (!kbLinked) { const ksErrorLog = kgqGL.getProgramInfoLog(kqProgram); console.log('Error in program linking:' + ksErrorLog); kgqGL.deleteProgram(kqProgram); return null; } return kqProgram; } const kgProgram = CreateTheProgram(); // Vertex shader variables const kqaPointIndicesLocation = kgqGL.getAttribLocation(kgProgram, 'faPointIndex'); const kqPointCountLocation = kgqGL.getUniformLocation(kgProgram, 'fPointCount'); const kqCanvasSizeLocation = kgqGL.getUniformLocation(kgProgram, 'daCanvasSize'); kgqGL.useProgram(kgProgram); // Make a buffer const kiPointCount = 100; const kiaPointIndices = new Float32Array(kiPointCount); kiaPointIndices.forEach((v, i) => { kiaPointIndices[i] = i; }); const kqIndexBuffer = kgqGL.createBuffer(); kgqGL.bindBuffer(kgqGL.ARRAY_BUFFER, kqIndexBuffer); kgqGL.bufferData(kgqGL.ARRAY_BUFFER, kiaPointIndices, kgqGL.STATIC_DRAW); kgqGL.enableVertexAttribArray(kqaPointIndicesLocation); // Get the data out of the buffer const kiEntriesPerIteration = 1; // 1 components per iteration const kiEntryType = kgqGL.FLOAT; // the data is 32bit floats const kbNormalize = false; // Do not alter the data to normalize it. const kiStride = 0; // Entries between iterations const kiOffset = 0; // Entry index at the beginning of the buffer kgqGL.vertexAttribPointer(kqaPointIndicesLocation, kiEntriesPerIteration, kiEntryType, kbNormalize, kiStride, kiOffset); kgqGL.canvas.width = kgqGL.canvas.clientWidth; kgqGL.canvas.height = kgqGL.canvas.clientHeight; kgqGL.viewport(0, 0, kgqGL.canvas.width, kgqGL.canvas.height); // Pass values to the shader kgqGL.uniform1f(kqPointCountLocation, kiPointCount); kgqGL.uniform2f(kqCanvasSizeLocation, kgqGL.canvas.width, kgqGL.canvas.height); const kiArrayOffset = 0; kgqGL.drawArrays(kgqGL.POINTS, kiArrayOffset, kiPointCount);
© 20072025 XoaX.net LLC. All rights reserved.