Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages
tcovbuf.h
00001 /* 00002 Copyright (C) 2002-2005 by Jorrit Tyberghein 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public 00015 License along with this library; if not, write to the Free 00016 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00017 */ 00018 00019 #ifndef __CS_CSGEOM_TCOVBUF_H__ 00020 #define __CS_CSGEOM_TCOVBUF_H__ 00021 00022 #include "csextern.h" 00023 00024 #include "csutil/scf_implementation.h" 00025 #include "iutil/dbghelp.h" 00026 #include "csutil/ref.h" 00027 00028 struct iGraphics2D; 00029 struct iGraphics3D; 00030 struct iBugPlug; 00031 00032 class csBox2; 00033 class csReversibleTransform; 00034 class csString; 00035 class csVector2; 00036 class csVector3; 00037 00038 00039 class csTiledCoverageBuffer; 00040 00041 00042 enum 00043 { 00044 SHIFT_TILECOL = 6, 00045 SHIFT_TILEROW = 5, 00046 00047 NUM_TILECOL = (1<<SHIFT_TILECOL), 00048 NUM_TILEROW = (1<<SHIFT_TILEROW), 00049 NUM_DEPTHROW = (NUM_TILEROW/8), 00050 NUM_DEPTHCOL = (NUM_TILECOL/8), 00051 NUM_DEPTH = (NUM_DEPTHROW * NUM_DEPTHCOL), 00052 00053 TILECOL_EMPTY = 0, 00054 TILECOL_FULL = ((uint32)~0), 00055 00056 TEST_OCCLUDER_QUALITY = 1, 00057 TB_DUMMY = -1 //to force it to signed 00058 }; 00059 00060 typedef uint32 csTileCol; 00061 00065 class csBox2Int 00066 { 00067 public: 00068 int minx, miny; 00069 int maxx, maxy; 00070 csBox2Int& operator+= (const csBox2Int& box) 00071 { 00072 if (box.minx < minx) minx = box.minx; 00073 if (box.miny < miny) miny = box.miny; 00074 if (box.maxx > maxx) maxx = box.maxx; 00075 if (box.maxy > maxy) maxy = box.maxy; 00076 return *this; 00077 } 00078 }; 00079 00084 struct csTestRectData 00085 { 00086 csBox2Int bbox; 00087 int startrow, endrow; 00088 int startcol, endcol; 00089 int start_x, end_x; 00090 }; 00091 00092 00093 // Line operations in a tile. 00094 enum 00095 { 00096 OP_LINE = 1, // General line. 00097 OP_VLINE = 2, // Vertical line. 00098 OP_FULLVLINE = 3 // Full vertical line (from 0 to 63). 00099 }; 00100 00101 // A definition for a line operation. 00102 struct csLineOperation 00103 { 00104 uint8 op; // One of OP_... 00105 // All coordinates are with 0,0 relative to top-left of tile. 00106 // x coordinates are also shifted 16 to the left. 00107 int x1; // Start of line. 00108 int y1; // Start of line. Not used with OP_FULLVLINE. 00109 int x2; // End of line. Only used with OP_LINE. 00110 int y2; // End of line. Not used with OP_FULLVLINE. 00111 int dx; // Slope to add to x1 (shifted 16 to left). 00112 }; 00113 00119 class CS_CRYSTALSPACE_EXPORT csCoverageTile 00120 { 00121 friend class csTiledCoverageBuffer; 00122 00123 private: 00124 // If true entire tile is full. 00125 bool tile_full; 00126 // If true tile is queued as empty but 'coverage' and other 00127 // data structures may not yet reflect this. 00128 bool queue_tile_empty; 00129 00130 // The coverage bits. 00131 csTileCol coverage[NUM_TILECOL]; 00132 00133 // The cache on which we will write lines before or-ing that to the 00134 // real coverage bits. 00135 static csTileCol coverage_cache[NUM_TILECOL]; 00136 00137 // This is an array of precalculated bit-sets for vertical line 00138 // segments that start at 'n' and go to 63. 00139 static csTileCol precalc_end_lines[NUM_TILEROW]; 00140 // This is an array of precalculated bit-sets for vertical line 00141 // segments that start at 0 and go to 'n'. 00142 static csTileCol precalc_start_lines[NUM_TILEROW]; 00143 // If true the two arrays above are initialized. 00144 static bool precalc_init; 00145 00146 // For every block a depth value (4 blocks on every row, ordered 00147 // by rows). 00148 float depth[NUM_DEPTH]; 00149 // Minimum depth of all blocks. 00150 float tile_min_depth; 00151 // Maximum depth of all blocks. 00152 float tile_max_depth; 00153 00154 // Line Operations that are waiting to be executed. 00155 int num_operations; 00156 int max_operations; 00157 csLineOperation* operations; 00158 00159 // A temporary values that are used to test if the objects in the write 00160 // queue can actually help cull the object. 00161 bool covered; 00162 bool fully_covered; 00163 00164 // Add an operation. 00165 csLineOperation& AddOperation (); 00166 00167 // Check if the precalc tables are precalculated. If not 00168 // precalculate them. 00169 static void MakePrecalcTables (); 00170 00171 // Count how many objects were occluded away that covered this tile. 00172 int objects_culled; 00173 00174 public: 00175 csCoverageTile () : 00176 tile_full (false), 00177 queue_tile_empty (true), 00178 num_operations (0), 00179 max_operations (16), 00180 covered (false) 00181 { 00182 operations = new csLineOperation [16]; 00183 MakePrecalcTables (); 00184 MakeEmpty (); 00185 } 00186 00187 ~csCoverageTile () 00188 { 00189 delete[] operations; 00190 } 00191 00196 inline void MarkEmpty () 00197 { 00198 queue_tile_empty = true; 00199 tile_full = false; 00200 objects_culled = 0; 00201 } 00202 00203 #define INIT_MIN_DEPTH 999999999.0f 00204 #define INIT_MIN_DEPTH_CMP 999900000.0f 00205 00210 inline void MakeEmpty () 00211 { 00212 tile_full = false; queue_tile_empty = false; 00213 memset (coverage, 0, sizeof (csTileCol)*NUM_TILECOL); 00214 memset (depth, 0, sizeof (float)*NUM_DEPTH); 00215 tile_min_depth = INIT_MIN_DEPTH; 00216 tile_max_depth = 0; 00217 objects_culled = 0; 00218 } 00219 00225 inline void MakeEmptyQuick () 00226 { 00227 queue_tile_empty = false; 00228 memset (depth, 0, sizeof (float)*NUM_DEPTH); 00229 tile_min_depth = INIT_MIN_DEPTH; 00230 tile_max_depth = 0; 00231 objects_culled = 0; 00232 } 00233 00237 inline void ClearOperations () 00238 { 00239 num_operations = 0; 00240 } 00241 00245 inline bool IsFull () const { return tile_full; } 00246 00252 inline bool IsEmpty () const { return queue_tile_empty; } 00253 00257 void PushLine (int x1, int y1, int x2, int y2, int dx); 00258 00262 void PushVLine (int x, int y1, int y2); 00263 00267 void PushFullVLine (int x); 00268 00272 void PerformOperations (); 00273 00279 void FlushOperations (); 00280 00285 void PerformOperationsOnlyFValue (csTileCol& fvalue); 00286 00293 void FlushOperationsOnlyFValue (csTileCol& fvalue); 00294 00295 //----------------------------------------------------------------- 00296 00306 bool Flush (csTileCol& fvalue, float maxdepth); 00307 00311 bool FlushIgnoreDepth (csTileCol& fvalue); 00312 00317 bool FlushForEmpty (csTileCol& fvalue, float maxdepth); 00318 00323 bool FlushForEmptyNoDepth (csTileCol& fvalue); 00324 00329 bool FlushForFull (csTileCol& fvalue, float maxdepth); 00330 00335 bool FlushNoDepth (csTileCol& fvalue); 00336 00341 bool FlushGeneral (csTileCol& fvalue, float maxdepth); 00342 00347 void FlushForEmptyConstFValue (csTileCol& fvalue, float maxdepth); 00348 00353 void FlushForFullConstFValue (csTileCol& fvalue, float maxdepth); 00354 00360 bool FlushNoDepthConstFValue (csTileCol& fvalue, float maxdepth); 00361 00367 bool FlushGeneralConstFValue (csTileCol& fvalue, float maxdepth); 00368 00369 //----------------------------------------------------------------- 00370 00375 bool TestCoverageFlush (csTileCol& fvalue, float mindepth, 00376 bool& do_depth_test); 00377 00381 bool TestCoverageFlushForFull (csTileCol& fvalue, float mindepth, 00382 bool& do_depth_test); 00383 00387 bool TestCoverageFlushGeneral (csTileCol& fvalue, float maxdepth, 00388 bool& do_depth_test); 00389 00390 //----------------------------------------------------------------- 00391 00396 bool TestDepthFlush (csTileCol& fvalue, float mindepth); 00397 00401 bool TestDepthFlushGeneral (csTileCol& fvalue, float maxdepth); 00402 00403 //----------------------------------------------------------------- 00404 00413 bool TestFullRect (float testdepth); 00414 00419 bool TestDepthRect (int start, int end, float testdepth); 00420 00426 bool TestDepthRect (const csTileCol& vermask, int start, int end, 00427 float testdepth); 00428 00433 bool TestCoverageRect (int start, int end, float testdepth, 00434 bool& do_depth_test); 00435 00441 bool TestCoverageRect (const csTileCol& vermask, int start, int end, 00442 float testdepth, bool& do_depth_test); 00443 00444 //----------------------------------------------------------------- 00449 bool TestPoint (int x, int y, float testdepth); 00450 00454 csPtr<iString> Debug_Dump (); 00455 00459 csPtr<iString> Debug_Dump_Cache (); 00460 }; 00461 00470 class CS_CRYSTALSPACE_EXPORT csTiledCoverageBuffer : 00471 public scfImplementation1<csTiledCoverageBuffer,iDebugHelper> 00472 { 00473 public: 00474 iBugPlug* bugplug; // For debugging... 00475 00476 private: 00477 int width, height; 00478 int width_po2; // Width after correcting for power of two. 00479 int height_64; // Height after making it a multiple of 64. 00480 int w_shift; // Horizontal shift for width_po2 for tile multiples. 00481 int num_tile_rows; 00482 00483 // All tiles representing the screen (ordered by rows). 00484 int num_tiles; 00485 csCoverageTile* tiles; 00486 00487 // For every row the following arrays contain the left-most and 00488 // right-most horizontal tile number that was affected by the polygon/outline. 00489 // DrawLine() will update these values. 00490 int* dirty_left; 00491 int* dirty_right; 00492 00499 void DrawLine (int x1, int y1, int x2, int y2, int yfurther = 0); 00500 00509 bool DrawPolygon (csVector2* verts, size_t num_verts, csBox2Int& bbox); 00510 00517 bool DrawOutline (const csReversibleTransform& trans, 00518 float fov, float sx, float sy, csVector3* verts, size_t num_verts, 00519 bool* used_verts, 00520 int* edges, size_t num_edges, csBox2Int& bbox, 00521 float& max_depth, bool splat_outline); 00522 00526 inline csCoverageTile* GetTile (int tx, int ty) 00527 { 00528 CS_ASSERT (tx >= 0); 00529 CS_ASSERT (ty >= 0 && ty < num_tile_rows); 00530 return &tiles[(ty<<w_shift) + tx]; 00531 } 00532 00536 inline void MarkTileDirty (int tx, int ty) 00537 { 00538 CS_ASSERT (ty >= 0 && ty < num_tile_rows); 00539 if (tx < dirty_left[ty]) dirty_left[ty] = tx; 00540 if (tx > dirty_right[ty]) dirty_right[ty] = tx; 00541 } 00542 00543 public: 00545 csTiledCoverageBuffer (int w, int h); 00547 virtual ~csTiledCoverageBuffer (); 00548 00550 void Setup (int w, int h); 00551 00553 void Initialize (); 00554 00564 bool TestPolygon (csVector2* verts, size_t num_verts, float min_depth); 00565 00569 void InsertPolygonInverted (csVector2* verts, size_t num_verts, float max_depth); 00570 00577 void InsertPolygonInvertedNoDepth (csVector2* verts, size_t num_verts); 00578 00589 int InsertPolygon (csVector2* verts, size_t num_verts, float max_depth, 00590 csBox2Int& modified_bbox); 00591 00603 int InsertPolygonNoDepth (csVector2* verts, size_t num_verts); 00604 00618 int InsertOutline (const csReversibleTransform& trans, 00619 float fov, float sx, float sy, csVector3* verts, size_t num_verts, 00620 bool* used_verts, 00621 int* edges, size_t num_edges, bool splat_outline, 00622 csBox2Int& modified_bbox); 00623 00629 bool PrepareTestRectangle (const csBox2& rect, csTestRectData& data); 00630 00637 bool TestRectangle (const csTestRectData& data, float min_depth); 00638 00646 bool QuickTestRectangle (const csTestRectData& data, float min_depth); 00647 00652 void MarkCulledObject (const csTestRectData& data); 00653 00658 int CountNotCulledObjects (const csBox2Int& bbox); 00659 00665 int PrepareWriteQueueTest (const csTestRectData& data, float min_depth); 00666 00674 int AddWriteQueueTest (const csTestRectData& maindata, 00675 const csTestRectData& data, bool& relevant); 00676 00682 bool TestPoint (const csVector2& point, float min_depth); 00683 00689 int StatusNoDepth (); 00690 00691 // Debugging functions. 00692 csPtr<iString> Debug_UnitTest (); 00693 csTicks Debug_Benchmark (int num_iterations); 00694 void Debug_Dump (iGraphics3D* g3d, int zoom = 1); 00695 csPtr<iString> Debug_Dump (); 00696 00697 virtual int GetSupportedTests () const 00698 { 00699 return CS_DBGHELP_UNITTEST | 00700 CS_DBGHELP_BENCHMARK | 00701 CS_DBGHELP_GFXDUMP | 00702 CS_DBGHELP_TXTDUMP; 00703 } 00704 virtual csPtr<iString> UnitTest () 00705 { 00706 return Debug_UnitTest (); 00707 } 00708 virtual csPtr<iString> StateTest () 00709 { 00710 return 0; 00711 } 00712 virtual csTicks Benchmark (int num_iterations) 00713 { 00714 return Debug_Benchmark (num_iterations); 00715 } 00716 virtual csPtr<iString> Dump () 00717 { 00718 return Debug_Dump (); 00719 } 00720 virtual void Dump (iGraphics3D* g3d) 00721 { 00722 Debug_Dump (g3d, 1); 00723 } 00724 virtual bool DebugCommand (const char*) 00725 { 00726 return false; 00727 } 00728 }; 00729 00730 #endif // __CS_CSGEOM_TCOVBUF_H__ 00731
Generated for Crystal Space by doxygen 1.4.4