04 Graphics (2D)
To create the final screen image which represents each frame of your application GLBasic uses three separate image buffers (or 'surfaces'). One is used to display the final image to the monitor, one is used to draw your GLBasic graphical objects (Sprites, Polygons etc.) and the last one is used to store the 'background' for your final image.
Let's take a look at these:
1. Primary Surface
This is what you see on the screen.
2. Back Buffer
This is where all graphical commands in GLBasic write to. It's invisible, that is it's not transferred to the monitor until you call the command SHOWSCREEN. This command takes current the back buffer and transfers it to the primary surface (the monitor).
Why not have GLBasic draw directly to the monitor (Primary Surface) rather than to a Back Buffer? If you did this you would see GLBasic processing its graphical commands individually 'on-screen' rather than all-at-once, and this would result in screen flicker.
Remember: If you don't see anything you might have forgotten SHOWSCREEN command.
3. Offscreen Surface
This screen can be accessed with 3 commands only, 'LOADBMP', 'BLACKSCREEN' and 'USEASBMP'.
LOADBMP loads a .BMP file to the offscreen surface to be used as the background for the Back Buffer.
BLACKSCREEN, creates a 'black' surface to the offscreen surface to be used as the background for the Back Buffer.
USEASBMP, uses the current Back Buffer to create a background. Whatever you have drawn to the Back Buffer up until this point will be used as the background.
When SHOWSCREEN is called, the Back Buffer and Primary Surface are swapped. The now unusable Back Buffer will be replaced (cleaned) with the Offscreen Surface which is black when no bitmap is loaded.
GLBasic uses hidden surfaces (Double Buffering) for graphical display. If you code something in GLBasic you will see nothing before your program calls the 'SHOWSCREEN' command.
If you don't see any result from your program, the first thing to check is whether you have forgotten to add the 'SHOWSCREEN' command to it.
Think of Double Buffering as two sheets of paper, one on top of the other where you draw on the bottom sheet. Once you're finished drawing, you swap the sheets and in the process erase the new bottom sheet. This hides the actual drawing of the sheet from the user and in the process eliminates screen flicker.
A game mostly is structured like this:
// My game
// Load further graphics as sprites...
// load level, setup (lives=3, time=100...)
//Move and draw player
//Move and draw enemies
What is a sprite? A sprite is usually a small graphic object that moves around the screen. As an example, in the game Pacman, Pacman and the Pac Ghosts are sprites and the maze is the background.
These are Pacman's sprites...
If you know anything about computers you might know the truth - the PC doesn't have real sprites. Real 'sprites' in the days of the Amiga or Atari XL, were little separate pieces of video memory that you could place an image in, these images were 'hardware overlayed' onto the display memory without damaging the background image. The PC does not have sprite hardware overlay technology but the good news is that GLBasic can emulate sprite hardware.
Sprites have to be what is referred to as "cookie cut" - i.e. the area around the shape of the sprite must be transparent. Without cookie cutting the sprite there would be a solid black rectangle around it when it was displayed.
How does the program know which parts of the sprite are to be displayed transparently? There are many ways depending on the program you are using. GLBasic uses the following: Every pixel of an image loaded for a sprite that has the color value red:255, green:0 and blue:128 (Hex: FF 00 80) (a shade of Pink) is considered to be transparent.
All graphic files loaded are in the Windows-Bitmap format with 8 or 24 bit color depths, uncompressed. You cannot load 16-color graphics. You have to reload and save them as either 8-bit or 24-bit color images.
You can also use png files. They use either RGB(255,0,128) for transparency or the alpha channel if it exists.
Your first sprite:
// load sprite image from file "Bubble.bmp" and assign it to ID 0
LOADSPRITE "Bubble.bmp" ,0
// show sprite image with ID 0 at position x=300, y=150
DRAWSPRITE 0, 300, 150
As you can see with just 3 commands you produced a visible result. Short, sweet and simple, all the technical nitty gritty is hidden from the user by the simplicity of GLBasic. If you were to try to do this in C++ for example, the code would several pages long.
The command LOADSPRITE command is fairly obvious. It loads a BMP file, which can be used as a sprite and assigns an ID (in this case 0) to it. Every sprite, needs a unique ID number, though the choice of ID is up to you. In the rest of the program this sprite will be referred to by its ID ( '0' in this case). See also: the command GENSPRITE().
Take a look at the .BMP file. You'll see there's a pink color around the image. This part of the image will be the its transparent pixels. To demonstrate this, we'd better load an image for the background by adding...
...to the beginning of the program.
The command DRAWSPRITE needs 3 parameters. The first is the ID of the sprite to be shown. Parameters 2 and 3 are the screen position of the sprite (X,Y coordinates). ALPHAMODE lets you specify an alpha value. GLBasic supports Alpha Blending. Never heard of 'Alpha Blending'? No problem...
Alpha Blending is when 2 images (namely the background and the sprite) are 'blended' together. GLBasic has two 'blending modes' for doing this.
Additive Alpha Blending:
A value from 0.001 to 1.0 mixes the 2 colour values of each pixel by adding the red, green and blue values (a value over 255 (or FF in Hexadecimal) is considered to be 255). It sounds complicated, but all work is done by GLBasic. A value more than +1 for the Alpha Blending is for effects like fire, explosions and glass screens. If you want two images to get brighter when they are displayed over each other then use this 'blending mode'.
Interpolated Alpha Blending:
a value from -0.001 to -1.0 melts the 2 objects by adding both values and dividing them by 2. You can use this for shadows and other nice effects.
A tip: Have a play with the different Alpha Blending modes, try some different shapes and colors, add a few different backgrounds. Even black and white background can create a great look with colored sprites and Alpha Blending. Play!
Some Special Sprite Commands:
Zooming a sprite to any size can be done with:
ZOOMSPRITE id, xstart, ystart, x%, y%
STRETCHSPRITE id, xstart, ystart, width, height
Rotating a sprite around its center can be done with the following:
ROTOSPRITE id, x, y, angle
'X' and 'Y' values are the positions of the sprite when not rotated. So the following code:
ROTOSPRITE 1,50,70, 0
is identically to:
ROTOZOOMSPRITE id, x, y, angle, size
'Size' is a value that specifies the scaling of the sprite. '0.5' is half the size. '2.0' is double scaling factor.
Special General Graphic Functions:
GLBasic has a command to fade from the current back buffer into a .BMP file. Fading to a black bitmap causes the screen to fade-out. This is an excellent effect for screen transitions.
GLBasic can play videos in all known installed video codecs. (AVI, MP2...) Simply use :
Vector Graphic Commands:
Sometimes you may want to draw something using basic shapes like lines and rectangles rather than using a sprite. GLBasic from version 5.10522 onwards features commands for the drawing of filled rectangles, lines and single pixels.
See the command reference for:
SETPIXEL - DRAWLINE - DRAWRECT