Você está na página 1de 7

BASIC4GL

Ok, hello and welcome to my tutorial. I hope you are familiar with the 3d coordinate
system. If not, I will try to explain... Basically, when you have a fresh screen (with no
rotations or translations added... Just the Identity matrix, and I will get to that)... There
are 3 coordinates you have to work with. These three values are what define the location
of your objects in 3d. If you put your finger smack dab in the middle of your monitor...
The tip of your finger will lye on the location 0,0,0...
• X is the left/right axis. If this number is negative, the location will be towards the left side of the
screen, if the X value is positive, the location will be towards the right side.
• Y is the up/down axis. If the Y value is negative, the location will be towards the bottom of the
screen, if the Y value is positive, the location will be towards the top side.
• Z is the towards/away-from axis. If this number is negative, the location will be away from you
(behind your monitor). If this value is positive, the location will be towards you (in front of your
monitor).

Most of the subjects covered in this will be based around opengl, specifically for Basic4gl. I am also
assuming that you have some knowledge of the BASIC language. The first thing you will need to know
is that we load the indentity matrix. Basically, this sets up our screen to its origin. It sets us to the 0,0,0
virtual location and it resets our rotation and our scale. Basically, it gives us a fresh start. Here is how
we use it:

glLoadIdentity()

Ok, now, with our playing field all set to the default, lets put something in it. For starters, we are going
to use points. The point command you are about to learn will simply put a dot on the screen. So, here's
how we make a dot in 3d space:

glLoadIdentity()
glBegin(GL_POINTS)
glVertex3f(0,0,-1)
glEnd()
SwapBuffers()

Now... Before you start asking questions, let me try to explain. First, we loaded our identity matrix.
This sets everything up to the default values. THEN... glBegin(GL_POINTS) told the computer that we
are about to draw a point (or multiple points, if you wish). After we inform the computer of what we
are about to do... glVertex3f(0,0,-1) puts a point in the 3d location 0,0,-1... Why the -1? Well, 0,0,0
would be DIRECTLY on the screen, and wont be rendered. We have to move it back a little in order to
see it. -1 places our point 1 unit away from us. Had we used 0,0,1 the point would have been one unit
towards us... And hence, wouldn't be rendered (the screen is like a window that only draws things that
are outside. Things inside will not be drawn).
After that, we tell it to stop drawing points... Thats what the glEnd() is for, and then SwapBuffers()
basically takes what we just drew and displays it on the screen. Essentially, everything we draw is
being drawn to a temporary screen... Not the real screen. Then, we are pasting all of the images that are
on the temporary screen to the real screen. Why would we use a temporary screen? Because then we
can draw everything, and then show it. Otherwise you would be able to see your content being drawn,
which wouldn't make very good graphics. That is what the SwapBuffers() does.
Ok, now lets draw 3 dots this time!!!
glLoadIdentity()
glBegin(GL_POINTS)
glVertex3f(-1,0,-10)
glVertex3f(1,0,-10)
glVertex3f(0,2,-10)
glEnd()
SwapBuffers()

Now, notice we used 3 of the glVertex3f commands... Each one is for an individual dot. We also placed
each dot 10 units away from us... This is so we can see what we are doing... Otherwise, it would be so
close to the screen that the dots would actually be off of the screen (unless we used very small decimal
numbers). So, now we have 3 dots, forming a triangle which is 10 units away from us. Lets try drawing
a triangle from these dots!!!

glLoadIdentity()
glBegin(GL_TRIANGLES)
glVertex3f(-1,0,-10)
glVertex3f(1,0,-10)
glVertex3f(0,2,-10)
glEnd()
SwapBuffers()

Ok, that was pretty simple wasn't it? All we did was change the GL_POINTS to GL_TRIANGLES. But
it looks so dull, its all plain and white. Lets add some color to it...

glLoadIdentity()
glBegin(GL_TRIANGLES)
glColor3f(1,0,1)
glVertex3f(-1,0,-10)
glVertex3f(1,0,-10)
glVertex3f(0,2,-10)
glEnd()
SwapBuffers()

Ok, cool, now we have a pinkish purple triangle. The glColor3f goes like this... The first number is the
amount of red, the second is the amount of green, and the third is the amount of blue. Each value can be
between 0 and 1. So...

0,0,0 would make black.


1,0,0 would make red
0,1,0 would make green
0,0,1 would make blue
1,0,1 makes purple (kindof pink if you ask me)
1,1,0 makes yellow (It sounds odd, but its light colors, not pigments)
1,1,1 makes white

