<!DOCTYPE HTML>
<!-- https://labs.mozilla.com/forum/index.php/topic,58.0.html -->
<!-- http://canvex.lazyilluminati.com/misc/photos.html -->
<!-- todo: persistent storage of the scripts every time they are run, needs a light weight sketchbook/version control -->
<!-- todo: mouse controlled translation / rotation of the entire scene -->
<title>jsxus</title>
<style>
body {
font-family: sans-serif;
background: white;
color: black;
margin: 0;
}
label {
display: block;
width: 100%;
}
small {
position: absolute;
bottom: 0.5em;
}
</style>
<script src="jquery-1.2.3.min.js" type="text/javascript" charset="utf-8"></script>
<script src="Log.js" type="text/javascript" charset="utf-8"></script>
<script src="Matrix.js" type="text/javascript" charset="utf-8"></script>
<script src="Vector.js" type="text/javascript" charset="utf-8"></script>
<script src="helpers.js" type="text/javascript" charset="utf-8"></script>
<script src="startup.js" type="text/javascript" charset="utf-8"></script>
<script type="application/javascript;version=1.7">
var audiolevel = 0;
function audioIn(level){
if(level>-1){
// this smoothing is working but possibly not fast enough.
audiolevel = (level+audiolevel)/2;
// $("#bouncer").css({width:level});
}
}
//tabs in text area script cribbed from: http://l4x.org/261/
Number.prototype.times = function(F){
for(var i=0;i<this;i++){
F(i);
}
}
function insertTab(event,obj) {
var tabKeyCode = 9;
if (event.which) // mozilla
var keycode = event.which;
else // ie
var keycode = event.keyCode;
if (keycode == tabKeyCode) {
if (event.type == "keydown") {
if (obj.setSelectionRange) {
// mozilla
var s = obj.selectionStart;
var e = obj.selectionEnd;
obj.value = obj.value.substring(0, s) +
"\t" + obj.value.substr(e);
obj.setSelectionRange(s + 1, s + 1);
obj.focus();
} else if (obj.createTextRange) {
// ie
document.selection.createRange().text="\t"
obj.onblur = function() { this.focus(); this.onblur = null; };
} else {
// unsupported browsers
}
}
if (event.returnValue) // ie ?
event.returnValue = false;
if (event.preventDefault) // dom
event.preventDefault();
return false; // should work in all browsers
}
return true;
}
$(document).ready(function(){
var lastkey = 0
$(document).keydown(function(e){
if(lastkey == 17 && e.which==75){
// console.log(e.which);
eval($("#code").val());
return false;
}else{
lastkey = e.which;
}
});
$(document).keyup(function(e){
// console.log(lastkey);
if(e.which==17){
lastkey = 0;
}
});
// before loading the gl, set the canvas to full width
// $('#c').css({width:100%});
everyframe = function(){
for(i=0;i<3;i++){
// gl.rotate(speed*t*i*1.50, .8, .4, 0);
// gl.translate(i*0.202*audiolevel, 0, 0);
// gl.rotate(170, 0, 1, 0);
// gl.rotate(speed*t*502.3, 1, .4, .3);
// drawplane();
}
}
var background = [0, 0, 0, 0];
// var background = [1, 1, 1, 1];
startup();
var drawcube = function (){
var buffers = {};
var vertArray = new Array();
var normArray = new Array();
var colorArray = new Array();
var m = makeIdentityMatrix();
// scale left up and dir vectors which are used to setup the vertex list
this.left = multiplyMatrixByVector(m, new Array(1.0,0,0));
this.up = multiplyMatrixByVector(m, Array(0,1.0,0));
this.dir = multiplyMatrixByVector(m, Array(0,0,1.0));
// This would be easier if we had an Index Buffer
var vecArr = [this.up, this.left, this.dir, // 1
this.up, this.left, multiplyVector(this.dir, -1.0), // 2
this.up, multiplyVector(this.left, -1.0), multiplyVector(this.dir, -1.0), // 3
multiplyVector(this.up, -1.0), multiplyVector(this.left, -1.0), multiplyVector(this.dir, -1.0), // 4
this.up, multiplyVector(this.left, -1.0), this.dir, // 5
multiplyVector(this.up, -1.0), multiplyVector(this.left, -1.0), this.dir, // 6
multiplyVector(this.up, -1.0), this.left, this.dir, // 7
multiplyVector(this.up, -1.0), multiplyVector(this.left, -1.0), multiplyVector(this.dir, -1.0), // 8
multiplyVector(this.up, -1.0), this.left, multiplyVector(this.dir, -1.0), // 9
this.up, this.left, multiplyVector(this.dir, -1.0), // 10
multiplyVector(this.up, -1.0), this.left, this.dir, // 11
this.up, this.left, this.dir, // 12
this.up, multiplyVector(this.left, -1.0), this.dir, // 13
this.up, multiplyVector(this.left, -1.0), multiplyVector(this.dir, -1.0) // 14
];
// Using the vectors above, calculate the verticies
for (var i = 0; i < (14 * 3); i += 3)
{
this.pos = new Array(0.0, 0.0, 0.0);
var v = makeVector();
v = addVectors(this.pos, vecArr[i]);
v = addVectors(v, vecArr[i + 1]);
v = addVectors(v, vecArr[i + 2]);
// console.log(v);
// Set the individual Vertex Coords
vertArray.push(v[0]);
vertArray.push(v[1]);
vertArray.push(v[2]);
// Calculate the Normals
var n = new Array(0.0, 0.0, 0.0);
n = addVectors(v, this.pos).slice();
n = normalizeVector(n);
normArray.push(n[0]);
normArray.push(n[1]);
normArray.push(n[2]);
// Set some colors
colorArray.push(1.0); // R
colorArray.push(0.0); // G
colorArray.push(0.0); // B
colorArray.push(1); // A
}
// Create Buffers
buffers.vertex = gl.createBuffer(gl.STATIC_DRAW, 3, gl.FLOAT, vertArray);
buffers.normal = gl.createBuffer(gl.STATIC_DRAW, 3, gl.FLOAT, normArray);
buffers.color = gl.createBuffer(gl.STATIC_DRAW, 4, gl.FLOAT, colorArray);
// Apply the buffers to OpenGL
gl.vertexPointer(buffers.vertex);
gl.normalPointer(buffers.normal);
gl.colorPointer(buffers.color);
// Flag OpenGL that we will be using buffers
// Draw
//gl.drawArrays(gl.LINES, 0, 14);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 14);
// Turn off Buffers
}
planeObject = function(){
this.vertices = [
-1,-1,0, 1,-1,0, -1,1,0,
-1,1,0, 1,-1,0, 1,1,0,
1,-1,0, -1,-1,0, -1,1,0,
1,-1,0, -1,1,0, 1,1,0,
];
this.texcoords = [
0,1, 1,1, 0,0,
0,0, 1,1, 1,0,
0,1, 1,1, 1,0,
0,1, 1,0, 0,0,
];
this.normals = [
0,0,1, 0,0,1, 0,0,1,
0,0,1, 0,0,1, 0,0,1,
0,0,-1, 0,0,-1, 0,0,-1,
0,0,-1, 0,0,-1, 0,0,-1,
];
this.colors = [
1,0,1,1, 0,0,1,1, 1,0,1,1,
1,0,1,1, 0,0,1,1, 1,0,1,1,
1,0,1,1, 0,0,1,1, 1,0,1,1,
1,0,1,1, 0,0,1,1, 1,0,1,1,
];
this.vertex_buffer = gl.createBuffer(gl.STATIC_DRAW, 3, gl.FLOAT, this.vertices);
this.texcoord_buffer = gl.createBuffer(gl.STATIC_DRAW, 2, gl.FLOAT, this.texcoords);
this.normal_buffer = gl.createBuffer(gl.STATIC_DRAW, 3, gl.FLOAT, this.normals);
this.color_buffer = gl.createBuffer(gl.STATIC_DRAW, 4, gl.FLOAT, this.colors);
}
var color = function(r, g, b, a){
gl.material(gl.FRONT_AND_BACK, gl.AMBIENT, [r, g, b, a]);
}
plane = new planeObject();
var drawplane = function(){
gl.vertexPointer(plane.vertex_buffer);
gl.texCoordPointer(plane.texcoord_buffer);
gl.normalPointer(plane.normal_buffer);
gl.colorPointer(plane.color_buffer);
// if we are doing wireframe mode
// gl.drawArrays(gl.LINES, 0, plane.vertices.length / 3);
gl.drawArrays(gl.TRIANGLES, 0, plane.vertices.length / 3);
}
setInterval(function() {
if (document.getElementById('pause').checked)
return;
//
gl.clearColor(0.1, 0.1, 0.1, 1.0);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
// gl.enable(gl.DEPTH_TEST)
// Set the camera in world space
// camera.applyToWorld(gl, thisScn);
gl.loadIdentity();
var pos = new Array(5.0, 0.0, -5.0);
var dir = new Array(-5.0, 0.0, 5.0);
var left = vectorCrossProduct(dir, new Array(0.0, 1.0, 0.0));
var up = vectorCrossProduct(dir, multiplyVector(left, -1.0));
gl.multMatrix(lookAt(pos, dir, up));
gl.translate(-pos[0], -pos[1], -pos[2]);
gl.enableClientState(gl.VERTEX_ARRAY);
gl.enableClientState(gl.NORMAL_ARRAY);
gl.enableClientState(gl.COLOR_ARRAY);
// Do Rendering
if(everyframe){
everyframe();
}
// Swap buffers to render
gl.swapBuffers();
gl.disableClientState(gl.VERTEX_ARRAY);
gl.disableClientState(gl.NORMAL_ARRAY);
gl.disableClientState(gl.COLOR_ARRAY);
}, 30);
$("#code").keydown(function(eventObject){
insertTab(eventObject,this);
})
$("#run_code").click(function(){
eval($("#code").val());
});
var t = 0;
everyframe = function(){
gl.rotate(t, 0, 1, 0);
drawcube();
gl.translate(-3, 0, 0);
drawcube();
t++;
}
});
var everyframe = function(){
}
window.addEventListener('load', function ()
{
}, false);
window.loaded_first_script = true;
</script>
<script>
if (! window.loaded_first_script)
{
alert("Sorry, your browser does not support JavaScript 1.7");
var canvas = document.getElementById('c');
canvas.parentNode.replaceChild(canvas.firstChild, canvas); // oops, doesn't work in Opera
}
</script>
<canvas width="800" height="600" id="c"></canvas>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="550" height="138" id="audioin" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="audioin.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#666666" /><embed src="audioin.swf" quality="high" bgcolor="#666666" width="550" height="138" name="audioin" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
<textarea name="code" rows="8" cols="40" id='code' style='position:absolute;top:0;left:0;border:0;background:none;color:#fff;padding:10px;width:800px;height:600px;'></textarea>
<p id='run_code'>run code</p>
<form onsubmit="flush_buffer(); return false">
<table>
<tr>
<td><label for="pause">Pause</label>
<td><input type="checkbox" id="pause">
</tr>
</table>
</form>
<h2>Ctrl+K to run</h2>
code to be entered:
<pre style='width:200px'>
var t = 0;
var turn = 0;
var speed = 0.002;
var img_id = 0;
everyframe = function(){
t++;
for(i=0;i<3;i++){
// gl.rotate(speed*t*i*1.50, .8, .4, 0);
gl.translate(i*0.202*audiolevel, 0, 0);
gl.rotate(speed*t*502.3, 1, .4, .3);
drawcube();
}
}
//more code:
var t=0;
everyframe = function(){
t += audiolevel;
gl.translate(-10,-10, 0);
//gl.rotate(290*t*.03, 1, .5, .4);
for(i=0;i<5;i++){
for(j=0;j<5;j++){
gl.pushMatrix();
gl.rotate(20*j*audiolevel, 1, .4, 0);
gl.translate(0, 0, -j*5);
for(k=0;k<3*audiolevel+1;k++){
gl.pushMatrix();
gl.translate(i*2.4*audiolevel, j*3.7*audiolevel, k*2.9*audiolevel);
drawcube();
gl.popMatrix();
}
gl.popMatrix();
}
}
}
</pre>
<img src='http://farm3.static.flickr.com/2380/2377064406_2366ab8d2d.jpg?v=0' id='texture_map'/>