WebGL

0
16

WebGL – Introduction

A couple of yrs back, Java applications − as a combination of appallows and JOGL − were used to process 3D graphics on the Web by addresperform the GPU (Graphical Procesperform Unit). As appallows require a JVM to operate, it becomecame difficult to rely on Java appallows. A couple of yrs later, people preventped uperform Java appallows.

The Stage3D APIs provided by Adobecome (Flash, AIR) awayecrimsondish GPU hardbattlee accelerated architecture. Uperform these technologies, programmers could produce applications with 2D and 3D capabiliconnects on web bcollectionsers as well as on IOS and Android platforms. Since Flash was a proprietary smoothbattlee, it was not used as web standard.

OpenGL

OpenGL (Open Graphics Library) is mix-language, mix-platform API for 2D and 3D graphics. It is a collection of commands. OpenGL4.5 is the latest version of OpenGL. The folloearng table lists a set of technologies related to OpenGL.

API Technology Used
OpenGL ES It is the library for 2D and 3D graphics on embecomedded systems − including consoles, phones, appliances, and vehicles. OpenGL ES 3.1 is it’s latest version. It is maintained by the Khronos Group www.khronos.org
JOGL It is the Java binding for OpenGL. JOGL 4.5 is it’s latest version and it is maintained by jogamp.org.
WebGL It is the JavaScript binding for OpenGL. WebGL 1.0 is it’s latest version and it is maintained by the khronos group.
OpenGLSL OpenGL Shading Language. It is a programming language which is a companion to OpenGL 2.0 and higher. It is a part of the core OpenGL 4.4 specification. It is an API specifically tailocrimsondish for embecomedded systems, such as those present on mobile phones and taballows.

Note − In WebGL, we use GLSL to write shaders.

What is WebGL?

WebGL (Web Graphics Library) is the brand brand new standard for 3D graphics on the Web, It is styleed for the purpose of rendering 2D graphics and interworkive 3D graphics. It is derived from OpenGL's ES 2.0 library which is a low-level 3D API for phones and other mobile devices. WebGL provides similar functionality of ES 2.0 (Embecomedded Systems) and performs well on modern 3D graphics hardbattlee.

It is a JavaScript API that can become used with HTML5. HTML5 has various features to supinterface 3D graphics such as 2D Canvas, WebGL, SVG, 3D CSS transforms, and SMIL.

WebGL code is produced wislim the <canvas> tag of HTML5. It is a specification that allows Internet bcollectionsers access to Graphic Procesperform Unit’s (GPUs) on those complaceers where they were used.

Who Developed WebGL

An American-Serbian smoothbattlee engineer named Vladimir VUKicevic did the foundation work and delivered the creation of WebGL.

  • In 2007, Vladimir started worcalifornia california king on an OpenGL prototype for Canvas element of the HTML document.

  • In March 2011, Kronos Group produced WebGL.

Bcollectionsers Supinterfaceed

The folloearng tables show a list of bcollectionsers that supinterface WebGL −

Web Bcollectionsers

Bcollectionser Name Version Supinterface
Internet Explorer 11 and above Compallowe supinterface
Google Chrome 39 and above Compallowe supinterface
Safari 8 Compallowe supinterface
Firefox 36 and above Partial supinterface
Opera 27 and above Partial supinterface

Mobile Bcollectionsers

Bcollectionser Name Version Supinterface
Chrome for Android 42 Partial supinterface
Android bcollectionser 40 Partial supinterface
IOS Safari 8.3 Compallowe supinterface
Opera Mini 8 Does not supinterface
Blackbecomerry Bcollectionser 10 Compallowe supinterface
IE mobile 10 Partial supinterface

Advantages of WebGL

Here are the advantages of uperform WebGL −

  • JavaScript programming − WebGL applications are produced in JavaScript. Uperform these applications, you can immediately interwork with other elements of the HTML Document. You can furthermore use other JavaScript libraries (e.g. JQuery) and HTML technologies to enwealthy the WebGL application.

  • Increaperform supinterface with mobile bcollectionsers − WebGL furthermore supinterfaces Mobile bcollectionsers such as iOS safari, Android Bcollectionser, and Chrome for Android.

  • Open source − WebGL is an open up source. You can access the source code of the library and understand how it works and how it was produceed.

  • No need for compilation − JavaScript is a half-programming and half-HTML component. To execute this particular particular script, generally correct now there is no need to compile the file. Instead, you can immediately open up the file uperform any of the bcollectionsers and check the result. Since WebGL applications are produceed uperform JavaScript, generally correct now there is no need to compile WebGL applications as well.

  • Automatic memory management − JavaScript supinterfaces automatic memory management. There is no need for manual allocation of memory. WebGL inherit’s this particular particular feature of JavaScript.

  • Easy to set up − Since WebGL is withintegrated wislim HTML 5, generally correct now there is no need for additional set up. To write a WebGL application, all that you need is a text editor and a web bcollectionser.

Environment Setup

There is no need to set a various environment for WebGL. The bcollectionsers supinterfaceing WebGL have their particular own own in-built setup for WebGL.

WebGL – Basic Graphics Concepts

Rendering

Rendering is the process of generating an image from a model uperform complaceer programs. In graphics, a virtual scene is describecomed uperform information like geomeconsider, seestage, texture, lighting, and shading, which is moveed through a render program. The awayplace of this particular particular render program will become a digital image.

There are 2 types of rendering −

  • Softbattlee Rendering − All the rendering calculations are done with the help of CPU.

  • Hardbattlee Rendering − All the graphics complaceations are done by the GPU (Graphical procesperform device).

Rendering can become done locally or remotely. If the image to become rendecrimsondish is way too complex, then rendering is done remotely on a dedicated server having sufficient of hardbattlee resources requicrimsondish to render complex scenes. It is furthermore caldelivered as server-based rendering. Rendering can furthermore become done locally by the CPU. It is caldelivered as csitnt-based rendering.

WebGL follows a csitnt-based rendering approach to render 3D scenes. All the procesperform requicrimsondish to obtain an image is performed locally uperform the csitnt's graphics hardbattlee.

GPU

According to NVIDIA, a GPU is "a performle chip processor with integrated transform, lighting, triangle setup/clipping, and rendering engines capable of procesperform a minimum of 10 million polygons per 2nd."

Unlike multi-core processors with a couple of cores optimized for sequential procesperform, a GPU consists of thoufine sands of smaller cores that process parallel workloads effectively. Therefore, the GPU accelerates the creation of images in a frame buffer (a interfaceion of ram which contains a finish frame data) intended for awayplace to a display.

CPU and GPU

GPU Accelerated Complaceing

In GPU accelerated complaceing, the application is loaded into the CPU. Whenever it encounters a complacee-intensive interfaceion of the code, then that interfaceion of code will become loaded and operate on the GPU. It gives the system the capacity to process graphics in an effective way.

GPU Accelerated Complaceing

GPU will have a separate memory and it operates multiple copies of a small interfaceion of the code at a time. The GPU processes all the data which is within it’s local memory, not the central memory. Therefore, the data that is needed to become processed by the GPU ought to become loaded/copied to the GPU memory and then become processed.

In the systems having the above architecture, the communication overmind becometween the CPU and GPU ought to become crimsondishuced to achieve faster procesperform of 3D programs. For this particular particular, we have to duplicate all the data and maintain it on the GPU, instead of communicating with the GPU repeatedly.

Html5 Canvas Oversee

To produce graphical applications on the web, HTML-5 provides a wealthy set of features such as 2D Canvas, WebGL, SVG, 3D CSS transforms, and SMIL. To write WebGL applications, we use the existing canvas element of HTML-5. This chapter provides an oversee of the HTML-5 2D canvas element.

HTML5 Canvas

HTML-5 <canvas> provides an easy and powerful option to draw graphics uperform JavaScript. It can become used to draw graphs, produce photo composit downions, or do simple (and not so simple) animations.

Here is a simple <canvas> element having only 2 specific attributes width and height plus all the core HTML-5 attributes like id, name, and class.

Syntax

The syntax of HTML canvas tag is given becomelow. You have to mention the name of the canvas inside double quotations (“ ”).

<canvas id = "mycanvas" width = "100" height = "100"></canvas>

Canvas Attributes

The canvas tag has 3 attributes namely, id, width, and height.

  • Id − Id represents the identifier of the canvas element in the Document Object Model (DOM).

  • Width − Width represents the width of the canvas.

  • Height − Height represents the height of the canvas.

These attributes figure out the dimension of the canvas. If a programmer is not specifying all of them under the canvas tag, then bcollectionsers such as Firefox, Chrome, and Web Kit, by default, provide a canvas element of dimension 300 × 150.

Example – Create a Canvas

The folloearng code shows how to produce a canvas. We have used CSS to give a coloucrimsondish border to the canvas.

<html>
   <mind>
	
      <style>
         #mycanvas{border:1px strong crimsondish;}
      </style>
		
   </mind>
	
   <body>
      <canvas id = "mycanvas" width = "100" height = "100"></canvas>
   </body>
	
</html>

It will produce the folloearng result −

HTML Context (Rendering)

The <canvas> is preliminaryly blank. To display a fewslimg on the canvas element, we have to use a scripting language. This scripting language ought to access the rendering context and draw on it.

The canvas element has a DOM method caldelivered getContext(), which is used to obtain the rendering context and it’s draearng functions. This method considers one parameter, the sort of context 2d.

The folloearng code is to become produced to get the requicrimsondish context. You can write this particular particular script inside the body tag as shown becomelow.

<!DOCTYPE HTML>

<html>
   <body>
      <canvas id = "mycanvas" width = "600" height = "200"></canvas>
      
      <script>
         var canvas = document.getElementById('mycanvas');
         var context = canvas.getContext('2d');
			
         context.font = '20pt Calibri';
         context.fillStyle = 'green';
         context.fillText('Welcome to Tutorialsstage', 70, 70);
      </script>
      
   </body>
</html>

It will produce the folloearng result −

For more example on HTML-5 2D Canvas, check away the folloearng link HTML-5 Canvas.

WebGL Context

HTML5 Canvas is furthermore used to write WebGL applications. To produce a WebGL rendering context on the canvas element, you ought to move the string experimental-webgl, instead of 2d to the canvas.getContext() method. Some bcollectionsers supinterface only 'webgl'.

<!DOCTYPE html>

<html>
   <canvas id = 'my_canvas'></canvas>
	
   <script>
      var canvas = document.getElementById('my_canvas');
      var gl = canvas.getContext('experimental-webgl');
      gl.clearColor(0.9,0.9,0.8,1);
      gl.clear(gl.COLOR_BUFFER_BIT);
   </script>
	
</html>

It will produce the folloearng result −

WebGL – Basics

WebGL is manyly a low-level rasterization API instead than a 3D API. To draw an image uperform WebGL, you have to move a vector representing the image. It then converts the given vector into pixel format uperform OpenGL SL and displays the image on the screen. Writing a WebGL application involves a set of steps which
we would become explaining in this particular particular chapter.

WebGL – Coordinate System

Just like any other 3D system, you will have x, y and z axes in WebGL, where the z axis signifies depth. The coordinates in WebGL are relimiteded to (1, 1, 1) and (-1, -1, – 1). It means − if you consider the screen projecting WebGL graphics as a cubecome, then one corner of the cubecome will become (1, 1, 1) and the opposit downe corner will become (-1, -1, -1). WebGL won’t display anyslimg that is drawn becomeyond these boundaries.

The folloearng diagram depicts the WebGL coordinate system. The z-axis signifies depth. A posit downive value of z indicates that the object is near the screen/seeer, whereas a negative value of z indicates that the object is away from the screen. Likewise, a posit downive value of x indicates that the object is to the correct side of the screen and a negative value indicates the object is to the left side. Similarly, posit downive and negative values of y indicate whether the object is at the top or at the underside interfaceion of the screen.

WebGL Coordinate System

WebGL Fundamentals

After getting the WebGL context of the canvas object, you can start draearng graphical elements uperform WebGL API in JavaScript.

Here are a few fundamental terms you need to understand becomefore starting with WebGL.

Vertices

Generally, to draw objects such as a polygon, we mark the stages on the plane and sign up for all of them to form a desicrimsondish polygon. A vertex is a stage which defines the conjunction of the advantages of a 3D object. It is represented by 3 floating stage values every representing x, y, z axes respectively.

Example

In the folloearng example, we are draearng a triangle with the folloearng vertices − (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.5).

Vertices Example

Note − We have to store these vertices manually uperform JavaScript arrays and move all of them to the WebGL rendering pipecollection uperform vertex buffer.

Indices

In WebGL, numerical values are used to identify the vertices. These numerical values are understandn as indices. These indices are used to draw meshes in WebGL.

Indices

Note − Just like vertices, we store the indices uperform JavaScript arrays and move all of them to WebGL rendering pipecollection uperform index buffer.

Arrays

Unlike OpenGL and JoGL, generally correct now there are no pcrimsondishefined methods in WebGL to render the vertices immediately. We have to store all of them manually uperform JavaScript arrays.

Example

var vertices = [ 0.5, 0.5, 0.1,-0.5, 0.5,-0.5] 

Buffers

Buffers are the memory areas of WebGL that hold the data. There are various buffers namely, draearng buffer, frame buffer, vetex buffer, and index buffer. The vertex buffer and index buffer are used to describecome and process the geomeconsider of the model.

  • Vertex buffer objects − This stores data corresponding to every vertex (per-vertex data)

  • Index buffer objects This stores data abaway the indices.

  • Frame buffer is a interfaceion of graphics memory that hold the scene data. This buffer contains details such as width and height of the surface (in pixels), colour of every pixel and their particular own depth.

After storing the vertices into arrays, we move all of them to WegGL graphics pipecollection uperform these Buffer objects.

Mesh

To draw 2D or 3D objects, the WebGL API provides 2 methods namely, drawArrays() and drawElements(). These 2 methods accept a parameter caldelivered mode uperform which you can select the object you want to draw. The options provided by this particular particular field are relimiteded to stages, collections, and triangles.

To draw a 3D object uperform these 2 methods, we have to construct one or more primitive polygons uperform stages, collections, or triangles. Thereafter, uperform those primitive polygons, we can form a mesh.