You can also use decimals to get a more precise color.

.5,.5,.5 would make medium grey


.25,.25,.25 would make dark grey
.5,.5,.7 makes a slighly blue grey

Ok, enough with the color lesson. Now... We can color a whole triangle, but now we are going to color
each corner of the triangle different...

glLoadIdentity()
glBegin(GL_TRIANGLES)
glColor3f(1,0,0)
glVertex3f(-1,0,-10)
glColor3f(1,1,0)
glVertex3f(1,0,-10)
glColor3f(0,0,1)
glVertex3f(0,2,-10)
glEnd()
SwapBuffers()

Thats pretty nifty looking if you ask me (for a triangle anyway). But say we want to draw a square?
Well, here is how that's done...
glLoadIdentity()
glBegin(GL_QUADS)
glVertex3f(-1,1,-10)
glVertex3f(-1,-1,-10)
glVertex3f(1,-1,-10)
glVertex3f(1,1,-10)
glEnd()
SwapBuffers()

So, there you have it. I'm sure you realized that all you have to do is change the GL_TRIANGLES to
GL_QUADS. And, of course, since this is a square... It has 4 corners. So we added another vertex.
Now...you can color this one on your own. Go for it...

Ok, now that you're done coloring in squares... Lets use some matrices (please excuse the jump from
kindergarten to algebra). First off, we will use the scale command. Lets make our square bigger!!!
glLoadIdentity()
glScalef(5,5,1)
glBegin(GL_QUADS)
glVertex3f(-1,1,-10)
glVertex3f(-1,-1,-10)
glVertex3f(1,-1,-10)
glVertex3f(1,1,-10)
glEnd()
SwapBuffers()

WHAO. Scared you didn't it? So, now you see what the scale command does. It changes the scale of
things. But, notice how we only scaled the last component to 1... Thats because that is the Z axis, and
since this is a flat square, we cant scale it on the Z axis. So, we used 1, which is the default scale. You
could also scale each component separately... Like this:
glLoadIdentity()
glScalef(5,1,1)
glBegin(GL_QUADS)
glVertex3f(-1,1,-10)
glVertex3f(-1,-1,-10)
glVertex3f(1,-1,-10)
glVertex3f(1,1,-10)
glEnd()
SwapBuffers()

Notice how the square was only stretched on the X axis (horizontally). Now, what would the scale
command to stretch it on the Y axis look like??? If you said 1,5,1 then you are correct. Ok, so you are
now able to draw things, color them, and scale them. Lets learn how to move them. We use the
Translate command for this, here it is...
glLoadIdentity()
glTranslatef(1,1,-10)
glBegin(GL_QUADS)
glVertex3f(-1,1,0)
glVertex3f(-1,-1,0)
glVertex3f(1,-1,0)
glVertex3f(1,1,0)
glEnd()
SwapBuffers()

Ok, so what we just did is move the square away from us 10 units... Now, say we want to move it away
from us 10 units, and to the left 4 units...

glLoadIdentity()
glTranslatef(-4,1,-10)
glBegin(GL_QUADS)
glVertex3f(-1,1,0)
glVertex3f(-1,-1,0)
glVertex3f(1,-1,0)
glVertex3f(1,1,0)
glEnd()
SwapBuffers()

And that is how you move things. Let me explain some of the logic here first... You need to put the
Translate command BEFORE the objects you want translated... If you put them AFTER, then it will not
affect them. Also, this can be used similar to the color command... Any thing after it will be translated,
until you specify otherwise. The scale sommand is the same way... If you use the scale command,
everything after that will be scaled as well. This, of course is why we use the LoadIdentity command...
Because it resets all of our scale/translation/rotations. Speaking of rotations... Lets learn how to rotate
something in 3d...

glLoadIdentity()
glTranslatef(0,0,-10)
glRotatef(30,0,1,0)
glBegin(GL_QUADS)
glVertex3f(-1,1,0)
glVertex3f(-1,-1,0)
glVertex3f(1,-1,0)
glVertex3f(1,1,0)
glEnd()
SwapBuffers()

