WebGL JavaScript

Animating a Point in Orbit

This JavaScript program demonstrates how to animate a point orbiting around another point in WebGL program.

AnimatePointOrbit.html

<!DOCTYPE html>
<html>
  <head>
    <title>XoaX.net's WebGL</title>

    <script  id="idVertexShader" type="c">
      attribute vec4 av4Vertex;
      attribute vec4 av4Color;
      varying vec4 vv4Color;
      void main() {
        gl_Position = av4Vertex;
        gl_PointSize = 10.0;
        vv4Color = av4Color;
      }
    </script>

    <script  id="idFragmantShader" type="c">
      precision mediump float;
      varying vec4 vv4Color;
      void main() {
        gl_FragColor = vv4Color;
      }
    </script>

    <script type="text/javascript">
    function CreateProgramAndContext(qInstanceWebGL) {
      // Get the WebGL Context
      var qCanvas = document.querySelector("#"+qInstanceWebGL.msCanvasID);
      qInstanceWebGL.mqGL = qCanvas.getContext("webgl");
      var qGL = qInstanceWebGL.mqGL;

      // Compile the vertex shader
      var sVertexShaderCode = document.querySelector("#"+qInstanceWebGL.msVertexShaderID).text;
      var qVertexShader = qGL.createShader(qGL.VERTEX_SHADER);
      qGL.shaderSource(qVertexShader, sVertexShaderCode);
      qGL.compileShader(qVertexShader);

      // Compile the fragment shader
      var sFragmentShaderCode = document.querySelector("#"+qInstanceWebGL.msFragmentShaderID).text;
      var qFragmentShader = qGL.createShader(qGL.FRAGMENT_SHADER);
      qGL.shaderSource(qFragmentShader, sFragmentShaderCode);
      qGL.compileShader(qFragmentShader);

      // Compile and link the program
      qInstanceWebGL.mqProgram = qGL.createProgram();
      qGL.attachShader(qInstanceWebGL.mqProgram, qVertexShader);
      qGL.attachShader(qInstanceWebGL.mqProgram, qFragmentShader);
      qGL.linkProgram(qInstanceWebGL.mqProgram);
      qGL.useProgram(qInstanceWebGL.mqProgram);
    }
    function CreateBuffers(qInstanceWebGL) {
      var qGL = qInstanceWebGL.mqGL;
      var qVerticesBuffer = qGL.createBuffer();
      qGL.bindBuffer(qGL.ARRAY_BUFFER, qVerticesBuffer);
      qGL.bufferData(qGL.ARRAY_BUFFER, qInstanceWebGL.mfaTransformedVertices, qGL.STATIC_DRAW);

      // uiVertexIndex is the index of the attritube.
      var uiVertexIndex = qGL.getAttribLocation(qInstanceWebGL.mqProgram, 'av4Vertex');
      // uiComponentsPerVertex specifies how many components are used per vertex
      var uiComponentsPerVertex = 4;
      // eDataType specifies the data type of each component of the array: gl.BYTE: [-128, 127], gl.UNSIGNED_BYTE: [0, 255],
      // gl.SHORT: [-32768, 32767], gl.UNSIGNED_SHORT: [0,65535], gl.FLOAT: 32 bit IEEE float
      // For WebGL 2, we have gl.HALF_FLOAT: 16 bit IEEE float, gl.INT: 32 bit signed integer, gl.UNSIGNED_INT: 32 bit unsigned integer,
      // gl.INT_2_10_10_10_REV: 32 bit signed integer [-512, 511], gl.UNSIGNED_INT_2_10_10_10_REV: 32 bit unsigned integer [0, 1023]
      var eDataType = qGL.FLOAT;
      // bIsNormalized is boolean value to indicated whether gl.BYTE and gl.SHORT should be normailed to the values [-1, 1] and
      // gl.UNSIGNED_BYTE and gl.UNSIGNED_SHORT should be normalized to the values [0, 1] when they are cast to a float.
      var bIsNormalized = false;
      // iStride is the offset, in bytes, between consecutive vertex attributes. It has the type GLsizei in the range [0,255]
      var iStride = 0;
      // iOffset is a GLintptr is the offset, in bytes, of the first component in the array. It must be a multiple of the size of eDataType.
      var iOffset = 0;
      qGL.vertexAttribPointer(uiVertexIndex, uiComponentsPerVertex, eDataType, bIsNormalized, iStride, iOffset);
      qGL.enableVertexAttribArray(uiVertexIndex);

      var qColorsBuffer = qGL.createBuffer();
      qGL.bindBuffer(qGL.ARRAY_BUFFER, qColorsBuffer);
      qGL.bufferData(qGL.ARRAY_BUFFER, qInstanceWebGL.mfaVertexColors, qGL.STATIC_DRAW);

      var qColors = qGL.getAttribLocation(qInstanceWebGL.mqProgram, 'av4Color');
      qGL.vertexAttribPointer(qColors, 4, qGL.FLOAT, false, 0, 0);
      qGL.enableVertexAttribArray(qColors);
    }
    var gqWebGL = null;
    var gfaVertices = null;
    function Initialization() {
      gfaVertices = new Float32Array([
        0.0, 0.0, 0.0, 1.0,
        0.5, 0.0, 0.0, 1.0
      ]);

      gqWebGL = new CInstanceWebGL("idCanvas", "idVertexShader", "idFragmantShader", 2);
      CreateProgramAndContext(gqWebGL);
      // Begin the animation loop. This should use requestAnimationFrame instead
      const kiIntervalId = setInterval(Render, 20);
    }
    function Render() {
        RenderModel(gqWebGL);
    }

    var gfAngle = 0.0;
    function RenderModel(qInstanceWebGL) {
      var faVert = qInstanceWebGL.mfaTransformedVertices;
      var faClr = qInstanceWebGL.mfaVertexColors;
      gfAngle = ((gfAngle + .02 >= 2.0*Math.PI) ? (gfAngle + .02 - 2.0*Math.PI) : gfAngle + .02);
      // First copy the vertices before the transformation
      var faColors = [1.0, 1.0, 0.5, 1.0, 0.5, 0.5, 1.0, 1.0];
      for (var i = 0; i < 8; ++i) {
        faVert[i] = gfaVertices[i];
        faClr[i] = faColors[i];
      }
      faVert[4] = .5*Math.cos(gfAngle);
      faVert[5] = .5*Math.sin(gfAngle);

      // We need to create the buffers afterward
      CreateBuffers(qInstanceWebGL);
      var qGL = qInstanceWebGL.mqGL;
      qGL.clearColor(0.0, 0.0, 0.0, 1.0);
      qGL.clear(qGL.COLOR_BUFFER_BIT);
      qGL.drawArrays(qGL.POINTS, 0, 2);
    }
    function CInstanceWebGL(sCanvasID, sVertexShaderID, sFragmentShaderID, iVertices) {
	  this.mqGL = null;
	  this.mqProgram = null;
	  this.msCanvasID = sCanvasID;
	  this.msVertexShaderID = sVertexShaderID;
	  this.msFragmentShaderID = sFragmentShaderID;
	  this.mfaTransformedVertices = new Float32Array(4*iVertices);
	  this.mfaVertexColors = new Float32Array(4*iVertices);
	}
    </script>
  </head>
  <body onload="Initialization();">
    <canvas id="idCanvas" width="400", height="400" style="border:1px solid lightgray"></canvas>
  </body>
</html>
 

Output

 
 

© 2007–2025 XoaX.net LLC. All rights reserved.