001/* 002 003*/ 004 005package renderer.pipeline; 006import renderer.scene.*; 007import renderer.framebuffer.*; 008 009import java.util.List; 010import java.util.ArrayList; 011 012/** 013 This renderer takes as its input a {@link Scene} data structure 014 and a {@link FrameBuffer} data structure. This renderer mutates 015 the {@link FrameBuffer}'s current viewport so that it is filled 016 in with the rendered image of the scene represented by the 017 {@link Scene} object. 018<p> 019 This implements our fifth rendering pipeline. This pipeline can 020 process the colors stored in each {@link Vertex}. This renderer 021 has the same four pipeline stages but {@link Vertex} color is 022 interpolated by the {@link Clip} stage and {@link Vertex} color 023 is also interpolated to pixels by the {@link Rasterize} stage. 024*/ 025public class Pipeline 026{ 027 public static boolean doAntialiasing = false; 028 public static boolean debug = false; 029 030 /** 031 Mutate the {@link FrameBuffer}'s current viewport so that 032 it holds the rendered image of the {@link Scene} object. 033 034 @param scene {@link Scene} object to render 035 @param fb {@link FrameBuffer} to hold rendered image of the {@link Scene} 036 */ 037 public static void render(Scene scene, FrameBuffer fb) 038 { 039 if ( debug ) 040 render_debug(scene, fb); 041 else 042 render_(scene, fb); 043 } 044 045 046 /** 047 Renderer the {@link Scene} without any debugging information. 048 049 @param scene {@link Scene} object to render 050 @param fb {@link FrameBuffer} to hold rendered image of the {@link Scene} 051 */ 052 private static void render_(Scene scene, FrameBuffer fb) 053 { 054 // Render every Model in the Scene. 055 for (Model model : scene.modelList) 056 { 057 if ( model.visible ) 058 { 059 // 0. Make a deep copy of the model. 060 Model model2 = new Model(model); 061 062 // 1. Apply the projection transformation. 063 Projection.project(model2.vertexList, scene.camera); 064 065 // 2. Clip each line segment to the standard view rectangle. 066 List<LineSegment> lineSegmentList2 = new ArrayList<>(); 067 for (LineSegment ls : model2.lineSegmentList) 068 { 069 if ( Clip.clip(ls) ) 070 { 071 // Keep the line segments that are visible. 072 lineSegmentList2.add(ls); 073 } 074 } 075 model2.lineSegmentList = lineSegmentList2; 076 077 // 3. Apply viewport transformation to each visible line segment. 078 // (Alternatively, we could apply viewport transformation to every vertex?) 079 boolean[] transformed = new boolean[model2.vertexList.size()]; 080 for (LineSegment ls : model2.lineSegmentList) 081 { 082 Viewport.viewport(ls, transformed, fb); 083 } 084 085 // 4. Rasterize each visible line segment into pixels. 086 for (LineSegment ls : model2.lineSegmentList) 087 { 088 if ( doAntialiasing ) 089 { 090 RasterizeAntialias.rasterize(ls, fb); 091 } 092 else 093 { 094 Rasterize.rasterize(ls, fb); 095 } 096 } 097 } 098 } 099 } 100 101 102 103 /** 104 Render the {@link Scene} with quite a bit of debugging information. 105 106 @param scene {@link Scene} object to render 107 @param fb {@link FrameBuffer} to hold rendered image of the {@link Scene} 108 */ 109 private static void render_debug(Scene scene, FrameBuffer fb) 110 { 111 System.out.println("=== Render Scene ==================================="); 112 113 // Render every Model in the Scene. 114 for (Model model : scene.modelList) 115 { 116 System.out.println("=== Render Model ==================================="); 117 118 if ( model.visible ) 119 { 120 // 0. Make a deep copy of the model. 121 Model model2 = new Model(model); 122 123 // log interesting information to standard output 124 logVertexList("0. Input ", model2.vertexList); 125 126 // 1. Apply the projection transformation. 127 Projection.project(model2.vertexList, scene.camera); 128 129 // log interesting information to standard output 130 logVertexList("1. Projected", model2.vertexList); 131 132 // 2. Clip each line segment to the standard view rectangle. 133 List<LineSegment> lineSegmentList2 = new ArrayList<>(); 134 for (LineSegment ls : model2.lineSegmentList) 135 { 136 // log interesting information to standard output 137 logLineSegment("2. Clipping", ls); 138 139 if ( Clip.clip(ls) ) 140 { 141 // log interesting information to standard output 142 logLineSegment("2. Clipped (accept)", ls); 143 144 // Keep the line segments that are visible. 145 lineSegmentList2.add(ls); 146 } 147 else 148 { 149 // log interesting information to standard output 150 logLineSegment("2. Clipped (reject)", ls); 151 } 152 } 153 model2.lineSegmentList = lineSegmentList2; 154 155 // log interesting information to standard output 156 logVertexList("2. Clipped ", model2.vertexList); 157 158 // 3. Apply viewport transformation to each visible line segment. 159 boolean[] transformed = new boolean[model2.vertexList.size()]; 160 for (LineSegment ls : model2.lineSegmentList) 161 { 162 Viewport.viewport(ls, transformed, fb); 163 164 // log interesting information to standard output 165 logLineSegment("3. Viewport ", ls); 166 } 167 168 // 4. Rasterize each visible line segment into pixels. 169 for (LineSegment ls : model2.lineSegmentList) 170 { 171 // log interesting information to standard output 172 logLineSegment("4. Rasterize", ls); 173 174 if ( doAntialiasing ) 175 { 176 RasterizeAntialias.rasterize(ls, fb); 177 } 178 else 179 { 180 Rasterize.rasterize(ls, fb); 181 } 182 } 183 System.out.println(); 184 } 185 else 186 { 187 System.out.println(" Hidden model."); 188 } 189 System.out.println("=== End Model ==================================="); 190 } 191 System.out.println("=== End Scene ==================================="); 192 } 193 194 195 /** 196 This method prints a {@link String} representation of the given vertex list. 197 198 @param stage name for the pipeline stage 199 @param vertexList vertex list whose string representation is to be printed 200 */ 201 private static void logVertexList(String stage, List<Vertex> vertexList) 202 { 203 int i = 0; 204 for (Vertex v : vertexList) 205 { 206 System.out.printf( stage + ": index = %3d, " + v.toString(), i ); 207 i++; 208 } 209 } 210 211 212 /** 213 This method prints a {@link String} representation of the given {@link LineSegment}. 214 215 @param stage name for the pipeline stage 216 @param ls {@link LineSegment} whose string representation is to be printed 217 */ 218 private static void logLineSegment(String stage, LineSegment ls) 219 { 220 System.out.print( stage + ": " + ls.toString() ); 221 int index0 = ls.index[0]; 222 int index1 = ls.index[1]; 223 Vertex v0 = ls.model.vertexList.get(index0); 224 Vertex v1 = ls.model.vertexList.get(index1); 225 System.out.printf(" index = %3d, " + v0.toString(), index0); 226 System.out.printf(" " + v0.toStringColor()); 227 System.out.printf(" index = %3d, " + v1.toString(), index1); 228 System.out.printf(" " + v1.toStringColor(), index1); 229 } 230}