001package pipeline; 002import scene.*; 003import framebuffer.*; 004 005/** 006 This renderer takes as its input a Scene data structure and 007 a FrameBuffer data structure. This renderer mutates the 008 FrameBuffer's current viewport so that it is filled in with 009 the rendered image of the scene represented by the Scene object. 010 011 This implements our third rendering pipeline. It adds a fourth 012 stage, clipping, between the projection and rasterizer stages. 013 The clipping stage clips off the parts of a line segment that 014 extend out of the view rectangle (within the view plane). 015*/ 016public class Pipeline 017{ 018 public static boolean debug = false; 019 public static boolean debug_visible = false; 020 021 /** 022 Mutate the FrameBuffer's current viewport so that it holds 023 the rendered image of the Scene object. 024 025 @param scene Scene object to render 026 @param fb FrameBuffer to hold rendered image of the scene 027 */ 028 public static void render(Scene scene, FrameBuffer fb) 029 { 030 if ( debug || debug_visible ) 031 render_debug(scene, fb); 032 else 033 render_(scene, fb); 034 } 035 036 037 /** 038 Renderer without any debugging information. 039 040 @param scene Scene object to render 041 @param fb FrameBuffer to hold rendered image of the scene 042 */ 043 private static void render_(Scene scene, FrameBuffer fb) 044 { 045 // For every Model in the Scene, render 046 // every LineSgement in the Model. 047 for (Model model : scene.modelList) 048 { 049 for (LineSegment ls : model.lineSegmentList) 050 { 051 // make a shallow copy of the line segment 052 LineSegment ls2 = new LineSegment(ls); 053 054 // 1. apply the projection transformation 055 Project.project(ls2, scene.camera); 056 057 // 2. clip the line segment to the standard view rectangle 058 if ( Clip.clip(ls2) ) 059 { 060 // 3. apply the viewport transformation 061 Viewport.viewport(ls2, fb); 062 063 // 4. rasterize the line segment into pixels 064 Rasterize.rasterize(ls2, fb); 065 } 066 } 067 } 068 } 069 070 071 072 /** 073 Render with quite a bit of debugging information. 074 075 @param scene Scene object to render 076 @param fb FrameBuffer to hold rendered image of the scene 077 */ 078 private static void render_debug(Scene scene, FrameBuffer fb) 079 { 080 System.out.println("=== Render Scene ==================================="); 081 082 // For every Model in the Scene, render 083 // every LineSgement in the Model. 084 for (Model model : scene.modelList) 085 { 086 System.out.println("=== Render Model ==================================="); 087 088 for (LineSegment ls : model.lineSegmentList) 089 { 090 StringBuilder result = new StringBuilder(); 091 092 // make a shallow copy of the line segment 093 LineSegment ls2 = new LineSegment(ls); 094 095 // log interesting information to standard output 096 logLineSegment("0. Input", ls2, result); 097 098 // 1. apply the projection transformation 099 Project.project(ls2, scene.camera); 100 101 // log interesting information to standard output 102 logLineSegment("1. Projected", ls2, result); 103 104 // 2. clip the line segment to the standard view rectangle 105 if ( Clip.clip(ls2) ) 106 { 107 // log interesting information to standard output 108 logLineSegment("2. Clipped", ls2, result); 109 110 // 3. apply the viewport transformation 111 Viewport.viewport(ls2, fb); 112 113 // log interesting information to standard output 114 logLineSegment("3. Viewport", ls2, result); 115 116 // 4. rasterize the line segment into pixels 117 Rasterize.rasterize(ls2, fb); 118 119 if ( debug_visible ) System.out.println( result ); 120 } 121 if ( ! debug_visible ) System.out.println(); 122 } 123 System.out.println("=== End Model ==================================="); 124 } 125 System.out.println("=== End Scene ==================================="); 126 } 127 128 129 private static void logLineSegment(String stage, LineSegment ls, StringBuilder accumulator) 130 { 131 if ( debug_visible ) 132 accumulator.append( stage + " " + ls.toString() ); 133 else 134 System.out.print( stage + " " + ls.toString() ); 135 } 136}