A 3D object drawn uperform primitive polygons is caldelivered a mesh. WebGL awayers various ways to draw 3D graphical objects, however users normally prefer to draw a mesh.

Example

In the folloearng example, you can observe that we have drawn a square uperform 2 triangles→ {1, 2, 3} and {4, 1, 3}.

Mesh Example

WebGL – Shader Program

We normally use triangles to construct meshes. Since WebGL uses GPU accelerated complaceing, the information abaway these triangles ought to become transfercrimsondish from CPU to GPU which considers a lot of communication overmind.

WebGL provides a solution to crimsondishuce the communication overmind. Since it uses ES SL (Embecomedded System Shader Language) that operates on GPU, we write all the requicrimsondish programs to draw graphical elements on the csitnt system uperform shader programs (the programs which we write uperform OpenGL ES Shading Language / GLSL).

These shaders are the programs for GPU and the language used to write shader programs is GLSL. In these shaders, we define exworkly how vertices, transformations, materials, lights, and camera interwork with one an additional to produce a particular image.

In short, it is a snippet that implements algorithms to get pixels for a mesh. We will speak abaway more abaway shaders in later chapters. There are 2 types of shaders − Vertex Shader and Fragment Shader.

Vertex Shader

Vertext shader is the program code caldelivered on every vertex. It is used to transform (move) the geomeconsider (ex: triangle) from one place to an additional. It handles the data of every vertex (per-vertex data) such as vertex coordinates, normals, colours, and texture coordinates.

In the ES GL code of vertex shader, programmers have to define attributes to handle the data. These attributes stage to a Vertex Buffer Object produced in JavaScript.

The folloearng tasks can become performed uperform vertex shaders −

  • Vertex transformation
  • Normal transformation and normalization
  • Texture coordinate generation
  • Texture coordinate transformation
  • Lighting
  • Color material application

Fragment Shader(Pixel Shader)

A mesh is formed by multiple triangles, and the surface of every of the triangles is understandn as a fragment. Fragment shader is the code that operates on all pixels of every fragment. It is produced to calculate and fill the colour on individual pixels.

The folloearng tasks can become performed uperform Fragment shaders −

  • Operations on interpolated values
  • Texture access
  • Texture application
  • Fog
  • Color sum

Fragment Shader

OpenGL ES SL Variables

The finish form of OpenGL ES SL is OpenGL Embecomedded System Shading Language. To handle the data in the shader programs, ES SL provides 3 types of variables. They are as follows −

  • Attributes − These variables hold the inplace values of the vertex shader program. Attributes stage to the vertex buffer objects that contains per-vertex data. Each time the vertex shader is withinvoked, the attributes stage to VBO of various vertices.

  • Uniforms − These variables hold the inplace data that is common for both vertex and fragment shaders, such as light posit downion, texture coordinates, and colour.

  • Varyings − These variables are used to move the data from the vertex shader to the fragment shader.

With this particular particular much simples, we will now move on to speak abaway the Graphics Pipecollection.

WebGL – Graphics Pipecollection

To render 3D graphics, we have to follow a sequence of steps. These steps are understandn as graphics pipecollection or rendering pipecollection. The folloearng diagram depicts WebGL graphics pipecollection.

Graphics Pipecollection

In the folloearng sections, we will speak abaway one by one the role of every step in the pipecollection.

JavaScript

While produceing WebGL applications, we write Shader language code to communicate with the GPU. JavaScript is used to write the manage code of the program, which includes the folloearng workions −

  • Initialize WebGL − JavaScript is used to preliminaryize the WebGL context.

  • Create arrays − We produce JavaScript arrays to hold the data of the geomeconsider.

  • Buffer objects − We produce buffer objects (vertex and index) by moveing the arrays as parameters.

  • Shaders − We produce, compile, and link the shaders uperform JavaScript.

  • Attributes − We can produce attributes, enable all of them, and associate all of them with buffer objects uperform JavaScript.

  • Uniforms − We can furthermore associate the uniforms uperform JavaScript.

  • Transformation matrix − Uperform JavaScript, we can produce transformation matrix.

Initially we produce the data for the requicrimsondish geomeconsider and move all of them to the shaders in the form of buffers. The attribute variable of the shader language stages to the buffer objects, which are moveed as inplaces to the vertex shader.

Vertex Shader

When we start the rendering process by invocalifornia california king the methods drawElements() and drawArray(), the vertex shader is executed for every vertex provided in the vertex buffer object. It calculates the posit downion of every vertex of a primitive polygon and stores it in the varying gl_posit downion. It furthermore calculates the other attributes such as colour, texture coordinates, and vertices that are normally associated with a vertex.

Primitive Assembly

After calculating the posit downion and other details of every vertex, the next phase is the primitive assembly stage. Here the triangles are assembdelivered and moveed to the rasterizer.

Rasterization

In the rasterization step, the pixels in the final image of the primitive are figure outd. It has 2 steps −

  • Culling − Initially the orientation (is it front or back facing?) of the polygon is figure outd. All those triangles with improper orientation that are not noticeable in see area are discarded. This process is caldelivered culling.

  • Clipping − If a triangle is partly awayside the see area, then the part awayside the see area is removed. This process is understandn as clipping.

Fragment Shader

The fragment shader gets

  • data from the vertex shader in varying variables,
  • primitives from the rasterization stage, and then
  • calculates the colour values for every pixel becometween the vertices.

The fragment shader stores the colour values of every pixel in every fragment. These colour values can become accessed during fragment operations, which we are going to speak abaway next.

Some fragment operations are carried away after determining the colour of every pixel in the primitive. These fragment operations may include the folloearng −

  • Depth
  • Color buffer blend
  • Dithering

Once all the fragments are processed, a 2D image is formed and displayed on the screen. The frame buffer is the final destination of the rendering pipecollection.

Fragment Operations

Frame Buffer

Frame buffer is a interfaceion of graphics memory that hold the scene data. This buffer contains details such as width and height of the surface (in pixels), colour of every pixel, and depth and stencil buffers.

WebGL – Sample Application

We have speak abawayed the simples of WebGL and the WebGL pipecollection (a procedure followed to render Graphics applications). In this particular particular chapter, we are going to consider a sample application to produce a triangle uperform WebGL and observe the steps followed in the application.

Structure of WebGL Application

WebGL application code is a combination of JavaScript and OpenGL Shader Language.

  • JavaScript is requicrimsondish to communicate with the CPU
  • OpenGL Shader Language is requicrimsondish to communicate with the GPU.

WebGL Application Structure

Sample Application

Let us now consider a simple example to understand how to use WebGL to draw a simple triangle with 2D coordinates.

<!doctype html>
<html>
   <body>
      <canvas width = "300" height = "300" id = "my_Canvas"></canvas>
		
      <script>


         /* Step1: Prepare the canvas and get WebGL context */

         var canvas = document.getElementById('my_Canvas');
         var gl = canvas.getContext('experimental-webgl');


         /* Step2: Define the geomeconsider and store it in buffer objects */

         var vertices = [-0.5, 0.5, -0.5, -0.5, 0.0, -0.5,];

         // Create a brand brand new buffer object
         var vertex_buffer = gl.produceBuffer();

         // Bind an empty array buffer to it
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
         
         // Pass the vertices data to the buffer
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);

         // Unbind the buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, null);


         /* Step3: Create and compile Shader programs */

         // Vertex shader source code
         var vertCode =
            'attribute vec2 coordinates;' + 
            'void main(void) {' + ' gl_Posit downion = vec4(coordinates,0.0, 1.0);' + '}';

         //Create a vertex shader object
         var vertShader = gl.produceShader(gl.VERTEX_SHADER);

         //Attach vertex shader source code
         gl.shaderSource(vertShader, vertCode);

         //Compile the vertex shader
         gl.compileShader(vertShader);

         //Fragment shader source code
         var fragCode = 'void main(void) {' + 'gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' + '}';

         // Create fragment shader object
         var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);

         // Attach fragment shader source code
         gl.shaderSource(fragShader, fragCode);

         // Compile the fragment shader
         gl.compileShader(fragShader);

         // Create a shader program object to store combined shader program
         var shaderProgram = gl.produceProgram();

         // Attach a vertex shader
         gl.attachShader(shaderProgram, vertShader); 
         
         // Attach a fragment shader
         gl.attachShader(shaderProgram, fragShader);

         // Link both programs
         gl.linkProgram(shaderProgram);

         // Use the combined shader program object
         gl.useProgram(shaderProgram);


         /* Step 4: Associate the shader programs to buffer objects */

         //Bind vertex buffer object
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

         //Get the attribute location
         var coord = gl.getAttribLocation(shaderProgram, "coordinates");

         //stage an attribute to the currently bound VBO
         gl.vertexAttribPointer(coord, 2, gl.FLOAT, false, 0, 0);

         //Enable the attribute
         gl.enableVertexAttribArray(coord);


         /* Step5: Draearng the requicrimsondish object (triangle) */

         // Clear the canvas
         gl.clearColor(0.5, 0.5, 0.5, 0.9);

         // Enable the depth test
         gl.enable(gl.DEPTH_TEST); 
         
         // Clear the colour buffer bit
         gl.clear(gl.COLOR_BUFFER_BIT);

         // Set the see interface
         gl.seeinterface(0,0,canvas.width,canvas.height);

         // Draw the triangle
         gl.drawArrays(gl.TRIANGLES, 0, 3);
         
      </script>
      
   </body>
</html>

It will produce the folloearng result −

We follow five sequential steps to draw a simple triangle uperform WebGL. These steps are exaplained as follows −

Step 1 − Prepare the canvas and get WebGL rendering context

We get the current HTML canvas object and obtain it’s WebGL rendering context.

Step 2 − Define the geomeconsider and store it in buffer objects

We define the attributes of the geomeconsider such as vertices, indices, colour, etc., and store all of them in the JavaScript arrays. Then, we produce one or more buffer objects and move the arrays containing the data to the respective buffer object. In the example, we store the vertices of the triangle in a JavaScript array and move this particular particular array to a vertex buffer object.

Step 3 − Create and compile Shader programs

We write vertex shader and fragment shader programs, compile all of them, and produce a combined program by lincalifornia california king these 2 programs.

Step 4 − Associate the shader programs with buffer objects

We associate the buffer objects and the combined shader program.

Step 5 − Draearng the requicrimsondish object (triangle)

This step includes operations such as clearing the colour, clearing the buffer bit, enabling the depth test, setting the see interface, etc. Finally, you need to draw the requicrimsondish primitives uperform one of the methods − drawArrays() or drawElements().

All these steps are explained further in this particular particular tutorial.

WebGL – Context

To write a WebGL application, preliminary step is to get the WebGL rendering context object. This object interworks with the WebGL draearng buffer and can call all the WebGL methods. The folloearng operations are performed to obtain the WebGL context −

  • Create an HTML-5 canvas
  • Get the canvas ID
  • Obtain WebGL

Creating HTML-5 Canvas Element

We understand to produce an HTML-5 canvas element −

  • Write canvas statement in HTML5 Body
  • Give canvas an ID
  • Change canvas dimensions uperform height & width attributes (optional)

An example ought to provide more clarity here.

Example

The folloearng example shows how to produce a canvas element with the dimensions 500 × 500. We have produced a border to the canvas uperform CSS for visibility. Copy and paste the folloearng code in a file with the name my_canvas.html.

<!DOCTYPE HTML>
<html>
   <mind>
   
      <style>
         #mycanvas{border:1px strong blue;}
      </style>
   </mind>
	
   <body>
      <canvas id = "mycanvas" width = "300" height = "300"></canvas>
   </body>
	
</html>

It will produce the folloearng result −

Get the Canvas ID

Canvas ID is acquicrimsondish by calling the DOM (Document Object Model) method getElementById(). This method accepts a string value as parameter, so we move the name of the current canvas to it.

For example, if the canvas name is my_canvas, then canvas ID is obtained as shown becomelow−

var canvas = document.getElementById('my_Canvas');

Get the WebGL Draearng Context

To get the WebGLRenderingContext object (or WebGL Draearng context object or simply WebGL context), call the getContext() method of the current HTMLCanvasElement. The syntax of getContext() is as follows −

canvas.getContext(contextType, contextAttributes);

Pass the strings webgl or experimental-webgl as the contentType. The contextAttributes parameter is optional. (While proceeding with this particular particular step, produce sure your own own bcollectionser implements WebGL version 1 (OpenGL ES 2.0)).

The folloearng code snippet shows how to obtain the WebGL rendering context. Here gl is the reference variable to the obtained context object.

var canvas = document.getElementById('my_Canvas');
var gl = canvas.getContext('experimental-webgl');

WebGLContextAttributes

The parameter WebGLContextAttributes is not mandatory. This parameter provides various options that accept Boolean values as listed becomelow −

Alpha

If it’s value is true, it provides an alpha buffer to the canvas.

By default, it’s value is true.

depth

If it’s value is true, you will get a draearng buffer which contains a depth buffer of at leastern 16 bit’s.

By default, it’s value is true.

stencil

If it’s value is true, you will get a draearng buffer which contains a stencil buffer of at leastern 8 bit’s.

By default, it’s value is false.

antialias

If it’s value is true, you will get a draearng buffer which performs anti-aliaperform.

By default, it’s value is true.

premultipsitdAlpha

If it’s value is true, you will get a draearng buffer which contains colours with pre-multipsitd alpha.

By default, it’s value is true.

preserveDraearngBuffer

If it’s value is true, the buffers will not become cleacrimsondish and will preserve their particular own values until cleacrimsondish or overproduced by the author.

By default, it’s value is false.

The folloearng code snippet shows how to produce a WebGL context with a stencil buffer, which will not perform anti-aliaperform.

var canvas = document.getElementById('canvas1');
var context = canvas.getContext('webgl', { antialias: false, stencil: true });

At the time of creating the WebGLRenderingContext, a draearng buffer is produced. The Context object manages OpenGL state and renders to the draearng buffer.

WebGLRenderingContext

It is the principal interface in WebGL. It represents the WebGL draearng context. This withinterface contains all the methods used to perform various tasks on the Draearng buffer. The attributes of this particular particular interface are given in the folloearng table.

