______________________________________________________________________________ | SECTION 1 PART A SUBPART 3 | 3D Programming | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -------------------------------------------- / / | --------------------------------------------- | 3D Graphics in BASIC - Part I.1: Introduction / --------------------------------------------- HEY YOU ! Interrested in programming vector graphics ? Bored of painting 2 dimensional diagrams. Feared of using C/C++ ? Or are you a math dummie ? No panic. Spend some time (and of course even more time at your PC) with me and join me into the wonderful world of ... 3D Graphics in BASIC (yep, it's possible !!!) Before I fill your brain with lot of stuff like vectors, matrix, filled polygons or shading techniques in the next five parts (this text included), I'll introduce me to my person: I'm Christian Garms, a german chemistry student and programmer. Last year I've made some nice money with Visual Basic programs in MS Excel and that's why I think BASIC is the opposite of a dead programming language. I'm a registered PB user but the examples that will be post in this article should work with both QB and PB (eventually with minor modifications). For questions, REMarks or comments send an e-mail to: garms@chemie.uni-hamburg.de I assume that you're not a BASIC beginner. Hope that you're at least an advanced programmer because this article is not a bedtime story. But the sweetest fruits are hidden and hard to get. Most programs will do the trick without any assembly additives to speed up the code. If x86-ASM is necessary I'll write it as INLINE Assembler. Sorry QB Users but I have not much time to spend for converting INLINE code into suitable OBJ-Files. ************************************************************************ Disclaimer: The author, Christian Garms, is not responsible for any errors or damage to your computer system caused by the posted BASIC programs. The BASIC programs and snippets are free for any use. ************************************************************************ ------------------------------------------------ / / | ------------------------------------------------ | 3D Graphics in BASIC - Part I.2: some basic math / ------------------------------------------------ The hardest part to understand of 3D graphics is the mathematical background that is - politely spoken - abstract. But lets begin with an easier entry point. Point - that is the right object to start with. In our three dimensional world all points consist of three components, the x-, y- and z-coordinate. With these values every point is strongly determined in his position. But to whom ? That is the next thing to be dealt with: Coordinate systems ! For the beginning we start with only one coordinate system, the world coordinates. That means all coordinates are related to an absolut center somewhere in our real world. E.g.: a value of x = 0 , y = 0 and z = 0 define a point exactly in the center of our world. For a mathematician every point in the whole 3D world is a vector. That's why 3D graphics is also called vector graphics. If we had a point Z who lies in the center of our world than the definition of Z will be: Z = (0 0 0) Any other point P with unequal values to zero of x-, y-, and z-coordinates would look like: P = ( ) The letters in the brackets are placeholders for the corresponding values. OK, lets return from the equation thicket to programming. For further use we should define our own TYPE of variable, a vector ! ************************************************************************** ' Creating own definition TYPE vector x AS INTEGER y AS INTEGER z AS INTEGER END TYPE ' Declare p as vector DIM p AS vector ' Sets p to the center of the world p.x = 0 p.y = 0 p.z = 0 ************************************************************************** Listing I-2.1 Listing I-2.1 demonstrates the usage of user-defined types. User-defined types makes your programs more structured and better understandable than Listing I-2.2. Especially when you have more than one point ! As you can see I'm using mostly integer arithmetics. That is a common trick to speed up the output of 3D graphics enormously. ************************************************************************** ' Define point in the middle of the universe px% = 0 py% = 0 pz% = 0 ************************************************************************** Listing I-2.2 ------------------------------------------------ / / | ------------------------------------------------ | 3D Graphics in BASIC - Part I.3: transformations / ------------------------------------------------ Now we have the simpliest object: a point. The next question is: How to convert a point in our 3D world - or mathematically spoken a vector - into a flat pixel on the screen. So here comes the moment to introduce you with a new coordinate system - the eye coordinate system. I think that you, dear reader, will ask WHY. Well, imagine a scenery from any 3D game you have in mind. In most cases of these games there is a craft that you fly, drive or move and others that will be steered by your computer or someone else. You can look in all directions without steering into this directions. This would be impossible if your eye coordinate system is non-existant. In other words: The eye coordinate system allows watching different from the world coordinate systems. And now the strategy to convert a point into a pixel: 1. Transformation of the world coordinates into eye coordinates 2. Transformation of eye coordinates into screen coordinates But some mathematics first. I hope you've got your machet right by your hand and follow me again into the equation jungle. This time it will be harder than last time. Mathematicians are sometimes lazy to write complex formulas. In the case of transformation of a vector to a new vector in another coordinate system like the transformation of the world coordinate system into the eye coordinate system they simply write: P_eye = P_world * T with P_eye eye coordinate vector P_world world coordinate vector T Transformation operator That means: transformation of coordinates is only a "simple" mathematical operation. But I would not go any further now because I've saved that for Part II. This time I'll explain the transformation by an example. Once again you must imagine to sit in a craft in our virtual 3D game. Say you're at Position x=100, y=0, z=0 and look to the center of our world. If you've reset your nav computer and set the absolute position (0 0 0) to your craft (the eye coordinate system) the center of the world now lies at x=-100, y=0, z=0. In Summary: the world coordinates of a point will transformed to eye coordinates via the following equations: x_eye = x_world - eyepos_x y_eye = y_world - eyepos_y z_eye = z_world - eyepos_z with x_eye x-coordinate of the point (eye coordinate system) dito with y_eye, z_eye x_world x-coordinate of the point (world coordinate system) dito with y-world, z_world eyepos_x position of the watcher (relative to world center) dito with eyepos_y, eyepos_z But we gained also a three-dimensional point. How to convert this one into a pixel? Now the mathematician comes in action. And he won't be lazy any more ! He will tell you something about triangles, pyramids ... and you're stuck complete helpless in the thickest formula thicket you could think about. If there would be a chalkboard he would easily write it full just for explanations. Simple, isn't it ? Instead of molto formulos there is THE golden wisdom of every 3D-Programmer: "The screen coordinates could be calculated by dividing the x- and y- position through the depth (z-coordinate)" In formula speak: x_screen = x_eye / z_eye y_screen = y_eye / z_eye with x_screen x-coordinate of the pixel y_screen y-coordinate of the pixel x_eye, y_eye, see above z_eye You gain a dimensionless number that must be fit to screen coordinates and to the middle of the screen. I assume that the width and the height of the screen are given so the formula results to: x_screen = (x_eye / z_eye) * width + width / 2 y_screen = (y_eye / z_eye) * height + height / 2 Now we've got all parts together to write some real 3D stuff. ************************************************************************** ' Simple 3D Object (Pyramid) ' Type declarations TYPE vector x AS INTEGER y AS INTEGER z AS INTEGER END TYPE TYPE pixel x AS INTEGER y AS INTEGER END TYPE ' Variable declaration DIM p(3) AS vector DIM eye AS vector DIM s(3) AS pixel DIM maxx AS INTEGER ' width of screen DIM maxy AS INTEGER ' height of screen ' Screen resolution maxx = 640 maxy = 480 ' Read Object Data FOR i = 0 TO 3 READ p(i).x READ p(i).y READ p(i).z NEXT i ' Definition of object DATA 30, 1, 1 DATA 1,30, 1 DATA 1, 1,30 DATA -30,-30,-30 ' Set Eye position (change if desired) eye.x = 0 eye.y = 0 eye.z = 100 ' Calculate the eye coordinates FOR i = 0 TO 3 p(i).x = p(i).x - eye.x p(i).y = p(i).y - eye.y p(i).z = p(i).z - eye.z NEXT i ' Calculate screen coordinates FOR i = 0 TO 3 s(i).x = (p(i).x / p(i).z) * maxx + maxx / 2 s(i).y = (p(i).y / p(i).z) * maxy + maxy / 2 NEXT i ' Draw object CLS SCREEN 12 FOR i = 0 TO 5 READ pt1, pt2 LINE (s(pt1).x,s(pt1).y)-(s(pt2).x,s(pt2).y) NEXT i DATA 0, 1, 0, 2, 0, 3, 1, 2, 1, 3, 2, 3 ************************************************************************** Listing I-3.1 OK, folks. Next time I will introduce you to animated vector graphics and the calclulation with matrix. Stay tuned and I hope that you enjoy this article. -------------------------------------------------------- * EDITOR'S NOTE: * This article was originally printed in Peter Cooper's BASIX Fanzine, * Issue #4 from January 1996.