www.xbdev.net xbdev - software development
Saturday December 15, 2018
home | about | contact | Donations

     
 

Slice of Java.

Its simple and its powerful...

 

 

 

Almost all 3D is made up of lots of Triangles

by Ben Kenwright


When you watch Toy-Story or the latest Shrek 2 movie, you might not know, that all the 3D models and 3D worlds are made up of millions and millions of triangles.  Of course the triangles are so small that the surfaces look smooth, and they wrap textures to the surfaces to get an even more realistic effect.  But its there basically triangles :)

 

 

 

 


I put together a nice diagramatic show above as you can see, showing a simple dragon model and how its just lots and lots of triangles :)  Believe me, it can take forever to model a really cool character, you need lots of patience and lots of coffee and no matter what, you shouldn't get angry with your computer if it doesn't do it exactly as you wanted..hehe

 

*Slurps his coffee and thinks*  Now let me see....the secret to rendering triangles is interpolation...similar to how we draw a line...but we draw two lines and fill in the gap between them.

 

Very very important and useful to know how to render triangles - once you can render solid triangles and understand the principle of linear interpolation, you can of course expand it to gourand shaded triangles and phong shaded triangles...then onto textured triangles :)

 

The secret to how it works, is to break the triangle up...a top half and a bottom half.

 

 

 

 

We have 3 points..(p0, p1, and p2).  The first thing we want to do, is sort them into order of height, so that p0 is at the top and p2 is at the bottom...we just compare the y values of each point and swap them if they are out of order.  We set our starting point at p0, and move down the triangles edges, drawing a horizontal line from left to write as we go down.

 

 

 

So we have two loops for our triangle...we have a loop which does y0 to y1....then we have a second loop for y1 to y2 which does the bottom of the triangle.  In the loop we draw a horizontal line from the left to the right.  This left and right value is calculated by interpolating a x value for left and an x value for the right.  The gradient for the left and right is called dx_left and dx_right...and we calculate the values for x_left and x_right each time round the y loops.

 

I've put together an applet tutorial for it, so you can click the left and right mouse button while over the applet to affect two of the mouse points and really test out the solid triangle drawing code.

 

 

Applet Source Code (Download)

/*********************************************************************************************/

/*                                                                                           */

/*  Java 3D Engine Basics Tutorials - Tut Solid Triangle                                     */

/*  Auth: bkenwright@xbdev.net                                                               */

/*  URL:  www.xbdev.net                                                                      */

/*                                                                                           */

/*  Drawing our own solid triangle using linear interpolation                                */

/*                                                                                           */

/*********************************************************************************************/

 

import java.awt.image.*;

import java.awt.*;

import java.applet.*;

 

public class solidtriangle extends Applet

{

  public void paint(Graphics g)

  {      SolidTriangle(g,  mouse_x_right, mouse_y_right,            

                           mouse_x_left,  mouse_y_left,

                           90, 230, Color.green);                       

  }// End of paint(..)

 

  public void setPixel(Graphics g, int x, int y, Color color )

  {           g.setColor( color );

              g.fillRect( x, y, 1, 1 );

  }// End of setPixel(..)

 

  int mouse_x_right= 10;

  int mouse_y_right= 10;

 

  int mouse_x_left= 100;

  int mouse_y_left= 100;

 

  public boolean mouseDown(Event evt, int x, int y)

  {

      if(evt.id == Event.MOUSE_DOWN)

      {

                  // Right mouse button

                  if( evt.metaDown() == true )

                  {

                              System.out.println( "Right MouseDown" );

                              mouse_x_right = x;

                              mouse_y_right = y;

                  }

                  else // right mouse button

                  {

                              System.out.println( "Left MouseDown" );

                              mouse_x_left = x;

                              mouse_y_left = y;

                  }

      }// End if

   

             repaint();

             return true;

   }// End of mouseDown(..)

     

 

   void SolidTriangle( Graphics g,

                       float x0, float y0,

                       float x1, float y1,

                       float x2, float y2,

                       Color colour )

