______________________________________________________________________________
| 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.