Monday, March 21, 2011

Why The 12 On The Alabama Helmet?

Learning to draw from code

Very often, the game graphics can 'be made up of simple geometric shapes, think of Pong, Breakout and Tetris. They are all games where the graphics are simple geometric shapes such as circles, rectangles and squares.

These graphics are made by the program by means of specific functions, that much are often the easy conversion to computer language of ones formulette analytic geometry that we were taught in school.

As in reality, 'we have to draw some suitable surface.
In the previous tutorial "move" very quickly, I have introduced a type of surface suitable and appropriate to our cause, the SDL_Surface. Specifically, an area within the program of a game and 'a memory (ram or video) as large as needed, which would contain information that is displayed on the screen as pixels, size and height. A pixel

and 'a box on the screen, including the three primary colors, Red, Green and Blue (RGB), which together with other composes the image on the screen.
More 'specifically, and' a data structure containing the color values \u200b\u200bof blocks of color that we want to use in shades desired. You can have pixel from 8 to 32 bits, in the latter case are divided into 8 bits per primary color. The first 8 are reserved for transparency image, these bits are often ignored.

surface and 'a buffer (one-dimensional array) containing various information such as already' mentioned, the more 'important than the pixels are the size, height and pitch.


The blue area and 'our game window, the orange zone and' the remaining area of \u200b\u200bthe screen.
The video driver in use on the system creates a buffer that it uses for handling graphics on the screen as large as the width of the chosen resolution system, and this buffer 'said Pitch (Italian Range).
If the resolution of the system and 'while the 800x600 game window and' 320x200, our area will be 'a wide buffer [320] and will have' a position that will pitch in 'great [800].

These two buffer although the basic one-dimensional arrays can be understood as tables consisting of rows and columns.
For example, if we were to draw a pixel at coordinates (10,20), we'll get to know the length of the screen in the first place. Multiplying the length of the screen to the number of lines, we will know at what point in pitch the line that begins we want (scroll down the Y axis with 320 * 20), now we're on the line wanted us just add the value of X coordinate for the number of bits per pixel (BPP, scroll through the X-axis of a number the correct byte) to move the desired column.

You can 'summarize the theoretical work in a practical function: void
  
drawPixel ( int x, int y, int color) {

uint32 bpp, ofs;

bpp = screen-> format-> BytesPerPixel;
ofs = screen-> pitch * y + x * bpp;

SDL_LockSurface (screen);
memcpy (screen-> pixels + Ofs, & color, bpp);
SDL_UnlockSurface (screen);}

The following function takes three parameters, two coordinates and a color.
variables "bpp" and "ofs" are, respectively, and BitPerPixel Offset , we refer to internal structures to the SDL library accessible from our surface "screen" to access the pixel format in use on the system and the famous pitch .
Before drawing our pixels, and 'good to know if we have exclusive access to the storage area, as can' be managed by third parties or from the driver. We use the function SDL_LockSurface () to block access to the portion memory and SDL_UnlockSurface () to restore access.
The color value is given in hexadecimal, so the function can 'be called in a similar manner:
  drawPixel (10, 10, 0xFF0000);  
Now we know how to draw a pixel on the screen, we can use this feature with the help of another to draw a line for example, the algorithm presented here is' said Bresenham's algorithm or algorithm of the middle point. "
two dates allows us to draw a stylized line coordinates in pixels on our surface, and that 'the algorithm' simple and used for this work. Does not involve extreme mathematical knowledge to understand operation, although a little 'notions of analytic geometry can not hurt.
    void drawLine (int   x1,   int y1, int   x2, y2   int, int   color) {

int slope;
int dx, dy , Ince, incNE, d, x, y;

/ / invert the line if x1> x2
if (x1> x2) {

drawLine (x2, y2, x1, y1, color) ;
return; / / We leave


} dx = x2 - x1, dy =
y2 - y1;

/ / Fixed the increase in line y-increment lines for negative slope
if (dy \u0026lt;0) {

slope = -1;
dy =-dy;

} else {

slope = 1;}

/ / Constants Bresenham
ince = 2 * dy;
incNE = 2 * dy - 2 * dx;
d = 2 * dy - dx;
y = y1;
/ / Drawing
for (x = x1; x <= x2; x++)
drawPixel {(x, y, color);
if (d \u0026lt;= 0 )
{d + = ince;}


else {d + =
incNE;
y + = slope;

}}}

To understand This function must have a few things clear, we start from the basic concept, in analytic geometry, and the line 'represented by the equation y = mx + B , where m and' the angular coefficient is the ratio of the length of a straight line on the X axis and its height on the Y axis at a given point, or DeltaX and deltaY .
This means that we can know all points y of a real line in a plane.
must take account of a thing, a real line can 'have non-integer values \u200b\u200b(float) while the screen of a PC can' only points represent the whole picture, that 'in our favor in terms of speed'! The line can
real 'through the middle' more or less than one pixel by dividing it into two, that 'would not be possible on a PC.
The picture we see the real hypothetical line through a grid of possible pixel and its equivalent on a PC, are also represented and deltaY DeltaX axis for clarity.
The key word of our discourse and ' grid, such images are called computer raster or grid-based.
How can 'see in the image, for a number of columns in the grid, the royal line through the pixels less then the top ones.
The green points are the half points, taking into account the position of the line with respect to each of them, if more 'right to draw' in pixels to their right, same thing for the left, above or below.