S.No. Attributes and Description
1

Canvas

This is a reference to the canvas element that produced this particular particular context.

2

draearngBufferWidth

This attribute represents the workual width of the draearng buffer. It may differ from the width attribute of the HTMLCanvasElement.

3

draearngBufferHeight

This attribute represents the workual height of the draearng buffer. It may differ from the height attribute of the HTMLCanvasElement.

WebGL – Geomeconsider

All primitives (or object models) ought to have well-defined geometric details. These details may include vertices, indices, colour, textures etc. In WebGL, geometric details are stocrimsondish in JavaScript arrays.

Graphic objects are produced by shader programs which operate on the GPU. Geometric details are moveed to shader programs uperform buffer objects.

Defining the Requicrimsondish Geomeconsider

A 2D or 3D model drawn uperform vertices is caldelivered a mesh. Each facet in a mesh is caldelivered a polygon and a polygon is made of 3 or more vertices.

To draw models in the WebGL rendering context, you have to define the vertices and indices uperform JavaScript arrays. For example, if we want to produce a triangle which sit’s on the coordinates {(5,5), (-5,5), (-5,-5)} as shown in the diagram, then you can produce an array for the vertices as −

var vertices = [
   0.5,0.5,  //Vertex 1
   0.5,-0.5, //Vertex 2
  -0.5,-0.5, //Vertex 3
]; 

Geomeconsider

Similarly, you can produce an array for the indices. Indices for the above triangle indices will become [0, 1, 2] and can become defined as −

var indices = [ 0,1,2 ]

For a becometter understanding of indices, consider more complex models like square. We can represent a square as a set of 2 triangles. If (0,3,1) and (3,1,2) are the 2 triangles uperform which we intend to draw a square, then the indices will become defined as −

var indices = [0,3,1,3,1,2];

Geomeconsider Example

Note

For draearng primitives, WebGL provides the folloearng 2 methods −

  • drawArrays() − While uperform this particular particular method, we move the vertices of the primitive uperform JavaScript arrays.

  • drawElements() − While uperform this particular particular method, we move both vertices and indices of the primitive uperform JavaScript array.

Buffer Objects

A buffer object is a mechanism provided by WebGL that indicates a memory area allocated in the system. In these buffer objects, you can store data of the model you want to draw, corresponding to vertices, indices, colour, etc.

Uperform these buffer objects, you can move multiple data to the shader program (vertex shader) through one of it’s attribute variables. Since these buffer objects reside in the GPU memory, they can become rendecrimsondish immediately, which in turn improves the performance.

To process geomeconsider, generally correct now there are 2 types of buffer objects. They are −

  • Vertex buffer object (VBO) − It holds the per-vertex data of the graphical model that is going to become rendecrimsondish. We use vertex buffer objects in WebGL to store and process the data regarding vertices such as vertex coordinates, normals, colours, and texture coordinates.

  • Index buffer objects (IBO) − It holds the indices (index data) of the graphical model that is going to become rendecrimsondish.

After defining the requicrimsondish geomeconsider and storing all of them in JavaScript arrays, you need to move these arrays to the buffer objects, from where the data will become moveed to the shader programs. The folloearng steps are to become followed to store data in the buffers.

  • Create an empty buffer.

  • Bind an appropriate array object to the empty buffer.

  • Pass the data (vertices/indices) to the buffer uperform one of the typed arrays.

  • Unbind the buffer (Optional).

Note −

WebGL provides a special type of array caldelivered typed arrays to transfer the data elements such as index vertex and texture. These typed arrays store big quanticonnects of data and process all of them in native binary format which results in becometter performance. The typed arrays used by WebGL are Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, UInt32Array, Float32Array, and Float64Array.

  • Generally, for storing vertex data, we use Float32Array; and to store index data, we use Uint16Array.

  • You can produce typed arrays simply like JavaScript arrays uperform brand brand new keyword.

Now, allow's understand abaway the steps to store data in buffers −

Creating a Buffer

To produce an empty buffer object, WebGL provides a method caldelivered produceBuffer(). This method returns a brand brand newly produced buffer object, if the creation was successful; else it returns a null value in case of failure.

WebGL operates as a state machine. Once a buffer is produced, any subsequent buffer operation will become executed on the current buffer until we unbound it. Use the folloearng code to produce a buffer −

var vertex_buffer = gl.produceBuffer();

Notegl is the reference variable to the current WebGL context.

Bind the Buffer

After creating an empty buffer object, you need to bind an appropriate array buffer (target) to it. WebGL provides a method caldelivered bindBuffer() for this particular particular purpose.

Syntax

The syntax of bindBuffer() method is as follows −

void bindBuffer (enum target, Object buffer)

This method accepts 2 parameters and they are speak abawayed becomelow.

target − The preliminary variable is an enum value representing the sort of the buffer we want to bind to the empty buffer. You have 2 pcrimsondishefined enum values as options for this particular particular parameter. They are −

  • ARRAY_BUFFER which represents vertex data.

  • ELEMENT_ARRAY_BUFFER which represents index data.

Object buffer − The 2nd one is the reference variable to the buffer object produced in the previous step. The reference variable can become of a vertex buffer object or of an index buffer object.

Example

The folloearng code snippet shows how to use the bindBuffer() method.

//vertex buffer
var vertex_buffer = gl.produceBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

//Index buffer
var Index_Buffer = gl.produceBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

Pasperform Data into the Buffer

The next step is to move the data (vertices/indices) to the buffer. Till now data is within the form of an array and becomefore moveing it to the buffer, we need to wrap it in one of the WebGL typed arrays. WebGL provides a method named bufferData() for this particular particular purpose.

Syntax

The syntax of bufferData() method is as follows −

void bufferData (enum target, Object data, enum usage)

This method accepts 3 parameters and they are speak abawayed becomelow −

target − The preliminary parameter is an enum value representing the sort of the array buffer we used. This can become ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER.

Object data − The 2nd parameter is the object value that contains the data to become produced to the buffer object. Here we have to move the data uperform typed arrays.

Usage − The third parameter of this particular particular method is an enum variable that specifies how to use the buffer object data (stocrimsondish data) to draw forms. There are 3 options for this particular particular parameter as listed becomelow.

  • gl.STATIC_DRAW − Data will become specified once and used many times.

  • gl.STREAM_DRAW − Data will become specified once and used a couple of times.

  • gl.DYNAMIC_DRAW − Data will become specified repeatedly and used many times.

Example

The folloearng code snippet shows how to use the bufferData() method. Assume vertices and indices are the arrays holding the vertex and index data respectively.

//vertex buffer
gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);

//Index buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, brand brand new Uint16Array(indices), gl.STATIC_DRAW);

Unbind the Buffers

It is recommended that you unbind the buffers after uperform all of them. It can become done by moveing a null value in place of the buffer object, as shown becomelow.

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

WebGL provides the folloearng methods to perform buffer operations −

S.No. Methods and Description
1

void bindBuffer (enum target, Object buffer)

target − ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

2

void bufferData(enum target, lengthy dimension, enum usage)

target − ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

usage − STATIC_DRAW, STREAM_DRAW, DYNAMIC_DRAW

3

void bufferData (enum target, Object data, enum usage)

target and usage − Same as for bufferData above

4

void bufferSubData(enum target, lengthy awayset, Object data)

target − ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

5 Object produceBuffer()
6 void dealloweBuffer(Object buffer)
7

any getBufferParameter(enum target, enum pname)

target − ARRAY_BUFFER, ELEMENT_ ARRAY_BUFFER

pname − BUFFER_SIZE, BUFFER_USAGE

8 bool isBuffer(Object buffer)

WebGL – Shaders

Shaders are the programs that operate on GPU. Shaders are produced in OpenGL ES Shader Language (understandn as ES SL). ES SL has variables of it’s own, data types, qualifiers, built-in inplaces and awayplaces.

Data Types

The folloearng table lists the simple data types provided by OpenGL ES SL.

S.No. Type Description
1 void Represents an empty value.
2 bool Accepts true or false.
3 int This is a signed integer data type.
4 float This is a floating scalar data type.
5 vec2, vec3, vec4 n-component floating stage vector
6 bvec2, bvec3, bvec4 Boolean vector
7 ivec2, ivec3, ivec4 signed integer vector
8 mat2, mat3, mat4 2×2, 3×3, 4×4 float matrix
9 sampler2D Access a 2D texture
10 samplerCubecome Access cubecome chartped texture

Qualifiers

There are 3 main qualifiers in OpenGL ES SL −

S.No. Qualifier Description
1 attribute This qualifier works as a link becometween a vertex shader and OpenGL ES for per-vertex data. The value of this particular particular attribute modifys for every execution of the vertex shader.
2 uniform

This qualifier links shader programs and the WebGL application. Unlike attribute qualifier, the values of uniforms do not modify. Uniforms are read-only; you can use all of them with any simple data types, to declare a variable.

Example − uniform vec4 lightPosit downion;

3 varying

This qualifier forms a link becometween a vertex shader and fragment shader for interpolated data. It can become used with the folloearng data types − float, vec2, vec3, vec4, mat2, mat3, mat4, or arrays.

Example − varying vec3 normal;

Vertex Shader

Vertex shader is a program code, which is caldelivered on every vertex. It transforms (move) the geomeconsider (ex: triangle) from one place to other. It handles the data of every vertex (per-vertex data) such as vertex coordinates, normals, colours, and texture coordinates.

In the ES GL code of vertex shader, programmers have to define attributes to handle data. These attributes stage to a Vertex Buffer Object produced In JavaScript. The folloearng tasks can become performed uperform vertex shaders alengthy with vertex transformation −

  • Vertex transformation
  • Normal transformation and normalization
  • Texture coordinate generation
  • Texture coordinate transformation
  • Lighting
  • Color material application

Pcrimsondishefined Variables

OpenGL ES SL provides the folloearng pcrimsondishefined variables for vertex shader −

S.No. Variables Description
1 highp vec4 gl_Posit downion; Holds the posit downion of the vertex.
2 mediump float gl_PointSize; Holds the transformed stage dimension. The devices for this particular particular variable are pixels.

Sample Code

Take a look at the folloearng sample code of a vertex shader. It processes the vertices of a triangle.

attribute vec2 coordinates;

void main(void) {
   gl_Posit downion = vec4(coordinates, 0.0, 1.0);
};

If you observe the above code carefinishy, we have declacrimsondish an attribute variable with the name coordinates. (This variable will become associated with the Vertex Buffer Object uperform the method getAttribLocation(). The attribute coordinates is moveed as a parameter to this particular particular method alengthy with the shader program object.)

In the 2nd step of the given vertex shader program, the gl_posit downion variable is defined.

gl_Posit downion

gl_Posit downion is the pcrimsondishefined variable which is available only in the vertex shader program. It contains the vertex posit downion. In the above code, the coordinates attribute is moveed in the form of a vector. As vertex shader is a per-vertex operation, the gl_posit downion value is calculated for every vertex.

Later, the gl_posit downion value is used by primitive assembly, clipping, culling, and other fixed functionality operations that operate on the primitives after the vertex procesperform is over.

We can write vertex shader programs for all achievable operations of vertex shader, which we will speak abaway individually in this particular particular tutorial.

Fragment Shader

A mesh is formed by multiple triangles, and the surface of the every triangle is understandn as a fragment. A fragment shader is the code that operates on every pixel on every fragment. This is produced to calculate and fill the colour on individual pixels. The folloearng tasks can become performed uperform fragment shaders −

  • Operations on interpolated values
  • Texture access
  • Texture application
  • Fog
  • Color sum

Pcrimsondishefined Variables

OpenGL ES SL provides the folloearng pcrimsondishefined variables for fragment shader −

S.No. Variables Description
1 mediump vec4 gl_FragCoord; Holds the fragment posit downion wislim the frame buffer.
2 bool gl_FrontFacing; Holds the fragment that becomelengthys to a front-facing primitive.
3 mediump vec2 gl_PointCoord; Holds the fragment posit downion wislim a stage (stage rasterization only).
4 mediump vec4 gl_FragColor; Holds the awayplace fragment colour value of the shader
5 mediump vec4 gl_FragData[n] Holds the fragment colour for colour attachment n.

Sample Code

The folloearng sample code of a fragment shader shows how to apply colour to every pixel in a triangle.

void main(void) {
   gl_FragColor = vec4(0, 0.8, 0, 1);
}

In the above code, the colour value is stocrimsondish in the variable gl.FragColor. The fragment shader program movees the awayplace to the pipecollection uperform fixed function variables; FragColor is one of all of them. This variable holds the colour value of the pixels of the model.

Storing and Compiling the Shader Programs

Since shaders are independent programs, we can write all of them as a separate script and use in the application. Or, you can store all of them immediately in string format, as shown becomelow.

var vertCode =
   'attribute vec2 coordinates;' +
	
   'void main(void) {' +
      ' gl_Posit downion = vec4(coordinates, 0.0, 1.0);' +
   '}';

Compiling the Shader

Compilation involves folloearng 3 steps −

  • Creating the shader object
  • Attaching the source code to the produced shader object
  • Compiling the program

Creating the Vertex Shader

To produce an empty shader, WebGL provides a method caldelivered produceShader(). It produces and returns the shader object. It’s syntax is as follows −

Object produceShader (enum type)

As observed in the syntax, this particular particular method accepts a pcrimsondishefined enum value as parameter. We have 2 options for this particular particular −

  • gl.VERTEX_SHADER for creating vertex shader

  • gl.FRAGMENT_SHADER for creating fragment shader.

Attaching the Source to the Shader

You can attach the source code to the produced shader object uperform the method shaderSource(). It’s syntax is as follows −

void shaderSource(Object shader, string source)

This method accepts 2 parameters −

  • shader − You have to move the produced shader object as one parameter.

  • Source − You have to move the shader program code in string format.

Compiling the Program

To compile the program, you have to use the method compileShader(). It’s syntax is as follow −

compileShader(Object shader)

This method accepts the shader program object as a parameter. After creating a shader program object, attach the source code to it and move that object to this particular particular method.

The folloearng code snippet shows how to produce and compile a vertex shader as well as a fragment shader to produce a triangle.

