1
+ var WebGL = function ( ) {
2
+ var gl , shaderProgram ;
3
+
4
+ gl = initializeWebGL ( gl ) ;
5
+
6
+ //Step 1 (Set background color): First specify the color with the help of Quadlet(R,G,B,Alpha) and the clear the buffer related to background.
7
+ gl . clearColor ( 0 , 0 , 0 , 1.0 ) ;
8
+ gl . clear ( gl . COLOR_BUFFER_BIT ) ;
9
+ //Note: The default background color in WebGl is white.
10
+
11
+ //Step 2 (Speficy vertices data): Speficy the coordinates (X,Y,Z) of the paper plane and other information related to each coordinates.
12
+ var total_vertices = 300
13
+ var verticesDataArrayJS = [ ] ;
14
+ for ( let i = 0 ; i < total_vertices * 6 ; i ++ )
15
+ {
16
+ randomData = Math . random ( ) * 2 - 1 ;
17
+ verticesDataArrayJS . push ( randomData ) ;
18
+ }
19
+
20
+ //Step 3 (Specify how to connect the points): Specify the order with which the coordinates defined in Step 2 will be joined.
21
+ var IndicesArrayJS = [ ] ;
22
+ for ( let i = 0 ; i < total_vertices ; i ++ )
23
+ {
24
+ IndicesArrayJS . push ( i ) ;
25
+ }
26
+
27
+ //Step 4 (Create GPU meomry buffer): In the GPU for holding vertices data of type ARRAY_BUFFER.
28
+ //gl.ARRAY_BUFFER type is used for holding vertex coordinates, color, texture coordinates or other informations on the GPU memory.
29
+ var rectVBO = gl . createBuffer ( ) ;
30
+ gl . bindBuffer ( gl . ARRAY_BUFFER , rectVBO ) ;
31
+
32
+ //Step 5 (Pass the vertices data to the buffer created previously).
33
+ gl . bufferData ( gl . ARRAY_BUFFER , new Float32Array ( verticesDataArrayJS ) , gl . STATIC_DRAW ) ;
34
+ //Notes: gl.STATIC_DRAW is used to specify that the data is passed once.
35
+ //gl.DYNAMIC_DRAW is used to specify that the data may be respecified repeatedly.
36
+ //gl.STREAM_DRAW is used to specify that the data may be respecified but not frequently.
37
+
38
+ //Step 6 (Pass the indices data to GPU buffer): repeat the steps 4 and 5 for the indices data but use ELEMENT_ARRAY_BUFFER.
39
+ //ELEMENT_ARRAY_BUFFER is used for holding the indices information on the GPU memory
40
+ var rectIBO = gl . createBuffer ( ) ;
41
+ gl . bindBuffer ( gl . ELEMENT_ARRAY_BUFFER , rectIBO ) ;
42
+ gl . bufferData ( gl . ELEMENT_ARRAY_BUFFER , new Uint16Array ( IndicesArrayJS ) , gl . STATIC_DRAW ) ;
43
+
44
+ //Seven Steps Shader side coding in JS to get the shader program.
45
+ shaderProgram = getShaderProgram ( gl ) ;
46
+
47
+ //Step 14 (Use the shader program):
48
+ gl . useProgram ( shaderProgram ) ;
49
+
50
+ //Step 15 (Get access to GPU's geometry coordinates): Get the pointer to the geometry coordinates defined in vertex shader through the shader program.
51
+ var coordinatesInfoPoniter = gl . getAttribLocation ( shaderProgram , 'geometryCoordinatesGPU' ) ;
52
+ var colorInfoPointer = gl . getAttribLocation ( shaderProgram , 'colorInfoAttrib' ) ;
53
+
54
+ var tranMatGPUPointer = gl . getUniformLocation ( shaderProgram , 'tranMatGPU' ) ;
55
+
56
+ //Step 16 (Enable Vertex Attribute Array): It enables the pointer defined in Step 8 to access the vertex buffered data.
57
+ gl . enableVertexAttribArray ( coordinatesInfoPoniter ) ;
58
+ gl . enableVertexAttribArray ( colorInfoPointer ) ;
59
+ gl . enableVertexAttribArray ( tranMatGPUPointer ) ;
60
+
61
+ //Step 17 (Buffer data definition): Define how the data on the GPU buffer is arranged. SO that the pointer defined in Step 8 can access the data from the buffer.
62
+ gl . vertexAttribPointer (
63
+ coordinatesInfoPoniter , // Attribute location
64
+ 3 , // Number of elements per attribute
65
+ gl . FLOAT , // Type of elements
66
+ gl . FALSE ,
67
+ 6 * Float32Array . BYTES_PER_ELEMENT , // Size of an individual vertex
68
+ 0 // Offset from the beginning of a single vertex to this attribute
69
+ ) ;
70
+
71
+ //Also specify how the color information has been arranged in the GPU buffer for the color pointer defined in VS
72
+ gl . vertexAttribPointer (
73
+ colorInfoPointer , // Color pointer
74
+ 3 , // Number of elements per attribute
75
+ gl . FLOAT , // Type of elements
76
+ gl . FALSE , // Data Normalization
77
+ 6 * Float32Array . BYTES_PER_ELEMENT , // Size of an individual vertex
78
+ 3 * Float32Array . BYTES_PER_ELEMENT // Offset from the beginning of a single vertex to this attribute
79
+ ) ;
80
+
81
+ //Step 18 (Draw the geometry): Issue the draw command to generate the geometry as defined by the indices and the type of primitive to create.
82
+ var tranMatGPUPointer = gl . getUniformLocation ( shaderProgram , 'tranMatGPU' ) ;
83
+
84
+ var tranArrayJS = new Float32Array ( 16 ) ;
85
+
86
+ var angle = 0 ;
87
+ var xIncr = 0.1 ;
88
+ var xDirection = 1 ;
89
+ var loop = function ( ) {
90
+ //angle = performance.now() / 1000 / 6 * 2 * Math.PI;
91
+ angle += 0.005 ;
92
+ //tranArrayJS = [1,0,0,0, 0,1,0,0, 0,0,1,0, xIncr,0,0,1];
93
+ //tranArrayJS = [1,0,0,0, 0,Math.cos(angle),Math.sin(angle),0, 0,-Math.sin(angle),Math.cos(angle),0, 0,0,0,1];
94
+ tranArrayJS = [ Math . cos ( angle ) , - Math . sin ( angle ) , 0 , 0 , Math . sin ( angle ) , Math . cos ( angle ) , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 ] ; //for rotation
95
+ //xIncr += 0.005;
96
+ if ( xDirection == 1 )
97
+ {
98
+ if ( xIncr > 2 ) {
99
+ xDirection = - 1 ;
100
+ //xIncr = 0;
101
+ }
102
+ xIncr += 0.01 ;
103
+ }
104
+ else
105
+ {
106
+ xIncr -= 0.01 ;
107
+ if ( xIncr < - 2 )
108
+ xDirection = 1 ;
109
+ }
110
+
111
+ gl . uniformMatrix4fv ( tranMatGPUPointer , gl . FALSE , tranArrayJS ) ;
112
+
113
+ //gl.clearColor(0, 0, 0, 1.0);
114
+ gl . clear ( gl . COLOR_BUFFER_BIT ) ;
115
+
116
+ gl . drawElements ( gl . POINTS , IndicesArrayJS . length , gl . UNSIGNED_SHORT , 0 ) ;
117
+
118
+ requestAnimationFrame ( loop ) ;
119
+ } ;
120
+ requestAnimationFrame ( loop ) ;
121
+ } ;
122
+
123
+ function initializeWebGL ( gl )
124
+ {
125
+ var canvas = document . getElementById ( 'canvas' ) ;
126
+
127
+ canvas . width = window . innerWidth ; ;
128
+ canvas . height = window . innerHeight ; ;
129
+
130
+ gl = canvas . getContext ( 'webgl' ) ;
131
+
132
+ if ( ! gl ) {
133
+ console . log ( 'WebGL not supported, falling back on experimental-webgl' ) ;
134
+ gl = canvas . getContext ( 'experimental-webgl' ) ;
135
+ }
136
+
137
+ if ( ! gl ) {
138
+ alert ( 'Your browser does not support WebGL' ) ;
139
+ return ;
140
+ }
141
+ return gl ;
142
+ }
143
+
144
+ //Seven steps of Shader side coding
145
+ function getShaderProgram ( gl )
146
+ {
147
+ //Step 7 (Define vertex shader text): Define the code of the vertex shader in the form of JS text.
148
+ var vertexShaderText =
149
+ ' precision mediump float; ' +
150
+ ' attribute vec3 geometryCoordinatesGPU; ' +
151
+ ' attribute vec3 colorInfoAttrib; ' +
152
+ ' varying vec3 colorInfoVarying; ' +
153
+ ' uniform mat4 tranMatGPU; ' +
154
+ ' const float boundaryY = 0.8;' +
155
+ ' void main() ' +
156
+ ' { ' +
157
+ //' tranMatGPU = mat4(vec4(1.0,0.0,0.0,0.0), vec4(0.0,1.0,0.0,0.0), vec4(0.0,0.0,1.0,0.0), vec4(0.1, 0.0,0.0,1.0)) ' +
158
+ ' colorInfoVarying = colorInfoAttrib; ' +
159
+ ' gl_Position = tranMatGPU * vec4(geometryCoordinatesGPU, 1.0); ' +
160
+ ' if( gl_Position.y > boundaryY ) ' +
161
+ ' gl_Position.y = boundaryY * 2.0 - gl_Position.y;' +
162
+ ' if( gl_Position.y < -boundaryY ) ' +
163
+ ' gl_Position.y = -boundaryY * 2.0 - gl_Position.y;' +
164
+ ' gl_PointSize = 5.0; ' +
165
+ ' } ' ;
166
+
167
+ //Step 8 (Create actual vertex shader): Create the actual vertex shader with the text defined in Step 1.
168
+ var vertexShader = gl . createShader ( gl . VERTEX_SHADER ) ;
169
+ gl . shaderSource ( vertexShader , vertexShaderText ) ;
170
+
171
+ //Step 9 (Compile vertex shader):
172
+ gl . compileShader ( vertexShader ) ;
173
+ if ( ! gl . getShaderParameter ( vertexShader , gl . COMPILE_STATUS ) ) {
174
+ console . error ( 'ERROR compiling vertex shader!' , gl . getShaderInfoLog ( vertexShader ) ) ;
175
+ return ;
176
+ }
177
+
178
+ //Step 10: Repeat the above 3 steps for fragment shader.
179
+ var fragmentShaderText =
180
+ ' precision mediump float; ' +
181
+ ' varying vec3 colorInfoVarying; ' +
182
+ ' void main() ' +
183
+ ' { ' +
184
+
185
+ ' gl_FragColor = vec4(colorInfoVarying, 1); ' +
186
+ ' if(gl_FragColor.r < 0.0) ' +
187
+ ' gl_FragColor.r += 1.0; ' +
188
+ ' if(gl_FragColor.g < 0.0) ' +
189
+ ' gl_FragColor.g += 1.0; ' +
190
+ ' if(gl_FragColor.b < 0.0) ' +
191
+ ' gl_FragColor.b += 1.0; ' +
192
+ //' gl_FragColor = vec4(colorInfoVarying, 0.7); ' +
193
+ //' gl_FragColor = vec4(colorInfoVarying, 0.1); ' +
194
+ ' } ' ;
195
+
196
+ var fragmentShader = gl . createShader ( gl . FRAGMENT_SHADER ) ;
197
+ gl . shaderSource ( fragmentShader , fragmentShaderText ) ;
198
+
199
+ gl . compileShader ( fragmentShader ) ;
200
+ if ( ! gl . getShaderParameter ( fragmentShader , gl . COMPILE_STATUS ) ) {
201
+ console . error ( 'ERROR compiling fragment shader!' , gl . getShaderInfoLog ( fragmentShader ) ) ;
202
+ return ;
203
+ }
204
+
205
+ //Step 11 (Shader program): With the compiled vertex and fragment shader, create the shader program.
206
+ var shaderProgram = gl . createProgram ( ) ;
207
+ gl . attachShader ( shaderProgram , vertexShader ) ;
208
+ gl . attachShader ( shaderProgram , fragmentShader ) ;
209
+
210
+ //Step 12 (Link shader program):
211
+ gl . linkProgram ( shaderProgram ) ;
212
+ if ( ! gl . getProgramParameter ( shaderProgram , gl . LINK_STATUS ) ) {
213
+ console . error ( 'ERROR linking program!' , gl . getProgramInfoLog ( shaderProgram ) ) ;
214
+ return ;
215
+ }
216
+
217
+ //Step 13 (Validate Shader program): Checks if the shader program has been succesfully linked and can be used further.
218
+ gl . validateProgram ( shaderProgram ) ;
219
+ if ( ! gl . getProgramParameter ( shaderProgram , gl . VALIDATE_STATUS ) ) {
220
+ console . error ( 'ERROR validating program!' , gl . getProgramInfoLog ( shaderProgram ) ) ;
221
+ return ;
222
+ }
223
+ return shaderProgram ;
224
+ }
0 commit comments