www.xbdev.net
xbdev - software development
Monday April 20, 2026
Home | Contact | Support | The Maths of 3D You can't have 3D without a little maths...
>>
     
 

The Maths of 3D

You can't have 3D without a little maths...

 

Rasterization : Solid Green Triangle

by bkenwright@xbdev.net



Well I say solid green in the title, but of course you can use any colour you want - and because we are only aiming to draw a solid triangle here - later on, when you add things like lighting and shading to your drawing/3D rasterization engine, the triangle will be multi-coloured....using Gourand shading for example :)


Green triangle rendered using rasterization.
Green triangle rendered using rasterization.


Part-1- of our code demonstrates the principle of how you would go about rendering a general triangle. Remember what I said 'General' Triangle. As you will most likely split up your rendering process into 3 parts eventually, so you can get the most speed. The 3 types of triangle, are a triangle with a flat bottom....and triangle with a flat top...and of course a general triangle...which can be any type of triangle.


I think the code is pretty simple to follow, but I will take the time to explain it in a bit - but be sure you understand how it works - as we will be modifying it to a fixed point 16-16 format later on so we can sqeeezzeee the most amount of speed from this simple triangle drawing algorithm.

DownloadSourceCode

Source Code


Below shows the key lines for the implementation example.


<?php
void setpixel(unsigned int* pBits, int w, int h, int pitch,
                    int x, int y, DWORD dwColour)
{
      pBits[x + y*(pitch>>2)]=dwColour;
}// end of setpixel
 
void cls(unsigned int* pBits, int w, int h, int pitch)
{
      for(int y=0; y<h; y++)
      {
            for(int x=0; x<w; x++)
            {
                  pBits[x + y*(pitch>>2)] = 0xff444444;
            }
      }
}// end of cls(..)
 
 
void SWAP(int& a, int& b)
{
      int temp = a;
      a = b;
      b = temp;
}
 
void SWAP(float& a, float& b)
{
      float temp = a;
      a = b;
      b = temp;
}
 
void Draw_Solid_Triangle(unsigned int* pBits, int w, int h, int pitch,
                        int x0, int y0,
                              int x1, int y1,
                              int x2, int y2, DWORD dwColour)
{
      // Sort our points into order of y
      // 0 top
      // 2 middle
      // 1 bottom
      if( y1 < y0 )
      {
            SWAP(y1, y0);
            SWAP(x1, x0);
      }
      if( y2 < y0 )
      {
            SWAP(y2, y0);
            SWAP(x2, x0);
      }
      if( y1 < y2 )
      {
            SWAP(y2, y1);
            SWAP(x2, x1);
      }
 
      float xl_edge = (float)x0;  // left edge
      float xr_edge = (float)x0;  // right edge
 
      float dxldy;
      float dxrdy;
 
      float dxdy1 = (float)(x2-x0)/(y2-y0);
      float dxdy2 = (float)(x1-x0)/(y1-y0);
 
      if( dxdy1 < dxdy2 )
      {
            dxldy = dxdy1;
            dxrdy = dxdy2;
      }
      else
      {
            dxldy = dxdy2;
            dxrdy = dxdy1;
      }
     
 
      // Top of the triangle
      for(int y=y0; y<y2; y++)
      {
 
            for(int x=xl_edge; x<xr_edge; x++)
            {
                  setpixel(pBits, w, h, pitch,
                             x, y, dwColour);
            }//end for loop x
 
            xl_edge = xl_edge + dxldy;
            xr_edge = xr_edge + dxrdy;
 
      }// end for loop y
 
 
      // Bottom half of the triangle
 
      if( dxdy1 < dxdy2 )
      {
            dxldy = (float)(x2-x1)/(y2-y1);
      }
      else
      {
            dxrdy = (float)(x2-x1)/(y2-y1);
      }
 
 
      for(int y=y2; y<y1; y++)
      {
 
            for(int x=xl_edge; x<xr_edge; x++)
            {
                  setpixel(pBits, w, h, pitch,
                             x, y, dwColour);
            }//end for loop x
 
            xl_edge = xl_edge + dxldy;
            xr_edge = xr_edge + dxrdy;
 
      }// end for loop y
     
 
      extern HWND hWnd;
      char buf[200];
      sprintf(buf, "y0: %d, y2: %d, y1:%d", y0, y2, y1);
      SetWindowText(hWnd, buf);
}
 
 
void Render(unsigned int* pBits, int w, int h, int pitch)
{
      // Clear our screen to black
      cls(pBits, w, h, pitch);
 
      int x0=100,  y0=100;
      static int x1=90;
      static int y1=100;
      int x2=260,  y2=350;
 
      extern HWND hWnd;
      POINT mousePos;
      GetCursorPos(&mousePos);
      ScreenToClient(hWnd, &mousePos);
 
      if( (mousePos.y < h) && (mousePos.x>0) && (mousePos.x<w) && (mousePos.y>0) )
      {
            char buf[200];
            sprintf(buf, "x: %d, y: %d", mousePos.x, mousePos.y);
            //SetWindowText(hWnd, buf);
 
            x1 = mousePos.x;
            y1 = mousePos.y;
      }
 
      Draw_Solid_Triangle(pBits, w, h, pitch,
                        x0, y0,
                              x1, y1,
                              x2, y2, 0xff00ff00);
 
}// end of Render(..)




 
Advert (Support Website)

 
 Visitor:
Copyright (c) 2002-2026 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.