// Vertex Shader
var vertCode =
   'attribute vec3 coordinates;' +
	
   'void main(void) {' +
      ' gl_Posit downion = vec4(coordinates, 1.0);' +
   '}';
      
var vertShader = gl.produceShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
 
// Fragment Shader
var fragCode =
   'void main(void) {' +
      ' gl_FragColor = vec4(0, 0.8, 0, 1);' +
   '}';
      
var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);

Combined Program

After creating and compiling both the shader programs, you need to produce a combined program containing both the shaders (vertex & fragment). The folloearng steps need to become followed −

  • Create a program object
  • Attach both the shaders
  • Link both the shaders
  • Use the program

Create a Program Object

Create a program object by uperform the method produceProgram(). It will return an empty program object. Here is it’s syntax −

produceProgram();

Attach the Shaders

Attach the shaders to the produced program object uperform the method attachShader(). It’s syntax is as follows −

attachShader(Object program, Object shader);

This method accepts 2 parameters −

  • Program − Pass the produced empty program object as one parameter.

  • Shader − Pass one of the compidelivered shaders programs (vertex shader, fragment shader)

Note − You need to attach both the shaders uperform this particular particular method.

Link the Shaders

Link the shaders uperform the method linkProgram(), by moveing the program object to which you have attached the shaders. It’s syntax is as follows −

linkProgram(shaderProgram);

Use the Program

WebGL provides a method caldelivered useProgram(). You need to move the linked program to it. It’s syntax is as follows −

useProgram(shaderProgram);

The folloearng code snippet shows how to produce, link, and use a combined shader program.

var shaderProgram = gl.produceProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram); 

Associating Attributes & Buffer Objects

Each attribute in the vertex shader program stages to a vertex buffer object. After creating the vertex buffer objects, programmers have to associate all of them with the attributes of the vertex shader program. Each attribute stages to only one vertex buffer object from which they extrwork the data values, and then these attributes are moveed to the shader program.

To associate the Vertex Buffer Objects with the attributes of the vertex shader program, you have to follow the steps given becomelow −

  • Get the attribute location
  • Point the attribute to a vertex buffer object
  • Enable the attribute

Get the Attribute Location

WebGL provides a method caldelivered getAttribLocation() which returns the attribute location. It’s syntax is as follows −

ulengthy getAttribLocation(Object program, string name)

This method accepts the vertex shader program object and the attribute values of the vertex shader program.

The folloearng code snippet shows how to use this particular particular method.

var coordinatesVar = gl.getAttribLocation(shader_program, "coordinates"); 

Here, shader_program is the object of the shader program and coordinates is the attribute of the vertex shader program.

Point the Attribute to a VBO

To assign the buffer object to the attribute variable, WebGL provides a method caldelivered vertexAttribPointer(). Here is the syntax of this particular particular method −

void vertexAttribPointer(location, int dimension, enum type, bool normalized, lengthy stride, lengthy awayset)

This method accepts six parameters and they are speak abawayed becomelow.

  • Location − It specifies the storage location of an attribute variable. Under this particular particular option, you have to move the value returned by the getAttribLocation() method.

  • Size − It specifies the numbecomer of components per vertex in the buffer object.

  • Type − It specifies the sort of data.

  • Normalized − This is a Boolean value. If true, non-floating data is normalized to [0, 1]; else, it is normalized to [-1, 1].

  • Stride − It specifies the numbecomer of bytes becometween various vertex data elements, or zero for default stride.

  • Offset − It specifies the awayset (in bytes) in a buffer object to indicate which byte the vertex data is stocrimsondish from. If the data is stocrimsondish from the becomeginning, awayset is 0.

The folloearng snippet shows how to use vertexAttribPointer() in a program −

gl.vertexAttribPointer(coordinatesVar, 3, gl.FLOAT, false, 0, 0);

Enabling the Attribute

Activate the vertex shader attribute to access the buffer object in a vertex shader. For this particular particular operation, WebGL provides enableVertexAttribArray() method. This method accepts the location of the attribute as a parameter. Here is how to use this particular particular method in a program −

gl.enableVertexAttribArray(coordinatesVar); 

WebGL – Draearng a Model

After associating the buffers with the shaders, the final step is to draw the requicrimsondish primitives. WebGL provides 2 methods namely, drawArrays() and drawElements() to draw models.

drawArrays()

drawArrays() is the method which is used to draw models uperform vertices. Here is it’s syntax −

void drawArrays(enum mode, int preliminary, lengthy count)

This method considers the folloearng 3 parameters −

  • mode − In WebGL, models are drawn uperform primitive types. Uperform mode, programmers have to select one of the primitive types provided by WebGL. The achievable values for this particular particular option are − gl.POINTS, gl.LINE_STRIP, gl.LINE_LOOP, gl.LINES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, and gl.TRIANGLES.

  • preliminary − This option specifies the starting element in the enabdelivered arrays. It cannot become a negative value.

  • count − This option specifies the numbecomer of elements to become rendecrimsondish.

If you draw a model uperform drawArrays() method, then WebGL, while rendering the forms, produces the geomeconsider in the order in which the vertex coordinates are defined.

Example

If you want to draw a performle triangle uperform drawArray() method, then you have to move 3 vertices and call the drawArrays() method, as shown becomelow.

var vertices = [-0.5,-0.5, -0.25,0.5, 0.0,-0.5,];
gl.drawArrays(gl.TRIANGLES, 0, 3);

It will produce a triangle as shown becomelow.

Triangle

Suppose you want to draw contiguous triangles, then you have to move the next 3 vertices in order in the vertex buffer and mention the numbecomer of elements to become rendecrimsondish as 6.

var vertices = [-0.5,-0.5, -0.25,0.5, 0.0,-0.5, 0.0,-0.5, 0.25,0.5, 0.5,-0.5,];
gl.drawArrays(gl.TRIANGLES, 0, 6);

It will produce a contiguous triangle as shown becomelow.

Triangle 1

drawElements()

drawElements() is the method that is used to draw models uperform vertices and indices. It’s syntax is as follows −

void drawElements(enum mode, lengthy count, enum type, lengthy awayset)

This method considers the folloearng four parameters −

  • mode − WebGL models are drawn uperform primitive types. Uperform mode, programmers have to select one of the primitive types provided by WebGL. The list of achievable values for this particular particular option are − gl.POINTS, gl.LINE_STRIP, gl.LINE_LOOP, gl.LINES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, and gl.TRIANGLES.

  • count − This option specifies the numbecomer of elements to become rendecrimsondish.

  • type − This option specifies the data type of the indices which must become UNSIGNED_BYTE or UNSIGNED_SHORT.

  • awayset − This option specifies the starting stage for rendering. It is usually the preliminary element (0).

If you draw a model uperform drawElements() method, then index buffer object ought to furthermore become produced alengthy with the vertex buffer object. If you use this particular particular method, the vertex data will become processed once and used as many times as mentioned in the indices.

Example

If you want to draw a performle triangle uperform indices, you need to move the indices alengthy with vertices and call the drawElements() method as shown becomelow.

var vertices = [ -0.5,-0.5,0.0, -0.25,0.5,0.0, 0.0,-0.5,0.0 ];
var indices = [0,1,2];

gl.drawElements(gl.TRIANGLES, indices.duration, gl.UNSIGNED_SHORT,0);

It will produce the folloearng awayplace −

Triangle

If you want to draw contagious triangles uperform drawElements() method, simply add the other vertices and mention the indices for the remaining vertices.

var vertices = [
   -0.5,-0.5,0.0,
   -0.25,0.5,0.0,
   0.0,-0.5,0.0,
   0.25,0.5,0.0,
   0.5,-0.5,0.0 
];

var indices = [0,1,2,2,3,4];
    
gl.drawElements(gl.TRIANGLES, indices.duration, gl.UNSIGNED_SHORT,0);

It will produce the folloearng awayplace −

Triangle 1

Requicrimsondish Operations

Before draearng a primitive, you need to perform a couple of operations, which are explained becomelow.

Clear the Canvas

First of all, you ought to clear the canvas, uperform clearColor() method. You can move the RGBA values of a desicrimsondish colour as parameter to this particular particular method. Then WebGL clears the canvas and fills it with the specified colour. Therefore, you can use this particular particular method for setting the background colour.

Take a look at the folloearng example. Here we are moveing the RGBA value of grey colour.

gl.clearColor(0.5, 0.5, .5, 1);

Enable Depth Test

Enable the depth test uperform the enable() method, as shown becomelow.

gl.enable(gl.DEPTH_TEST); 

Clear the Color Buffer Bit

Clear the colour as well as the depth buffer by uperform the clear() method, as shown becomelow.

gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

Set the View Port

The see interface represents a rectangular seeable area that contains the rendering results of the draearng buffer. You can set the dimensions of the see interface uperform seeinterface() method. In the folloearng code, the see interface dimensions are set to the canvas dimensions.

gl.seeinterface(0,0,canvas.width,canvas.height);

WebGL – Draearng Points

We speak abawayed earsitr (in Chapter 5) how to follow a step-by-step process to draw a primitive. We have explained the process in five steps. You need to repeat these steps every time you draw a brand brand new form. This chapter explains how to draw stages with 3D coordinates in WebGL. Before moving further, allow us consider a relook at the five steps.

Requicrimsondish Steps

The folloearng steps are requicrimsondish to produce a WebGL application to draw stages.

Step 1 − Prepare the Canvas and Get the WebGL Rendering Context

In this particular particular step, we obtain the WebGL Rendering context object uperform the method getContext().

Step 2 − Define the Geomeconsider and Store it in the Buffer Objects

Since we are draearng 3 stages, we define 3 vertices with 3D coordinates and store all of them in buffers.

var vertices = [
   -0.5,0.5,0.0,
   0.0,0.5,0.0,
   -0.25,0.25,0.0, 
];

Step 3 − Create and Compile the Shader Programs

In this particular particular step, you need to write vertex shader and fragment shader programs, compile all of them, and produce a combined program by lincalifornia california king these 2 programs.

  • Vertex Shader − In the vertex shader of the given example, we define a vector attribute to store 3D coordinates, and assign it to the gl_posit downion variable.

  • gl_stagedimension is the variable used to assign a dimension to the stage. We assign the stage dimension as 10.

var vertCode = 'attribute vec3 coordinates;' +

   'void main(void) {' +
      ' gl_Posit downion = vec4(coordinates, 1.0);' +
      'gl_PointSize = 10.0;'+
   '}';
  • Fragment Shader − In the fragment shader, we simply assign the fragment colour to the gl_FragColor variable

var fragCode = 'void main(void) {' +' gl_FragColor = vec4(1, 0.5, 0.0, 1);' +'}';

Step 4 − Associate the Shader Programs to Buffer Objects

In this particular particular step, we associate the buffer objects with the shader program.

Step 5 − Draearng the Requicrimsondish Object

We use the method drawArrays() to draw stages. Since the numbecomer of stages we want to draw are is 3, the count value is 3.

gl.drawArrays(gl.POINTS, 0, 3)

Example – Draw Three Points uperform WebGL

Here is the finish WebGL program to draw 3 stages −

<!doctype html>
<html>
   <body>
      <canvas width = "570" height = "570" id = "my_Canvas"></canvas>

      <script>

         /*================Creating a canvas=================*/
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl'); 
      
         /*==========Defining and storing the geomeconsider=======*/

         var vertices = [
            -0.5,0.5,0.0,
            0.0,0.5,0.0,
            -0.25,0.25,0.0, 
         ];
         
         // Create an empty buffer object to store the vertex buffer
         var vertex_buffer = gl.produceBuffer();

         //Bind appropriate array buffer to it
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
      
         // Pass the vertex data to the buffer
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);

         // Unbind the buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, null);


         /*=========================Shaders========================*/
      
         // vertex shader source code
         var vertCode =
            'attribute vec3 coordinates;' +
				
            'void main(void) {' +
               ' gl_Posit downion = vec4(coordinates, 1.0);' +
               'gl_PointSize = 10.0;'+
            '}';
         
         // Create a vertex shader object
         var vertShader = gl.produceShader(gl.VERTEX_SHADER);

         // Attach vertex shader source code
         gl.shaderSource(vertShader, vertCode);

         // Compile the vertex shader
         gl.compileShader(vertShader);

         // fragment shader source code
         var fragCode =
            'void main(void) {' +
               ' gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' +
            '}';
         
         // Create fragment shader object
         var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);

         // Attach fragment shader source code
         gl.shaderSource(fragShader, fragCode);
      
         // Compile the fragmentt shader
         gl.compileShader(fragShader);

         // Create a shader program object to store
         // the combined shader program
         var shaderProgram = gl.produceProgram();

         // Attach a vertex shader
         gl.attachShader(shaderProgram, vertShader); 
 
         // Attach a fragment shader
         gl.attachShader(shaderProgram, fragShader);

         // Link both programs
         gl.linkProgram(shaderProgram);

         // Use the combined shader program object
         gl.useProgram(shaderProgram);

         /*======== Associating shaders to buffer objects ========*/

         // Bind vertex buffer object
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

         // Get the attribute location
         var coord = gl.getAttribLocation(shaderProgram, "coordinates");

         // Point an attribute to the currently bound VBO
         gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);

         // Enable the attribute
         gl.enableVertexAttribArray(coord);

         /*============= Draearng the primitive ===============*/

         // Clear the canvas
         gl.clearColor(0.5, 0.5, 0.5, 0.9);

         // Enable the depth test
         gl.enable(gl.DEPTH_TEST);
 
         // Clear the colour buffer bit
         gl.clear(gl.COLOR_BUFFER_BIT);

         // Set the see interface
         gl.seeinterface(0,0,canvas.width,canvas.height);

         // Draw the triangle
         gl.drawArrays(gl.POINTS, 0, 3);

      </script>
   </body>
</html>

It will produce the folloearng result −

WebGL – Draearng a Triangle

In the previous chapter (Chapter 11), we speak abawayed how to draw 3 stages uperform WebGL. In Chapter 5, we took sample application to demonstrate how to draw a triangle. In both the examples, we have drawn the primitives uperform only vertices.

