Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

glt/countsrf.cpp

Go to the documentation of this file.
00001 #include "countsrf.h"
00002 
00015 #include <glt/rgb.h>
00016 #include <glt/zplane.h>
00017 #include <glt/error.h>
00018 
00019 #include <node/shape.h>
00020 
00021 #ifdef DEBUG
00022 #include <iostream>
00023 using namespace std;
00024 #endif
00025 
00027 
00028 void countSurfaces(const GltShape &shape)
00029 {
00030     GLERROR
00031     glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT | 
00032                  GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
00033 
00034         // Ensure stencil buffer is fully zero
00035 
00036         glClearStencil(0);
00037         glStencilMask(~0);
00038         glClear(GL_STENCIL_BUFFER_BIT);
00039         
00040         // Disable z buffer test & update
00041         
00042         glDepthMask(GL_FALSE);
00043         glDepthFunc(GL_ALWAYS);
00044 
00045         // Use stencil test to count surfaces
00046 
00047         glEnable(GL_STENCIL_TEST);
00048         glStencilFunc(GL_ALWAYS,0,~0);
00049         glStencilOp(GL_INCR,GL_INCR,GL_INCR);
00050 
00051         // Disable updates to colour buffer
00052 
00053         glDisable(GL_LIGHTING);
00054         glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
00055 
00056         // Draw all objects
00057         shape.draw();
00058 
00059     glPopAttrib();
00060     GLERROR
00061 }
00062 
00063 GLubyte
00064 countSurfaces
00065 (
00066     const GltShape &shape,
00067     const countSurfacesMode mode
00068 )
00069 {
00070     countSurfaces(shape);
00071 
00072     GLERROR
00073 
00074     // Get stencil buffer histogram
00075     
00076     GLuint histogram[256];
00077     GLuint pixels = stencilHistogram(histogram);
00078 
00079     GLubyte max = 0;
00080 
00081     switch (mode)
00082     {
00083         case COUNT_SURFACES_ALL:
00084             {
00085                 for (GLuint p=0; p<256; p++)
00086                     if (histogram[p]>0)
00087                         max = p;
00088             }
00089             break;
00090 
00091         case COUNT_SURFACES_99TH_PERCENTILE:
00092             {
00093                 GLuint accum = 0;
00094                 for (GLuint p=0; p<256; p++)
00095                 {
00096                     accum += histogram[p];
00097                     if ((double) accum / pixels >= 0.999)
00098                     {
00099                         max = p;
00100                         break;
00101                     }
00102                 }
00103             }
00104             break;
00105     }
00106 
00107     #ifdef DEBUG
00108     GLint stencilSize = 0;
00109     glGetIntegerv(GL_STENCIL_BITS,&stencilSize);
00110 
00111     if ( GLubyte(GLubyte(1)<<stencilSize) == max+1 )
00112         cout << "WARNING: Stencil Buffer may be too small for countSurfaces" << endl;
00113     #endif
00114 
00115     GLERROR
00116 
00117     return max;
00118 }
00119 
00121 
00123 const GLuint maxColors=8;
00124  
00126 const GltColor surfaceColor[maxColors] =
00127 {
00128     red,
00129     green,
00130     blue,
00131     yellow,
00132     cyan,
00133     magenta,
00134     black,
00135     white
00136 };
00137 
00138 GLubyte
00139 countSurfacesVisualise(const GltShape &shape)
00140 {
00141     glPushAttrib( GL_ENABLE_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
00142 
00143         GLubyte layers = countSurfaces(shape,COUNT_SURFACES_ALL);
00144 
00145         glEnable(GL_STENCIL_TEST);
00146         glStencilMask(0xffff);
00147         glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
00148 
00149         glEnable(GL_DEPTH_TEST);
00150         glDepthFunc(GL_ALWAYS);
00151         glDepthMask(GL_FALSE);
00152 
00153         glDisable(GL_LIGHTING);
00154 
00155         glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
00156 
00157         for (GLuint l=0; l<layers && l<maxColors; l++)
00158         {
00159             if (l<layers)
00160             {
00161                 glStencilFunc(GL_EQUAL,l+1,0xff);
00162                 surfaceColor[l%(maxColors-1)].glColor();
00163             }
00164             else
00165             {
00166                 glStencilFunc(GL_GEQUAL,l+1,0xff);
00167                 surfaceColor[maxColors-1].glColor();
00168             }
00169 
00170             drawZnear();
00171         }
00172 
00173     glPopAttrib();
00174 
00175     return layers;
00176 }
00177 
00179 
00180 GLuint 
00181 stencilHistogram(GLuint histogram[256])
00182 {
00183     // Get the viewport dimensions
00184 
00185     GLuint viewport[4];
00186     glGetIntegerv(GL_VIEWPORT,(GLint *) viewport);
00187 
00188     // Allocate enough memory to get a copy of the stencil buffer
00189 
00190     GLuint   pixels = viewport[2] * viewport[3];
00191     GLubyte *pixel  = new GLubyte[pixels];
00192 
00193     // Read the stencil buffer
00194 
00195     glPixelStorei(GL_PACK_ALIGNMENT,sizeof(GLubyte));
00196     glReadPixels(0,0,viewport[2],viewport[3],GL_STENCIL_INDEX,GL_UNSIGNED_BYTE,pixel);
00197 
00198     // Initialise Histogram
00199 
00200     GLuint x;
00201 
00202     for (x=0;x<256;x++)
00203         histogram[x] = 0;
00204 
00205     // Build Histogram
00206 
00207     for (x=0;x<pixels;x++)
00208         histogram[pixel[x]]++;
00209 
00210     // Free allocated memory
00211 
00212     delete [] pixel;
00213 
00214     return pixels;
00215 }

Generated on Tue Nov 5 11:11:03 2002 for GLT by doxygen1.2.18