Click here if you are stuck in someone else's frames.

If this page looks like garbage then you need one of these browsers...

Microsoft Internet Explorer

Netscape Navigator

Please sign my programmer's page guestbook.

Please sign my guestbook

View my guestbook entries

Pixels, Lines and Circles

Okay, now that we know how the graphics system is like let's see how we can exploit this. First let's start with the simplest graphics element, a pixel. Well, looking at our equations before we figured out that a pixel can be mapped like so.

Pixel (X, Y)
Pixel Location = A000:0000 + (Y * 320) + X
    

Setting pixels

Well, how much harder can it be, with each pixel using a single byte, just load that byte with the color value (0-255). Alright enough the talk, let's see that in action.

  #include <dos.h>
  #include <conio.h>
  #include <stdlib.h>

  #define Mode13H  0x13
  #define TextMode 0x03

  char far *VideoMem = (char far *)0xA0000000L;

  void SetVideoMode(int Mode);
  void SetPixel(int x, int y, int color);

  /* This program plots random pixels on the VGA screen.
     Check out the SetPixel function below and see how
     easy it is to set a pixel in Mode13H
  */
  int main(void)
  {
      SetVideoMode(Mode13H);

      while(!kbhit())
          SetPixel(rand() % 320, rand() % 200, rand() % 256);

      SetVideoMode(TextMode);
      return 0;
  }

  void SetVideoMode(int Mode)
  {
      union REGS regs;

      regs.x.ax = Mode;
      int86(0x10, &regs, &regs);
  }

  /* A one line wonder.  The VideoMem pointer is treated
     as an array that is offset by the equation we derived
     earlier.  The byte is loaded with the color value to
     achieve setting a pixel.
  */
  void SetPixel(int x, int y, unsigned char color)
  {
      VideoMem[y * 320 + x] = color;
  }
    

Now that wasn't so hard. In fact we can easily set any pixel to any color this way. Now that we've learned how to set pixels, let's draw lines.


Drawing lines

Okay, now that we can plot a single pixel, we can draw a line. The hardest part to drawing lines is determining the slope and angle of the lines based on deltaX and deltaY of the two lines. Let's observe...

First we figure out which two pixel point we want to draw a line between. Let's choose (50,50) and (100,100). Why, why not? Then we must determine the slope of the tangent line, did anybody remember their geometry? Well, for those of you who forget (like I did till I landed in Calculus) here is the formula below.

              Y2 - Y1
  Slope (m) = -------
              X2 - X1
    

Looking at our two points (X1,Y1) and (X2,Y2) we surmise that the following is true.

  X1 = 50
  Y1 = 50

  X2 = 100
  Y2 = 100
    

Looking at the equations of the slope, we must also take into account that if the equation is undefined (denominator is 0) our line is a vertical line and if the equation is zero, the line is horizontal.

So okay, enough theory, let's code this sucker...

  void Line(int x1, int y1, int x2, int y2, unsigned char color)
  {
      float m;  /* Slope of tangent line */
      int i;
      int temp;

      /* X2 must be greater than X1 */
      if (x1 > x2) {
          temp = x1;
          x1 = x2;
          x2 = temp;
      }

      if (x2 == x1) {
          /* Undefined slope, draw a vertical line */

          for (i = y1; i <= y2; i++)
              SetPixel(x1, i, color);
      } else {
          /* Define our slope and draw our line */

          m = ((float)y2 - (float)y1) / ((float)x2 - (float)x1);
          for (i = x1; i <= x2; i++)
              SetPixel(i, m * (i - x1) + y1, color);
      }
  }
    

Simple, elegant, and straight to the point. With this function, we can draw any line that we wish. Okay, one more function, circle...


Drawing Circles

Now to draw a circle. One way to draw a circle is by use of the SINE and COSINE functions that fortunately are packed with the C language. Just include the 'math.h' header and make use of the sine and cosine functions to draw your circle.

The implementation of this function is not very difficult, especially if you know trig. If you don't know it, I won't bother trying to teach you any of that since we're here to learn programming, not trig. So anyway, here's the function...

  #include <math.h>

  void Circle(int x, int y, int Radius, unsigned char Color)
  {
      double pi;
      double i;
      double rad;
      pi = 4 * atan(1);  /* define PI */

      /* Cycle through the 360 degrees 
         For better circle, change the 'i++' to 'i+=.1' */

      for (i=0; i<360; i++) {
          /* Convert degrees to radians */
          rad = i * (pi / 180);
          SetPixel(Radius*sin(rad)+x, Radius*cos(rad)+y, Color);
      }
  }
    

Well these functions look simple enough and in fact they do work. However, there is one problem with all the line and circle functions that cannot be ignored. They all run extremely slow!!! This is because of the fact that they use floating point arithmetic and in a video game, you never use floating points unless there use is deemed absolutely necessary. In the case here, the use of floating points can be eliminated and the functions can be sped up dramatically by using integers instead...

Since I trust that you know so much about graphics, I will leave this part up to you...


Send your questions, comments, or ideas to: wilkeg@gamewood.net

This page hosted by GeoCities Get your own Free Home Page
Next |  Back