First we need to know what it's worth "m" in the ordination, we would have the value of m and DeltaX deltaY, can be known respectively as the difference with the X coordinate greater than, the same goes for the Y.
  dx = x2 - x1; 
dy = y2 - y1;
Their relationship as already 'told us the first value m, then the formula becomes hours y = (dy / dx) * x + B . You can 'move the member right to the left to simplify, dx = dy * y * B * x + dx and finally bring it all on one side only to have 0 = dx-dy * x * y * dx + B .
This 'is not enough, since every point of the middle and' between a pixel and the other, you need to have internal values \u200b\u200bfor each of them, multiplied by 2 to both sides to address the matter, F (x, y) = 2 * dy * dx * x -2 * y +2 * B * dx. Take the example of
mathematical function just obtained and passiamogli as arguments the current values \u200b\u200bof X and Y in the plan more 'for further extension, the increase and' intended as the next location of our current pixel in the plan.
To increase the vertical or Y will 'to be considered 1 / 2, we take account of Y given that we are working on the equation of the line.
F (x +1, y + 1 / 2) = 2DY (x +1)-2DX (y +1 / 2) +2 * B * dx.

Here we can easily rewrite the function by separating the various terms and topics. Multiply the
2 * dy as a single element for each element of the brackets and so 'way for the second period, simple math concepts.
You will have 'yet another rewriting of the function , F (x +1, y + 1 / 2) = (2DY * x) +2 * y-dy-2DX +2 * B * dx dx .

still not enough, we can clean up a bit 'of things this function until you have only F (x +1, y + 1 / 2) = (2DY * x) -2DX +2 * dy-dx y +2 * B * dx.

What we will remain 'our decision function d = 2DY- right, we will be back' useful to know where in the middle of the slope of the line and 'more' close and possibly increase or decrease the coordinates X and Y in our grid to draw the pixel in the desired position.

To increase or decrease the mathematical function we have many before, if the right (east) you can 'make the difference between the next point and the current ince = F (x +1, y) - F (x, y), while an increase in vertical always right simply by adding a well coordinated to Y (north East) incNE = F (x +1, y +1) - F (x, y) .
functions easier to get start something like this:
  ince = 2 * dy; 
incNE = 2 * dy - 2 * dx;
d = 2 * dy - dx;
These formulas in the function, if we look have utility 'in the loop, this cycle will flow' each X coordinate of the line and trace 'one pixel at a current position X and Y properly.
    for (x = x1; x <=x2; x++)
{
drawPixel (x, y, color);
if (d <=0) d+=incE; else
{
d + = incNE;
y + = slope;
}
}
L 'algorithm pretends that the final coordinate is greater than the initial one, therefore if it is not calls itself by sending specially arguments reversed.
   / / Reverse lines WHERE x1> x2  
if (x1> x2 )

{drawLine (x2, y2, x1, y1);
return;}

takes into account a special variable instead, the slope of line in drawing:
   / / Fixed the increase of y-increment for line in lines if    negative slope (dy {< style="font-weight: bold;"> 
slope = -1;
dy = -dy;}

else {

slope = 1;}

Now we know how to draw a line and a pixel, we can also make circles:
  
void drawCircle ( int xc, yc int, int r, int c)
{
int x = r;
int y = 0;
int d = 0;

for (;;)
{
drawPixel (xc + x, yc + y, c);
drawPixel (xc + y, yc + x, c);

if (x! = 0) {

drawPixel (xc - x, yc + y, c);
drawPixel (xc + y, yc - x, c);}


if (y! = 0) {

drawPixel (xc + x, yc - y, c);
drawPixel (xc - y, yc + x, c);}


if (x! = 0 & & y! = 0) {

drawPixel (xc - x, yc - y, c);
drawPixel (xc - y, yc - x, c);
}

if (x <= y) break ;

d + = 2 * y + 1;
y + +;

if (d> x)
{
d + = 1 - 2 * x;
x -;}

}}

This one always Bresenham algorithm, has many similarities with that of the line, the concept of work and 'almost' similar . This function draws
starting the eighth circle of 45 degrees, changing the arguments you will also have the remaining 7 / 8 remaining until full circle.

We can leave aside the mathematical explanations, you can 'understand the function works very well by analyzing just one part of it:
   void  drawCircle (  int xc, yc   int, int   r,   int c) {

int x = r;
int y = 0;
int d = 0;

for (;;)

drawPixel {(xc + x, yc + y, c);

if (x <= y) break ;

d + = 2 * y + 1;
y + +;

if (d> x)
{
d + = 1 - 2 * x;
x -;

}}}

One could go on implementing features for the most 'from these three different forms, such as triangles, ellipses , rectangles and so on.
There are also a multitude of implementations of these algorithms themselves more 'or less efficient, and my advice' to use a special library as a standard for this work and also for save time.
most libraries 'use of these works are SDL Gfx or more' lean and less known SDL Draw for the latter should act in a hand to install it properly.

0 comments:

Post a Comment