CrystalSpace

Public API Reference

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