webgl-tools
diff sanegl.js @ 0:4fe036e28796
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 15 Jun 2011 20:04:49 +0300 |
parents | |
children | 9eb4c37ce415 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/sanegl.js Wed Jun 15 20:04:49 2011 +0300 1.3 @@ -0,0 +1,416 @@ 1.4 +/* 1.5 +SaneGL - a small library to bring back sanity to WebGL 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 +const GL_MODELVIEW = 0; 1.22 +const GL_PROJECTION = 1; 1.23 +const GL_TEXTURE = 2; 1.24 + 1.25 +const GL_POINTS = 1; 1.26 +const GL_LINES = 2; 1.27 +const GL_TRIANGLES = 3; 1.28 +const GL_QUADS = 4; 1.29 + 1.30 +var gl_ident_val = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; 1.31 +var gl_mmode = GL_MODELVIEW; 1.32 +var gl_mat = new Array( 1.33 + [new Float32Array(gl_ident_val)], 1.34 + [new Float32Array(gl_ident_val)], 1.35 + [new Float32Array(gl_ident_val)]); 1.36 + 1.37 +/* XXX change after debugging */ 1.38 +const GL_MAX_VERTS = 32; 1.39 + 1.40 +var gl_prim = 0; 1.41 +var gl_vbuf = null, gl_nbuf = null, gl_cbuf = null, gl_tbuf = null; 1.42 +var gl_vertex, gl_normal, gl_color, gl_texcoord; 1.43 +var gl_nverts, gl_vert_calls; 1.44 +var gl_curr_normal = new Float32Array(3); 1.45 +var gl_curr_color = new Float32Array(4); 1.46 +var gl_curr_texcoord = new Float32Array(2); 1.47 +var gl_vloc, gl_nloc, gl_cloc, gl_tloc; 1.48 +var gl_use_normal, gl_use_color, gl_use_texcoord; 1.49 + 1.50 +function glMatrixMode(mode) 1.51 +{ 1.52 + gl_mmode = mode; 1.53 +} 1.54 + 1.55 +function glPushMatrix() 1.56 +{ 1.57 + var mtop = gl_mat[gl_mmode].length - 1; 1.58 + 1.59 + gl_mat[gl_mmode].push(new Float32Array(16)); 1.60 + m4_copy(gl_mat[gl_mmode][mtop + 1], gl_mat[gl_mmode][mtop]); 1.61 +} 1.62 + 1.63 +function glPopMatrix() 1.64 +{ 1.65 + if(gl_mat[gl_mmode].length <= 1) { 1.66 + alert('glPopMatrix underflow'); 1.67 + } 1.68 + gl_mat[gl_mmode].pop(); 1.69 +} 1.70 + 1.71 +function glLoadIdentity() 1.72 +{ 1.73 + var mtop = gl_mat[gl_mmode].length - 1; 1.74 + m4_identity(gl_mat[gl_mmode][mtop]); 1.75 +} 1.76 + 1.77 +function glLoadMatrixf(mat) 1.78 +{ 1.79 + var mtop = gl_mat[gl_mmode].length - 1; 1.80 + m4_copy(gl_mat[gl_mmode][mtop], mat); 1.81 +} 1.82 + 1.83 +function glMultMatrixf(mat) 1.84 +{ 1.85 + var mtop = gl_mat[gl_mmode].length - 1; 1.86 + m4_mul(gl_mat[gl_mmode][mtop], gl_mat[gl_mmode][mtop], mat); 1.87 +} 1.88 + 1.89 +function glTranslatef(x, y, z) 1.90 +{ 1.91 + var xform = new Float32Array(16); 1.92 + m4_translation(xform, x, y, z); 1.93 + glMultMatrixf(xform); 1.94 +} 1.95 + 1.96 +function glRotatef(angle, x, y, z) 1.97 +{ 1.98 + var angle_rads = Math.PI * angle / 180.0; 1.99 + var xform = new Float32Array(16); 1.100 + m4_rotation(xform, angle_rads, x, y, z); 1.101 + glMultMatrixf(xform); 1.102 +} 1.103 + 1.104 +function glScalef(x, y, z) 1.105 +{ 1.106 + var xform = new Float32Array(16); 1.107 + m4_scale(xform, x, y, z); 1.108 + glMultMatrixf(xform); 1.109 +} 1.110 + 1.111 +function glOrtho(left, right, bottom, top, near, far) 1.112 +{ 1.113 + var dx = right - left; 1.114 + var dy = top - bottom; 1.115 + var dz = far - near; 1.116 + 1.117 + var tx = -(right + left) / dx; 1.118 + var ty = -(top + bottom) / dy; 1.119 + var tz = -(far + near) / dz; 1.120 + 1.121 + var sx = 2.0 / dx; 1.122 + var sy = 2.0 / dy; 1.123 + var sz = -2.0 / dz; 1.124 + 1.125 + var xform = new Float32Array(16); 1.126 + xform[0] = sx; 1.127 + xform[5] = sy; 1.128 + xform[10] = sz; 1.129 + xform[12] = tx; 1.130 + xform[13] = ty; 1.131 + xform[14] = tz; 1.132 + xform[15] = 1.0; 1.133 + xform[1] = xform[2] = xform[3] = xform[4] = xform[6] = xform[7] = xform[8] = xform[9] = 0.0; 1.134 + 1.135 + glMultMatrixf(xform); 1.136 +} 1.137 + 1.138 +function glFrustum(left, right, bottom, top, near, far) 1.139 +{ 1.140 + var dx = right - left; 1.141 + var dy = top - bottom; 1.142 + var dz = far - near; 1.143 + 1.144 + var a = (right + left) / dx; 1.145 + var b = (top + bottom) / dy; 1.146 + var c = -(far + near) / dz; 1.147 + var d = -2.0 * far * near / dz; 1.148 + 1.149 + var xform = new Float32Array(16); 1.150 + xform[0] = 2.0 * near / dx; 1.151 + xform[5] = 2.0 * near / dy; 1.152 + xform[8] = a; 1.153 + xform[9] = b; 1.154 + xform[10] = c; 1.155 + xform[11] = -1.0; 1.156 + xform[14] = d; 1.157 + xform[1] = xform[2] = xform[3] = xform[4] = xform[6] = xform[7] = xform[12] = xform[13] = xform[15] = 0.0; 1.158 + 1.159 + glMultMatrixf(xform); 1.160 +} 1.161 + 1.162 +function gl_apply_xform(prog) 1.163 +{ 1.164 + var mvtop = gl_mat[GL_MODELVIEW].length - 1; 1.165 + var ptop = gl_mat[GL_PROJECTION].length - 1; 1.166 + var ttop = gl_mat[GL_TEXTURE].length - 1; 1.167 + 1.168 + var loc = gl.getUniformLocation(prog, "mvmat"); 1.169 + if(loc != -1) { 1.170 + gl.uniformMatrix4fv(loc, gl.FALSE, gl_mat[GL_MODELVIEW][mvtop]); 1.171 + } 1.172 + 1.173 + loc = gl.getUniformLocation(prog, "projmat"); 1.174 + if(loc != -1) { 1.175 + gl.uniformMatrix4fv(loc, gl.FALSE, gl_mat[GL_PROJECTION][ptop]); 1.176 + } 1.177 + 1.178 + loc = gl.getUniformLocation(prog, "texmat"); 1.179 + if(loc != -1) { 1.180 + gl.uniformMatrix4fv(loc, gl.FALSE, gl_mat[GL_TEXTURE][ttop]); 1.181 + } 1.182 +} 1.183 + 1.184 +function glBegin(prim) 1.185 +{ 1.186 + gl_vertex = new Float32Array(GL_MAX_VERTS * 4); 1.187 + gl_normal = new Float32Array(GL_MAX_VERTS * 3); 1.188 + gl_color = new Float32Array(GL_MAX_VERTS * 4); 1.189 + gl_texcoord = new Float32Array(GL_MAX_VERTS * 4); 1.190 + 1.191 + if(gl_vbuf == null) { 1.192 + gl_vbuf = gl.createBuffer(); 1.193 + gl.bindBuffer(gl.ARRAY_BUFFER, gl_vbuf); 1.194 + gl.bufferData(gl.ARRAY_BUFFER, GL_MAX_VERTS * 4 * Float32Array.BYTES_PER_ELEMENT, gl.STREAM_DRAW); 1.195 + logmsg("vertex buffer size: " + gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE) + "\n"); 1.196 + 1.197 + gl_nbuf = gl.createBuffer(); 1.198 + gl.bindBuffer(gl.ARRAY_BUFFER, gl_nbuf); 1.199 + gl.bufferData(gl.ARRAY_BUFFER, GL_MAX_VERTS * 3 * Float32Array.BYTES_PER_ELEMENT, gl.STREAM_DRAW); 1.200 + logmsg("normal buffer size: " + gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE) + "\n"); 1.201 + 1.202 + gl_cbuf = gl.createBuffer(); 1.203 + gl.bindBuffer(gl.ARRAY_BUFFER, gl_cbuf); 1.204 + gl.bufferData(gl.ARRAY_BUFFER, GL_MAX_VERTS * 4 * Float32Array.BYTES_PER_ELEMENT, gl.STREAM_DRAW); 1.205 + logmsg("color buffer size: " + gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE) + "\n"); 1.206 + 1.207 + gl_tbuf = gl.createBuffer(); 1.208 + gl.bindBuffer(gl.ARRAY_BUFFER, gl_tbuf); 1.209 + gl.bufferData(gl.ARRAY_BUFFER, GL_MAX_VERTS * 4 * Float32Array.BYTES_PER_ELEMENT, gl.STREAM_DRAW); 1.210 + logmsg("texcoord buffer size: " + gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE) + "\n"); 1.211 + } 1.212 + 1.213 + gl_prim = prim; 1.214 + gl_nverts = gl_vert_calls = 0; 1.215 + 1.216 + gl_prog = gl.getParameter(gl.CURRENT_PROGRAM); 1.217 + if(gl_prog != null) { 1.218 + gl_apply_xform(gl_prog); 1.219 + 1.220 + gl_vloc = gl.getAttribLocation(gl_prog, "attr_vertex"); 1.221 + gl_nloc = gl.getAttribLocation(gl_prog, "attr_normal"); 1.222 + gl_cloc = gl.getAttribLocation(gl_prog, "attr_color"); 1.223 + gl_tloc = gl.getAttribLocation(gl_prog, "attr_texcoord"); 1.224 + } else { 1.225 + logmsg("no program currently bound\n"); 1.226 + gl_vloc = gl_nloc = gl_cloc = gl_tloc = -1; 1.227 + } 1.228 + 1.229 + if(gl_vloc == -1) { 1.230 + logmsg("attr_vertex not found in currently bound program: " + prog + "\n"); 1.231 + } 1.232 + 1.233 + gl_use_normal = gl_nloc != -1; 1.234 + gl_use_color = gl_cloc != -1; 1.235 + gl_use_texcoord = gl_tloc != -1; 1.236 +} 1.237 + 1.238 +function glEnd() 1.239 +{ 1.240 + if(gl_nverts > 0) { 1.241 + gl_draw_immediate(); 1.242 + } 1.243 +} 1.244 + 1.245 +function gl_draw_immediate() 1.246 +{ 1.247 + var gles_prim; 1.248 + 1.249 + if(gl_vloc == -1) { 1.250 + return; 1.251 + } 1.252 + 1.253 + switch(gl_prim) { 1.254 + case GL_POINTS: 1.255 + gles_prim = gl.POINTS; 1.256 + break; 1.257 + case GL_LINES: 1.258 + gles_prim = gl.LINES; 1.259 + break; 1.260 + case GL_TRIANGLES: 1.261 + case GL_QUADS: 1.262 + gles_prim = gl.TRIANGLES; 1.263 + break; 1.264 + default: 1.265 + } 1.266 + 1.267 + gl.bindBuffer(gl.ARRAY_BUFFER, gl_vbuf); 1.268 + gl.bufferSubData(gl.ARRAY_BUFFER, 0, gl_vertex); 1.269 + gl.vertexAttribPointer(gl_vloc, 4, gl.FLOAT, false, 0, 0); 1.270 + gl.enableVertexAttribArray(gl_vloc); 1.271 + 1.272 + if(gl_use_normal) { 1.273 + gl.bindBuffer(gl.ARRAY_BUFFER, gl_nbuf); 1.274 + gl.bufferSubData(gl.ARRAY_BUFFER, 0, gl_normal); 1.275 + gl.vertexAttribPointer(gl_nloc, 3, gl.FLOAT, false, 0, 0); 1.276 + gl.enableVertexAttribArray(gl_nloc); 1.277 + } 1.278 + 1.279 + if(gl_use_color) { 1.280 + gl.bindBuffer(gl.ARRAY_BUFFER, gl_cbuf); 1.281 + gl.bufferSubData(gl.ARRAY_BUFFER, 0, gl_color); 1.282 + gl.vertexAttribPointer(gl_cloc, 4, gl.FLOAT, true, 0, 0); 1.283 + gl.enableVertexAttribArray(gl_cloc); 1.284 + } 1.285 + 1.286 + if(gl_use_texcoord) { 1.287 + gl.bindBuffer(gl.ARRAY_BUFFER, gl_tbuf); 1.288 + gl.bufferSubData(gl.ARRAY_BUFFER, 0, gl_texcoord); 1.289 + gl.vertexAttribPointer(gl_tloc, 4, gl.FLOAT, false, 0, 0); 1.290 + gl.enableVertexAttribArray(gl_tloc); 1.291 + } 1.292 + 1.293 + gl.drawArrays(gles_prim, 0, gl_nverts); 1.294 + 1.295 + gl.disableVertexAttribArray(gl_vloc); 1.296 + if(gl_use_normal) { 1.297 + gl.disableVertexAttribArray(gl_nloc); 1.298 + } 1.299 + if(gl_use_color) { 1.300 + gl.disableVertexAttribArray(gl_cloc); 1.301 + } 1.302 + if(gl_use_texcoord) { 1.303 + gl.disableVertexAttribArray(gl_tloc); 1.304 + } 1.305 +} 1.306 + 1.307 + 1.308 +function glVertex2f(x, y) 1.309 +{ 1.310 + glVertex3f(x, y, 0.0); 1.311 +} 1.312 + 1.313 +function glVertex3f(x, y, z) 1.314 +{ 1.315 + var i = 0; 1.316 + var vidx = gl_nverts * 4; 1.317 + var nidx = gl_nverts * 3; 1.318 + 1.319 + if(gl_prim == GL_QUADS && gl_vert_calls % 4 == 3) { 1.320 + var v = vidx - 12; 1.321 + var n = nidx - 9; 1.322 + 1.323 + for(i=0; i<4; i++) { 1.324 + if(gl_use_color) { 1.325 + gl_color[vidx] = gl_color[v]; 1.326 + } 1.327 + if(gl_use_texcoord) { 1.328 + gl_texcoord[vidx] = gl_texcoord[v]; 1.329 + } 1.330 + gl_vertex[vidx++] = gl_vertex[v++]; 1.331 + 1.332 + if(gl_use_normal && i < 3) { 1.333 + gl_normal[nidx++] = gl_normal[n++]; 1.334 + } 1.335 + } 1.336 + v += 4; 1.337 + n += 3; 1.338 + for(i=0; i<4; i++) { 1.339 + if(gl_use_color) { 1.340 + gl_color[vidx] = gl_color[v]; 1.341 + } 1.342 + if(gl_use_texcoord) { 1.343 + gl_texcoord[vidx] = gl_texcoord[v]; 1.344 + } 1.345 + gl_vertex[vidx++] = gl_vertex[v++]; 1.346 + 1.347 + if(gl_use_normal && i < 3) { 1.348 + gl_normal[nidx++] = gl_normal[n++]; 1.349 + } 1.350 + } 1.351 + 1.352 + gl_nverts += 2; 1.353 + } 1.354 + 1.355 + gl_vertex[vidx] = x; 1.356 + gl_vertex[vidx + 1] = y; 1.357 + gl_vertex[vidx + 2] = z; 1.358 + gl_vertex[vidx + 3] = 1.0; 1.359 + 1.360 + if(gl_use_color) { 1.361 + gl_color[vidx] = gl_curr_color[0]; 1.362 + gl_color[vidx + 1] = gl_curr_color[1]; 1.363 + gl_color[vidx + 2] = gl_curr_color[2]; 1.364 + gl_color[vidx + 3] = gl_curr_color[3]; 1.365 + } 1.366 + 1.367 + if(gl_use_normal) { 1.368 + gl_normal[nidx] = gl_curr_normal[0]; 1.369 + gl_normal[nidx + 1] = gl_curr_normal[1]; 1.370 + gl_normal[nidx + 2] = gl_curr_normal[2]; 1.371 + } 1.372 + 1.373 + if(gl_use_texcoord) { 1.374 + gl_texcoord[vidx] = gl_curr_texcoord[0]; 1.375 + gl_texcoord[vidx + 1] = gl_curr_texcoord[1]; 1.376 + gl_texcoord[vidx + 2] = gl_texcoord[vidx + 3] = 0.0; 1.377 + } 1.378 + 1.379 + gl_vert_calls++; 1.380 + if(++gl_nverts >= GL_MAX_VERTS) { 1.381 + gl_draw_immediate(); 1.382 + glBegin(gl_prim); /* reset everything */ 1.383 + } 1.384 +} 1.385 + 1.386 +function glNormal3f(x, y, z) 1.387 +{ 1.388 + gl_curr_normal[0] = x; 1.389 + gl_curr_normal[1] = y; 1.390 + gl_curr_normal[3] = z; 1.391 +} 1.392 + 1.393 +function glColor3f(r, g, b) 1.394 +{ 1.395 + gl_curr_color[0] = r; 1.396 + gl_curr_color[1] = g; 1.397 + gl_curr_color[2] = b; 1.398 + gl_curr_color[3] = 1.0; 1.399 +} 1.400 + 1.401 +function glColor4f(r, g, b, a) 1.402 +{ 1.403 + gl_curr_color[0] = r; 1.404 + gl_curr_color[1] = g; 1.405 + gl_curr_color[2] = b; 1.406 + gl_curr_color[3] = a; 1.407 +} 1.408 + 1.409 +function glTexCoord1f(s) 1.410 +{ 1.411 + gl_curr_texcoord[0] = s; 1.412 + gl_curr_texcoord[1] = 0.0; 1.413 +} 1.414 + 1.415 +function glTexCoord2f(s, t) 1.416 +{ 1.417 + gl_curr_texcoord[0] = s; 1.418 + gl_curr_texcoord[1] = t; 1.419 +}