001/*
002
003*/
004
005package renderer.pipeline;
006import  renderer.scene.*;
007import  renderer.framebuffer.*;
008
009/**
010    This renderer takes as its input a {@link Scene} data structure
011    and a {@link FrameBuffer} data structure. This renderer mutates
012    the FrameBuffer's current viewport so that it is filled in with
013    the rendered image of the scene represented by the Scene object.
014<p>
015    This implements our third rendering pipeline. It is essentially the
016    same as the previous renderer but it adds an optional antialiasing
017    rasterizing stage, {@link RasterizeAntialias}, that is an alternative
018    to the regular rasterizing stage, {@link Rasterize}. (So there are
019    still just four pipeline stages.)
020*/
021public class Pipeline
022{
023   public static boolean doAntialiasing = false;
024   public static boolean debug = false;
025   public static boolean debug_visible = false;
026
027   /**
028      Mutate the {@link FrameBuffer}'s current viewport so that
029      it holds the rendered image of the {@link Scene} object.
030
031      @param scene  Scene object to render
032      @param fb     FrameBuffer to hold rendered image of the Scene
033   */
034   public static void render(Scene scene, FrameBuffer fb)
035   {
036      if ( debug || debug_visible )
037         render_debug(scene, fb);
038      else
039         render_(scene, fb);
040   }
041
042
043   /**
044      Renderer the {@link Scene} without any debugging information.
045
046      @param scene  Scene object to render
047      @param fb     FrameBuffer to hold rendered image of the Scene
048   */
049   private static void render_(Scene scene, FrameBuffer fb)
050   {
051      // For every Model in the Scene, render
052      // every LineSgement in the Model.
053      for (Model model : scene.modelList)
054      {
055         if ( ! model.hidden )
056         for (LineSegment ls : model.lineSegmentList)
057         {
058            // Make a deep copy of the line segment.
059            LineSegment ls2 = new LineSegment(ls);
060
061            // 1. Apply the projection transformation.
062            Projection.project(ls2, scene.camera);
063
064            // 2. Clip the line segment to the standard view rectangle.
065            if ( Clip.clip(ls2) )
066            {
067               // 3. Apply the viewport transformation.
068               Viewport.viewport(ls2, fb);
069
070               // 4. Rasterize the line segment into pixels.
071               if ( doAntialiasing )
072               {
073                  RasterizeAntialias.rasterize(ls2, fb);
074                //RasterizeAntialiasSimple.rasterize(ls2, fb);
075               }
076               else
077               {
078                  Rasterize.rasterize(ls2, fb);
079               }
080            }
081         }
082      }
083   }
084
085
086
087   /**
088      Render the {@link Scene} with quite a bit of debugging information.
089
090      @param scene  Scene object to render
091      @param fb     FrameBuffer to hold rendered image of the scene
092   */
093   private static void render_debug(Scene scene, FrameBuffer fb)
094   {
095      System.out.println("=== Render Scene ===================================");
096
097      // For every Model in the Scene, render
098      // every LineSgement in the Model.
099      for (Model model : scene.modelList)
100      {
101         System.out.println("=== Render Model ===================================");
102
103         if ( ! model.hidden )
104         for (LineSegment ls : model.lineSegmentList)
105         {
106            StringBuilder result = new StringBuilder();
107
108            // Make a deep copy of the line segment.
109            LineSegment ls2 = new LineSegment(ls);
110
111            // log interesting information to standard output
112            logLineSegment("0. Input", ls2, result);
113
114            // 1. Apply the projection transformation.
115            Projection.project(ls2, scene.camera);
116
117            // log interesting information to standard output
118            logLineSegment("1. Projected", ls2, result);
119
120            // 2. Clip the line segment to the standard view rectangle.
121            if ( Clip.clip(ls2) )
122            {
123               // log interesting information to standard output
124               logLineSegment("2. Clipped", ls2, result);
125
126               // 3. Apply the viewport transformation.
127               Viewport.viewport(ls2, fb);
128
129               // log interesting information to standard output
130               logLineSegment("3. Viewport", ls2, result);
131
132               // 4. Rasterize the line segment into pixels.
133               if ( doAntialiasing )
134               {
135                  RasterizeAntialias.rasterize(ls2, fb);
136                //RasterizeAntialiasSimple.rasterize(ls2, fb);
137               }
138               else
139               {
140                  Rasterize.rasterize(ls2, fb);
141               }
142               if ( debug_visible ) System.out.println( result );
143            }
144            if ( ! debug_visible ) System.out.println();
145         }
146         System.out.println("=== End Model ===================================");
147      }
148      System.out.println("=== End Scene ===================================");
149   }
150
151
152   /**
153      This method either prints a String representation of the given
154      LineSegment or it accumulates the String representation in the
155      accumulator variable (for printing later).
156
157      @param stage  name for the pipeline stage
158      @param ls     LineSegment whose string representation is to be (eventually) printed
159      @param acc    accumulates the string representations for all the line segments in this stage
160   */
161   private static void logLineSegment(String stage, LineSegment ls, StringBuilder acc)
162   {
163      if ( debug_visible )
164         acc.append( stage + " " + ls.toString() );
165      else
166         System.out.print( stage + " " + ls.toString() );
167   }
168}