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 +