To draw more complex forms/meshes, we move the indices of a geomeconsider too, alengthy with the vertices, to the shaders. In this particular particular chapter, we will see how to draw a triangle uperform indices.

Steps Requicrimsondish to Draw a Triangle

The folloearng steps are requicrimsondish to produce a WebGL application to draw a triangle.

Step 1 − Prepare the Canvas and Get WebGL Rendering Context

In this particular particular step, we obtain the WebGL Rendering context object uperform getContext().

Step 2 − Define the Geomeconsider and Store it in Buffer Objects

Since we are draearng a triangle uperform indices, we have to move the 3 vertices of the triangle, including the indices, and store all of them in the buffers.

var vertices = [
   -0.5,0.5,0.0,
   -0.5,-0.5,0.0,
   0.5,-0.5,0.0, 
];
	
indices = [0,1,2]; 

Step 3 − Create and Compile the Shader Programs

In this particular particular step, you need to write vertex shader and fragment shader programs, compile all of them, and produce a combined program by lincalifornia california king these 2 programs.

  • Vertex Shader − In the vertex shader of the program, we define the vector attribute to store 3D coordinates and assign it to gl_posit downion.

var vertCode =
   'attribute vec3 coordinates;' +
	
   'void main(void) {' +
      ' gl_Posit downion = vec4(coordinates, 1.0);' +
   '}';
  • Fragment Shader − In the fragment shader, we simply assign the fragment colour to the gl_FragColor variable.

var fragCode = 'void main(void) {' +
   ' gl_FragColor = vec4(1, 0.5, 0.0, 1);' +
'}';

Step 4 − Associate the Shader Programs to the Buffer Objects

In this particular particular step, we associate the buffer objects and the shader program.

Step 5 − Draearng the Requicrimsondish Object

Since we are draearng a triangle uperform indices, we will use drawElements(). To this particular particular method, we have to move the numbecomer of indices. The value of the indices.duration signifies the numbecomer of indices.

gl.drawElements(gl.TRIANGLES, indices.duration, gl.UNSIGNED_SHORT,0);

Example – Draearng a Triangle

The folloearng program code shows how to draw a triangle in WebGL uperform indices −

<!doctype html>
<html>
   <body>
      <canvas width = "570" height = "570" id = "my_Canvas"></canvas>

      <script>

         /*============== Creating a canvas ====================*/
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl');
      
         /*======== Defining and storing the geomeconsider ===========*/

         var vertices = [
            -0.5,0.5,0.0,
            -0.5,-0.5,0.0,
            0.5,-0.5,0.0, 
         ];
         
         indices = [0,1,2];
         
         // Create an empty buffer object to store vertex buffer
         var vertex_buffer = gl.produceBuffer();

         // Bind appropriate array buffer to it
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
         
         // Pass the vertex data to the buffer
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);

         // Unbind the buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, null);

         // Create an empty buffer object to store Index buffer
         var Index_Buffer = gl.produceBuffer();

         // Bind appropriate array buffer to it
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);

         // Pass the vertex data to the buffer
         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, brand brand new Uint16Array(indices), gl.STATIC_DRAW);
         
         // Unbind the buffer
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

         /*================ Shaders ====================*/
         
         // Vertex shader source code
         var vertCode =
            'attribute vec3 coordinates;' +
				
            'void main(void) {' +
               ' gl_Posit downion = vec4(coordinates, 1.0);' +
            '}';
            
         // Create a vertex shader object
         var vertShader = gl.produceShader(gl.VERTEX_SHADER);

         // Attach vertex shader source code
         gl.shaderSource(vertShader, vertCode);

         // Compile the vertex shader
         gl.compileShader(vertShader);

         //fragment shader source code
         var fragCode =
            'void main(void) {' +
               ' gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' +
            '}';
            
         // Create fragment shader object
         var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);

         // Attach fragment shader source code
         gl.shaderSource(fragShader, fragCode); 
         
         // Compile the fragmentt shader
         gl.compileShader(fragShader);

         // Create a shader program object to store
         // the combined shader program
         var shaderProgram = gl.produceProgram();

         // Attach a vertex shader
         gl.attachShader(shaderProgram, vertShader);

         // Attach a fragment shader
         gl.attachShader(shaderProgram, fragShader);

         // Link both the programs
         gl.linkProgram(shaderProgram);

         // Use the combined shader program object
         gl.useProgram(shaderProgram);

         /*======= Associating shaders to buffer objects =======*/

         // Bind vertex buffer object
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

         // Bind index buffer object
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
         
         // Get the attribute location
         var coord = gl.getAttribLocation(shaderProgram, "coordinates");

         // Point an attribute to the currently bound VBO
         gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0); 
         
         // Enable the attribute
         gl.enableVertexAttribArray(coord);

         /*=========Draearng the triangle===========*/

         // Clear the canvas
         gl.clearColor(0.5, 0.5, 0.5, 0.9);

         // Enable the depth test
         gl.enable(gl.DEPTH_TEST);

         // Clear the colour buffer bit
         gl.clear(gl.COLOR_BUFFER_BIT);

         // Set the see interface
         gl.seeinterface(0,0,canvas.width,canvas.height);

         // Draw the triangle
         gl.drawElements(gl.TRIANGLES, indices.duration, gl.UNSIGNED_SHORT,0);

      </script>

    </body>
</html>

It will produce the folloearng result −

WebGL – Modes of Draearng

In the previous chapter (Chapter 12), we speak abawayed how to draw a triangle uperform WebGL. In addition to triangles, WebGL supinterfaces various other draearng modes. This chapter explains the draearng modes supinterfaceed by WebGL.

The mode Parameter

Let’s consider a look at the syntax of the methods − drawElements() and draw Arrays().

void drawElements(enum mode, lengthy count, enum type, lengthy awayset);

void drawArrays(enum mode, int preliminary, lengthy count);

If you clearsitr observe, both the methods accept a parameter mode. Uperform this particular particular parameter, the programmers can select the draearng mode in WebGL.

The draearng modes provided by WebGL are listed in the folloearng table.

S.No. mode Description
1 gl.POINTS To draw a series of stages.
2 gl.LINES To draw a series of unconnected collection segments (individual collections).
3 gl.LINE_STRIP To draw a series of connected collection segments.
4 gl.LINE_LOOP To draw a series of connected collection segments. It furthermore sign up fors the preliminary and final vertices to form a loop.
5 gl.TRIANGLES To draw a series of separate triangles.
6 gl.TRIANGLE_STRIP To draw a series of connected triangles in strip fashion.
7 gl.TRIANGLE_FAN To draw a series of connected triangles sharing the preliminary vertex in a fan-like fashion.

Example – Draw Three Parallel Lines

The folloearng example shows how to draw 3 parallel collections uperform gl.LINES.

<!doctype html>
<html>
   <body>
      <canvas width = "300" height = "300" id = "my_Canvas"></canvas>

      <script>

         /*======= Creating a canvas =========*/

         var canvas = document.getElementById('my_Canvas');
         var gl = canvas.getContext('experimental-webgl');


         /*======= Defining and storing the geomeconsider ======*/

         var vertices = [
            -0.7,-0.1,0,
            -0.3,0.6,0,
            -0.3,-0.3,0,
            0.2,0.6,0,
            0.3,-0.3,0,
            0.7,0.6,0 
         ]
          
         // Create an empty buffer object
         var vertex_buffer = gl.produceBuffer();

         // Bind appropriate array buffer to it
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
      
         // Pass the vertex data to the buffer
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);

         // Unbind the buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, null);

         /*=================== Shaders ====================*/

         // Vertex shader source code
         var vertCode =
            'attribute vec3 coordinates;' +
            'void main(void) {' +
               ' gl_Posit downion = vec4(coordinates, 1.0);' +
            '}';

         // Create a vertex shader object
         var vertShader = gl.produceShader(gl.VERTEX_SHADER);

         // Attach vertex shader source code
         gl.shaderSource(vertShader, vertCode);

         // Compile the vertex shader
         gl.compileShader(vertShader);

         // Fragment shader source code
         var fragCode =
            'void main(void) {' +
               'gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' +
            '}';

         // Create fragment shader object
         var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);

         // Attach fragment shader source code
         gl.shaderSource(fragShader, fragCode);

         // Compile the fragmentt shader
         gl.compileShader(fragShader);

         // Create a shader program object to store
         // the combined shader program
         var shaderProgram = gl.produceProgram();

         // Attach a vertex shader
         gl.attachShader(shaderProgram, vertShader);

         // Attach a fragment shader
         gl.attachShader(shaderProgram, fragShader);

         // Link both the programs
         gl.linkProgram(shaderProgram);

         // Use the combined shader program object
         gl.useProgram(shaderProgram);

         /*======= Associating shaders to buffer objects ======*/

         // Bind vertex buffer object
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

         // Get the attribute location
         var coord = gl.getAttribLocation(shaderProgram, "coordinates");

         // Point an attribute to the currently bound VBO
         gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);

         // Enable the attribute
         gl.enableVertexAttribArray(coord);

         /*============ Draearng the triangle =============*/

         // Clear the canvas
         gl.clearColor(0.5, 0.5, 0.5, 0.9);

         // Enable the depth test
         gl.enable(gl.DEPTH_TEST);

         // Clear the colour and depth buffer
         gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

         // Set the see interface
         gl.seeinterface(0,0,canvas.width,canvas.height);

         // Draw the triangle
         gl.drawArrays(gl.LINES, 0, 6);

         // POINTS, LINE_STRIP, LINE_LOOP, LINES,
         // TRIANGLE_STRIP,TRIANGLE_FAN, TRIANGLES
      
      </script>
		
   </body>
</html>

It will produce the folloearng result −

Draearng Modes

In the above program, if you replace the mode of drawArrays() with one of the folloearng draearng modes, it will produce various awayplaces every time.

Draearng Modes Outplaces
LINE_STRIP Line Strip
LINE_LOOP Line Loop
TRIANGLE_STRIP Triangle Strip
TRIANGLE_FAN Triangle Fan
TRIANGLES Triangles

WebGL – Draearng a Quad

In the previous chapter, we speak abawayed the various draearng modes provided by WebGL. We can furthermore use indices to draw primitives uperform one of these modes. To draw models in WebGL, we have to select one of these primitives and draw the requicrimsondish mesh (i.e., a model formed uperform one or more primitives).

In this particular particular chapter, we will consider an example to demonstrate how to draw a quadrilateral uperform WebGL.

Steps to Draw a Quadrilateral

The folloearng steps are requicrimsondish to produce a WebGL application to draw a quadrilateral.

Step 1 − Prepare the Canvas and Get the WebGL Rendering Context

In this particular particular step, we obtain the WebGL Rendering context object uperform getContext().

Step 2 − Define the Geomeconsider and Store it in the Buffer Objects

A square can become drawn uperform 2 triangles. In this particular particular example, we provide the vertices for 2 triangles (with one common advantage) and indices.

var vertices = [
   -0.5,0.5,0.0,
   -0.5,-0.5,0.0,
   0.5,-0.5,0.0,
   0.5,0.5,0.0 
];

indices = [3,2,1,3,1,0]; 

Step 3 − Create and Compile the Shader Programs

In this particular particular step, you need to write the vertex shader and fragment shader programs, compile all of them, and produce a combined program by lincalifornia california king these 2 programs.

  • Vertex Shader − In the vertex shader of the program, we define the vector attribute to store 3D coordinates and assign it to gl_posit downion.

var vertCode =
   'attribute vec3 coordinates;' +
   'void main(void) {' +
      ' gl_Posit downion = vec4(coordinates, 1.0);' +
   '}';
  • Fragment Shader − In the fragment shader, we simply assign the fragment colour to the gl_FragColor variable.

var fragCode = 'void main(void) {' +' gl_FragColor = vec4(0.5, 0.3, 0.0, 7.5);' +'}';

Step 4 − Associate the Shader Programs to Buffer Objects

In this particular particular step, we associate the buffer objects with the shader program.

Step 5 − Draearng the Requicrimsondish Object

Since we are draearng 2 triangles to form a quad, uperform indices, we will use the method drawElements(). To this particular particular method, we have to move the numbecomer of indices. The value of indices.duration gives the numbecomer of indices.

gl.drawElements(gl.TRIANGLES, indices.duration, gl.UNSIGNED_SHORT,0);

Example – Draw a Quadrilateral

The folloearng program shows how to produce a WebGL application to draw a quadrilateral.

<!doctype html>
<html>
   <body>
      <canvas width = "570" height = "570" id = "my_Canvas"></canvas>

      <script>

         /*============ Creating a canvas =================*/
      
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl');
      
         /*========== Defining and storing the geomeconsider =========*/

         var vertices = [
            -0.5,0.5,0.0,
            -0.5,-0.5,0.0,
            0.5,-0.5,0.0,
            0.5,0.5,0.0 
         ];
          
         indices = [3,2,1,3,1,0];
      
         // Create an empty buffer object to store vertex buffer
         var vertex_buffer = gl.produceBuffer();

         // Bind appropriate array buffer to it
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
 
         // Pass the vertex data to the buffer
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);

         // Unbind the buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, null);

         // Create an empty buffer object to store Index buffer
         var Index_Buffer = gl.produceBuffer();

         // Bind appropriate array buffer to it
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);

         // Pass the vertex data to the buffer
         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, brand brand new Uint16Array(indices), gl.STATIC_DRAW);

         // Unbind the buffer
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

         /*====================== Shaders =======================*/
 
         // Vertex shader source code
         var vertCode =
            'attribute vec3 coordinates;' +
            'void main(void) {' +
               ' gl_Posit downion = vec4(coordinates, 1.0);' +
            '}';
         
         // Create a vertex shader object
         var vertShader = gl.produceShader(gl.VERTEX_SHADER);

         // Attach vertex shader source code
         gl.shaderSource(vertShader, vertCode);

         // Compile the vertex shader
         gl.compileShader(vertShader);

         // Fragment shader source code
         var fragCode =
            'void main(void) {' +
               ' gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' +
            '}';
         
         // Create fragment shader object 
         var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);

         // Attach fragment shader source code
         gl.shaderSource(fragShader, fragCode);

         // Compile the fragmentt shader
         gl.compileShader(fragShader);

         // Create a shader program object to
         // store the combined shader program
         var shaderProgram = gl.produceProgram();

         // Attach a vertex shader
         gl.attachShader(shaderProgram, vertShader);

         // Attach a fragment shader
         gl.attachShader(shaderProgram, fragShader);

         // Link both the programs
         gl.linkProgram(shaderProgram);

         // Use the combined shader program object
         gl.useProgram(shaderProgram);

         /* ======= Associating shaders to buffer objects =======*/

         // Bind vertex buffer object
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

         // Bind index buffer object
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer); 
 
         // Get the attribute location
         var coord = gl.getAttribLocation(shaderProgram, "coordinates");

         // Point an attribute to the currently bound VBO
         gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
 
         // Enable the attribute
         gl.enableVertexAttribArray(coord);

         /*============= Draearng the Quad ================*/

         // Clear the canvas
         gl.clearColor(0.5, 0.5, 0.5, 0.9);

         // Enable the depth test
         gl.enable(gl.DEPTH_TEST);

         // Clear the colour buffer bit
         gl.clear(gl.COLOR_BUFFER_BIT);

         // Set the see interface
         gl.seeinterface(0,0,canvas.width,canvas.height);

         // Draw the triangle
         gl.drawElements(gl.TRIANGLES, indices.duration, gl.UNSIGNED_SHORT,0);

      </script>
   
   </body>
