OpenGL Point Functionality in WebGL

In OpenGL, you can draw define such points:

glBegin(GL_POINTS); for(float theta=0, radius=60.0; radius>1.0; theta+=0.1, radius-=0.3){ glColor3f(radius/60.0,0.3,1-(radius/60.0)); glVertex2i(200+radius*cos(theta),200+radius*sin(theta)); } glEnd(); 

How do you perform the same functionality in WebGL?

+4
source share
2 answers

The code you wrote really does nothing but define some points. To do this, in WebGL, you could do this as follows:

 var colors = []; var verts = []; var theta=0 for(var radius=60.0; radius>1.0; radius-=0.3) { colors.push(radius/60.0, 0.3, 1-(radius/60.0)); verts.push(200+radius*Math.cos(theta),200+radius*Math.sin(theta)); theta+=0.1; } var numPoints = colors.length / 3; 

This will create 2 JavaScript arrays. Then you will need to put them in WebGLBuffers

 var colorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var vertBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW); 

After that, although you need to write a shader and configure it. Shaders are a huge topic. For your specific data, I assume that these shaders will do

Vertex shader

 uniform mat4 u_matrix; attribute vec4 a_vertex; attribute vec4 a_color; varying vec4 v_color; void main() { // Set the size of the point gl_PointSize = 3.0; // multiply each vertex by a matrix. gl_Position = u_matrix * a_vertex; // pass the color to the fragment shader v_color = a_color; } 

Fragment shader

 precision mediump float; varying vec4 v_color; void main() { gl_FragColor = v_color; } 

Then you need to initialize the shaders and parameters. I assume that I put shaders in script tags with the identifiers "vshader" and "fshader" and used this template code to load them.

 var program = createProgramFromScriptTags(gl, "vshader", "fshader"); gl.useProgram(program); // look up the locations for the inputs to our shaders. var u_matLoc = gl.getUniformLocation(program, "u_matrix"); var colorLoc = gl.getAttribLocation(program, "a_color"); var vertLoc = gl.getAttribLocation(program, "a_vertex"); // Set the matrix to some that makes 1 unit 1 pixel. gl.uniformMatrix4fv(u_matLoc, false, [ 2 / width, 0, 0, 0, 0, 2 / height, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]); // Tell the shader how to get data out of the buffers. gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.vertexAttribPointer(colorLoc, 3, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(colorLoc); gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer); gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(vertLoc); 

and finally draw the points

 gl.drawArrays(gl.POINTS, 0, numPoints); 

Here is a fragment

 var canvas = document.getElementById("c"); var gl = canvas.getContext("webgl"); if (!gl) { alert("no WebGL"); //return; } var colors = []; var verts = []; var theta=0 for(var radius=160.0; radius>1.0; radius-=0.3) { colors.push(radius/160.0, 0.3, 1-(radius/160.0)); verts.push(radius*Math.cos(theta),radius*Math.sin(theta)); theta+=0.1; } var numPoints = colors.length / 3; var colorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); var vertBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW); var program = twgl.createProgramFromScripts(gl, ["vshader", "fshader"]); gl.useProgram(program); // look up the locations for the inputs to our shaders. var u_matLoc = gl.getUniformLocation(program, "u_matrix"); var colorLoc = gl.getAttribLocation(program, "a_color"); var vertLoc = gl.getAttribLocation(program, "a_vertex"); function draw() { gl.clear(gl.COLOR_BUFFER_BIT); gl.clearColor(1.0, 1.0, 1.0, 1.0); // Set the matrix to some that makes 1 unit 1 pixel. gl.uniformMatrix4fv(u_matLoc, false, [ 2 / canvas.width, 0, 0, 0, 0, -2 / canvas.height, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.vertexAttribPointer(colorLoc, 3, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(colorLoc); gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer); gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(vertLoc); gl.drawArrays(gl.POINTS, 0, numPoints); requestAnimationFrame(draw, canvas); } draw(); 
 canvas { border: 1px solid black; } 
 <script src="https://twgljs.org/dist/3.x/twgl.min.js"></script> <script id="vshader" type="whatever"> uniform mat4 u_matrix; attribute vec4 a_vertex; attribute vec4 a_color; varying vec4 v_color; void main() { // Set the size of the point gl_PointSize = length(a_vertex) * 0.1; // multiply each vertex by a matrix. gl_Position = u_matrix * a_vertex; // pass the color to the fragment shader v_color = a_color; } </script> <script id="fshader" type="whatever"> precision mediump float; varying vec4 v_color; void main() { gl_FragColor = v_color; } </script> <canvas id="c" width="400" height="400"></canvas> 

You may find these WebGL guides useful .

+13
source

WebGL is based on OpenGL ES 2.0 (see here ), which has dropped support for instant mode.

This specification describes the additional rendering context and support objects for the HTML 5 canvas element [CANVAS]. This context allows rendering using the API, which is closely related to the OpenGL ES 2.0 API.

You need to use vertex buffers to store vertex data. See here 1 for a good explanation of how everything works in saved mode. And there for a small little example to get you started.

1 : Kudos to the one who posted it here.

+2
source

All Articles