ToglCache.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:5k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. // ToglCache.cc              cache togl frame buffer for fast redraws
  2. // created 10/27/98          magi
  3. #include <assert.h>
  4. #include <iostream.h>
  5. #include "togl.h"
  6. #include "ToglCache.h"
  7. #include "plvGlobals.h"
  8. #include "plvDraw.h"
  9. #include "Trackball.h"
  10. DisplayCache::DisplayCache (struct Togl* togl)
  11. {
  12.   mTogl = togl;
  13.   mData = NULL;
  14.   mZData = NULL;
  15.   mValid = false;
  16.   mX = mY = 0;
  17.   mEnabled = true;
  18.   // save callbacks for chaining
  19.   mOldDestroyProc = Togl_GetDestroyFunc (togl);
  20.   mOldReshapeProc = Togl_GetReshapeFunc (togl);
  21.   mOldDisplayProc = Togl_GetDisplayFunc (togl);
  22.   // then replace them
  23.   Togl_SetDestroyFunc (togl, DC_ToglDestroy);
  24.   Togl_SetReshapeFunc (togl, DC_ToglReshape);
  25.   Togl_SetDisplayFunc (togl, DC_ToglDisplay);
  26.   AddToglDC (togl, this);
  27.   Allocate();
  28. }
  29. DisplayCache::~DisplayCache (void)
  30. {
  31.   Free();
  32. }
  33. bool
  34. DisplayCache::Render (void)
  35. {
  36.   if (!mEnabled)
  37.     return false;
  38.   // write from our cache to frame buffer
  39.   if (!mValid) {
  40. #if TOGLCACHE_DEBUG
  41.     cout << "can't render from cache" << endl;
  42. #endif
  43.     return false;
  44.   }
  45.   glDrawBuffer (GL_FRONT);
  46.   while (glGetError() != GL_NO_ERROR)
  47.     ; // clear error state since we don't care if this fails
  48.   glMatrixMode (GL_PROJECTION);
  49.   glPushMatrix();
  50.   glLoadIdentity();
  51.   glMatrixMode (GL_MODELVIEW);
  52.   glPushMatrix();
  53.   glLoadIdentity();
  54.   glDisable (GL_DEPTH_TEST);
  55.   glRasterPos2f (-1, -1);
  56.   glDepthMask(GL_FALSE);
  57.   glDrawPixels (mX, mY, GL_RGBA, GL_UNSIGNED_BYTE, mData);
  58.   glRasterPos2f (-1, -1);
  59.   glDepthMask(GL_TRUE);
  60.   glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  61.   glDrawPixels (mX, mY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, mZData);
  62.   if (glGetError() != GL_NO_ERROR) {
  63.     cout << "ERROR in glDrawPixels!" << endl;
  64.   }
  65.   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  66.   glPopMatrix();
  67.   glMatrixMode (GL_PROJECTION);
  68.   glPopMatrix();
  69.   glMatrixMode (GL_MODELVIEW);
  70.   glEnable (GL_DEPTH_TEST);
  71.   glDrawBuffer (GL_BACK);
  72. #if TOGLCACHE_DEBUG
  73.   cout << "mX, mY = " << mX << "," << mY << endl;
  74.   cout << "render from cache" << endl;
  75. #endif
  76.   return true;
  77. }
  78. bool
  79. DisplayCache::Update (void)
  80. {
  81.   mValid = false;
  82.   if (mEnabled) {
  83.     // read cache from frame buffer
  84.     glReadBuffer (GL_BACK);
  85.     while (glGetError() != GL_NO_ERROR)
  86.       ; // clear error state since we don't care if this fails
  87.     glReadPixels (0, 0, mX, mY, GL_RGBA, GL_UNSIGNED_BYTE, mData);
  88.     glReadPixels (0, 0, mX, mY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, mZData);
  89.     if (!glGetError()) {
  90. #if TOGLCACHE_DEBUG
  91.       cout << "creating cache" << endl;
  92. #endif
  93.       mValid = true;
  94.     } // buffer read succeeded
  95.   } // enabled
  96.   return mValid;
  97. }
  98. bool
  99. DisplayCache::Invalidate (void)
  100. {
  101.   mValid = false;
  102.   return true;
  103. }
  104. void
  105. DisplayCache::Enable (bool bEnable)
  106. {
  107.   mEnabled = bEnable;
  108. }
  109. bool
  110. DisplayCache::Allocate (void)
  111. {
  112.   Free();
  113. #if TOGLCACHE_DEBUG
  114.   cout << "Reallocating cache" << endl;
  115. #endif
  116.   mValid = false;
  117.   mX = Togl_Width (mTogl);
  118.   mY = Togl_Height (mTogl);
  119.   mData = new char [4 * mX * mY];
  120.   mZData = new char [sizeof(unsigned int) * mX * mY];
  121.   return true;
  122. }
  123. bool
  124. DisplayCache::Free (void)
  125. {
  126.   if (mData) {
  127.     delete[] mData;
  128.     mData = NULL;
  129.     delete[] mZData;
  130.     mZData = NULL;
  131.     mX = mY = 0;
  132.     mValid = false;
  133.   }
  134.   return true;
  135. }
  136. void
  137. DisplayCache::InvalidateToglCache (struct Togl* togl)
  138. {
  139.   DisplayCache* dc = FindToglDC (togl);
  140.   if (dc != NULL)
  141.     dc->Invalidate();
  142. }
  143. void
  144. DisplayCache::UpdateToglCache (struct Togl* togl)
  145. {
  146.   DisplayCache* dc = FindToglDC (togl);
  147.   if (dc != NULL)
  148.     dc->Update();
  149. }
  150. void
  151. DisplayCache::EnableToglCache (struct Togl* togl, bool bEnable)
  152. {
  153.   DisplayCache* dc = FindToglDC (togl);
  154.   assert (dc);
  155.   dc->Enable (bEnable);
  156. }
  157. void
  158. DisplayCache::DC_ToglDestroy (struct Togl* togl)
  159. {
  160.   DisplayCache* dc = FindToglDC (togl);
  161.   assert (dc);
  162.   if (dc->mOldDestroyProc)
  163.     dc->mOldDestroyProc (togl);
  164.   delete dc;
  165. }
  166. void
  167. DisplayCache::DC_ToglReshape (struct Togl* togl)
  168. {
  169.   DisplayCache* dc = FindToglDC (togl);
  170.   assert (dc);
  171.   dc->Allocate();
  172.   if (dc->mOldReshapeProc)
  173.     dc->mOldReshapeProc (togl);
  174. }
  175. void
  176. DisplayCache::DC_ToglDisplay (struct Togl* togl)
  177. {
  178.   DisplayCache* dc = FindToglDC (togl);
  179.   assert (dc);
  180.   if (!dc->Render()) {
  181.     dc->mOldDisplayProc (togl);
  182.   }
  183. }
  184. #include <hash_map.h>
  185. struct eqtoglptr
  186. {
  187.   bool operator()(unsigned long t1, unsigned long t2) const
  188.   {
  189.     return (t1 == t2);
  190.   }
  191. };
  192. typedef hash_map<unsigned long, DisplayCache*, hash<unsigned long>,
  193.   eqtoglptr> DCToglHash;
  194. static DCToglHash dcHash;
  195. void
  196. DisplayCache::AddToglDC (struct Togl* togl, DisplayCache* dc)
  197. {
  198.   unsigned long hash = (unsigned long)togl;
  199.   dcHash[hash] = dc;
  200. }
  201. DisplayCache*
  202. DisplayCache::FindToglDC (struct Togl* togl)
  203. {
  204.   unsigned long hash = (unsigned long)togl;
  205.   return dcHash[hash];
  206. }