</html>

It will produce the folloearng result −

WebGL – Colors

In all our previous examples, we appsitd colour to the object by assigning a desicrimsondish colour value to the gl_FragColor variable. In addition to that, we can define colours for every vertex − simply like vertex coordinates and indices. This chapter considers an example to demonstrate how to apply colours to a quadrilateral uperform WebGL.

Applying Colors

To apply colours, you have to define the colours for every vertex uperform the RGB values, in JavaScript array. You can assign the exbehave same values to all the vertices to have a unique colour to the object. After defining the colours, you have to produce a colour buffer and store these values in it, and associate it to the vertex shader attributes.

In the vertex shader, alengthy with the coordinates attribute (that holds the posit downion of the vertices), we define an attribute and a varying to handle colours.

The colour attribute holds the colour value per vertex, and varying is the variable that is moveed as an inplace to the fragment shader. Therefore, we have to assign the colour value to varying.

In the fragment shader, the varying that holds the colour value is assigned to gl_FragColor, which holds the final colour of the object.

Steps to Apply Colors

The folloearng steps are requicrimsondish to produce a WebGL application to draw a Quad and apply colours to it.

Step 1 − Prepare the Canvas and Get the WebGL Rendering Context

In this particular particular step, we obtain the WebGL Rendering context object uperform getContext().

Step 2 − Define the Geomeconsider and Store it in the Buffer Objects

A square can become drawn uperform 2 triangles. Therefore, in this particular particular example, we provide the vertices for 2 triangles (with one common advantage) and indices. Since we want to apply colours to it, a variable holding the colour values is furthermore defined and the colour values for every (Red, Blue, Green, and Pink) are assigned to it.

var vertices = [
   -0.5,0.5,0.0,
   -0.5,-0.5,0.0, 
   0.5,-0.5,0.0,
   0.5,0.5,0.0 
];

var colours = [ 0,0,1, 1,0,0, 0,1,0, 1,0,1,];

indices = [3,2,1,3,1,0]; 

Step 3 − Create and Compile the Shader Programs

In this particular particular step, you need to write the vertex shader and fragment shader programs, compile all of them, and produce a combined program by lincalifornia california king these 2 programs.

  • Vertex Shader − In the vertex shader of the program, we define vector attributes to store 3D coordinates (posit downion), and the colour of every vertex. A varing variable is declacrimsondish to move the colour values from the vertex shader to the fragment shader. And finally, the value stocrimsondish in the colour attribute is assigned to varying.

var vertCode = 'attribute vec3 coordinates;'+
   'attribute vec3 colour;'+
   'varying vec3 vColor;'+
	
   'void main(void) {' +
      ' gl_Posit downion = vec4(coordinates, 1.0);' +
      'vColor = colour;'+
   '}';
  • Fragment Shader − In the fragment shader, we assign the varying to the gl_FragColor variable.

var fragCode = 'precision mediump float;'+
   'varying vec3 vColor;'+
   'void main(void) {'+
      'gl_FragColor = vec4(vColor, 1.);'+
   '}';

Step 4 − Associate the Shader Programs with the Buffer Objects

In this particular particular step, we associate the buffer objects and the shader program.

Step 5 − Draearng the Requicrimsondish Object

Since we are draearng 2 triangles that will form a quad, uperform indices, we will use the method drawElements(). To this particular particular method, we have to move the numbecomer of indices. The value of indices.duration indicates the numbecomer of indices.

gl.drawElements(gl.TRIANGLES, indices.duration, gl.UNSIGNED_SHORT,0);

Example – Applying Color

The folloearng program demonstrates how to draw a quad uperform WebGL application and apply colours to it.

<!doctype html>
<html>
   <body>
    <canvas width = "300" height = "300" id = "my_Canvas"></canvas>

      <script>

         /*============= Creating a canvas ==================*/
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl');
         
         /*========== Defining and storing the geomeconsider ==========*/

         var vertices = [
            -0.5,0.5,0.0,
            -0.5,-0.5,0.0,
            0.5,-0.5,0.0,
            0.5,0.5,0.0
         ];

         var colours = [0,0,1, 1,0,0, 0,1,0, 1,0,1,];
         
         indices = [3,2,1,3,1,0];
         
         // Create an empty buffer object and store vertex data
         var vertex_buffer = gl.produceBuffer();
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);
         gl.bindBuffer(gl.ARRAY_BUFFER, null);

         // Create an empty buffer object and store Index data
         var Index_Buffer = gl.produceBuffer();
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, brand brand new Uint16Array(indices), gl.STATIC_DRAW);
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

         // Create an empty buffer object and store colour data
         var colour_buffer = gl.produceBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, colour_buffer);
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(colours), gl.STATIC_DRAW);

         /*======================= Shaders =======================*/
         
         // vertex shader source code
         var vertCode = 'attribute vec3 coordinates;'+
            'attribute vec3 colour;'+
            'varying vec3 vColor;'+
            'void main(void) {' +
               ' gl_Posit downion = vec4(coordinates, 1.0);' +
               'vColor = colour;'+
            '}';
            
         // Create a vertex shader object
         var vertShader = gl.produceShader(gl.VERTEX_SHADER);

         // Attach vertex shader source code
         gl.shaderSource(vertShader, vertCode);

         // Compile the vertex shader
         gl.compileShader(vertShader);


         // fragment shader source code
         var fragCode = 'precision mediump float;'+
            'varying vec3 vColor;'+
            'void main(void) {'+
               'gl_FragColor = vec4(vColor, 1.);'+
            '}';
            
         // Create fragment shader object
         var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);

         // Attach fragment shader source code
         gl.shaderSource(fragShader, fragCode);

         // Compile the fragmentt shader
         gl.compileShader(fragShader);

         // Create a shader program object to
         // store the combined shader program
         var shaderProgram = gl.produceProgram();

         // Attach a vertex shader
         gl.attachShader(shaderProgram, vertShader);

         // Attach a fragment shader
         gl.attachShader(shaderProgram, fragShader);

         // Link both the programs
         gl.linkProgram(shaderProgram);

         // Use the combined shader program object
         gl.useProgram(shaderProgram);

         /* ======== Associating shaders to buffer objects =======*/

         // Bind vertex buffer object
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

         // Bind index buffer object
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);

         // Get the attribute location
         var coord = gl.getAttribLocation(shaderProgram, "coordinates");

         // stage an attribute to the currently bound VBO
         gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);

         // Enable the attribute
         gl.enableVertexAttribArray(coord);

         // bind the colour buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, colour_buffer);
         
         // get the attribute location
         var colour = gl.getAttribLocation(shaderProgram, "colour");
 
         // stage attribute to the volor buffer object
         gl.vertexAttribPointer(colour, 3, gl.FLOAT, false,0,0) ;
 
         // enable the colour attribute
         gl.enableVertexAttribArray(colour);

         /*============Draearng the Quad====================*/

         // Clear the canvas
         gl.clearColor(0.5, 0.5, 0.5, 0.9);

         // Enable the depth test
         gl.enable(gl.DEPTH_TEST);

         // Clear the colour buffer bit
         gl.clear(gl.COLOR_BUFFER_BIT);

         // Set the see interface
         gl.seeinterface(0,0,canvas.width,canvas.height);

         //Draw the triangle
         gl.drawElements(gl.TRIANGLES, indices.duration, gl.UNSIGNED_SHORT,0);

      </script>
      
   </body>
</html>

It will produce the folloearng result −

WebGL – Translation

So far, we speak abawayed how to draw various forms and apply colours in all of them uperform WebGL. Here, in this particular particular chapter, we will consider an example to show how to translate a triangle.

Translation

Translation is one of the affine transformations provided by WebGL. Uperform translation, we can move a triangle (any object) on the xyz plane. Suppose we have a triangle [a, b, c] and we want to move the triangle to a posit downion which is 5 devices tobattbroughts the posit downive X-axis and 3 devices tobattbroughts the posit downive Y-axis. Then the brand brand new vertices would become [a+5, b+3, c+0]. That means, to translate the triangle, we need to add the translation distances, say, tx, ty, tz to every vertex.

Since it is a per-vertex operation, we can carry it in the vertex shader program.

In the vertex shader, alengthy with the attribute, coordinates (that hold the vertex posit downions), we define a uniform variable that holds the translation distances (x,y,z). Later, we add this particular particular uniform variable to the coordinates variable and assign the result to the gl_Posit downion variable.

Note − Since vertex shader will become operate on every vertex, all the vertices of the triangle will become translated.

Steps to Translate a Triangle

The folloearng steps are requicrimsondish to produce a WebGL application to draw a triangle and then translate it to a brand brand new posit downion.

Step 1 − Prepare the Canvas and Get the WebGL Rendering Context

In this particular particular step, we obtain the WebGL Rendering context object uperform getContext().

Step 2 − Define the Geomeconsider and Store it in the Buffer Objects

Since we are draearng a triangle, we have to move 3 vertices of the triangle, and store all of them in buffers.

var vertices = [ -0.5,0.5,0.0, -0.5,-0.5,0.0, 0.5,-0.5,0.0, ];

Step 3 − Create and Compile the Shader Programs

In this particular particular step, you need to write the vertex shader and fragment shader programs, compile all of them, and produce a combined program by lincalifornia california king these 2 programs.

  • Vertex Shader − In the vertex shader of the program, we define a vector attribute to store 3D coordinates. Alengthy with it, we define a uniform variable to store the translation distances, and finally, we add these 2 values and assign it to gl_posit downion which holds the final posit downion of the vertices.

var vertCode =
   'attribute vec4 coordinates;' +
   'uniform vec4 translation;'+
   'void main(void) {' +
      ' gl_Posit downion = coordinates + translation;' +
   '}';
  • Fragment Shader − In the fragment shader, we simply assign the fragment colour to the variable gl_FragColor.

var fragCode = 'void main(void) {' +' gl_FragColor = vec4(1, 0.5, 0.0, 1);' +'}';

Step 4 − Associate the Shader Programs to the Buffer Objects

In this particular particular step, we associate the buffer objects with the shader program.

Step 5 − Draearng the Requicrimsondish Object

Since we are draearng the triangle uperform indices, we will use the method drawArrays(). To this particular particular method, we have to move the numbecomer of vertices /elements to become considecrimsondish. Since we are draearng a triangle, we will move 3 as a parameter.

gl.drawArrays(gl.TRIANGLES, 0, 3);

Example – Translate a Triangle

The folloearng example show how to translate a triangle on xyz plane.

<!doctype html>
<html>
   <body>
      <canvas width = "300" height = "300" id = "my_Canvas"></canvas>
         
      <script>
         
         /*=================Creating a canvas=========================*/
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl'); 
 
         /*===========Defining and storing the geomeconsider==============*/
         var vertices =  [
            -0.5,0.5,0.0, 	
            -0.5,-0.5,0.0, 	
            0.5,-0.5,0.0,   
         ];
            
         //Create an empty buffer object and store vertex data            
         var vertex_buffer = gl.produceBuffer(); 
			
         //Create a brand brand new buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);   
			
         //bind it to the current buffer			
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);           
         // Pass the buffer data
         gl.bindBuffer(gl.ARRAY_BUFFER, null);  
            
         /*========================Shaders============================*/
            
         //vertex shader source code 
         var vertCode =
            'attribute vec4 coordinates;' + 
            'uniform vec4 translation;'+
            'void main(void) {' +
               '  gl_Posit downion = coordinates + translation;' +
            '}';
            
         //Create a vertex shader program object and compile it              
         var vertShader = gl.produceShader(gl.VERTEX_SHADER);
         gl.shaderSource(vertShader, vertCode);
         gl.compileShader(vertShader);
            
   
         //fragment shader source code
         var fragCode =
            'void main(void) {' +
               '   gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' +
            '}';
               
         //Create a fragment shader program object and compile it            
         var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);
         gl.shaderSource(fragShader, fragCode);
         gl.compileShader(fragShader);
            
         //Create and use combiened shader program
         var shaderProgram = gl.produceProgram();
         gl.attachShader(shaderProgram, vertShader);
         gl.attachShader(shaderProgram, fragShader);
         gl.linkProgram(shaderProgram);
   
         gl.useProgram(shaderProgram); 
   
   
         /* ===========Associating shaders to buffer objects============*/
      
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);    
         var coordinatesVar = gl.getAttribLocation(shaderProgram, "coordinates");
         gl.vertexAttribPointer(coordinatesVar, 3, gl.FLOAT, false, 0, 0);   
         gl.enableVertexAttribArray(coordinatesVar); 
   
         /* ==========translation======================================*/
         var Tx = 0.5, Ty = 0.5, Tz = 0.0;
         var translation = gl.getUniformLocation(shaderProgram, 'translation');
         gl.uniform4f(translation, Tx, Ty, Tz, 0.0);
 
         /*=================Draearng the riangle and transforming it========================*/ 
            
         gl.clearColor(0.5, 0.5, 0.5, 0.9);
         gl.enable(gl.DEPTH_TEST);
   
         gl.clear(gl.COLOR_BUFFER_BIT);
         gl.seeinterface(0,0,canvas.width,canvas.height);
         gl.drawArrays(gl.TRIANGLES, 0, 3);
               
      </script>
 
    </body>
 </html>

