ParserGL.cpp
Go to the documentation of this file.
00001 /*
00002  This file is part of the VRender library.
00003  Copyright (C) 2005 Cyril Soler (Cyril.Soler@imag.fr)
00004  Version 1.0.0, released on June 27, 2005.
00005 
00006  http://artis.imag.fr/Members/Cyril.Soler/VRender
00007 
00008  VRender is free software; you can redistribute it and/or modify
00009  it under the terms of the GNU General Public License as published by
00010  the Free Software Foundation; either version 2 of the License, or
00011  (at your option) any later version.
00012 
00013  VRender is distributed in the hope that it will be useful,
00014  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  GNU General Public License for more details.
00017 
00018  You should have received a copy of the GNU General Public License
00019  along with VRender; if not, write to the Free Software Foundation, Inc.,
00020  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
00021 */
00022 
00023 /****************************************************************************
00024 
00025  Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
00026 
00027  This file is part of the QGLViewer library version 2.4.0.
00028 
00029  http://www.libqglviewer.com - contact@libqglviewer.com
00030 
00031  This file may be used under the terms of the GNU General Public License 
00032  versions 2.0 or 3.0 as published by the Free Software Foundation and
00033  appearing in the LICENSE file included in the packaging of this file.
00034  In addition, as a special exception, Gilles Debunne gives you certain 
00035  additional rights, described in the file GPL_EXCEPTION in this package.
00036 
00037  libQGLViewer uses dual licensing. Commercial/proprietary software must
00038  purchase a libQGLViewer Commercial License.
00039 
00040  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00041  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00042 
00043 *****************************************************************************/
00044 
00045 #include <assert.h>
00046 #include <math.h>
00047 #include <stdio.h>
00048 
00049 #include "VRender.h"
00050 #include "ParserGL.h"
00051 
00052 using namespace vrender ;
00053 using namespace std;
00054 
00055 class ParserUtils
00056 {
00057         public:
00058                 static void NormalizeBufferCoordinates(GLint size, GLfloat * buffer, GLfloat MaxSize, GLfloat& zmin, GLfloat& zmax) ;
00059 
00060                 static PtrPrimitive checkPoint(Point *& P);
00061                 static PtrPrimitive checkSegment(Segment *& P);
00062                 static PtrPrimitive checkPolygon(Polygone *& P);
00063 
00064                 static void ComputeBufferBB(GLint size, GLfloat * buffer,
00065                                 GLfloat & xmin, GLfloat & xmax,
00066                                 GLfloat & ymin, GLfloat & ymax,
00067                                 GLfloat & zmin, GLfloat & zmax) ;
00068 
00069         private:
00070                 static void print3DcolorVertex(GLint size, GLint * count, GLfloat * buffer) ;
00071                 static void debug_printBuffer(GLint size, GLfloat *buffer) ;
00072 
00073                 static void NormalizePrimitiveCoordinates(GLfloat * & loc,GLfloat MaxSize,GLfloat zmin,GLfloat zmax) ;
00074                 static void ComputePrimitiveBB( GLfloat * & loc,
00075                                 GLfloat & xmin,GLfloat & xmax,
00076                                 GLfloat & ymin,GLfloat & ymax,
00077                                 GLfloat & zmin,GLfloat & zmax);
00078 
00079                 static const char *nameOfToken(int token);
00080 
00081                 static const double EGALITY_EPS ;
00082 };
00083 
00084 const double ParserUtils::EGALITY_EPS = 0.00001 ;
00085 
00086 void ParserGL::parseFeedbackBuffer(     GLfloat *buffer,int size,
00087                                                                                                 std::vector<PtrPrimitive>& primitive_tab,
00088                                                                                                 VRenderParams& vparams)
00089 {
00090         int token;
00091         int nvertices = 0 ;
00092         nb_lines = 0 ;
00093         nb_polys = 0 ;
00094         nb_points = 0 ;
00095         nb_degenerated_lines = 0 ;
00096         nb_degenerated_polys = 0 ;
00097         nb_degenerated_points = 0 ;
00098 
00099         // pre-treatment of coordinates so as to get something more consistent
00100 
00101         _xmin = FLT_MAX ;
00102         _ymin = FLT_MAX ;
00103         _zmin = FLT_MAX ;
00104         _xmax = -FLT_MAX ;
00105         _ymax = -FLT_MAX ;
00106         _zmax = -FLT_MAX ;
00107 
00108         ParserUtils::ComputeBufferBB(size, buffer, _xmin,_xmax,_ymin,_ymax,_zmin,_zmax) ;
00109 
00110 #ifdef DEBUGEPSRENDER
00111         printf("Buffer bounding box: %f %f %f %f %f %f\n",xmin,xmax,ymin,ymax,zmin,zmax) ;
00112 #endif
00113         float Zdepth = max(_ymax-_ymin,_xmax-_xmin) ;
00114         ParserUtils::NormalizeBufferCoordinates(size,buffer,Zdepth,_zmin,_zmax) ;
00115 
00116         // now, read buffer
00117         GLfloat *end = buffer + size;
00118 
00119         GLfloat *loc = buffer ;
00120         int next_step = 0 ;
00121         int N = size/200 + 1 ;
00122 
00123         while (loc < end)
00124         {
00125                 token = int(0.5f + *loc) ;
00126                 loc++;
00127 
00128                 if((end-loc)/N >= next_step)
00129                         vparams.progress((end-loc)/(float)size, QGLViewer::tr("Parsing feedback buffer.")), ++next_step ;
00130 
00131                 switch (token)
00132                 {
00133                         case GL_LINE_TOKEN:
00134                         case GL_LINE_RESET_TOKEN:
00135                                 {
00136                                         Segment *S = new Segment(Feedback3DColor(loc),Feedback3DColor(loc+Feedback3DColor::sizeInBuffer())) ;
00137 
00138                                         primitive_tab.push_back(ParserUtils::checkSegment(S)) ;
00139 
00140                                         if(S == NULL)
00141                                                 nb_degenerated_lines++ ;
00142 
00143                                         nb_lines++ ;
00144                                         loc += 2*Feedback3DColor::sizeInBuffer();
00145                                 }
00146                                 break;
00147 
00148                         case GL_POLYGON_TOKEN:
00149                                 {
00150                                         nvertices = int(0.5f + *loc) ;
00151                                         loc++;
00152 
00153                                         std::vector<Feedback3DColor> verts ;
00154 
00155                                         for(int i=0;i<nvertices;++i)
00156                                                 verts.push_back(Feedback3DColor(loc)),loc+=Feedback3DColor::sizeInBuffer() ;
00157 
00158                                         Polygone *P = new Polygone(verts) ;
00159 
00160                                         primitive_tab.push_back(ParserUtils::checkPolygon(P)) ;
00161 
00162                                         if(P == NULL)
00163                                                 nb_degenerated_polys++ ;
00164 
00165                                         nb_polys++ ;
00166                                 }
00167                                 break ;
00168 
00169                         case GL_POINT_TOKEN:
00170                                 {
00171                                         Point *Pt = new Point(Feedback3DColor(loc)) ;
00172 
00173                                         primitive_tab.push_back(Pt);//ParserUtils::checkPoint(Pt)) ;
00174 
00175                                         if(Pt == NULL)
00176                                                 nb_degenerated_points++ ;
00177 
00178                                         nb_points++ ;
00179                                         loc += Feedback3DColor::sizeInBuffer();
00180                                 }
00181                                 break;
00182                         default:
00183                                 break;
00184                 }
00185         }
00186 
00187 }
00188 
00189 // Traitement des cas degeneres. Renvoie false si le polygone est degenere.
00190 // Traitement des cas degeneres. Renvoie false si le segment est degenere.
00191 
00192 PtrPrimitive ParserUtils::checkPoint(Point *& P)
00193 {
00194         return P ;
00195 }
00196 
00197 PtrPrimitive ParserUtils::checkSegment(Segment *& P)
00198 {
00199         if((P->vertex(0) - P->vertex(1)).infNorm() < EGALITY_EPS)
00200         {
00201                 Point *pp = new Point(P->sommet3DColor(0)) ;
00202                 delete P ;
00203                 P = NULL ;
00204 
00205                 return checkPoint(pp) ;
00206         }
00207 
00208         return P ;
00209 }
00210 
00211 PtrPrimitive ParserUtils::checkPolygon(Polygone *& P)
00212 {
00213         if(P->nbVertices() != 3)
00214         {
00215                 cout << "unexpected case: Polygon with " << P->nbVertices() << " vertices !" << endl ;
00216                 delete P ;
00217                 return NULL ;
00218         }
00219 
00220         if(P->FlatFactor() < FLAT_POLYGON_EPS)
00221         {
00222                 // On ne traite que le cas du triangle plat, vu qu'on est sur d'avoir un triangle
00223 
00224                 int n = P->nbVertices() ;
00225 
00226                 for(int i=0;i<n;++i)
00227                         if( (P->vertex(i) - P->vertex((i+1)%n)).norm() > EGALITY_EPS)
00228                         {
00229                                 Segment *pp = new Segment(P->sommet3DColor((i+1)%n),P->sommet3DColor((i+2)%n)) ;
00230                                 delete P ;
00231                                 P = NULL ;
00232 
00233                                 return checkSegment(pp) ;
00234                         }
00235 
00236                 Point *pp = new Point(P->sommet3DColor(0)) ;
00237                 delete P ;
00238                 P = NULL ;
00239 
00240                 return checkPoint(pp) ;
00241         }
00242 
00243         // No problem detected.
00244 
00245         return P ;
00246 }
00247 
00248 
00249 /* Write contents of one vertex to stdout. */
00250 
00251 void ParserUtils::print3DcolorVertex(GLint size, GLint * count, GLfloat * buffer)
00252 {
00253         int i;
00254 
00255         printf("  ");
00256         for (i = 0; i < Feedback3DColor::sizeInBuffer(); i++)
00257         {
00258                 printf("%4.2f ", buffer[size - (*count)]);
00259                 *count = *count - 1;
00260         }
00261         printf("\n");
00262 }
00263 
00264 void ParserUtils::debug_printBuffer(GLint size, GLfloat * buffer)
00265 {
00266         GLint count;
00267         int token, nvertices;
00268 
00269         count = size;
00270         while (count) {
00271                 token = int(buffer[size - count]);
00272                 count--;
00273                 switch (token)
00274                 {
00275                         case GL_PASS_THROUGH_TOKEN:
00276                                 printf("GL_PASS_THROUGH_TOKEN\n");
00277                                 printf("  %4.2f\n", buffer[size - count]);
00278                                 count--;
00279                                 break;
00280                         case GL_POINT_TOKEN:
00281                                 printf("GL_POINT_TOKEN\n");
00282                                 print3DcolorVertex(size, &count, buffer);
00283                                 break;
00284                         case GL_LINE_TOKEN:
00285                                 printf("GL_LINE_TOKEN\n");
00286                                 print3DcolorVertex(size, &count, buffer);
00287                                 print3DcolorVertex(size, &count, buffer);
00288                                 break;
00289                         case GL_LINE_RESET_TOKEN:
00290                                 printf("GL_LINE_RESET_TOKEN\n");
00291                                 print3DcolorVertex(size, &count, buffer);
00292                                 print3DcolorVertex(size, &count, buffer);
00293                                 break;
00294                         case GL_POLYGON_TOKEN:
00295                                 printf("GL_POLYGON_TOKEN\n");
00296                                 nvertices = int(buffer[size - count]) ;
00297                                 count--;
00298                                 for (; nvertices > 0; nvertices--)
00299                                         print3DcolorVertex(size, &count, buffer);
00300                 }
00301         }
00302 }
00303 
00304 void ParserUtils::NormalizePrimitiveCoordinates(GLfloat * & loc,GLfloat MaxSize,GLfloat zmin,GLfloat zmax)
00305 {
00306         int token;
00307         int nvertices, i;
00308 
00309         token = int(*loc) ;
00310         loc++;
00311         int size = Feedback3DColor::sizeInBuffer() ;
00312 
00313         switch (token)
00314         {
00315                 case GL_LINE_RESET_TOKEN:
00316                 case GL_LINE_TOKEN:
00317                         {
00318                                 for (i = 0; i < 2; i++)
00319                                         (loc+size*i)[2] = ((loc+size*i)[2] - zmin)/(zmax-zmin)*MaxSize ;
00320 
00321                                 loc += 2*size;          /* Each vertex element in the feedback buffer is size GLfloats. */
00322                                 break;
00323                         }
00324                 case GL_POLYGON_TOKEN:
00325                         {
00326                                 nvertices = int(*loc) ;
00327                                 loc++;
00328 
00329                                 for (i = 0; i < nvertices; i++)
00330                                         (loc+size*i)[2] = ((loc+size*i)[2] - zmin)/(zmax-zmin)*MaxSize ;
00331 
00332                                 loc += nvertices * size;  /* Each vertex element in the feedback buffer is size GLfloats. */
00333                                 break;
00334                         }
00335                 case GL_POINT_TOKEN:
00336                         {
00337                                 loc[2] = (loc[2] - zmin)/(zmax-zmin)*MaxSize ;
00338 
00339                                 loc += size;           /* Each vertex element in the feedback buffer is size GLfloats. */
00340                                 break;
00341                         }
00342                 default:
00343                         /* XXX Left as an excersie to the reader. */
00344 #ifdef DEBUGEPSRENDER
00345                         printf("%s (%d) not handled yet. Sorry.\n", ParserUtils::nameOfToken(token), token);
00346 #endif
00347                         ;
00348         }
00349 }
00350 
00351 void ParserUtils::ComputePrimitiveBB(GLfloat * & loc,GLfloat & xmin,GLfloat & xmax,GLfloat & ymin,GLfloat & ymax, GLfloat & zmin,GLfloat & zmax)
00352 {
00353         int token;
00354         int nvertices, i;
00355 
00356         token = int(*loc) ;
00357         loc++;
00358         int size = Feedback3DColor::sizeInBuffer() ;
00359 
00360         switch (token)
00361         {
00362                 case GL_LINE_RESET_TOKEN:
00363                 case GL_LINE_TOKEN:
00364                         {
00365                                 for (i = 0; i < 2; i++)
00366                                 {
00367                                         Feedback3DColor f(loc+size*i) ;
00368 
00369                                         if(f.x() < xmin) xmin = GLfloat(f.x()) ;
00370                                         if(f.y() < ymin) ymin = GLfloat(f.y()) ;
00371                                         if(f.z() < zmin) zmin = GLfloat(f.z()) ;
00372                                         if(f.x() > xmax) xmax = GLfloat(f.x()) ;
00373                                         if(f.y() > ymax) ymax = GLfloat(f.y()) ;
00374                                         if(f.z() > zmax) zmax = GLfloat(f.z()) ;
00375                                 }
00376 
00377                                 loc += 2*size;          /* Each vertex element in the feedback
00378                                                                                                         buffer is size GLfloats. */
00379                                 break;
00380                         }
00381                 case GL_POLYGON_TOKEN:
00382                         {
00383                                 nvertices = int(*loc) ;
00384                                 loc++;
00385 
00386                                 for (i = 0; i < nvertices; i++)
00387                                 {
00388                                         Feedback3DColor f(loc+size*i) ;
00389 
00390                                         if(f.x() < xmin) xmin = GLfloat(f.x()) ;
00391                                         if(f.y() < ymin) ymin = GLfloat(f.y()) ;
00392                                         if(f.z() < zmin) zmin = GLfloat(f.z()) ;
00393                                         if(f.x() > xmax) xmax = GLfloat(f.x()) ;
00394                                         if(f.y() > ymax) ymax = GLfloat(f.y()) ;
00395                                         if(f.z() > zmax) zmax = GLfloat(f.z()) ;
00396                                 }
00397 
00398                                 loc += nvertices * size;  /* Each vertex element in the
00399                                                                                                           feedback buffer is size GLfloats. */
00400                                 break;
00401                         }
00402                 case GL_POINT_TOKEN:
00403                         {
00404                                 Feedback3DColor f(loc) ;
00405 
00406                                 if(f.x() < xmin) xmin = GLfloat(f.x()) ;
00407                                 if(f.y() < ymin) ymin = GLfloat(f.y()) ;
00408                                 if(f.z() < zmin) zmin = GLfloat(f.z()) ;
00409                                 if(f.x() > xmax) xmax = GLfloat(f.x()) ;
00410                                 if(f.y() > ymax) ymax = GLfloat(f.y()) ;
00411                                 if(f.z() > zmax) zmax = GLfloat(f.z()) ;
00412 
00413                                 loc += size;           /* Each vertex element in the feedback
00414                                                                                                   buffer is size GLfloats. */
00415                                 break;
00416                         }
00417                 default:
00418                         /* XXX Left as an excersie to the reader. */
00419 #ifdef DEBUGEPSRENDER
00420                         printf("Incomplete implementation.  Unexpected token (%d).\n", token);
00421 #endif
00422                         ;
00423         }
00424 }
00425 
00426 void ParserUtils::NormalizeBufferCoordinates(GLint size, GLfloat * buffer, GLfloat MaxSize, GLfloat& zmin,GLfloat& zmax)
00427 {
00428         GLfloat *loc, *end;
00429 
00430         if(zmax == zmin)
00431         {
00432 #ifdef DEBUGEPSRENDER
00433                 printf("Warning: zmin = zmax in NormalizePrimitiveCoordinates\n") ;
00434 #endif
00435                 return ;
00436         }
00437 
00438         loc = buffer;
00439         end = buffer + size;
00440 
00441         while (loc < end)
00442                 NormalizePrimitiveCoordinates(loc,MaxSize,zmin,zmax);
00443 
00444         zmin = 0.0 ;
00445         zmax = MaxSize ;
00446 }
00447 
00448 void ParserUtils::ComputeBufferBB(GLint size, GLfloat * buffer,
00449                      GLfloat & xmin, GLfloat & xmax,
00450                      GLfloat & ymin, GLfloat & ymax,
00451                      GLfloat & zmin, GLfloat & zmax)
00452 {
00453         GLfloat *loc, *end;
00454 
00455         loc = buffer;
00456         end = buffer + size;
00457 
00458         while (loc < end)
00459                 ComputePrimitiveBB(loc,xmin,xmax,ymin,ymax,zmin,zmax);
00460 }
00461 
00462 typedef struct _DepthIndex {
00463   GLfloat *ptr;
00464   GLfloat depth;
00465 } DepthIndex;
00466 
00467 const char *ParserUtils::nameOfToken(int token)
00468 {
00469         switch(token)
00470         {
00471                 case GL_PASS_THROUGH_TOKEN:     return "GL_PASS_THROUGH_TOKEN" ;
00472                 case GL_POINT_TOKEN:                    return "GL_POINT_TOKEN" ;
00473                 case GL_LINE_TOKEN:                             return "GL_LINE_TOKEN" ;
00474                 case GL_POLYGON_TOKEN:                  return "GL_POLYGON_TOKEN" ;
00475                 case GL_BITMAP_TOKEN:                   return "GL_BITMAP_TOKEN" ;
00476                 case GL_DRAW_PIXEL_TOKEN:               return "GL_DRAW_PIXEL_TOKEN" ;
00477                 case GL_COPY_PIXEL_TOKEN:               return "GL_COPY_PIXEL_TOKEN" ;
00478                 case GL_LINE_RESET_TOKEN:               return "GL_LINE_RESET_TOKEN" ;
00479                 default:
00480                                                                                                 return "(Unidentified token)" ;
00481         }
00482 }
00483 


octovis
Author(s): Kai M. Wurm , Armin Hornung
autogenerated on Thu Aug 27 2015 14:13:26