webgl-tools

annotate 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
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@0 19 var gl;
nuclear@0 20 var canvas, console;
nuclear@0 21 var glass_data_loaded, glass_data_count;
nuclear@0 22 var glass_progr_prog;
nuclear@0 23 var glass_start_time = 0;
nuclear@0 24
nuclear@0 25 var glass_cb_disp = null;
nuclear@2 26 var glass_cb_mouse = null;
nuclear@2 27 var glass_cb_motion = null;
nuclear@0 28
nuclear@0 29 function glass_init(canv_id, cons_id)
nuclear@0 30 {
nuclear@0 31 if(cons_id && (console = document.getElementById(cons_id))) {
nuclear@0 32 console.value = "";
nuclear@0 33 }
nuclear@0 34
nuclear@0 35 if(!(canvas = document.getElementById(canv_id))) {
nuclear@0 36 logmsg("canvas \"" + canv_id + "\" does not exist\n");
nuclear@0 37 return false;
nuclear@0 38 }
nuclear@0 39 try {
nuclear@0 40 gl = canvas.getContext("experimental-webgl");
nuclear@0 41 }
nuclear@0 42 catch(e) {
nuclear@0 43 logmsg("can't get an OpenGL context\n");
nuclear@0 44 return false;
nuclear@0 45 }
nuclear@0 46
nuclear@0 47 var vs = create_shader(glass_progr_vs_src, gl.VERTEX_SHADER);
nuclear@0 48 var ps = create_shader(glass_progr_ps_src, gl.FRAGMENT_SHADER);
nuclear@0 49 if(!vs || !ps || !(glass_progr_prog = create_program(vs, ps))) {
nuclear@0 50 logmsg("internal glass error\n");
nuclear@0 51 return false;
nuclear@0 52 }
nuclear@0 53
nuclear@0 54 glass_data_loaded = glass_data_count = 0;
nuclear@0 55 return true;
nuclear@0 56 }
nuclear@0 57
nuclear@0 58 function glass_start()
nuclear@0 59 {
nuclear@2 60 if(glass_cb_motion) {
nuclear@2 61 canvas.onmousemove = function(ev) {
nuclear@2 62 glass_cb_motion(ev.clientX, ev.clientY);
nuclear@2 63 }
nuclear@2 64 }
nuclear@2 65
nuclear@2 66 if(glass_cb_mouse) {
nuclear@2 67 canvas.onmousedown = function(ev) {
nuclear@2 68 glass_cb_mouse(ev.button, true, ev.clientX, ev.clientY);
nuclear@2 69 }
nuclear@2 70 canvas.onmouseup = function(ev) {
nuclear@2 71 glass_cb_mouse(ev.button, false, ev.clientX, ev.clientY);
nuclear@2 72 }
nuclear@2 73 }
nuclear@2 74
nuclear@0 75 glass_start_time = get_msec();
nuclear@0 76 glass_redraw();
nuclear@0 77 }
nuclear@0 78
nuclear@0 79 function glass_display_func(func)
nuclear@0 80 {
nuclear@0 81 glass_cb_disp = func;
nuclear@0 82 }
nuclear@0 83
nuclear@2 84 function glass_mouse_func(func)
nuclear@2 85 {
nuclear@2 86 glass_cb_mouse = func;
nuclear@2 87 }
nuclear@2 88
nuclear@2 89 function glass_motion_func(func)
nuclear@2 90 {
nuclear@2 91 glass_cb_motion = func;
nuclear@2 92 }
nuclear@2 93
nuclear@2 94
nuclear@0 95 function glass_redraw()
nuclear@0 96 {
nuclear@0 97 var msec = get_msec();
nuclear@0 98
nuclear@0 99 if(glass_data_loaded < glass_data_count || !glass_cb_disp) {
nuclear@0 100 glass_draw_progress(msec);
nuclear@0 101 } else {
nuclear@0 102 glass_cb_disp(msec);
nuclear@0 103 }
nuclear@0 104 request_redisplay(glass_redraw);
nuclear@0 105 }
nuclear@0 106
nuclear@0 107 function get_msec()
nuclear@0 108 {
nuclear@0 109 return new Date().getTime() - glass_start_time;
nuclear@0 110 }
nuclear@0 111
nuclear@0 112 /* ---- textures ---- */
nuclear@0 113 function load_texture(name)
nuclear@0 114 {
nuclear@0 115 glass_data_count++;
nuclear@0 116
nuclear@0 117 var tex = gl.createTexture();
nuclear@0 118 tex.image = new Image();
nuclear@0 119 tex.image.onload = function() { glass_tex_load_done(tex); }
nuclear@0 120 tex.image.onerror = glass_tex_load_failed;
nuclear@0 121 tex.image.src = name;
nuclear@0 122 return tex;
nuclear@0 123 }
nuclear@0 124
nuclear@0 125 function glass_tex_load_done(tex)
nuclear@0 126 {
nuclear@0 127 gl.bindTexture(gl.TEXTURE_2D, tex);
nuclear@0 128 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tex.image);
nuclear@0 129 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
nuclear@0 130 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
nuclear@0 131 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
nuclear@0 132 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
nuclear@0 133 gl.bindTexture(gl.TEXTURE_2D, null);
nuclear@0 134 glass_data_loaded++;
nuclear@0 135 logmsg("loaded image: " + tex.image.src +
nuclear@0 136 " (" + glass_data_loaded + "/" + glass_data_count + ")\n");
nuclear@0 137 }
nuclear@0 138
nuclear@0 139 function glass_tex_load_failed()
nuclear@0 140 {
nuclear@0 141 logmsg("failed to load texture: " + this.src + "\n");
nuclear@0 142 }
nuclear@0 143
nuclear@0 144
nuclear@0 145 /* ---- shaders ---- */
nuclear@0 146 function load_shader(name, type)
nuclear@0 147 {
nuclear@0 148 var xhr = new XMLHttpRequest();
nuclear@0 149 xhr.open("GET", name, false);
nuclear@0 150 xhr.overrideMimeType("text/plain");
nuclear@0 151 xhr.send(null);
nuclear@0 152
nuclear@0 153 var src = xhr.responseText;
nuclear@2 154 return create_shader(src, type, name);
nuclear@0 155 }
nuclear@0 156
nuclear@2 157 function create_shader(src, type, name)
nuclear@0 158 {
nuclear@0 159 var sdr = gl.createShader(type);
nuclear@0 160 gl.shaderSource(sdr, src);
nuclear@0 161 gl.compileShader(sdr);
nuclear@0 162
nuclear@0 163 if(!gl.getShaderParameter(sdr, gl.COMPILE_STATUS)) {
nuclear@2 164 if(!name) {
nuclear@2 165 name = "<unnamed>";
nuclear@2 166 }
nuclear@2 167 logmsg("failed to compile shader: " + name + ": " + gl.getShaderInfoLog(sdr));
nuclear@0 168 return null;
nuclear@0 169 }
nuclear@0 170 return sdr;
nuclear@0 171 }
nuclear@0 172
nuclear@0 173 function load_program(vsname, psname)
nuclear@0 174 {
nuclear@0 175 var vs, ps;
nuclear@0 176
nuclear@0 177 if(!(vs = load_shader(vsname, gl.VERTEX_SHADER))) {
nuclear@0 178 return null;
nuclear@0 179 }
nuclear@0 180 if(!(ps = load_shader(psname, gl.FRAGMENT_SHADER))) {
nuclear@0 181 return null;
nuclear@0 182 }
nuclear@0 183 return create_program(vs, ps);
nuclear@0 184 }
nuclear@0 185
nuclear@0 186 function create_program(vs, ps)
nuclear@0 187 {
nuclear@0 188 var prog = gl.createProgram();
nuclear@0 189 gl.attachShader(prog, vs);
nuclear@0 190 gl.attachShader(prog, ps);
nuclear@0 191 gl.linkProgram(prog);
nuclear@0 192
nuclear@0 193 if(!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
nuclear@0 194 logmsg("Failed to link GLSL program (" + vsname + " - " + psname + ")\n");
nuclear@0 195 return null;
nuclear@0 196 }
nuclear@0 197 return prog;
nuclear@0 198 }
nuclear@0 199
nuclear@2 200 function set_uniform1f(p, name, v)
nuclear@2 201 {
nuclear@2 202 var loc = gl.getUniformLocation(p, name);
nuclear@2 203 if(loc != -1) {
nuclear@2 204 gl.useProgram(p);
nuclear@2 205 gl.uniform1f(loc, v);
nuclear@2 206 }
nuclear@2 207 }
nuclear@2 208
nuclear@2 209 function set_uniform2f(p, name, x, y)
nuclear@2 210 {
nuclear@2 211 var loc = gl.getUniformLocation(p, name);
nuclear@2 212 if(loc != -1) {
nuclear@2 213 gl.useProgram(p);
nuclear@2 214 gl.uniform2f(loc, x, y);
nuclear@2 215 }
nuclear@2 216 }
nuclear@2 217
nuclear@2 218 function set_uniform3f(p, name, x, y, z)
nuclear@2 219 {
nuclear@2 220 var loc = gl.getUniformLocation(p, name);
nuclear@2 221 if(loc != -1) {
nuclear@2 222 gl.useProgram(p);
nuclear@2 223 gl.uniform3f(loc, x, y, z);
nuclear@2 224 }
nuclear@2 225 }
nuclear@2 226
nuclear@2 227 function set_uniform4f(p, name, x, y, z, w)
nuclear@2 228 {
nuclear@2 229 var loc = gl.getUniformLocation(p, name);
nuclear@2 230 if(loc != -1) {
nuclear@2 231 gl.useProgram(p);
nuclear@2 232 gl.uniform4f(loc, x, y, z, w);
nuclear@2 233 }
nuclear@2 234 }
nuclear@2 235
nuclear@2 236 function set_uniform_matrix4fv(p, name, mat)
nuclear@2 237 {
nuclear@2 238 var loc = gl.getUniformLocation(p, name);
nuclear@2 239 if(loc != -1) {
nuclear@2 240 gl.useProgram(p);
nuclear@2 241 gl.uniformMatrix4fv(loc, false, mat);
nuclear@2 242 }
nuclear@2 243 }
nuclear@2 244
nuclear@0 245 function logmsg(str)
nuclear@0 246 {
nuclear@0 247 if(console) {
nuclear@0 248 console.value += str;
nuclear@0 249 }
nuclear@0 250 }
nuclear@0 251
nuclear@0 252 window.request_redisplay = (function() {
nuclear@0 253 return window.requestAnimationFrame ||
nuclear@0 254 window.webkitRequestAnimationFrame ||
nuclear@0 255 window.mozRequestAnimationFrame ||
nuclear@0 256 window.oRequestAnimationFrame ||
nuclear@0 257 window.msRequestAnimationFrame ||
nuclear@0 258 function(callback, element) { window.setTimeout(callback, 1000/60); };
nuclear@0 259 })();
nuclear@0 260
nuclear@0 261
nuclear@0 262 var glass_progr_vs_src =
nuclear@0 263 "attribute vec4 attr_vertex, attr_color;\n" +
nuclear@0 264 "uniform mat4 mvmat, projmat;\n" +
nuclear@0 265 "varying vec4 color;\n" +
nuclear@0 266 "void main()\n{\n" +
nuclear@0 267 "\tmat4 mvp = projmat * mvmat;\n" +
nuclear@0 268 "\tgl_Position = mvp * attr_vertex;\n" +
nuclear@0 269 "\tcolor = attr_color;\n}\n";
nuclear@0 270
nuclear@0 271 var glass_progr_ps_src =
nuclear@0 272 "precision highp float;\n" +
nuclear@0 273 "varying vec4 color;\n" +
nuclear@0 274 "void main()\n{\n" +
nuclear@0 275 "\tgl_FragColor = color;\n}\n";
nuclear@0 276
nuclear@0 277 function glass_draw_progress(msec)
nuclear@0 278 {
nuclear@0 279 glMatrixMode(GL_PROJECTION);
nuclear@0 280 glPushMatrix();
nuclear@0 281 glLoadIdentity();
nuclear@0 282
nuclear@0 283 glMatrixMode(GL_MODELVIEW);
nuclear@0 284 glPushMatrix();
nuclear@0 285 glLoadIdentity();
nuclear@0 286
nuclear@0 287 gl.clearColor(0, 0, 0, 1);
nuclear@0 288 gl.clear(gl.COLOR_BUFFER_BIT);
nuclear@0 289
nuclear@0 290 var progr = glass_data_loaded / glass_data_count;
nuclear@0 291
nuclear@0 292 gl.useProgram(glass_progr_prog);
nuclear@0 293
nuclear@0 294 glBegin(GL_QUADS);
nuclear@0 295 glColor3f(0.3, 0.5, 0.8);
nuclear@0 296 glVertex2f(-0.55, -0.1);
nuclear@0 297 glVertex2f(0.55, -0.1);
nuclear@0 298 glVertex2f(0.55, 0.1);
nuclear@0 299 glVertex2f(-0.55, 0.1);
nuclear@0 300
nuclear@0 301 glColor3f(0, 0, 0);
nuclear@0 302 glVertex2f(-0.525, -0.075);
nuclear@0 303 glVertex2f(0.525, -0.075);
nuclear@0 304 glVertex2f(0.525, 0.075);
nuclear@0 305 glVertex2f(-0.525, 0.075);
nuclear@0 306
nuclear@0 307 glColor3f(1.0, 0.3, 0.2);
nuclear@0 308 glVertex2f(-0.5, -0.05);
nuclear@0 309 glVertex2f(progr - 0.5, -0.05);
nuclear@0 310 glVertex2f(progr - 0.5, 0.05);
nuclear@0 311 glVertex2f(-0.5, 0.05);
nuclear@0 312 glEnd();
nuclear@0 313
nuclear@0 314 glMatrixMode(GL_PROJECTION);
nuclear@0 315 glPopMatrix();
nuclear@0 316 glMatrixMode(GL_MODELVIEW);
nuclear@0 317 glPopMatrix();
nuclear@0 318 }
nuclear@0 319