1
+ < html >
2
+ < head >
3
+ < title > WebGL - Two Triangle Transform Program</ title >
4
+ </ head >
5
+ < body onload ="main() ">
6
+ < canvas id ="canvas " ondblclick ="mouseHandler() " width ="600 " height ="600 ">
7
+ Your browser does not support HTML5
8
+ </ canvas >
9
+ < br />
10
+ < script >
11
+ var mouseX , mouseY ;
12
+ var gl , shaderProgram ;
13
+ function main ( ) {
14
+ gl = initializeWebGL ( gl ) ;
15
+
16
+ //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.
17
+ gl . clearColor ( 0 , 0 , 0 , 1.0 ) ;
18
+ gl . clear ( gl . COLOR_BUFFER_BIT ) ;
19
+ //Note: The default background color in WebGl is white.
20
+
21
+ //Step 2 (Speficy vertices data): Speficy the coordinates (X,Y,Z) of the geometry and other information related to each coordinates.
22
+ // var verticesDataArrayJS =
23
+ // [ // X, Y, Z
24
+ // -0.3, 0.7, 0, //A
25
+ // 0.3, 0.7, 0, //B
26
+ // 0, 0, 0, //C
27
+ // 0.3, -0.7, 0, //D
28
+ // -0.3, -0.7, 0 //E
29
+ // ];
30
+ var verticesDataArrayJS = [ 0.2 , 0.2 ,
31
+ 0.6 , 0.2 ,
32
+ 0.4 , 0.5
33
+ ] ;
34
+ //Step 3 (Specify how to connect the points): Specify the order with which the coordinates defined in Step2 will be joined.
35
+ var IndicesArrayJS =
36
+ [
37
+ // A-0, B-1, C-2, D-3, E-4
38
+ 0 , 1 , 2 , //ABC
39
+ //2, 3, 4 //CDE
40
+ ] ;
41
+
42
+ //Step 4 (Create GPU meomry buffer): In the GPU for holding vertices data of type ARRAY_BUFFER.
43
+ var rectVBO = gl . createBuffer ( ) ;
44
+ gl . bindBuffer ( gl . ARRAY_BUFFER , rectVBO ) ;
45
+
46
+ //Step 5 (Pass the vertices data to the buffer created previously).
47
+ gl . bufferData ( gl . ARRAY_BUFFER , new Float32Array ( verticesDataArrayJS ) , gl . STATIC_DRAW ) ;
48
+
49
+ //Step 6 (Pass the indices data to GPU buffer): repeat the steps 4 and 5 for the indices data but use ELEMENT_ARRAY_BUFFER.
50
+ var rectIBO = gl . createBuffer ( ) ;
51
+ gl . bindBuffer ( gl . ELEMENT_ARRAY_BUFFER , rectIBO ) ;
52
+ gl . bufferData ( gl . ELEMENT_ARRAY_BUFFER , new Uint16Array ( IndicesArrayJS ) , gl . STATIC_DRAW ) ;
53
+
54
+ //Seven Steps Shader side coding in JS to get the shader program.
55
+ shaderProgram = getShaderProgram ( gl ) ;
56
+
57
+ //Step 14 (Use the shader program):
58
+ gl . useProgram ( shaderProgram ) ;
59
+
60
+ //Step 15 (Get access to GPU's geometry coordinates): Get the pointer to the geometry coordinates defined in vertex shader through the shader program.
61
+ var positionAttribLocation = gl . getAttribLocation ( shaderProgram , 'geometryCoordinatesGPU' ) ;
62
+
63
+ var GPU_T1 = gl . getUniformLocation ( shaderProgram , 'GPU_T1' ) ;
64
+ var GPU_T2 = gl . getUniformLocation ( shaderProgram , 'GPU_T2' ) ;
65
+ var GPU_T3 = gl . getUniformLocation ( shaderProgram , 'GPU_T3' ) ;
66
+
67
+ //Step 16 (Enable Vertex Attribute Array): It enables the pointer defined in Step 8 to access the vertex buffered data.
68
+ gl . enableVertexAttribArray ( positionAttribLocation ) ;
69
+
70
+ //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.
71
+ gl . vertexAttribPointer (
72
+ positionAttribLocation , // Attribute location
73
+ 2 , // Number of elements per attribute
74
+ gl . FLOAT , // Type of elements
75
+ gl . FALSE ,
76
+ 2 * Float32Array . BYTES_PER_ELEMENT , // Size of an individual vertex
77
+ 0 // Offset from the beginning of a single vertex to this attribute
78
+ ) ;
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 angle = 90 ;
83
+ var radian = angle * ( 3.14 / 180 ) ;
84
+ var m = - 0.4 , n = - 0.3 ;
85
+ var T1 = new Float32Array ( 16 ) ;
86
+ var T2 = new Float32Array ( 16 ) ;
87
+ var T3 = new Float32Array ( 16 ) ;
88
+
89
+ //T1 = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; //for translation
90
+ T1 = [ 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , - m , - n , 0 , 1 ] ; //for translation
91
+ //T2 = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; //for translation
92
+ T2 = [ Math . cos ( radian ) , Math . sin ( radian ) , 0 , 0 , - Math . sin ( radian ) , Math . cos ( radian ) , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 ] ; //for translation
93
+
94
+ //T3 = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; //for translation
95
+ T3 = [ 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , m , n , 0 , 1 ] ; //for translation
96
+
97
+ gl . uniformMatrix4fv ( GPU_T1 , gl . FALSE , T1 ) ;
98
+ gl . uniformMatrix4fv ( GPU_T2 , gl . FALSE , T2 ) ;
99
+ gl . uniformMatrix4fv ( GPU_T3 , gl . FALSE , T3 ) ;
100
+
101
+ animate ( ) ;
102
+
103
+ m = 0 ; n = 0 ;
104
+ function animate ( ) {
105
+ m = - mouseX ;
106
+ n = - mouseY ;
107
+ gl . clear ( gl . COLOR_BUFFER_BIT ) ;
108
+ radian += 0.03 ;
109
+ //T1 = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; //for translation
110
+ T1 = [ 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , - m , - n , 0 , 1 ] ; //for translation
111
+ //T2 = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; //for translation
112
+ T2 = [ Math . cos ( radian ) , Math . sin ( radian ) , 0 , 0 , - Math . sin ( radian ) , Math . cos ( radian ) , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 ] ; //for translation
113
+
114
+ //T3 = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; //for translation
115
+ T3 = [ 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , m , n , 0 , 1 ] ; //for translation
116
+
117
+ gl . uniformMatrix4fv ( GPU_T1 , gl . FALSE , T1 ) ;
118
+ gl . uniformMatrix4fv ( GPU_T2 , gl . FALSE , T2 ) ;
119
+ gl . uniformMatrix4fv ( GPU_T3 , gl . FALSE , T3 ) ;
120
+
121
+ gl . drawElements ( gl . TRIANGLES , IndicesArrayJS . length , gl . UNSIGNED_SHORT , 0 ) ;
122
+ requestAnimationFrame ( animate ) ;
123
+ }
124
+
125
+ gl . drawElements ( gl . TRIANGLES , IndicesArrayJS . length , gl . UNSIGNED_SHORT , 0 ) ;
126
+ }
127
+ function initializeWebGL ( gl )
128
+ {
129
+ var canvas = document . getElementById ( 'canvas' ) ;
130
+
131
+ //canvas.width = window.innerWidth;;
132
+ //canvas.height = window.innerHeight;;
133
+
134
+ gl = canvas . getContext ( 'webgl' ) ;
135
+
136
+ if ( ! gl ) {
137
+ console . log ( 'WebGL not supported, falling back on experimental-webgl' ) ;
138
+ gl = canvas . getContext ( 'experimental-webgl' ) ;
139
+ }
140
+
141
+ if ( ! gl ) {
142
+ alert ( 'Your browser does not support WebGL' ) ;
143
+ return ;
144
+ }
145
+ return gl ;
146
+ }
147
+
148
+ //Seven steps of Shader side coding
149
+ function getShaderProgram ( gl )
150
+ {
151
+ //Step 7 (Define vertex shader text): Define the code of the vertex shader in the form of JS text.
152
+ var vertexShaderText =
153
+ ' precision mediump float; ' +
154
+ ' attribute vec2 geometryCoordinatesGPU; ' +
155
+ ' uniform mat4 GPU_T1; ' +
156
+ ' uniform mat4 GPU_T2; ' +
157
+ ' uniform mat4 GPU_T3; ' +
158
+ ' void main() ' +
159
+ ' { ' +
160
+ ' gl_Position = GPU_T1 * GPU_T2 * GPU_T3 * vec4(geometryCoordinatesGPU, 0.0, 1.0); ' +
161
+ ' } ' ;
162
+
163
+ //Step 8 (Create actual vertex shader): Create the actual vertex shader with the text defined in Step 1.
164
+ var vertexShader = gl . createShader ( gl . VERTEX_SHADER ) ;
165
+ gl . shaderSource ( vertexShader , vertexShaderText ) ;
166
+
167
+ //Step 9 (Compile vertex shader):
168
+ gl . compileShader ( vertexShader ) ;
169
+ if ( ! gl . getShaderParameter ( vertexShader , gl . COMPILE_STATUS ) ) {
170
+ console . error ( 'ERROR compiling vertex shader!' , gl . getShaderInfoLog ( vertexShader ) ) ;
171
+ return ;
172
+ }
173
+
174
+ //Step 10: Repeat the above 3 steps for fragment shader.
175
+ var fragmentShaderText =
176
+ ' void main() ' +
177
+ ' { ' +
178
+ ' gl_FragColor = vec4(0, 1, 0, 1); ' +
179
+ ' } ' ;
180
+
181
+ var fragmentShader = gl . createShader ( gl . FRAGMENT_SHADER ) ;
182
+ gl . shaderSource ( fragmentShader , fragmentShaderText ) ;
183
+
184
+ gl . compileShader ( fragmentShader ) ;
185
+ if ( ! gl . getShaderParameter ( fragmentShader , gl . COMPILE_STATUS ) ) {
186
+ console . error ( 'ERROR compiling fragment shader!' , gl . getShaderInfoLog ( fragmentShader ) ) ;
187
+ return ;
188
+ }
189
+
190
+ //Step 11 (Shader program): With the compiled vertex and fragment shader, create the shader program.
191
+ var shaderProgram = gl . createProgram ( ) ;
192
+ gl . attachShader ( shaderProgram , vertexShader ) ;
193
+ gl . attachShader ( shaderProgram , fragmentShader ) ;
194
+
195
+ //Step 12 (Link shader program):
196
+ gl . linkProgram ( shaderProgram ) ;
197
+ if ( ! gl . getProgramParameter ( shaderProgram , gl . LINK_STATUS ) ) {
198
+ console . error ( 'ERROR linking program!' , gl . getProgramInfoLog ( shaderProgram ) ) ;
199
+ return ;
200
+ }
201
+
202
+ //Step 13 (Validate Shader program): Checks if the shader program has been succesfully linked and can be used further.
203
+ gl . validateProgram ( shaderProgram ) ;
204
+ if ( ! gl . getProgramParameter ( shaderProgram , gl . VALIDATE_STATUS ) ) {
205
+ console . error ( 'ERROR validating program!' , gl . getProgramInfoLog ( shaderProgram ) ) ;
206
+ return ;
207
+ }
208
+ return shaderProgram ;
209
+ }
210
+ function mouseHandler ( ) {
211
+ mouseX = event . clientX ; // Get the horizontal coordinate
212
+ mouseY = event . clientY ; // Get the vertical coordinate
213
+ mouseY = canvas . width - mouseY ;
214
+ mouseCoordinateToWebGL ( ) ;
215
+ var coor = "X coords: " + mouseX + ", Y coords: " + mouseY ;
216
+ console . log ( coor ) ;
217
+ }
218
+ function mouseCoordinateToWebGL ( ) {
219
+ // formula: low2 + (value - low1) * (high2 - low2) / (high1 - low1)
220
+ mouseX = - 1 + ( mouseX ) * 2 / canvas . width ;
221
+ mouseY = - 1 + ( mouseY ) * 2 / canvas . height ;
222
+ }
223
+ </ script >
224
+ </ body >
225
+ </ html >
0 commit comments