webgl-tools

view glass.js @ 2:9eb4c37ce415

- added set_uniform functions in glass.js - added normal matrix uniform in sanegl.js
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 16 Jun 2011 07:13:20 +0300
parents c52b17d412f3
children 56ae66e32998
line source
1 /*
2 glass - (web)gl-assistant.
3 Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
19 var gl;
20 var canvas, console;
21 var glass_data_loaded, glass_data_count;
22 var glass_progr_prog;
23 var glass_start_time = 0;
25 var glass_cb_disp = null;
26 var glass_cb_mouse = null;
27 var glass_cb_motion = null;
29 function glass_init(canv_id, cons_id)
30 {
31 if(cons_id && (console = document.getElementById(cons_id))) {
32 console.value = "";
33 }
35 if(!(canvas = document.getElementById(canv_id))) {
36 logmsg("canvas \"" + canv_id + "\" does not exist\n");
37 return false;
38 }
39 try {
40 gl = canvas.getContext("experimental-webgl");
41 }
42 catch(e) {
43 logmsg("can't get an OpenGL context\n");
44 return false;
45 }
47 var vs = create_shader(glass_progr_vs_src, gl.VERTEX_SHADER);
48 var ps = create_shader(glass_progr_ps_src, gl.FRAGMENT_SHADER);
49 if(!vs || !ps || !(glass_progr_prog = create_program(vs, ps))) {
50 logmsg("internal glass error\n");
51 return false;
52 }
54 glass_data_loaded = glass_data_count = 0;
55 return true;
56 }
58 function glass_start()
59 {
60 if(glass_cb_motion) {
61 canvas.onmousemove = function(ev) {
62 glass_cb_motion(ev.clientX, ev.clientY);
63 }
64 }
66 if(glass_cb_mouse) {
67 canvas.onmousedown = function(ev) {
68 glass_cb_mouse(ev.button, true, ev.clientX, ev.clientY);
69 }
70 canvas.onmouseup = function(ev) {
71 glass_cb_mouse(ev.button, false, ev.clientX, ev.clientY);
72 }
73 }
75 glass_start_time = get_msec();
76 glass_redraw();
77 }
79 function glass_display_func(func)
80 {
81 glass_cb_disp = func;
82 }
84 function glass_mouse_func(func)
85 {
86 glass_cb_mouse = func;
87 }
89 function glass_motion_func(func)
90 {
91 glass_cb_motion = func;
92 }
95 function glass_redraw()
96 {
97 var msec = get_msec();
99 if(glass_data_loaded < glass_data_count || !glass_cb_disp) {
100 glass_draw_progress(msec);
101 } else {
102 glass_cb_disp(msec);
103 }
104 request_redisplay(glass_redraw);
105 }
107 function get_msec()
108 {
109 return new Date().getTime() - glass_start_time;
110 }
112 /* ---- textures ---- */
113 function load_texture(name)
114 {
115 glass_data_count++;
117 var tex = gl.createTexture();
118 tex.image = new Image();
119 tex.image.onload = function() { glass_tex_load_done(tex); }
120 tex.image.onerror = glass_tex_load_failed;
121 tex.image.src = name;
122 return tex;
123 }
125 function glass_tex_load_done(tex)
126 {
127 gl.bindTexture(gl.TEXTURE_2D, tex);
128 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tex.image);
129 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
130 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
131 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
132 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
133 gl.bindTexture(gl.TEXTURE_2D, null);
134 glass_data_loaded++;
135 logmsg("loaded image: " + tex.image.src +
136 " (" + glass_data_loaded + "/" + glass_data_count + ")\n");
137 }
139 function glass_tex_load_failed()
140 {
141 logmsg("failed to load texture: " + this.src + "\n");
142 }
145 /* ---- shaders ---- */
146 function load_shader(name, type)
147 {
148 var xhr = new XMLHttpRequest();
149 xhr.open("GET", name, false);
150 xhr.overrideMimeType("text/plain");
151 xhr.send(null);
153 var src = xhr.responseText;
154 return create_shader(src, type, name);
155 }
157 function create_shader(src, type, name)
158 {
159 var sdr = gl.createShader(type);
160 gl.shaderSource(sdr, src);
161 gl.compileShader(sdr);
163 if(!gl.getShaderParameter(sdr, gl.COMPILE_STATUS)) {
164 if(!name) {
165 name = "<unnamed>";
166 }
167 logmsg("failed to compile shader: " + name + ": " + gl.getShaderInfoLog(sdr));
168 return null;
169 }
170 return sdr;
171 }
173 function load_program(vsname, psname)
174 {
175 var vs, ps;
177 if(!(vs = load_shader(vsname, gl.VERTEX_SHADER))) {
178 return null;
179 }
180 if(!(ps = load_shader(psname, gl.FRAGMENT_SHADER))) {
181 return null;
182 }
183 return create_program(vs, ps);
184 }
186 function create_program(vs, ps)
187 {
188 var prog = gl.createProgram();
189 gl.attachShader(prog, vs);
190 gl.attachShader(prog, ps);
191 gl.linkProgram(prog);
193 if(!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
194 logmsg("Failed to link GLSL program (" + vsname + " - " + psname + ")\n");
195 return null;
196 }
197 return prog;
198 }
200 function set_uniform1f(p, name, v)
201 {
202 var loc = gl.getUniformLocation(p, name);
203 if(loc != -1) {
204 gl.useProgram(p);
205 gl.uniform1f(loc, v);
206 }
207 }
209 function set_uniform2f(p, name, x, y)
210 {
211 var loc = gl.getUniformLocation(p, name);
212 if(loc != -1) {
213 gl.useProgram(p);
214 gl.uniform2f(loc, x, y);
215 }
216 }
218 function set_uniform3f(p, name, x, y, z)
219 {
220 var loc = gl.getUniformLocation(p, name);
221 if(loc != -1) {
222 gl.useProgram(p);
223 gl.uniform3f(loc, x, y, z);
224 }
225 }
227 function set_uniform4f(p, name, x, y, z, w)
228 {
229 var loc = gl.getUniformLocation(p, name);
230 if(loc != -1) {
231 gl.useProgram(p);
232 gl.uniform4f(loc, x, y, z, w);
233 }
234 }
236 function set_uniform_matrix4fv(p, name, mat)
237 {
238 var loc = gl.getUniformLocation(p, name);
239 if(loc != -1) {
240 gl.useProgram(p);
241 gl.uniformMatrix4fv(loc, false, mat);
242 }
243 }
245 function logmsg(str)
246 {
247 if(console) {
248 console.value += str;
249 }
250 }
252 window.request_redisplay = (function() {
253 return window.requestAnimationFrame ||
254 window.webkitRequestAnimationFrame ||
255 window.mozRequestAnimationFrame ||
256 window.oRequestAnimationFrame ||
257 window.msRequestAnimationFrame ||
258 function(callback, element) { window.setTimeout(callback, 1000/60); };
259 })();
262 var glass_progr_vs_src =
263 "attribute vec4 attr_vertex, attr_color;\n" +
264 "uniform mat4 mvmat, projmat;\n" +
265 "varying vec4 color;\n" +
266 "void main()\n{\n" +
267 "\tmat4 mvp = projmat * mvmat;\n" +
268 "\tgl_Position = mvp * attr_vertex;\n" +
269 "\tcolor = attr_color;\n}\n";
271 var glass_progr_ps_src =
272 "precision highp float;\n" +
273 "varying vec4 color;\n" +
274 "void main()\n{\n" +
275 "\tgl_FragColor = color;\n}\n";
277 function glass_draw_progress(msec)
278 {
279 glMatrixMode(GL_PROJECTION);
280 glPushMatrix();
281 glLoadIdentity();
283 glMatrixMode(GL_MODELVIEW);
284 glPushMatrix();
285 glLoadIdentity();
287 gl.clearColor(0, 0, 0, 1);
288 gl.clear(gl.COLOR_BUFFER_BIT);
290 var progr = glass_data_loaded / glass_data_count;
292 gl.useProgram(glass_progr_prog);
294 glBegin(GL_QUADS);
295 glColor3f(0.3, 0.5, 0.8);
296 glVertex2f(-0.55, -0.1);
297 glVertex2f(0.55, -0.1);
298 glVertex2f(0.55, 0.1);
299 glVertex2f(-0.55, 0.1);
301 glColor3f(0, 0, 0);
302 glVertex2f(-0.525, -0.075);
303 glVertex2f(0.525, -0.075);
304 glVertex2f(0.525, 0.075);
305 glVertex2f(-0.525, 0.075);
307 glColor3f(1.0, 0.3, 0.2);
308 glVertex2f(-0.5, -0.05);
309 glVertex2f(progr - 0.5, -0.05);
310 glVertex2f(progr - 0.5, 0.05);
311 glVertex2f(-0.5, 0.05);
312 glEnd();
314 glMatrixMode(GL_PROJECTION);
315 glPopMatrix();
316 glMatrixMode(GL_MODELVIEW);
317 glPopMatrix();
318 }