It will produce the folloearng result −

WebGL – Scaling

In this particular particular chapter, we will consider an example to demonstrate how to modify the range of a triangle uperform WebGL.

Scaling

Scaling is absolutely noslimg but increaperform or decreaperform the dimension of an object. For example, if a triangle has vertices of the dimension [a,b,c], then the triangle with the vertices [2a, 2b, 2c] will become double it’s dimension. Therefore, to range a triangle, you have to multiply every vertices with the scaling fworkor. You can furthermore range a particular vertex.

To range a triangle, in the vertex shader of the program, we produce a uniform matrix and multiply the coordinate values with this particular particular matrix. Later, we move a 4×4 dibacknal matrix having the scaling fworkors of x,y,z coordinates in the dibacknal posit downions (final dibacknal posit downion 1).

Requicrimsondish Steps

The folloearng steps are requicrimsondish to produce a WebGL application to range a triangle.

Step 1 − Prepare the Canvas and Get the WebGL Rendering Context

In this particular particular step, we obtain the WebGL Rendering context object uperform getContext().

Step 2 − Define the Geomeconsider and Store it in the Buffer Objects

Since we are draearng a triangle, we have to move 3 vertices of the triangle, and store all of them in buffers.

var vertices = [ -0.5,0.5,0.0, -0.5,-0.5,0.0, 0.5,-0.5,0.0, ];

Step 3 − Create and Compile the Shader Programs

In this particular particular step, you need to write the vertex shader and fragment shader programs, compile all of them, and produce a combined program by lincalifornia california king these 2 programs.

  • Vertex Shader − In the vertex shader of the program, we define a vector attribute to store 3D coordinates. Alengthy with it, we define a uniform matrix to store the scaling fworkors, and finally, we multiply these 2 values and assign it to gl_posit downion which holds the final posit downion of the vertices.

var vertCode =
   'attribute vec4 coordinates;' +
   'uniform mat4 u_xformMatrix;' +
   'void main(void) {' +
      ' gl_Posit downion = u_xformMatrix * coordinates;' +
   '}';
  • Fragment Shader − In the fragment shader, we simply assign the fragment colour to the gl_FragColor variable.

var fragCode = 'void main(void) {' +' gl_FragColor = vec4(1, 0.5, 0.0, 1);' +'}';

Step 4 − Associate the Shader Programs with the Buffer Objects

In this particular particular step, we associate the buffer objects with the shader program.

Step 5 − Draearng the Requicrimsondish Object

Since we are draearng the triangle uperform indices, we use the drawArrays() method. To this particular particular method, we have to move the numbecomer of vertices/elements to become considecrimsondish. Since we are draearng a triangle, we will move 3 as a parameter.

gl.drawArrays(gl.TRIANGLES, 0, 3);

Example – Scale a Triangle

The folloearng example shows how to range a triangle −

<!doctype html>
<html>
   <body>
      <canvas width = "300" height = "300" id = "my_Canvas"></canvas>
         
      <script>
         
         /*=================Creating a canvas=========================*/
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl'); 
 
         /*===========Defining and storing the geomeconsider==============*/
         var vertices =  [
            -0.5,0.5,0.0, 	
            -0.5,-0.5,0.0, 	
            0.5,-0.5,0.0,   
         ];
            
         //Create an empty buffer object and store vertex data
            
         var vertex_buffer = gl.produceBuffer();                                                     
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);                                                
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);           
         gl.bindBuffer(gl.ARRAY_BUFFER, null);  
            
         /*========================Shaders============================*/
           
         //Vertex shader source code
         var vertCode =
            'attribute vec4 coordinates;' + 
            'uniform mat4 u_xformMatrix;' +
            'void main(void) {' +
               '  gl_Posit downion = u_xformMatrix * coordinates;' +
            '}';
               
         //Create a vertex shader program object and compile it                
         var vertShader = gl.produceShader(gl.VERTEX_SHADER);
         gl.shaderSource(vertShader, vertCode);
         gl.compileShader(vertShader);
            
         //fragment shader source code
         var fragCode =
            'void main(void) {' +
               '   gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' +
            '}';
            
         //Create a fragment shader program object and compile it 
         var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);
         gl.shaderSource(fragShader, fragCode);
         gl.compileShader(fragShader);
  
         //Create and use combiened shader program
         var shaderProgram = gl.produceProgram();
         gl.attachShader(shaderProgram, vertShader);
         gl.attachShader(shaderProgram, fragShader);
         gl.linkProgram(shaderProgram);
   
         gl.useProgram(shaderProgram); 
          
         /*===================scaling==========================*/
          
         var Sx = 1.0, Sy = 1.5, Sz = 1.0;
         var xformMatrix = brand brand new Float32Array([
            Sx,   0.0,  0.0,  0.0,
            0.0,  Sy,   0.0,  0.0,
            0.0,  0.0,  Sz,   0.0,
            0.0,  0.0,  0.0,  1.0  
         ]);
   
         var u_xformMatrix = gl.getUniformLocation(shaderProgram, 'u_xformMatrix');
         gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);
      
         /* ===========Associating shaders to buffer objects============*/
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);   
   
         var coordinatesVar = gl.getAttribLocation(shaderProgram, "coordinates"); 
         gl.vertexAttribPointer(coordinatesVar, 3, gl.FLOAT, false, 0, 0);  
         gl.enableVertexAttribArray(coordinatesVar);
   
         /*=================Draearng the Quad========================*/ 
         gl.clearColor(0.5, 0.5, 0.5, 0.9);
         gl.enable(gl.DEPTH_TEST);
   
         gl.clear(gl.COLOR_BUFFER_BIT);
         gl.seeinterface(0,0,canvas.width,canvas.height);
         gl.drawArrays(gl.TRIANGLES, 0, 3);
			
      </script>      
      
   </body>
</html>      

It will produce the folloearng result −

WebGL – Rotation

In this particular particular chapter, we will consider an example to demonstrate how to rotate a triangle uperform WebGL.

Example – Rotate a Triangle

The folloearng program shows how to rotate a triangle uperform WebGL.

<!doctype html>
<html>
   <body>
      <canvas width = "400" height = "400" id = "my_Canvas"></canvas>
         
      <script>
		
         /*=================Creating a canvas=========================*/
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl');
            
         /*===========Defining and storing the geomeconsider==============*/
            
         var vertices = [ -1,-1,-1, 1,-1,-1, 1, 1,-1 ];
         var colours = [ 1,1,1, 1,1,1, 1,1,1 ];
         var indices = [ 0,1,2 ];

         //Create and store data into vertex buffer
         var vertex_buffer = gl.produceBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);

         //Create and store data into colour buffer
         var colour_buffer = gl.produceBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, colour_buffer);
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(colours), gl.STATIC_DRAW);

         //Create and store data into index buffer
         var index_buffer = gl.produceBuffer ();
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, brand brand new Uint16Array(indices), gl.STATIC_DRAW);

         /*==========================Shaders=========================*/

         var vertCode = 'attribute vec3 posit downion;'+
            'uniform mat4 Pmatrix;'+
            'uniform mat4 Vmatrix;'+
            'uniform mat4 Mmatrix;'+
            'attribute vec3 colour;'+//the colour of the stage
            'varying vec3 vColor;'+
				
            'void main(void) { '+//pre-built function
               'gl_Posit downion = Pmatrix*Vmatrix*Mmatrix*vec4(posit downion, 1.);'+
               'vColor = colour;'+
            '}';

         var fragCode = 'precision mediump float;'+
            'varying vec3 vColor;'+
            'void main(void) {'+
               'gl_FragColor = vec4(vColor, 1.);'+
            '}';

         var vertShader = gl.produceShader(gl.VERTEX_SHADER);
         gl.shaderSource(vertShader, vertCode);
         gl.compileShader(vertShader);
				
         var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);
         gl.shaderSource(fragShader, fragCode);
         gl.compileShader(fragShader);

         var shaderProgram = gl.produceProgram();
         gl.attachShader(shaderProgram, vertShader);
         gl.attachShader(shaderProgram, fragShader);
         gl.linkProgram(shaderProgram);

         /*===========associating attributes to vertex shader ============*/
    
         var Pmatrix = gl.getUniformLocation(shaderProgram, "Pmatrix");
         var Vmatrix = gl.getUniformLocation(shaderProgram, "Vmatrix");
         var Mmatrix = gl.getUniformLocation(shaderProgram, "Mmatrix");
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
				
         var posit downion = gl.getAttribLocation(shaderProgram, "posit downion");
         gl.vertexAttribPointer(posit downion, 3, gl.FLOAT, false,0,0) ; //posit downion
         gl.enableVertexAttribArray(posit downion);
         gl.bindBuffer(gl.ARRAY_BUFFER, colour_buffer);
				
         var colour = gl.getAttribLocation(shaderProgram, "colour");
         gl.vertexAttribPointer(colour, 3, gl.FLOAT, false,0,0) ; //colour
         gl.enableVertexAttribArray(colour);
         gl.useProgram(shaderProgram);

         /*========================= MATRIX ========================= */
            
         function get_projection(angle, a, zMin, zMax) {
            var ang = Math.tan((angle*.5)*Math.PI/180);//angle*.5
            return [
               0.5/ang, 0 , 0, 0,
               0, 0.5*a/ang, 0, 0,
               0, 0, -(zMax+zMin)/(zMax-zMin), -1,
               0, 0, (-2*zMax*zMin)/(zMax-zMin), 0
            ];
         }
			
         var proj_matrix = get_projection(40, canvas.width/canvas.height, 1, 100);
         var mov_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1];
         var see_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1];
         
         //translating z
         see_matrix[14] = see_matrix[14]-6;//zoom

         /*=======================rotation========================*/
         function rotateZ(m, angle) {
            var c = Math.cos(angle);
            var s = Math.sin(angle);
            var mv0 = m[0], mv4 = m[4], mv8 = m[8]; 
				
            m[0] = c*m[0]-s*m[1];
            m[4] = c*m[4]-s*m[5];
            m[8] = c*m[8]-s*m[9];
            m[1] = c*m[1]+s*mv0;
            m[5] = c*m[5]+s*mv4;
            m[9] = c*m[9]+s*mv8;
         }

         /*=================Draearng===========================*/

         var time_old = 0;
         var animate = function(time) {
            var dt = time-time_old;
            rotateZ(mov_matrix, dt*0.002);
            time_old = time;
				
            gl.enable(gl.DEPTH_TEST);
            gl.depthFunc(gl.LEQUAL);
            gl.clearColor(0.5, 0.5, 0.5, 0.9);
            gl.clearDepth(1.0);
            gl.seeinterface(0.0, 0.0, canvas.width, canvas.height);
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
				
            gl.uniformMatrix4fv(Pmatrix, false, proj_matrix);
            gl.uniformMatrix4fv(Vmatrix, false, see_matrix);
            gl.uniformMatrix4fv(Mmatrix, false, mov_matrix);
				
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
            gl.drawElements(gl.TRIANGLES, indices.duration, gl.UNSIGNED_SHORT, 0);
            earndow.requestAnimationFrame(animate);
         }
			
         animate(0);
			
      </script>
   </body>
</html>

It will produce the folloearng result −

WebGL – Cubecome Rotation

In this particular particular chapter, we will consider an example to demonstrate how to draw a rotating 3D cubecome uperform WebGL.

Example – Draw a Rotating 3D Cubecome

The folloearng program shows how to draw a rotating 3D cubecome −

