webgl-tools

annotate glass.js @ 5:7b3ed284e4bb

added glass_fullscreen
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 18 Jun 2011 05:29:39 +0300
parents 06d05a65bd77
children
rev   line source
nuclear@0 1 /*
nuclear@0 2 glass - (web)gl-assistant.
nuclear@0 3 Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org>
nuclear@0 4
nuclear@0 5 This program is free software: you can redistribute it and/or modify
nuclear@0 6 it under the terms of the GNU General Public License as published by
nuclear@0 7 the Free Software Foundation, either version 3 of the License, or
nuclear@0 8 (at your option) any later version.
nuclear@0 9
nuclear@0 10 This program is distributed in the hope that it will be useful,
nuclear@0 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
nuclear@0 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nuclear@0 13 GNU General Public License for more details.
nuclear@0 14
nuclear@0 15 You should have received a copy of the GNU General Public License
nuclear@0 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
nuclear@0 17 */
nuclear@0 18
nuclear@4 19 /* public interface
nuclear@4 20
nuclear@4 21 bool glass_init(canvas-id, optional-console-textarea-id);
nuclear@4 22 void glass_start(void);
nuclear@4 23
nuclear@4 24 void glass_display_func(callback);
nuclear@4 25 void glass_reshape_func(callback);
nuclear@4 26 void glass_mouse_func(callback);
nuclear@4 27 void glass_motion_func(callback);
nuclear@4 28
nuclear@4 29 void glass_resize(x, y);
nuclear@4 30
nuclear@4 31 WebGLTexture load_texture(uri);
nuclear@4 32
nuclear@4 33 WebGLShader load_shader(uri, type);
nuclear@4 34 WebGLShader create_shader(source, type, optional-sdrname);
nuclear@4 35 WebGLProgram load_program(vertex-uri, fragment-uri);
nuclear@4 36 WebGLProgram create_program(vertex-shader, fragment-shader);
nuclear@4 37
nuclear@4 38 void set_uniform1i(program, uniform-name, value);
nuclear@4 39 void set_uniform1f(program, uniform-name, value);
nuclear@4 40 void set_uniform2f(program, uniform-name, x, y);
nuclear@4 41 void set_uniform3f(program, uniform-name, x, y, z);
nuclear@4 42 void set_uniform4f(program, uniform-name, x, y, z, w);
nuclear@4 43 void set_uniform_matrix4fv(program, uniform-name, matrix);
nuclear@4 44
nuclear@4 45 void request_redisplay(void);
nuclear@4 46
nuclear@4 47 void logmsg(string);
nuclear@4 48 */
nuclear@4 49
nuclear@0 50 var gl;
nuclear@0 51 var canvas, console;
nuclear@5 52 var glass_orig_width, glass_orig_height;
nuclear@0 53 var glass_data_loaded, glass_data_count;
nuclear@0 54 var glass_progr_prog;
nuclear@0 55 var glass_start_time = 0;
nuclear@5 56 var glass_fullscr = false;
nuclear@0 57
nuclear@0 58 var glass_cb_disp = null;
nuclear@4 59 var glass_cb_reshape = null;
nuclear@2 60 var glass_cb_mouse = null;
nuclear@2 61 var glass_cb_motion = null;
nuclear@0 62
nuclear@0 63 function glass_init(canv_id, cons_id)
nuclear@0 64 {
nuclear@0 65 if(cons_id && (console = document.getElementById(cons_id))) {
nuclear@0 66 console.value = "";
nuclear@0 67 }
nuclear@0 68
nuclear@0 69 if(!(canvas = document.getElementById(canv_id))) {
nuclear@0 70 logmsg("canvas \"" + canv_id + "\" does not exist\n");
nuclear@0 71 return false;
nuclear@0 72 }
nuclear@0 73 try {
nuclear@0 74 gl = canvas.getContext("experimental-webgl");
nuclear@0 75 }
nuclear@0 76 catch(e) {
nuclear@0 77 logmsg("can't get an OpenGL context\n");
nuclear@0 78 return false;
nuclear@0 79 }
nuclear@0 80
nuclear@5 81 glass_orig_width = canvas.width;
nuclear@5 82 glass_orig_height = canvas.height;
nuclear@5 83
nuclear@0 84 var vs = create_shader(glass_progr_vs_src, gl.VERTEX_SHADER);
nuclear@0 85 var ps = create_shader(glass_progr_ps_src, gl.FRAGMENT_SHADER);
nuclear@0 86 if(!vs || !ps || !(glass_progr_prog = create_program(vs, ps))) {
nuclear@0 87 logmsg("internal glass error\n");
nuclear@0 88 return false;
nuclear@0 89 }
nuclear@0 90
nuclear@0 91 glass_data_loaded = glass_data_count = 0;
nuclear@0 92 return true;
nuclear@0 93 }
nuclear@0 94
nuclear@0 95 function glass_start()
nuclear@0 96 {
nuclear@2 97 if(glass_cb_motion) {
nuclear@2 98 canvas.onmousemove = function(ev) {
nuclear@2 99 glass_cb_motion(ev.clientX, ev.clientY);
nuclear@2 100 }
nuclear@2 101 }
nuclear@2 102
nuclear@2 103 if(glass_cb_mouse) {
nuclear@2 104 canvas.onmousedown = function(ev) {
nuclear@2 105 glass_cb_mouse(ev.button, true, ev.clientX, ev.clientY);
nuclear@2 106 }
nuclear@2 107 canvas.onmouseup = function(ev) {
nuclear@2 108 glass_cb_mouse(ev.button, false, ev.clientX, ev.clientY);
nuclear@2 109 }
nuclear@2 110 }
nuclear@2 111
nuclear@0 112 glass_start_time = get_msec();
nuclear@4 113
nuclear@4 114 if(glass_cb_reshape) {
nuclear@4 115 glass_cb_reshape(canvas.width, canvas.height);
nuclear@4 116 }
nuclear@0 117 glass_redraw();
nuclear@0 118 }
nuclear@0 119
nuclear@0 120 function glass_display_func(func)
nuclear@0 121 {
nuclear@0 122 glass_cb_disp = func;
nuclear@0 123 }
nuclear@0 124
nuclear@4 125 function glass_reshape_func(func)
nuclear@4 126 {
nuclear@4 127 glass_cb_reshape = func;
nuclear@4 128 }
nuclear@4 129
nuclear@2 130 function glass_mouse_func(func)
nuclear@2 131 {
nuclear@2 132 glass_cb_mouse = func;
nuclear@2 133 }
nuclear@2 134
nuclear@2 135 function glass_motion_func(func)
nuclear@2 136 {
nuclear@2 137 glass_cb_motion = func;
nuclear@2 138 }
nuclear@2 139
nuclear@4 140 function glass_resize(x, y)
nuclear@4 141 {
nuclear@5 142 canvas.width = glass_orig_width = x;
nuclear@5 143 canvas.height = glass_orig_height = y;
nuclear@4 144
nuclear@4 145 if(glass_cb_reshape) {
nuclear@4 146 glass_cb_reshape(x, y);
nuclear@4 147 }
nuclear@4 148 }
nuclear@4 149
nuclear@5 150 function glass_fullscreen(state)
nuclear@5 151 {
nuclear@5 152 if(state == null) {
nuclear@5 153 glass_fullscr = !glass_fullscr;
nuclear@5 154 } else {
nuclear@5 155 glass_fullscr = state;
nuclear@5 156 }
nuclear@5 157
nuclear@5 158 if(glass_fullscr) {
nuclear@5 159 canvas.style.position = "absolute";
nuclear@5 160 canvas.style.left = 0;
nuclear@5 161 canvas.style.top = 0;
nuclear@5 162 canvas.width = window.innerWidth;
nuclear@5 163 canvas.height = window.innerHeight;
nuclear@5 164
nuclear@5 165 window.onresize = function() {
nuclear@5 166 canvas.width = window.innerWidth;
nuclear@5 167 canvas.height = window.innerHeight;
nuclear@5 168 if(glass_cb_reshape) {
nuclear@5 169 glass_cb_reshape(canvas.width, canvas.height);
nuclear@5 170 }
nuclear@5 171 }
nuclear@5 172 } else {
nuclear@5 173 canvas.style.position = "static";
nuclear@5 174 canvas.width = glass_orig_width;
nuclear@5 175 canvas.height = glass_orig_height;
nuclear@5 176
nuclear@5 177 window.onresize = null;
nuclear@5 178 }
nuclear@5 179
nuclear@5 180 if(glass_cb_reshape) {
nuclear@5 181 glass_cb_reshape(canvas.width, canvas.height);
nuclear@5 182 }
nuclear@5 183 }
nuclear@5 184
nuclear@2 185
nuclear@0 186 function glass_redraw()
nuclear@0 187 {
nuclear@0 188 var msec = get_msec();
nuclear@0 189
nuclear@0 190 if(glass_data_loaded < glass_data_count || !glass_cb_disp) {
nuclear@0 191 glass_draw_progress(msec);
nuclear@0 192 } else {
nuclear@0 193 glass_cb_disp(msec);
nuclear@0 194 }
nuclear@0 195 request_redisplay(glass_redraw);
nuclear@0 196 }
nuclear@0 197
nuclear@0 198 function get_msec()
nuclear@0 199 {
nuclear@0 200 return new Date().getTime() - glass_start_time;
nuclear@0 201 }
nuclear@0 202
nuclear@0 203 /* ---- textures ---- */
nuclear@0 204 function load_texture(name)
nuclear@0 205 {
nuclear@0 206 glass_data_count++;
nuclear@0 207
nuclear@0 208 var tex = gl.createTexture();
nuclear@0 209 tex.image = new Image();
nuclear@0 210 tex.image.onload = function() { glass_tex_load_done(tex); }
nuclear@0 211 tex.image.onerror = glass_tex_load_failed;
nuclear@0 212 tex.image.src = name;
nuclear@0 213 return tex;
nuclear@0 214 }
nuclear@0 215
nuclear@0 216 function glass_tex_load_done(tex)
nuclear@0 217 {
nuclear@0 218 gl.bindTexture(gl.TEXTURE_2D, tex);
nuclear@0 219 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tex.image);
nuclear@0 220 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
nuclear@0 221 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
nuclear@0 222 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
nuclear@0 223 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
nuclear@0 224 gl.bindTexture(gl.TEXTURE_2D, null);
nuclear@0 225 glass_data_loaded++;
nuclear@0 226 logmsg("loaded image: " + tex.image.src +
nuclear@0 227 " (" + glass_data_loaded + "/" + glass_data_count + ")\n");
nuclear@0 228 }
nuclear@0 229
nuclear@0 230 function glass_tex_load_failed()
nuclear@0 231 {
nuclear@0 232 logmsg("failed to load texture: " + this.src + "\n");
nuclear@0 233 }
nuclear@0 234
nuclear@0 235
nuclear@0 236 /* ---- shaders ---- */
nuclear@0 237 function load_shader(name, type)
nuclear@0 238 {
nuclear@0 239 var xhr = new XMLHttpRequest();
nuclear@0 240 xhr.open("GET", name, false);
nuclear@0 241 xhr.overrideMimeType("text/plain");
nuclear@0 242 xhr.send(null);
nuclear@0 243
nuclear@0 244 var src = xhr.responseText;
nuclear@2 245 return create_shader(src, type, name);
nuclear@0 246 }
nuclear@0 247
nuclear@2 248 function create_shader(src, type, name)
nuclear@0 249 {
nuclear@0 250 var sdr = gl.createShader(type);
nuclear@0 251 gl.shaderSource(sdr, src);
nuclear@0 252 gl.compileShader(sdr);
nuclear@0 253
nuclear@0 254 if(!gl.getShaderParameter(sdr, gl.COMPILE_STATUS)) {
nuclear@2 255 if(!name) {
nuclear@2 256 name = "<unnamed>";
nuclear@2 257 }
nuclear@2 258 logmsg("failed to compile shader: " + name + ": " + gl.getShaderInfoLog(sdr));
nuclear@0 259 return null;
nuclear@0 260 }
nuclear@0 261 return sdr;
nuclear@0 262 }
nuclear@0 263
nuclear@0 264 function load_program(vsname, psname)
nuclear@0 265 {
nuclear@0 266 var vs, ps;
nuclear@0 267
nuclear@0 268 if(!(vs = load_shader(vsname, gl.VERTEX_SHADER))) {
nuclear@0 269 return null;
nuclear@0 270 }
nuclear@0 271 if(!(ps = load_shader(psname, gl.FRAGMENT_SHADER))) {
nuclear@0 272 return null;
nuclear@0 273 }
nuclear@0 274 return create_program(vs, ps);
nuclear@0 275 }
nuclear@0 276
nuclear@0 277 function create_program(vs, ps)
nuclear@0 278 {
nuclear@0 279 var prog = gl.createProgram();
nuclear@0 280 gl.attachShader(prog, vs);
nuclear@0 281 gl.attachShader(prog, ps);
nuclear@0 282 gl.linkProgram(prog);
nuclear@0 283
nuclear@0 284 if(!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
nuclear@0 285 logmsg("Failed to link GLSL program (" + vsname + " - " + psname + ")\n");
nuclear@0 286 return null;
nuclear@0 287 }
nuclear@0 288 return prog;
nuclear@0 289 }
nuclear@0 290
nuclear@3 291 function set_uniform1i(p, name, v)
nuclear@3 292 {
nuclear@3 293 var loc = gl.getUniformLocation(p, name);
nuclear@3 294 if(loc != -1) {
nuclear@3 295 gl.useProgram(p);
nuclear@3 296 gl.uniform1i(loc, v);
nuclear@3 297 }
nuclear@3 298 }
nuclear@3 299
nuclear@2 300 function set_uniform1f(p, name, v)
nuclear@2 301 {
nuclear@2 302 var loc = gl.getUniformLocation(p, name);
nuclear@2 303 if(loc != -1) {
nuclear@2 304 gl.useProgram(p);
nuclear@2 305 gl.uniform1f(loc, v);
nuclear@2 306 }
nuclear@2 307 }
nuclear@2 308
nuclear@2 309 function set_uniform2f(p, name, x, y)
nuclear@2 310 {
nuclear@2 311 var loc = gl.getUniformLocation(p, name);
nuclear@2 312 if(loc != -1) {
nuclear@2 313 gl.useProgram(p);
nuclear@2 314 gl.uniform2f(loc, x, y);
nuclear@2 315 }
nuclear@2 316 }
nuclear@2 317
nuclear@2 318 function set_uniform3f(p, name, x, y, z)
nuclear@2 319 {
nuclear@2 320 var loc = gl.getUniformLocation(p, name);
nuclear@2 321 if(loc != -1) {
nuclear@2 322 gl.useProgram(p);
nuclear@2 323 gl.uniform3f(loc, x, y, z);
nuclear@2 324 }
nuclear@2 325 }
nuclear@2 326
nuclear@2 327 function set_uniform4f(p, name, x, y, z, w)
nuclear@2 328 {
nuclear@2 329 var loc = gl.getUniformLocation(p, name);
nuclear@2 330 if(loc != -1) {
nuclear@2 331 gl.useProgram(p);
nuclear@2 332 gl.uniform4f(loc, x, y, z, w);
nuclear@2 333 }
nuclear@2 334 }
nuclear@2 335
nuclear@2 336 function set_uniform_matrix4fv(p, name, mat)
nuclear@2 337 {
nuclear@2 338 var loc = gl.getUniformLocation(p, name);
nuclear@2 339 if(loc != -1) {
nuclear@2 340 gl.useProgram(p);
nuclear@2 341 gl.uniformMatrix4fv(loc, false, mat);
nuclear@2 342 }
nuclear@2 343 }
nuclear@2 344
nuclear@0 345 function logmsg(str)
nuclear@0 346 {
nuclear@0 347 if(console) {
nuclear@0 348 console.value += str;
nuclear@0 349 }
nuclear@0 350 }
nuclear@0 351
nuclear@0 352 window.request_redisplay = (function() {
nuclear@0 353 return window.requestAnimationFrame ||
nuclear@0 354 window.webkitRequestAnimationFrame ||
nuclear@0 355 window.mozRequestAnimationFrame ||
nuclear@0 356 window.oRequestAnimationFrame ||
nuclear@0 357 window.msRequestAnimationFrame ||
nuclear@0 358 function(callback, element) { window.setTimeout(callback, 1000/60); };
nuclear@0 359 })();
nuclear@0 360
nuclear@0 361
nuclear@0 362 var glass_progr_vs_src =
nuclear@0 363 "attribute vec4 attr_vertex, attr_color;\n" +
nuclear@0 364 "uniform mat4 mvmat, projmat;\n" +
nuclear@0 365 "varying vec4 color;\n" +
nuclear@0 366 "void main()\n{\n" +
nuclear@0 367 "\tmat4 mvp = projmat * mvmat;\n" +
nuclear@0 368 "\tgl_Position = mvp * attr_vertex;\n" +
nuclear@0 369 "\tcolor = attr_color;\n}\n";
nuclear@0 370
nuclear@0 371 var glass_progr_ps_src =
nuclear@0 372 "precision highp float;\n" +
nuclear@0 373 "varying vec4 color;\n" +
nuclear@0 374 "void main()\n{\n" +
nuclear@0 375 "\tgl_FragColor = color;\n}\n";
nuclear@0 376
nuclear@0 377 function glass_draw_progress(msec)
nuclear@0 378 {
nuclear@0 379 glMatrixMode(GL_PROJECTION);
nuclear@0 380 glPushMatrix();
nuclear@0 381 glLoadIdentity();
nuclear@0 382
nuclear@0 383 glMatrixMode(GL_MODELVIEW);
nuclear@0 384 glPushMatrix();
nuclear@0 385 glLoadIdentity();
nuclear@0 386
nuclear@0 387 gl.clearColor(0, 0, 0, 1);
nuclear@0 388 gl.clear(gl.COLOR_BUFFER_BIT);
nuclear@0 389
nuclear@0 390 var progr = glass_data_loaded / glass_data_count;
nuclear@0 391
nuclear@0 392 gl.useProgram(glass_progr_prog);
nuclear@0 393
nuclear@0 394 glBegin(GL_QUADS);
nuclear@0 395 glColor3f(0.3, 0.5, 0.8);
nuclear@0 396 glVertex2f(-0.55, -0.1);
nuclear@0 397 glVertex2f(0.55, -0.1);
nuclear@0 398 glVertex2f(0.55, 0.1);
nuclear@0 399 glVertex2f(-0.55, 0.1);
nuclear@0 400
nuclear@0 401 glColor3f(0, 0, 0);
nuclear@0 402 glVertex2f(-0.525, -0.075);
nuclear@0 403 glVertex2f(0.525, -0.075);
nuclear@0 404 glVertex2f(0.525, 0.075);
nuclear@0 405 glVertex2f(-0.525, 0.075);
nuclear@0 406
nuclear@0 407 glColor3f(1.0, 0.3, 0.2);
nuclear@0 408 glVertex2f(-0.5, -0.05);
nuclear@0 409 glVertex2f(progr - 0.5, -0.05);
nuclear@0 410 glVertex2f(progr - 0.5, 0.05);
nuclear@0 411 glVertex2f(-0.5, 0.05);
nuclear@0 412 glEnd();
nuclear@0 413
nuclear@0 414 glMatrixMode(GL_PROJECTION);
nuclear@0 415 glPopMatrix();
nuclear@0 416 glMatrixMode(GL_MODELVIEW);
nuclear@0 417 glPopMatrix();
nuclear@0 418 }
nuclear@0 419