Human Fly (UFly) 2.1 - questions and answers ============================================================================ What is it? A 3d rendering pipeline for modern atari tos computers. Where can I get it? Well you got this file, so you got Human Fly too, right? =:P What are it's features? - open source and interface for whatever special implementations you like - handles multi-transformations with matrices - dynamic viewport dimensions (outer and inner), focal-length, aspect ratio - spline based keyframer - primitive types: - sprite (rle) - line: flat, gouraud, phong - polygon: flat, gouraud, phong, texturemap, envmap, alphatexture, bump - directly accessible primitive paint routs! - flexible object format: - normal vectors - texture vertices - free choice of primitivetype and palette/texture/image per primitive - dynamic paintmodes: - move, or, add, saturated add logic operations - pixels can be bytes or words - bytes to skip after each pixel - full clipping on all primitives - painters algo sorting - linear morphing - bounding boxes for efficient culling and background restoring What if I wanna use all this shit and I dunno about matrices or vector or..? Oh boy! Well, you can always try one of the fine docs out there on the net about 3d basics. I know Denthor of Asphyxia (pc dude) made a good tutorial about these things. If you want a book, you can buy somekind of bible: 'Computer Graphics - principles and practice' by Foley and van Dam. You can come back after you glanced at this a few times. How does it work? It is basicly an 68K assembler library. You include it in your favourite asm sourcecode and make some 3d animations with it. The Human Fly library is supplied as source and not as a binary. The way to work with Human Fly is not unlike OpenGL, but less flexible and less complicated. There are no windowing libs, no floating point routs, no nurbs shit, multi lights or teapots, no bullshit. What systems are currently supported? Only the ataris with 020 or better I'm afraid. The current Human Fly implementations are video hardware independent. You can make them render bytes, words, etc to a block of memory of your choice. So it runs on Falcon, but also on TT (with c2p) or clones(!). What's this open source and interface stuff? The hflycore.s file is basicly a header file or interface if you like for the whole pipeline. It has information on the functioning of all the routs. It contains equates and stuff every implementation of Human Fly should use. Everybody can make their own Human Fly implementation using this header file. If you want to make a VDI or a 3d accelerator specific version: please be my most honoured guest! At this moment version 2.1 knows two implementations: - dsp falcon (fast, limited amount of objects) - general cpu version (slow on standard falc, but can handle more objects!) Where to start? It's best to start with some of the example source supplied with this package. Check out those fancy Human Fly calls and then take a hike over to hflycore.s to check out what they do. Yeah, and now in detail please! The pipeline is alot like OpenGL and basicly you should work like this: 1) initialize viewport, initialize primitive painters, register objects This is done only once. 2) set up transformation matrices and use them on objects to transform 3) tell the pipeline to do depthsorting, complete and then paint 1) For a full complex scene you need alot of initialisation. A better idea is to start with the most simple situation like a only one flatshaded cube or pyramid. Even for this you to call the obligatory init calls. Registering palettes and objects, setting up your viewport and even setting the texturetable to a null are necessary. Calls are as follows: - HumanFly.init - Viewport.update - Polygon.init - ObjectRegistry.clear - ObjectRegistry.set 2) Also the most transformation calls are needed. Even if you only wanna display 1 stupid object in front of you. You need first to set up a rotation matrix by passing x,y,z rotation angles, all 0 in this case. Then you need to translate it a bit along the z axis, say (0,0,500). Then you need to call the transform rout with object handle and transformmode. - Matrix.generate - Matrix.translate - Matrix.push - TransformObject.transform - Matrix.pop 3) For painting on screen you need to register the viewport buffer. Now you can restore the background and so on with some Human Fly calls as well. After that you can (if needed) depthsort the primitives. For one convex object like cubes, spheres or pyramids this is shit, but for everything else you should really use depthsort! Finally you can tell the pipeline to complete and paint. - Primitive.setScreenbuffer - PrimitiveMesh.new - PrimitiveMesh.sortZ - PrimitiveMesh.complete - (Viewport.paintRectangle) - PrimitiveMesh.paint How are the functions didived? Human Fly is somewhat inspired by thinking in terms of objects. This means that the pipeline has a range of objects. Each of these objects has it's responsibilities. For instance: the Viewport object has control over the dimensions of the screenbuffer, the Matrix object has the responsibility to contain consecutive rotations and translations and so forth... In a rendering pipeline you can roughly divide functions up in two parts: - transformation (3d) - rendering (2d) And ofcourse you have the usual more global utility engine stuff. In Human Fly transformation covers the following objects: - ObjectRegistry - Matrix - TransformObject And for rendering the following objects are used: - Primitive - Sprite - Line - Polygon - PrimitiveMesh - Viewport The more global objects are: - HumanFly - Keyframer - WorldTree How to build objects with moving parts? Ah! This is where matrices come in. HumanFly handles a stack of these. This is needed for multi rotation/translation. For instance: you've got a world. In this world you got a car. A car has got wheels, doors, etc. All of these have their own rotation and possible translation. To transform a wheel you need need one rotation/translation. On top of that you need the car's rotation/translation. Finally you need the world rotation/translation. Multiply/add all these matrices toghether and you got yourself the final transformation matrix of the wheel. Human Fly handles this paradigm simple. These multiplies are implicit and handled within a stack structure. To handle the transformation of the wheel for instance you first calc and push the world matrix. Then you calc and push the car matrix. Finally you calc and push the wheel matrix. Now you perform a call to the transformobject. Inside the car you can easily transform other parts very easily. Now you just pop off one entry of the matrix stack, calc and push the door matrix, push it and then call transform. This is the most efficient and easy way to implement flexible world construction. Ofcourse this idea was ripped from OpenGL, what else? Can I just use HumanFly only to paint some 2d primitives? The answer is yes. You can directly call any primitive routine by supplying it with a table of vertices. This way you can make your own 2d or 3d pipeline only using HumanFly's painting routines. There are both clipping as well as unclipping flavours. The first catagory is perfectly safe, but beware when using the second!! How to get alphablending? Setting the paintmode is the answer. You need to divide your rendering in two stages. One is the foreground and the other is the alphalayer. For each stage you you set the paintmode anew. A (relatively) cheap way of getting alpha is to set both stages to bytes and 1 byte pixelskip. Stage 1 should have a byteoffset=0, stage 2 should have byteoffet=1. This way, when you have finished both you can read out pairs of bytes (words) and use them to index a big 256*256 word alphablending table!