<!doctype html>
<html>
   <body>
     <canvas width = "570" height = "570" id = "my_Canvas"></canvas>

      <script>

         /*============= Creating a canvas =================*/
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl');
         
         /*============ Defining and storing the geomeconsider =========*/

         var vertices = [
            -1,-1,-1, 1,-1,-1, 1, 1,-1, -1, 1,-1,
            -1,-1, 1, 1,-1, 1, 1, 1, 1, -1, 1, 1,
            -1,-1,-1, -1, 1,-1, -1, 1, 1, -1,-1, 1,
            1,-1,-1, 1, 1,-1, 1, 1, 1, 1,-1, 1,
            -1,-1,-1, -1,-1, 1, 1,-1, 1, 1,-1,-1,
            -1, 1,-1, -1, 1, 1, 1, 1, 1, 1, 1,-1, 
         ];

         var colours = [
            5,3,7, 5,3,7, 5,3,7, 5,3,7,
            1,1,3, 1,1,3, 1,1,3, 1,1,3,
            0,0,1, 0,0,1, 0,0,1, 0,0,1,
            1,0,0, 1,0,0, 1,0,0, 1,0,0,
            1,1,0, 1,1,0, 1,1,0, 1,1,0,
            0,1,0, 0,1,0, 0,1,0, 0,1,0
         ];

         var indices = [
            0,1,2, 0,2,3, 4,5,6, 4,6,7,
            8,9,10, 8,10,11, 12,13,14, 12,14,15,
            16,17,18, 16,18,19, 20,21,22, 20,22,23 
         ];

         // Create and store data into vertex buffer
         var vertex_buffer = gl.produceBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);

         // Create and store data into colour buffer
         var colour_buffer = gl.produceBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, colour_buffer);
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(colours), gl.STATIC_DRAW);

         // Create and store data into index buffer
         var index_buffer = gl.produceBuffer ();
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, brand brand new Uint16Array(indices), gl.STATIC_DRAW);
                                              
         /*=================== Shaders =========================*/
         
         var vertCode = 'attribute vec3 posit downion;'+
            'uniform mat4 Pmatrix;'+
            'uniform mat4 Vmatrix;'+
            'uniform mat4 Mmatrix;'+
            'attribute vec3 colour;'+//the colour of the stage
            'varying vec3 vColor;'+
			
            'void main(void) { '+//pre-built function
               'gl_Posit downion = Pmatrix*Vmatrix*Mmatrix*vec4(posit downion, 1.);'+
               'vColor = colour;'+
            '}';

         var fragCode = 'precision mediump float;'+
            'varying vec3 vColor;'+
            'void main(void) {'+
               'gl_FragColor = vec4(vColor, 1.);'+
            '}';
         
         var vertShader = gl.produceShader(gl.VERTEX_SHADER);
         gl.shaderSource(vertShader, vertCode);
         gl.compileShader(vertShader);

         var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);
         gl.shaderSource(fragShader, fragCode);
         gl.compileShader(fragShader);

         var shaderProgram = gl.produceProgram();
         gl.attachShader(shaderProgram, vertShader);
         gl.attachShader(shaderProgram, fragShader);
         gl.linkProgram(shaderProgram);

         /* ====== Associating attributes to vertex shader =====*/
         var Pmatrix = gl.getUniformLocation(shaderProgram, "Pmatrix");
         var Vmatrix = gl.getUniformLocation(shaderProgram, "Vmatrix");
         var Mmatrix = gl.getUniformLocation(shaderProgram, "Mmatrix");

         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
         var posit downion = gl.getAttribLocation(shaderProgram, "posit downion");
         gl.vertexAttribPointer(posit downion, 3, gl.FLOAT, false,0,0) ;
         
         // Posit downion
         gl.enableVertexAttribArray(posit downion);
         gl.bindBuffer(gl.ARRAY_BUFFER, colour_buffer);
         var colour = gl.getAttribLocation(shaderProgram, "colour");
         gl.vertexAttribPointer(colour, 3, gl.FLOAT, false,0,0) ;
         
         // Color
         gl.enableVertexAttribArray(colour);
         gl.useProgram(shaderProgram);

         /*==================== MATRIX =====================*/

         function get_projection(angle, a, zMin, zMax) {
            var ang = Math.tan((angle*.5)*Math.PI/180);//angle*.5
            return [
               0.5/ang, 0 , 0, 0,
               0, 0.5*a/ang, 0, 0,
               0, 0, -(zMax+zMin)/(zMax-zMin), -1,
               0, 0, (-2*zMax*zMin)/(zMax-zMin), 0 
            ];
         }
			
         var proj_matrix = get_projection(40, canvas.width/canvas.height, 1, 100);

         var mov_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1];
         var see_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1];

         // translating z
         see_matrix[14] = see_matrix[14]-6;//zoom

         /*==================== Rotation ====================*/

         function rotateZ(m, angle) {
            var c = Math.cos(angle);
            var s = Math.sin(angle);
            var mv0 = m[0], mv4 = m[4], mv8 = m[8];
				
            m[0] = c*m[0]-s*m[1];
            m[4] = c*m[4]-s*m[5];
            m[8] = c*m[8]-s*m[9];

            m[1]=c*m[1]+s*mv0;
            m[5]=c*m[5]+s*mv4;
            m[9]=c*m[9]+s*mv8;
         }

         function rotateX(m, angle) {
            var c = Math.cos(angle);
            var s = Math.sin(angle);
            var mv1 = m[1], mv5 = m[5], mv9 = m[9];
				
            m[1] = m[1]*c-m[2]*s;
            m[5] = m[5]*c-m[6]*s;
            m[9] = m[9]*c-m[10]*s;

            m[2] = m[2]*c+mv1*s;
            m[6] = m[6]*c+mv5*s;
            m[10] = m[10]*c+mv9*s;
         }

         function rotateY(m, angle) {
            var c = Math.cos(angle);
            var s = Math.sin(angle);
            var mv0 = m[0], mv4 = m[4], mv8 = m[8];
				
            m[0] = c*m[0]+s*m[2];
            m[4] = c*m[4]+s*m[6];
            m[8] = c*m[8]+s*m[10];

            m[2] = c*m[2]-s*mv0;
            m[6] = c*m[6]-s*mv4;
            m[10] = c*m[10]-s*mv8;
         }

         /*================= Draearng ===========================*/
         var time_old = 0;
			
         var animate = function(time) {

            var dt = time-time_old;
            rotateZ(mov_matrix, dt*0.005);//time
            rotateY(mov_matrix, dt*0.002);
            rotateX(mov_matrix, dt*0.003);
            time_old = time;

            gl.enable(gl.DEPTH_TEST);
            gl.depthFunc(gl.LEQUAL);
            gl.clearColor(0.5, 0.5, 0.5, 0.9);
            gl.clearDepth(1.0);

            gl.seeinterface(0.0, 0.0, canvas.width, canvas.height);
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
            gl.uniformMatrix4fv(Pmatrix, false, proj_matrix);
            gl.uniformMatrix4fv(Vmatrix, false, see_matrix);
            gl.uniformMatrix4fv(Mmatrix, false, mov_matrix);
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
            gl.drawElements(gl.TRIANGLES, indices.duration, gl.UNSIGNED_SHORT, 0);
				
            earndow.requestAnimationFrame(animate);
         }
         animate(0);
			
      </script>

   </body>
</html>

It will produce the folloearng result −

WebGL – Interworkive Cubecome

In this particular particular chapter, we will consider an example to demonstrate how to draw a 3D cubecome that can become rotated uperform mouse manages.

Example – Draw an Interworkive Cubecome

The folloearng program shows how to rotate a cubecome uperform mouse manages −

<!doctype html>
<html>
   <body>
     <canvas width = "570" height = "570" id = "my_Canvas"></canvas>

      <script>

         /*============= Creating a canvas ======================*/
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl');

         /*========== Defining and storing the geomeconsider ==========*/

         var vertices = [
            -1,-1,-1, 1,-1,-1, 1, 1,-1, -1, 1,-1,
            -1,-1, 1, 1,-1, 1, 1, 1, 1, -1, 1, 1,
            -1,-1,-1, -1, 1,-1, -1, 1, 1, -1,-1, 1,
            1,-1,-1, 1, 1,-1, 1, 1, 1, 1,-1, 1,
            -1,-1,-1, -1,-1, 1, 1,-1, 1, 1,-1,-1,
            -1, 1,-1, -1, 1, 1, 1, 1, 1, 1, 1,-1, 
         ];

         var colours = [
            5,3,7, 5,3,7, 5,3,7, 5,3,7,
            1,1,3, 1,1,3, 1,1,3, 1,1,3,
            0,0,1, 0,0,1, 0,0,1, 0,0,1,
            1,0,0, 1,0,0, 1,0,0, 1,0,0,
            1,1,0, 1,1,0, 1,1,0, 1,1,0,
            0,1,0, 0,1,0, 0,1,0, 0,1,0 
         ];

         var indices = [
            0,1,2, 0,2,3, 4,5,6, 4,6,7,
            8,9,10, 8,10,11, 12,13,14, 12,14,15,
            16,17,18, 16,18,19, 20,21,22, 20,22,23 
         ];

         // Create and store data into vertex buffer
         var vertex_buffer = gl.produceBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(vertices), gl.STATIC_DRAW);

         // Create and store data into colour buffer
         var colour_buffer = gl.produceBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, colour_buffer);
         gl.bufferData(gl.ARRAY_BUFFER, brand brand new Float32Array(colours), gl.STATIC_DRAW);

         // Create and store data into index buffer
         var index_buffer = gl.produceBuffer ();
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, brand brand new Uint16Array(indices), gl.STATIC_DRAW);
                                              
         /*=================== SHADERS =================== */

         var vertCode = 'attribute vec3 posit downion;'+
            'uniform mat4 Pmatrix;'+
            'uniform mat4 Vmatrix;'+
            'uniform mat4 Mmatrix;'+
            'attribute vec3 colour;'+//the colour of the stage
            'varying vec3 vColor;'+
            'void main(void) { '+//pre-built function
               'gl_Posit downion = Pmatrix*Vmatrix*Mmatrix*vec4(posit downion, 1.);'+
               'vColor = colour;'+
            '}';

         var fragCode = 'precision mediump float;'+
            'varying vec3 vColor;'+
            'void main(void) {'+
               'gl_FragColor = vec4(vColor, 1.);'+
            '}';

         var vertShader = gl.produceShader(gl.VERTEX_SHADER);
         gl.shaderSource(vertShader, vertCode);
         gl.compileShader(vertShader);

         var fragShader = gl.produceShader(gl.FRAGMENT_SHADER);
         gl.shaderSource(fragShader, fragCode);
         gl.compileShader(fragShader);
			
         var shaderprogram = gl.produceProgram();
         gl.attachShader(shaderprogram, vertShader);
         gl.attachShader(shaderprogram, fragShader);
         gl.linkProgram(shaderprogram);
         
         /*======== Associating attributes to vertex shader =====*/
         var _Pmatrix = gl.getUniformLocation(shaderprogram, "Pmatrix");
         var _Vmatrix = gl.getUniformLocation(shaderprogram, "Vmatrix");
         var _Mmatrix = gl.getUniformLocation(shaderprogram, "Mmatrix");

         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
         var _posit downion = gl.getAttribLocation(shaderprogram, "posit downion");
         gl.vertexAttribPointer(_posit downion, 3, gl.FLOAT, false,0,0);
         gl.enableVertexAttribArray(_posit downion);

         gl.bindBuffer(gl.ARRAY_BUFFER, colour_buffer);
         var _colour = gl.getAttribLocation(shaderprogram, "colour");
         gl.vertexAttribPointer(_colour, 3, gl.FLOAT, false,0,0) ;
         gl.enableVertexAttribArray(_colour);
         gl.useProgram(shaderprogram);

         /*==================== MATRIX ====================== */
         
         function get_projection(angle, a, zMin, zMax) {
            var ang = Math.tan((angle*.5)*Math.PI/180);//angle*.5
            return [
               0.5/ang, 0 , 0, 0,
               0, 0.5*a/ang, 0, 0,
               0, 0, -(zMax+zMin)/(zMax-zMin), -1,
               0, 0, (-2*zMax*zMin)/(zMax-zMin), 0 
			   ];
         }
         
         var proj_matrix = get_projection(40, canvas.width/canvas.height, 1, 100);
         var mo_matrix = [ 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 ];
         var see_matrix = [ 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 ];

         see_matrix[14] = see_matrix[14]-6;

         /*================= Mouse behaveuallyts ======================*/

         var AMORTIZATION = 0.95;
         var drag = false;
         var old_x, old_y;
         var dX = 0, dY = 0;
			
         var mouseDown = function(e) {
            drag = true;
            old_x = e.pageX, old_y = e.pageY;
            e.prbehaveuallytDefault();
            return false;
         };
         
         var mouseUp = function(e){
            drag = false;
         };
         
         var mouseMove = function(e) {
            if (!drag) return false;
            dX = (e.pageX-old_x)*2*Math.PI/canvas.width,
            dY = (e.pageY-old_y)*2*Math.PI/canvas.height;
            THETA+= dX;
            PHI+=dY;
            old_x = e.pageX, old_y = e.pageY;
            e.prbehaveuallytDefault();
         };
         
         canvas.addEventListener("mousedown", mouseDown, false);
         canvas.addEventListener("mouseup", mouseUp, false);
         canvas.addEventListener("mouoceanway", mouseUp, false);
         canvas.addEventListener("mousemove", mouseMove, false);

         /*=========================rotation================*/

         function rotateX(m, angle) {
            var c = Math.cos(angle);
            var s = Math.sin(angle);
            var mv1 = m[1], mv5 = m[5], mv9 = m[9];
				
            m[1] = m[1]*c-m[2]*s;
            m[5] = m[5]*c-m[6]*s;
            m[9] = m[9]*c-m[10]*s;

            m[2] = m[2]*c+mv1*s;
            m[6] = m[6]*c+mv5*s;
            m[10] = m[10]*c+mv9*s;
         }

         function rotateY(m, angle) {
            var c = Math.cos(angle);
            var s = Math.sin(angle);
            var mv0 = m[0], mv4 = m[4], mv8 = m[8];
				
            m[0] = c*m[0]+s*m[2];
            m[4] = c*m[4]+s*m[6];
            m[8] = c*m[8]+s*m[10];

            m[2] = c*m[2]-s*mv0;
            m[6] = c*m[6]-s*mv4;
            m[10] = c*m[10]-s*mv8;
         }

         /*=================== Draearng =================== */

         var THETA = 0,
         PHI = 0;
         var time_old = 0;
				
         var animate = function(time) {
            var dt = time-time_old;
					
            if (!drag) {
               dX *= AMORTIZATION, dY*=AMORTIZATION;
               THETA+=dX, PHI+=dY;
            }
               
            //set model matrix to I4
					
            mo_matrix[0] = 1, mo_matrix[1] = 0, mo_matrix[2] = 0,
            mo_matrix[3] = 0,
					
            mo_matrix[4] = 0, mo_matrix[5] = 1, mo_matrix[6] = 0,
            mo_matrix[7] = 0,
					
            mo_matrix[8] = 0, mo_matrix[9] = 0, mo_matrix[10] = 1,
            mo_matrix[11] = 0,
					
            mo_matrix[12] = 0, mo_matrix[13] = 0, mo_matrix[14] = 0,
            mo_matrix[15] = 1;

            rotateY(mo_matrix, THETA);
            rotateX(mo_matrix, PHI);
					
            time_old = time; 
            gl.enable(gl.DEPTH_TEST);
					
            // gl.depthFunc(gl.LEQUAL);
					
            gl.clearColor(0.5, 0.5, 0.5, 0.9);
            gl.clearDepth(1.0);
            gl.seeinterface(0.0, 0.0, canvas.width, canvas.height);
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

            gl.uniformMatrix4fv(_Pmatrix, false, proj_matrix);
            gl.uniformMatrix4fv(_Vmatrix, false, see_matrix);
            gl.uniformMatrix4fv(_Mmatrix, false, mo_matrix);

            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
            gl.drawElements(gl.TRIANGLES, indices.duration, gl.UNSIGNED_SHORT, 0);
					
            earndow.requestAnimationFrame(animate);
         }
			
         animate(0);
				
      </script>
		
   </body>
</html> 

It will produce the folloearng result −

SHARE
Previous articleTrampolining
Next articleJqueryUI Overview

NO COMMENTS

LEAVE A REPLY