Ok, you are probably wondering about the 4 numbers in the rotate command... The first number is the
amount
you are rotating by (the degree). Then... The next three are the x,y,z... You usually just want to keep
them
at either a 1 or a 0... 0 will not affect that axis, and 1 will. So, that little piece of code rotates our
square 30 degrees on its Y axis... To help understand the nature of the rotation, you have to understand
the axis... Since this is for the Y, imagine a rod going through our square from top to bottom, and our
square is able to spin on this rod all the way around. If we use the X axis, then the rod would be going
from the left to the right, and our square could spin around that rod. And, the Z of course is like a rod
going straight through the middle of the square... From in front of your monitor, to behind your
monitor.
And the square can spin around that rod too.

Cool... Now you should know the basic's of 3d object manipulation. Let me fill you in on a very key
point
when using these commands... ORDER DOES MATTER. By that I mean... Rotate an object first, and
then you
translate it... The object will be tranlated by the axis AFTER the rotation... So it will not be in the same
position as if you simply translated it. Rotating ALSO changes all of the axis coordinates as well. Keep
that
in mind. This is a very common problem, you just have to imagine what is happening, in order, to
understand
it.

The next thing you will need to know is how to integrate BASIC programming logic into your 3d
routines. This
is what will allow you to dynamically control your objects, as I am sure you are sick of making all of
these
still shots by now... But first we have to learn a simple, yet long command. Its kindof like the CLS
command in Qbasic... And if you are not familiar with that... It just clears the screen. If you are making
a 3d program that uses animating or basically any changes
being done on a frame-by-frame basis, then you will need to clear the screen, or else you will be
drawing your objects on top of the
previously drawn objects... And then the next frame you will be drawing the objects on top of the
previously drawn objects that were
drawn on the ones before that... Ok, I'll stop that now, but I just wanted you to get the point... You will
most likely have to clear the
screen
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)

And thats it, that will clear your screen. Basically you will want to use that before you draw each
frame. BUT, don't use it in between objects, or it will erase the previous object... You will only need
that command once every frame. So, with that said, lets animate something. We will start with a basic
spinning square. For this, you will need to create a variable that will hold the angle of the rotation, and
then you will need to increase that angle a little each frame. For that, I use the for/next commands
(which you should know from any basic programming). And since this is a very fast routine, I used the
sleep() command to slow it down... Here it is:
Dim Angle#

do
for Angle#=1 to 360
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glRotatef(Angle#,0,0,1)
glTranslatef(0,0,-10)
glBegin(GL_QUADS)
glVertex3f(-1,1,0)
glVertex3f(-1,-1,0)
glVertex3f(1,-1,0)
glVertex3f(1,1,0)
glEnd()
SwapBuffers()
sleep (10)
next
loop

Ok, but there is no interactivity... So, lets add some basic key presses to that code and make this a little
more interesting!
Dim Angle#

do

glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)


glLoadIdentity()
glRotatef(Angle#,0,0,1)
glTranslatef(0,0,-10)
glBegin(GL_QUADS)
glVertex3f(-1,1,0)
glVertex3f(-1,-1,0)
glVertex3f(1,-1,0)
glVertex3f(1,1,0)
glEnd()
SwapBuffers()

if scankeydown(VK_LEFT) then
Angle#=Angle#+.25
endif

if scankeydown(VK_RIGHT) then
Angle#=Angle#-.25
endif

loop

Awesome, with that example, you can rotate the square using the left and right keys. Examine the code
and you will find that ScanKeyDown(VK_LEFT) and ScanKeyDown(VK_RIGHT) are our keypresses.
One of them adds to the angle of the square, and one of them subtracts from it. But... This is only
simple 2d rotation... What about the cool 3d rotations you say? Well, for that you need 2 angles... An X
angle and a Y angle. Take a look at this...
Dim XAngle#
Dim YAngle#

do

glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)


glLoadIdentity()
glTranslatef(0,0,-10)
glRotatef(XAngle#,1,0,0)
glRotatef(YAngle#,0,1,0)
glBegin(GL_QUADS)
glVertex3f(-1,1,0)
glVertex3f(-1,-1,0)
glVertex3f(1,-1,0)
glVertex3f(1,1,0)
glEnd()
SwapBuffers()

if scankeydown(VK_LEFT) then
YAngle#=YAngle#+.25
endif

if scankeydown(VK_RIGHT) then
YAngle#=YAngle#-.25
endif

if scankeydown(VK_UP) then
XAngle#=XAngle#+.25
endif

if scankeydown(VK_DOWN) then
XAngle#=XAngle#-.25
endif

loop

Now thats a pretty nice looking example if you ask me!

Você também pode gostar