webgl-tools
diff glass.js @ 0:4fe036e28796
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 15 Jun 2011 20:04:49 +0300 |
parents | |
children | c52b17d412f3 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/glass.js Wed Jun 15 20:04:49 2011 +0300 1.3 @@ -0,0 +1,243 @@ 1.4 +/* 1.5 +glass - (web)gl-assistant. 1.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 1.7 + 1.8 +This program is free software: you can redistribute it and/or modify 1.9 +it under the terms of the GNU General Public License as published by 1.10 +the Free Software Foundation, either version 3 of the License, or 1.11 +(at your option) any later version. 1.12 + 1.13 +This program is distributed in the hope that it will be useful, 1.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 +GNU General Public License for more details. 1.17 + 1.18 +You should have received a copy of the GNU General Public License 1.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 1.20 +*/ 1.21 + 1.22 +var gl; 1.23 +var canvas, console; 1.24 +var glass_data_loaded, glass_data_count; 1.25 +var glass_progr_prog; 1.26 +var glass_start_time = 0; 1.27 + 1.28 +var glass_cb_disp = null; 1.29 + 1.30 +function glass_init(canv_id, cons_id) 1.31 +{ 1.32 + if(cons_id && (console = document.getElementById(cons_id))) { 1.33 + console.value = ""; 1.34 + } 1.35 + 1.36 + if(!(canvas = document.getElementById(canv_id))) { 1.37 + logmsg("canvas \"" + canv_id + "\" does not exist\n"); 1.38 + return false; 1.39 + } 1.40 + try { 1.41 + gl = canvas.getContext("experimental-webgl"); 1.42 + } 1.43 + catch(e) { 1.44 + logmsg("can't get an OpenGL context\n"); 1.45 + return false; 1.46 + } 1.47 + 1.48 + var vs = create_shader(glass_progr_vs_src, gl.VERTEX_SHADER); 1.49 + var ps = create_shader(glass_progr_ps_src, gl.FRAGMENT_SHADER); 1.50 + if(!vs || !ps || !(glass_progr_prog = create_program(vs, ps))) { 1.51 + logmsg("internal glass error\n"); 1.52 + return false; 1.53 + } 1.54 + 1.55 + glass_data_loaded = glass_data_count = 0; 1.56 + return true; 1.57 +} 1.58 + 1.59 +function glass_start() 1.60 +{ 1.61 + glass_start_time = get_msec(); 1.62 + glass_redraw(); 1.63 +} 1.64 + 1.65 +function glass_display_func(func) 1.66 +{ 1.67 + glass_cb_disp = func; 1.68 +} 1.69 + 1.70 +function glass_redraw() 1.71 +{ 1.72 + var msec = get_msec(); 1.73 + 1.74 + if(glass_data_loaded < glass_data_count || !glass_cb_disp) { 1.75 + glass_draw_progress(msec); 1.76 + } else { 1.77 + glass_cb_disp(msec); 1.78 + } 1.79 + request_redisplay(glass_redraw); 1.80 +} 1.81 + 1.82 +function get_msec() 1.83 +{ 1.84 + return new Date().getTime() - glass_start_time; 1.85 +} 1.86 + 1.87 +/* ---- textures ---- */ 1.88 +function load_texture(name) 1.89 +{ 1.90 + glass_data_count++; 1.91 + 1.92 + var tex = gl.createTexture(); 1.93 + tex.image = new Image(); 1.94 + tex.image.onload = function() { glass_tex_load_done(tex); } 1.95 + tex.image.onerror = glass_tex_load_failed; 1.96 + tex.image.src = name; 1.97 + return tex; 1.98 +} 1.99 + 1.100 +function glass_tex_load_done(tex) 1.101 +{ 1.102 + gl.bindTexture(gl.TEXTURE_2D, tex); 1.103 + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tex.image); 1.104 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 1.105 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 1.106 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); 1.107 + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); 1.108 + gl.bindTexture(gl.TEXTURE_2D, null); 1.109 + glass_data_loaded++; 1.110 + logmsg("loaded image: " + tex.image.src + 1.111 + " (" + glass_data_loaded + "/" + glass_data_count + ")\n"); 1.112 +} 1.113 + 1.114 +function glass_tex_load_failed() 1.115 +{ 1.116 + logmsg("failed to load texture: " + this.src + "\n"); 1.117 +} 1.118 + 1.119 + 1.120 +/* ---- shaders ---- */ 1.121 +function load_shader(name, type) 1.122 +{ 1.123 + var xhr = new XMLHttpRequest(); 1.124 + xhr.open("GET", name, false); 1.125 + xhr.overrideMimeType("text/plain"); 1.126 + xhr.send(null); 1.127 + 1.128 + var src = xhr.responseText; 1.129 + return create_shader(src, type); 1.130 +} 1.131 + 1.132 +function create_shader(src, type) 1.133 +{ 1.134 + var sdr = gl.createShader(type); 1.135 + gl.shaderSource(sdr, src); 1.136 + gl.compileShader(sdr); 1.137 + 1.138 + if(!gl.getShaderParameter(sdr, gl.COMPILE_STATUS)) { 1.139 + logmsg("failed to compile shader: " + elem.src + ": " + gl.getShaderInfoLog(sdr)); 1.140 + return null; 1.141 + } 1.142 + return sdr; 1.143 +} 1.144 + 1.145 +function load_program(vsname, psname) 1.146 +{ 1.147 + var vs, ps; 1.148 + 1.149 + if(!(vs = load_shader(vsname, gl.VERTEX_SHADER))) { 1.150 + return null; 1.151 + } 1.152 + if(!(ps = load_shader(psname, gl.FRAGMENT_SHADER))) { 1.153 + return null; 1.154 + } 1.155 + return create_program(vs, ps); 1.156 +} 1.157 + 1.158 +function create_program(vs, ps) 1.159 +{ 1.160 + var prog = gl.createProgram(); 1.161 + gl.attachShader(prog, vs); 1.162 + gl.attachShader(prog, ps); 1.163 + gl.linkProgram(prog); 1.164 + 1.165 + if(!gl.getProgramParameter(prog, gl.LINK_STATUS)) { 1.166 + logmsg("Failed to link GLSL program (" + vsname + " - " + psname + ")\n"); 1.167 + return null; 1.168 + } 1.169 + return prog; 1.170 +} 1.171 + 1.172 +function logmsg(str) 1.173 +{ 1.174 + if(console) { 1.175 + console.value += str; 1.176 + } 1.177 +} 1.178 + 1.179 +window.request_redisplay = (function() { 1.180 + return window.requestAnimationFrame || 1.181 + window.webkitRequestAnimationFrame || 1.182 + window.mozRequestAnimationFrame || 1.183 + window.oRequestAnimationFrame || 1.184 + window.msRequestAnimationFrame || 1.185 + function(callback, element) { window.setTimeout(callback, 1000/60); }; 1.186 +})(); 1.187 + 1.188 + 1.189 +var glass_progr_vs_src = 1.190 + "attribute vec4 attr_vertex, attr_color;\n" + 1.191 + "uniform mat4 mvmat, projmat;\n" + 1.192 + "varying vec4 color;\n" + 1.193 + "void main()\n{\n" + 1.194 + "\tmat4 mvp = projmat * mvmat;\n" + 1.195 + "\tgl_Position = mvp * attr_vertex;\n" + 1.196 + "\tcolor = attr_color;\n}\n"; 1.197 + 1.198 +var glass_progr_ps_src = 1.199 + "precision highp float;\n" + 1.200 + "varying vec4 color;\n" + 1.201 + "void main()\n{\n" + 1.202 + "\tgl_FragColor = color;\n}\n"; 1.203 + 1.204 +function glass_draw_progress(msec) 1.205 +{ 1.206 + glMatrixMode(GL_PROJECTION); 1.207 + glPushMatrix(); 1.208 + glLoadIdentity(); 1.209 + 1.210 + glMatrixMode(GL_MODELVIEW); 1.211 + glPushMatrix(); 1.212 + glLoadIdentity(); 1.213 + 1.214 + gl.clearColor(0, 0, 0, 1); 1.215 + gl.clear(gl.COLOR_BUFFER_BIT); 1.216 + 1.217 + var progr = glass_data_loaded / glass_data_count; 1.218 + 1.219 + gl.useProgram(glass_progr_prog); 1.220 + 1.221 + glBegin(GL_QUADS); 1.222 + glColor3f(0.3, 0.5, 0.8); 1.223 + glVertex2f(-0.55, -0.1); 1.224 + glVertex2f(0.55, -0.1); 1.225 + glVertex2f(0.55, 0.1); 1.226 + glVertex2f(-0.55, 0.1); 1.227 + 1.228 + glColor3f(0, 0, 0); 1.229 + glVertex2f(-0.525, -0.075); 1.230 + glVertex2f(0.525, -0.075); 1.231 + glVertex2f(0.525, 0.075); 1.232 + glVertex2f(-0.525, 0.075); 1.233 + 1.234 + glColor3f(1.0, 0.3, 0.2); 1.235 + glVertex2f(-0.5, -0.05); 1.236 + glVertex2f(progr - 0.5, -0.05); 1.237 + glVertex2f(progr - 0.5, 0.05); 1.238 + glVertex2f(-0.5, 0.05); 1.239 + glEnd(); 1.240 + 1.241 + glMatrixMode(GL_PROJECTION); 1.242 + glPopMatrix(); 1.243 + glMatrixMode(GL_MODELVIEW); 1.244 + glPopMatrix(); 1.245 +} 1.246 +