www.xbdev.net
xbdev - software development
Sunday May 11, 2025
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.


void setpixel(unsigned intpBitsint wint hint pitch,
                    
int xint yDWORD dwColour)
{
      
pBits[y*(pitch>>2)]=dwColour;
}
// end of setpixel
 
void cls(unsigned intpBitsint wint hint pitch)
{
      for(
int y=0y<hy++)
      {
            for(
int x=0x<wx++)
            {
                  
pBits[y*(pitch>>2)] = 0xff444444;
            }
      }
}
// end of cls(..)
 
 
void SWAP(intaintb)
{
      
int temp a;
      
b;
      
temp;
}
 
void SWAP(floatafloatb)
{
      
float temp a;
      
b;
      
temp;
}
 
void Draw_Solid_Triangle(unsigned intpBitsint wint hint pitch,
                        
int x0int y0,
                              
int x1int y1,
                              
int x2int y2DWORD dwColour)
{
      
// Sort our points into order of y
      // 0 top
      // 2 middle
      // 1 bottom
      
if( y1 y0 )
      {
            
SWAP(y1y0);
            
SWAP(x1x0);
      }
      if( 
y2 y0 )
      {
            
SWAP(y2y0);
            
SWAP(x2x0);
      }
      if( 
y1 y2 )
      {
            
SWAP(y2y1);
            
SWAP(x2x1);
      }
 
      
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=y0y<y2y++)
      {
 
            for(
int x=xl_edgex<xr_edgex++)
            {
                  
setpixel(pBitswhpitch,
                             
xydwColour);
            }
//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=y2y<y1y++)
      {
 
            for(
int x=xl_edgex<xr_edgex++)
            {
                  
setpixel(pBitswhpitch,
                             
xydwColour);
            }
//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"y0y2y1);
      
SetWindowText(hWndbuf);
}
 
 
void Render(unsigned intpBitsint wint hint pitch)
{
      
// Clear our screen to black
      
cls(pBitswhpitch);
 
      
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.h) && (mousePos.x>0) && (mousePos.x<w) && (mousePos.y>0) )
      {
            
char buf[200];
            
sprintf(buf"x: %d, y: %d"mousePos.xmousePos.y);
            
//SetWindowText(hWnd, buf);
 
            
x1 mousePos.x;
            
y1 mousePos.y;
      }
 
      
Draw_Solid_Triangle(pBitswhpitch,
                        
x0y0,
                              
x1y1,
                              
x2y20xff00ff00);
 
}
// end of Render(..)




 
Advert (Support Website)

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