Skip to content

Commit

Permalink
Initial import of pre3d, an immediate mode JavaScript 3d engine.
Browse files Browse the repository at this point in the history
  - pre3d.js, core math, datastructures, and engine
  - pre3d_shape_utils.js, some tessellation and procedural mesh code
  - colorscube demo
  • Loading branch information
deanm committed Mar 26, 2009
1 parent e582844 commit 6120588
Show file tree
Hide file tree
Showing 6 changed files with 2,055 additions and 1 deletion.
37 changes: 36 additions & 1 deletion README
Original file line number Diff line number Diff line change
@@ -1 +1,36 @@
A JavaScript 3d rendering engine.
Pre3d is a JavaScript library, which will project a 3d scene into 2d, and draw
it to a <canvas> element. The API is immediate mode, with the basic primitive
of a Shape, consisting of QuadFace quad and/or triangle faces. The library is
designed to be low-level and direct, there is no retrained or scene graph API.

There are currently 2 JavaScript files, the core engine and some mesh utils.
There are no external dependencies, and the DOM shouldn't be touched outside
of using the <canvas> element passed to the Renderer.

pre3d.js - The core math routines, data structures, and rendering code. It
does not touch the DOM, except the <canvas> element passed to the Renderer.

pre3d_shape_utils.js - While pre3d.js defines the basic shape datastructures,
it implement much code for working with them. This is a collection of code
for creating new Shapes (cube, sphere, etc), and for manipulating Shapes. It
implements some basic procedural operators like smooth and subdivide.

There are some demo applications implemented in the demos/ directory. Along
with the comments in the source code, the demos are the best source of
documentation. They should give you an idea of how to use the engine, and what
it is capable of. demos/demo_utils.js implements some UI helpers, like moving
camera when the canvas element is dragged on, etc.

License:
The engine code is free to use under the BSD license. The examples / demos
are (c) Dean McNamee, All rights reserved.

Credits:
Kragen's torus is the best/simplest/cleanest JS 3d code I've seen, and was
a good source of inspiration. http://www.canonical.org/~kragen/sw/torus.html

The Demoscene has strongly influenced how I think about graphics, and this
engine is a joke compared to what is being done there.

Thatcher Ulrich gave me a bunch of help and ideas, and implemented the
textured triangle drawing.
54 changes: 54 additions & 0 deletions demos/colorscube.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<html>

<head>

<title>A 3d demo in JavaScript</title>

<style>
body * {
font-family: sans-serif;
font-size: 14px;
}
body.white {
background-color: white;
color: black;
}
body.black {
background-color: black;
color: white;
}
span.spaceyspan { margin-right: 20px; }
div.centeredDiv { text-align: center; }
li { list-style: none; }
td { padding-right: 10px; }
</style>

<script src="../pre3d.js"></script>
<script src="../pre3d_shape_utils.js"></script>
<script src="demo_utils.js"></script>
<script src="colorscube.js"></script>
</head>

<body class="black">

<div class="centeredDiv">
<canvas id="canvas" width="800" height="600">
Sorry, this demo requires a web browser which supports HTML5 canvas!
</canvas>
</div>

<p>
JavaScript software 3d renderer &nbsp; &copy 2009 Dean McNamee (dean at gmail)
</p>

<table>
<tr><td>Press t</td><td>&rarr;</td><td>toggle background color</td></tr>
<tr><td>Press p</td><td>&rarr;</td><td>pause</td></tr>
<tr><td>Mouse</td><td>&rarr;</td><td>rotate around origin x and y axis</td></tr>
<tr><td>Mouse + ctrl</td><td>&rarr;</td><td>pan x / y</td></tr>
<tr><td>Mouse + shift</td><td>&rarr;</td><td>pan z</td></tr>
<tr><td>Mouse + ctrl + shift</td><td>&rarr;</td><td>adjust focal length</td></tr>
</table>

</body>
</html>
65 changes: 65 additions & 0 deletions demos/colorscube.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// (c) Dean McNamee <dean@gmail.com>. All rights reserved.

window.addEventListener('load', function() {
var black = new Pre3d.RGBA(0, 0, 0, 1);
var white = new Pre3d.RGBA(1, 1, 1, 1);

var screen_canvas = document.getElementById('canvas');
var renderer = new Pre3d.Renderer(screen_canvas);

var cubes = [ ];

for (var i = 0; i < 10; ++i) {
for (var j = 0; j < 10; ++j) {
for (var k = 0; k < 10; ++k) {
if (i == 0 || j == 0 || k == 0 ||
i == 9 || j == 9 || k == 9) {
var cube = Pre3d.ShapeUtils.makeCube(0.5);
var transform = new Pre3d.Transform();
transform.translate(i - 5, j - 5, k - 5);
cubes.push({
shape: cube,
color: new Pre3d.RGBA(i / 10, j / 10, k / 10, 0.3),
trans: transform});
}
}
}
}

var num_cubes = cubes.length;

function draw() {
for (var i = 0; i < num_cubes; ++i) {
var cube = cubes[i];
renderer.fill_rgba = cube.color;
renderer.transform = cube.trans;
renderer.bufferShape(cube.shape);
}
renderer.draw();
renderer.emptyBuffer();
}

renderer.camera.focal_length = 2.5;
// Have the engine handle mouse / camera movement for us.
DemoUtils.autoCamera(renderer, 0, 0, -30, 0.40, -1.06, 0, draw);

renderer.background_rgba = black;

cur_white = false;
document.addEventListener('keydown', function(e) {
if (e.keyCode != 84) // t
return;

if (cur_white) {
document.body.className = "black";
renderer.background_rgba = black;
} else {
document.body.className = "white";
renderer.background_rgba = white;
}
cur_white = !cur_white;
draw();
}, false);

draw();
}, false);
Loading

0 comments on commit 6120588

Please sign in to comment.