  {

   //Sort into order y0 -> y1 -> y2

   float temp;

   if( y1 < y0 )

   {

      temp=y1; y1=y0; y0=temp;

      temp=x1; x1=x0; x0=temp;

   }

   if( y2 < y0 )

   {

      temp=y2; y2=y0; y0=temp;

      temp=x2; x2=x0; x0=temp;

   }

   if( y2 < y1 )

   {

      temp=y2; y2=y1; y1=temp;

      temp=x2; x2=x1; x1=temp;

   }

 

   // Draw Top Half Triangle

   float x_left  = x0;

       float x_right = x0;

        

   float dx_left  = x1 - x0;   // to the middle then we change it

   float dx_right = x2 - x0;   // all the way to the bottom :)

 

        

   dx_left  = (x1 - x0) / (y1 - y0);

   dx_right = (x2 - x0) / (y2 - y0);

        

   int s = 0;

   float t; // temp variable

   if( dx_left > dx_right )

   {

      t     = dx_left;

      dx_left  = dx_right;

      dx_right = t;

      s=1;

   }//End if

        

   for(float y=y0; y<y1; y++)

   {

      for(float x=x_left; x<x_right; x++)

      {

         setPixel(g, (int)x, (int)y, colour );

      }// End inner for loop

      x_left  += dx_left;

      x_right += dx_right;

   }// End outer for loop

     

 

   // Now for the bottom of the triangle

   // Whats the s==0 for?  Well we made the assumption that dx_left

   // goes all the way to p2 (the bottom) if now we set s to 1, and then

   // dx_right goes all the way to the bottom.

   if( s == 0 )

   {

      dx_left = (x2 - x1) / (y2 - y1);

   }

   else

   {

      dx_right = (x2 - x1) / (y2 - y1);

   }

        

        

   for(float y=y1; y<y2; y++)

   {

      for(float x=x_left; x<x_right; x++)

      {

         setPixel(g, (int)x, (int)y, colour);

      }

      x_left  += dx_left;

      x_right += dx_right;

   }// End outer for loop

  

 }// End SolidTriangle(..)

     

}// End of our Applet

 

 

 

 

 

WARNING!
The triangle drawing code doesn't take into account if your triangle is partly off the screen....or if it is totally of the screen (e.g. all 3 points ).  So you could check for things like this at the start of the code.  And posibly modify the inner loop that draws the horizontal line, so that it won't plot pixels that are not on screen either.

 

 

 

An Easier Method For Solid Triangles

Well of course there's a built in Java API which will allow you to draw solid triangles as well - and I'll show you that now.  But we'll expand on this triangle drawing routine later to incorporate cool things such as textures and gourand shading :) which the java api's don't give you.

 

Applet Source Code (Download)
 

 

import java.awt.image.*;

import java.awt.*;

import java.applet.*;

 

public class solidtriangle extends Applet

{

  public void paint(Graphics g)

  {      SolidTriangleAPI(g,  10,  10,            

                              150, 80,

                              90,  230, Color.green);                       

  }// End of paint(..)

 

  void SolidTriangleAPI( Graphics g,

                             float x0, float y0,

                             float x1, float y1,

                             float x2, float y2,

                             Color c )

      {

             Polygon     triangle = new Polygon();

             triangle.addPoint((int)x0, (int)y0);

             triangle.addPoint((int)x1, (int)y1);

             triangle.addPoint((int)x2, (int)y2);

             triangle.addPoint((int)x0, (int)y0);

 

             g.setColor( c );

             // Wireframe Mode

             // g.drawPolygon(triangle);

             // Solid Mode

             g.fillPolygon(triangle);

      }// End of drawTriangleFlatAPI(..)

     

}// End of our Applet

 

 

Notice you can modify the code with 'g.drawPolygon(triangle)' to render wireframe triangles.  This is very useful when you want to do fast rendering or want to debug in 3D.

 

 

 

 

 

 

 

 

 

 

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.