This is a little toy that I have been playing with on and off for the past two years. It is a 3D wireframe viewer/renderer, and a perfect example of creeping featurism. It is written with X Windows and Motif. It has not been optimized for eather speed or space efficiency. It should build and run on sparcstations, decstations, RS6000, and SGI 4.0. Feel free to send questions/comments/requests/bugs/patches/cookies/candy. I love to get mail! Please clearly mark any cookies or candy so they get first priority and don't go stale. Eric Bina 508 E. Michigan, #35, Urbana, IL 61801 ebina@ncsa.uiuc.edu Anyways, in a moment of generosity I decided to share my toy with you. (lucky you :-) This software is provided as free as I can possible make it. There are two modules that are not my work. The gif image dumping code in writegif.c belongs to David Rowley, and it says so in the beginning of the file. Also, I am forever in debt to Pat Kane for spending a week of his life deciphering Perlin's paper on noise and solid texturing and producing the module S3Noise.c which is all his (I don't even claim to totally understand it). With the exception of those two modules you can do whatever you want with this code. However, I should mention that I believe all code should be free, and if you decide to try and make money off my work, I hope you can sleep knowing there is someone out there who thinks you are more disgusting than rotted slug-slime drippings. Alas, I am terrible at documentation, so there is none (other than this file). However, the code is commented. Hmmmm... So lets see what's to say. (Please note, I am not going to proof read or spell check this README, so all you English majors out there should grit your teeth.) File Format: Sorry, I didn't use any standard file format, just one I made up. It is really simple though, so it should be easy to convert back and forth to your favorite renders. It is an ascii format. First line is number of points in the object. The second line is the number of triangles in the object. The following lines are points, one point per line described as x y z (separated by spaces). The rest of the lines are triangles, one triangle per line, put the point indicies of the three corners on the line (separated by spaces). If you want to be able to see the object, keep x, y, and z values all between -1.0 and 1.0. Also not that point indicies start at 0, not 1. Thats all you need for a basic input file. Bells and Whistles: As time passed I wanted to describe more than just a bunch of triangles. I wanted to give a color to each triangle. So optionally, on each triangle description line, after the verticies, you can specify a pixel to color that triangle with. Example "0 1 2 P3" says draw the triangle made up of points 0, 1, and 2 with pixel color 3. What the hell is pixel color three you ask? Well, by default the colormap is a 256 shade grayscale from black to white. But, you can change that colormap. At the end of the file, just after describing the last triangle put the line "Colormap 256". Follow that immediately by the line "red green blue" Ok, now you can enter your colormap. Put one color on a line which is red greenblue (separated by white space) varying between 0 and 255. You don't have to specify all 256 colors, but the colors are automatically numbered in order, so if you want to specify pixel 30, you better have specified pixels 0 through 29 first. Confused yet? Another "feature". You can also specify an opacity to go with each triangle. Opacity ranges from 0.0 to 1.0, here is an example "0 1 2 O0.5" specifies that this triangle is only 50% opaque. What this really means is that this triangle will only be drawn 50% of the time, and the other 50% of the time it will not be drawn. This means that if you have an object made up totaly of O0.5 triangles, and each triangle is only 1 pixel in size, it will appear as an object shaped cloud of dots on your screen. Souds useless? Yep, it is, but it sounded neat at the time, and when it ended up being a disappointment, I didn't rip the code out. Note: O0.0 is a special case. A triangle of opacity 0.0 is actually a transparent filter, that passes color based on its pixel value. Example: 3 1 1.0 -0.5 0.0 -1.0 -0.5 0.0 0.0 1.0 0.0 2 0 1 P3 O0.0 Colormap 256 red green blue 0 0 0 1 1 1 255 255 255 128 0 30 The previous file describes a triangle that will pass 128/255 of the red no green, and 30/255 blue of whatever is behind it (since this example has nothing behind it, it will be black) Finally, if you are going to give triangle both opacities and pixels, they must be described pixel and then opacity. Reversing the order will probably make it core dump. That's all I can think of about the object format, I will provide a few sample objects with the code. Command line Options: type "wframe -help". I'm sorry, but I used the Motif widget set, and you need Motif to compile it. Its is all basic widgets though, and should be easy to port to Athena or Open Look widgets, or whatever. All triangles are one sided. If the normal vector points toward you, you can see it, if not, it is transparent. If the vertex description of a triangle has vertices that proceed in a clockwise direction from first to last, it will be visible. A two sided triangle needs to be described with 2 triangles that use the same three points back to back. When started you get 4 scrollbars and a menu bar. The scrollbars control rotation of the object about the X, Y, and Z axis, and its distance from the viewer. Rotation is always relative to the viewer, not the object. Note, order matters, if you rotate in X, then in Y, then unrotate the X, and then unrotate the Y, it will NOT be back where you started, this is not a bug, it is the way rotation works. What? You don't see any image? The "Commands" menu has a "Display" button. This toggles on and off the display window. Note, because the object viewed in the display window can sometimes take hours to draw, that window makes no attempts to redraw itself when it receives expose events. It will always redraw when popped up. The "Dump" button dumps the contents of the view window. It currently defaults to dumping in GIF format. The only other format it knows is ebc format which is an image format I made up, so it is useless to you, but it works well with all my other toys. "Perspective" toggles off and on perspective projection of the view window. "Lattice" re-initializes the random number array for solid texturing functions. "Quit" is self explanatory. The "Read" and "Write" under the "File" menu should be obvious. The "Read Script" needs explaining. Sometimes I want to make an animation, and it takes a long time per frame. I added a VERY BASIC scripting language to let me describe a sequence of motions and and frames to draw. After executing a script the program always exits! Script commands are of 2 kinds. Example 1: Draw 18 2 0 10 0 0.2 Example 2: Move 1 2 90 0 0 -2.0 The first example says take 18 pictures at detail level 2. On each picture rotate 0 degrees X, 10 degrees Y, and 0 degrees Z, and add 0.2 to the objects distance. The texture in the picture is whatever was set before reading the script file. The second example shows the Move command. This moves the object by rotating it 90 degrees in the X and subtracting 2.0 from distance. Any number of Draw and Move commands can be chained together. The "Edit" menu. WARNING: I thought I wanted to be able to edit as well as view objects, but I didn't like the results. I don't use this feature much and it may be buggy. To make a complex object, I usually write a program to do it. You must first choose "Select" to use any of the editing features. This automatically turns off the default removal of all back facing triangles. In Edit(Select) you can click on any vertex and have it be selected, showing you its x, y, and z values, and letting you move it in the x, y, or z direction with the control panel. The control panel moves all currently selected points together. Click again on a selected point to unselect it. Edit(Delete) deletes all currently selected points ans all triangles that use them! Edit(Add) adds a triangle. Each sequence of 3 mouse clicks adds a triangle described by those three points. Edit(Link) allows you to link any three verticies to make a new triangle. The link takes the closest vertex to your mouse click. It must be an unselected vertex. If it is selected, the first click unselects it, and you have to click again to link it. My shading model is VERY BASIC, each triangle is filled with a solid color. To get good pictures each triangle needs to fill only one pixel. The "Detail" menu gives you an easy way to do that. Each level of detailing subdivides each triangle into 4 smaller triangles. Detail 9 is adequate to make even the largest object have far too many tiny triangles. "Textures". "Wire" displays the object as a wireframe, back facing triangles removed. "Shade" shades the object in a grayscale. "Fire" is part of a broken attempt on my part to add a neat special effect. I think it currently shades the object in a yellowscale. "Granite", "Marble", and "Wood" will render the object out of those materials based on a solid texturing and solid noise function. "BaseColor" just displays each triangle in the color that was specified with the P option in the input file. "BaseShade" colors each triangle with the basecolor shaded based on angle from the lightsource (which is a point source at the viewer location). It does this by dynamically allocating from the colormap, and matching best fit color once the colormap fills up. That's All Folks! Have Fun! Eric Bina ebina@ncsa.uiuc.edu