1
+ < html >
2
+ < head >
3
+ < title > WebGL - Rotating Cuboid in 3D virtual world</ title >
4
+ </ head >
5
+ < link rel ="stylesheet " href ="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css " integrity ="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u " crossorigin ="anonymous ">
6
+ < body onload ="InitDemo(); ">
7
+ < div class ="main ">
8
+ < div class ="left_pane col-lg-2 ">
9
+ < br > < br > < br > < br >
10
+ < button type ="button " id ="xAxis " onclick ="setXAxis() " class ="btn btn-primary "> X-axis</ button >
11
+ < br > < br > < br > < br >
12
+ < button type ="button " id ="yAxis " onclick ="setYAxis() " class ="btn btn-primary "> Y-axis</ button >
13
+ < br > < br > < br > < br >
14
+ < button type ="button " id ="zAxis " onclick ="setZAxis() " class ="btn btn-primary "> Z-axis</ button >
15
+ </ div >
16
+ < div class ="canvas_div col-lg-9 ">
17
+ < canvas id ="canvasId "> </ canvas >
18
+ </ div >
19
+ </ div >
20
+ < script src ="gl-matrix.js "> </ script >
21
+
22
+ < script >
23
+ var gl ;
24
+ var program ;
25
+ var lineX = 1 ;
26
+ var lineY = 0 ;
27
+ var lineZ = 0 ;
28
+
29
+ var InitDemo = function ( ) {
30
+
31
+ var canvas = document . getElementById ( 'canvasId' ) ;
32
+
33
+ windoWidth = window . innerWidth ;
34
+ windowHeight = window . innerHeight ;
35
+
36
+ canvas . width = windoWidth * 0.8 ;
37
+ canvas . height = windowHeight * 0.98 ;
38
+
39
+ gl = getWebGLContext ( canvas ) ;
40
+
41
+ //Step 1: Clear the background color
42
+ gl . clearColor ( 0 , 0 , 0 , 1.0 ) ;
43
+ gl . clear ( gl . COLOR_BUFFER_BIT ) ;
44
+
45
+ //Enable and set the Depth Buffer which is used to remove the objects which are behind the front objects
46
+ //as per the camera position.
47
+ gl . clear ( gl . DEPTH_BUFFER_BIT ) ;
48
+ gl . enable ( gl . DEPTH_TEST ) ;
49
+
50
+ //Enable and remove back facing objects not in the camera sight.
51
+ gl . enable ( gl . CULL_FACE ) ;
52
+ gl . cullFace ( gl . BACK ) ;
53
+
54
+ //Specify how the front face has to be considered. Either Counter Clock Wise (CCW) or Clock Wise(CW).
55
+ gl . frontFace ( gl . CCW ) ;
56
+
57
+
58
+ //Step 2:- Define the vertices of the 3 D geometry and the indices to create the desired geometry.in a JS array.
59
+ var cuboidVerticesArrayJS =
60
+ [ // X, Y, Z
61
+ 0 , 0 , 10 , //A
62
+ 20 , 0 , 10 , //B
63
+ 20 , 30 , 10 , //C
64
+ 0 , 30 , 10 , //D
65
+ 0 , 0 , 0 , //E
66
+ 20 , 0 , 0 , //F
67
+ 20 , 30 , 0 , //G
68
+ 0 , 30 , 0 , //H
69
+ ] ;
70
+
71
+ var cuboidIndicesArrayJS =
72
+ [
73
+ //A-0 B-1 C-2 D-3 E-4 F-5 G-6 H-7
74
+ //Front
75
+ 0 , 1 , 2 , // ABC
76
+ 0 , 2 , 3 , //ACD
77
+ //Back
78
+ 4 , 6 , 5 , //EGF
79
+ 4 , 7 , 6 , //EHG
80
+ //TOP
81
+ 7 , 3 , 2 , //HDC
82
+ 7 , 2 , 6 , //HCG
83
+ // BOTTOM
84
+ 0 , 4 , 1 , //AEB
85
+ 1 , 4 , 5 , //BEF
86
+ //LEFT
87
+ 0 , 3 , 4 , //ADE
88
+ 3 , 7 , 4 , //DHE
89
+ //RIGHT
90
+ 2 , 1 , 5 , //CBF
91
+ 2 , 5 , 6 //CFG
92
+ ] ;
93
+
94
+
95
+ //Step 3: Create buffers for vertices and indices arrays.
96
+ var rectVBO = gl . createBuffer ( ) ;
97
+ gl . bindBuffer ( gl . ARRAY_BUFFER , rectVBO ) ;
98
+ gl . bufferData ( gl . ARRAY_BUFFER , new Float32Array ( cuboidVerticesArrayJS ) , gl . STATIC_DRAW ) ;
99
+
100
+
101
+ //Step 4: Pass the vertex and indices data fron the JS array to the buffers created in Step 3.
102
+ var rectIBO = gl . createBuffer ( ) ;
103
+ gl . bindBuffer ( gl . ELEMENT_ARRAY_BUFFER , rectIBO ) ;
104
+ gl . bufferData ( gl . ELEMENT_ARRAY_BUFFER , new Uint16Array ( cuboidIndicesArrayJS ) , gl . STATIC_DRAW ) ;
105
+
106
+
107
+ // Create shaders
108
+ //Step 5: Define vertex and fragment shader as JS text.
109
+ //The proj, view and tran matrices are declared as uniform as all the shaders have to have the same copy
110
+ //of these matrices.
111
+ var vertexShaderText =
112
+ ' precision mediump float; ' +
113
+ ' attribute vec3 verticesGPU; ' +
114
+ ' uniform mat4 projMatGPU; ' +
115
+ ' uniform mat4 viewMatGPU; ' +
116
+ ' uniform mat4 tranMatGPU; ' +
117
+ ' void main() ' +
118
+ ' { ' +
119
+ ' gl_Position = projMatGPU * viewMatGPU * tranMatGPU * vec4(verticesGPU, 1.0); ' +
120
+ ' } ' ;
121
+
122
+ var fragmentShaderText =
123
+ ' void main() ' +
124
+ ' { ' +
125
+ ' gl_FragColor = vec4(0, 1, 0, 1); ' +
126
+ ' } ' ;
127
+
128
+
129
+ //Step 6: Create the validated shader program with the vertex shader and fragment shader text.
130
+ program = getShaderProgram ( vertexShaderText , fragmentShaderText ) ;
131
+
132
+
133
+ //Step 7: Get pointer to the vertices defined in vertex shader using shader program.
134
+ var verticesGPUPointer = gl . getAttribLocation ( program , 'verticesGPU' ) ;
135
+
136
+
137
+ //Step 8: State how vertex shader will fetch vertices data from the buffer using a pointer defined previously.
138
+ gl . vertexAttribPointer (
139
+ verticesGPUPointer , // Attribute location
140
+ 3 , // Number of elements per attribute
141
+ gl . FLOAT , // Type of elements
142
+ gl . FALSE ,
143
+ 3 * Float32Array . BYTES_PER_ELEMENT , // Size of an individual vertex
144
+ 0 // Offset from the beginning of a single vertex to this attribute
145
+ ) ;
146
+
147
+
148
+ //Step 9: Enable GPU vertices pointer and start using the shader program.
149
+ gl . enableVertexAttribArray ( verticesGPUPointer ) ;
150
+ gl . useProgram ( program ) ;
151
+
152
+
153
+ //Step 10: Get pointer from shader program for view and projection matrices.
154
+ var viewMatGPUPointer = gl . getUniformLocation ( program , 'viewMatGPU' ) ;
155
+ var projMatGPUPointer = gl . getUniformLocation ( program , 'projMatGPU' ) ;
156
+ var tranMatGPUPointer = gl . getUniformLocation ( program , 'tranMatGPU' ) ;
157
+
158
+
159
+ //Step 11: Create JS array for view and projection related information.
160
+ var viewArrayJS = new Float32Array ( 16 ) ;
161
+ var projArrayJS = new Float32Array ( 16 ) ;
162
+ var tranArrayJS = new Float32Array ( 16 ) ;
163
+
164
+
165
+ //Step 12: Specify view related information to lookAt() method
166
+ //and projection related information to perspective() method to get the view and the projection matrix.
167
+ mat4 . lookAt ( viewArrayJS , [ 0 , 20 , 100 ] , [ 0 , 0 , 0 ] , [ 0 , 1 , 0 ] ) ;
168
+ mat4 . perspective ( projArrayJS , glMatrix . toRadian ( 45 ) , canvas . clientWidth / canvas . clientHeight , 0.1 , 1000.0 ) ;
169
+
170
+ //mat4.identitye(tranArrayJS);
171
+ //mat4.rotate(tranArrayJS, tranArrayJS, 30, [0,1,0]);
172
+
173
+ //Step 13: Pass the view and projection information out of
174
+ //JS arrays defined in previous step to vertex shader variables.
175
+ gl . uniformMatrix4fv ( viewMatGPUPointer , gl . FALSE , viewArrayJS ) ;
176
+ gl . uniformMatrix4fv ( projMatGPUPointer , gl . FALSE , projArrayJS ) ;
177
+
178
+
179
+ //Step 14: Finally, issue the draw command.
180
+ var angle = 0 ;
181
+ angle = Math . PI / 30 ;
182
+ var identityMatrix = new Float32Array ( 16 ) ;
183
+ mat4 . identity ( identityMatrix ) ;
184
+ var loop = function ( ) {
185
+ angle = angle + 0.02 ;
186
+ mat4 . rotate ( tranArrayJS , identityMatrix , angle , [ lineX , lineY , lineZ ] ) ; //Rotation around standard X
187
+ //mat4.rotate(tranArrayJS, identityMatrix, angle, [1, 0, 0]); //Rotation around standard X
188
+ //mat4.rotate(tranArrayJS, identityMatrix, angle, [0, 1, 0]); //Rotation around standard Y
189
+ //mat4.rotate(tranArrayJS, identityMatrix, angle, [0, 0, 1]); ////Rotation around standard Z
190
+ gl . uniformMatrix4fv ( tranMatGPUPointer , gl . FALSE , tranArrayJS ) ;
191
+ gl . clear ( gl . COLOR_BUFFER_BIT ) ;
192
+ gl . drawElements ( gl . TRIANGLES , cuboidIndicesArrayJS . length , gl . UNSIGNED_SHORT , 0 ) ;
193
+ requestAnimationFrame ( loop ) ;
194
+ } ;
195
+ requestAnimationFrame ( loop ) ;
196
+ } ;
197
+
198
+ function getShaderProgram ( vertexShaderText , fragmentShaderText )
199
+ {
200
+ var vertexShader = gl . createShader ( gl . VERTEX_SHADER ) ;
201
+ var fragmentShader = gl . createShader ( gl . FRAGMENT_SHADER ) ;
202
+
203
+ gl . shaderSource ( vertexShader , vertexShaderText ) ;
204
+ gl . shaderSource ( fragmentShader , fragmentShaderText ) ;
205
+
206
+ gl . compileShader ( vertexShader ) ;
207
+ if ( ! gl . getShaderParameter ( vertexShader , gl . COMPILE_STATUS ) ) {
208
+ console . error ( 'ERROR compiling vertex shader!' , gl . getShaderInfoLog ( vertexShader ) ) ;
209
+ return ;
210
+ }
211
+
212
+ gl . compileShader ( fragmentShader ) ;
213
+ if ( ! gl . getShaderParameter ( fragmentShader , gl . COMPILE_STATUS ) ) {
214
+ console . error ( 'ERROR compiling fragment shader!' , gl . getShaderInfoLog ( fragmentShader ) ) ;
215
+ return ;
216
+ }
217
+
218
+ var program = gl . createProgram ( ) ;
219
+
220
+ gl . attachShader ( program , vertexShader ) ;
221
+ gl . attachShader ( program , fragmentShader ) ;
222
+ gl . linkProgram ( program ) ;
223
+ if ( ! gl . getProgramParameter ( program , gl . LINK_STATUS ) ) {
224
+ console . error ( 'ERROR linking program!' , gl . getProgramInfoLog ( program ) ) ;
225
+ return ;
226
+ }
227
+
228
+ gl . validateProgram ( program ) ;
229
+ if ( ! gl . getProgramParameter ( program , gl . VALIDATE_STATUS ) ) {
230
+ console . error ( 'ERROR validating program!' , gl . getProgramInfoLog ( program ) ) ;
231
+ return ;
232
+ }
233
+ return program ;
234
+ }
235
+
236
+ function getWebGLContext ( canvas )
237
+ {
238
+ gl = canvas . getContext ( 'webgl' ) ;
239
+
240
+ if ( ! gl ) {
241
+ console . log ( 'WebGL not supported, falling back on experimental-webgl' ) ;
242
+ gl = canvas . getContext ( 'experimental-webgl' ) ;
243
+ }
244
+
245
+ if ( ! gl ) {
246
+ alert ( 'Your browser does not support WebGL' ) ;
247
+ }
248
+ return gl ;
249
+ }
250
+ function setXAxis ( ) {
251
+ lineX = 1 ;
252
+ lineY = 0 ;
253
+ lineZ = 0 ;
254
+ }
255
+ function setYAxis ( ) {
256
+ lineX = 0 ;
257
+ lineY = 1 ;
258
+ lineZ = 0 ;
259
+ }
260
+ function setZAxis ( ) {
261
+ lineX = 0 ;
262
+ lineY = 0 ;
263
+ lineZ = 1 ;
264
+ }
265
+ </ script >
266
+ </ body >
267
+ </ html >
0 commit comments