/* This file is part of the VRender library. Copyright (C) 2005 Cyril Soler (Cyril.Soler@imag.fr) Version 1.0.0, released on June 27, 2005. http://artis.imag.fr/Members/Cyril.Soler/VRender VRender is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. VRender is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with VRender; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /**************************************************************************** Copyright (C) 2002-2006 Gilles Debunne (Gilles.Debunne@imag.fr) This file is part of the QGLViewer library. Version 2.2.4-1, released on December 12, 2006. http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer libQGLViewer is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. libQGLViewer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with libQGLViewer; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *****************************************************************************/ #ifdef WIN32 # include #endif #ifdef __APPLE__ # include #else # include #endif #include #include #include "VRender.h" #include "ParserGL.h" #include "Exporter.h" #include "SortMethod.h" #include "Optimizer.h" using namespace vrender ; using namespace std ; void vrender::VectorialRender(RenderCB render_callback, void *callback_params, VRenderParams& vparams) { GLfloat *feedbackBuffer = NULL ; SortMethod *sort_method = NULL ; Exporter *exporter = NULL ; try { GLint returned = -1 ; vparams.error() = 0 ; int nb_renders = 0 ; vparams.progress(0.0,string("Rendering")) ; while(returned < 0) { if(feedbackBuffer != NULL) delete[] feedbackBuffer ; feedbackBuffer = new GLfloat[vparams.size()] ; if(feedbackBuffer == NULL) throw std::runtime_error("Out of memory during feedback buffer allocation.") ; glFeedbackBuffer(vparams.size(), GL_3D_COLOR, feedbackBuffer); glRenderMode(GL_FEEDBACK); render_callback(callback_params); returned = glRenderMode(GL_RENDER); nb_renders++ ; if(returned < 0) vparams.size() *= 2 ; } #ifdef A_VOIR if(SortMethod != EPS_DONT_SORT) { GLint depth_bits ; glGetIntegerv(GL_DEPTH_BITS, &depth_bits) ; EGALITY_EPS = 2.0/(1 << depth_bits) ; LINE_EGALITY_EPS = 2.0/(1 << depth_bits) ; } #endif if (returned > vparams.size()) vparams.size() = returned; #ifdef _VRENDER_DEBUG cout << "Size = " << vparams.size() << ", returned=" << returned << endl ; #endif // On a un beau feedback buffer tout plein de saloperies. Faut aller // defricher tout ca. Ouaiiiis ! vector primitive_tab ; ParserGL parserGL ; parserGL.parseFeedbackBuffer(feedbackBuffer,returned,primitive_tab,vparams) ; if(feedbackBuffer != NULL) { delete[] feedbackBuffer ; feedbackBuffer = NULL ; } if(vparams.isEnabled(VRenderParams::OptimizeBackFaceCulling)) { BackFaceCullingOptimizer bfopt ; bfopt.optimize(primitive_tab,vparams) ; } // Lance la methode de sorting switch(vparams.sortMethod()) { case VRenderParams::AdvancedTopologicalSort: case VRenderParams::TopologicalSort: { TopologicalSortMethod *tsm = new TopologicalSortMethod() ; tsm->setBreakCycles(vparams.sortMethod() == VRenderParams::AdvancedTopologicalSort) ; sort_method = tsm ; } break ; case VRenderParams::BSPSort: sort_method = new BSPSortMethod() ; break ; case VRenderParams::NoSorting: sort_method = new DontSortMethod() ; break ; default: throw std::runtime_error("Unknown sorting method.") ; } sort_method->sortPrimitives(primitive_tab,vparams) ; // Lance les optimisations. L'ordre est important. if(vparams.isEnabled(VRenderParams::CullHiddenFaces)) { VisibilityOptimizer vopt ; vopt.optimize(primitive_tab,vparams) ; } #ifdef A_FAIRE if(vparams.isEnabled(VRenderParams::OptimizePrimitiveSplit)) { PrimitiveSplitOptimizer psopt ; psopt.optimize(primitive_tab) ; } #endif // Ecrit le fichier switch(vparams.format()) { case VRenderParams::EPS: exporter = new EPSExporter() ; break ; case VRenderParams::PS: exporter = new PSExporter() ; break ; case VRenderParams::XFIG:exporter = new FIGExporter() ; break ; #ifdef A_FAIRE case VRenderParams::SVG: exporter = new SVGExporter() ; break ; #endif default: throw std::runtime_error("Sorry, this output format is not handled now. Only EPS and PS are currently supported.") ; } // sets background and black & white options GLfloat viewport[4],clearColor[4],lineWidth,pointSize ; glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor); glGetFloatv(GL_LINE_WIDTH, &lineWidth); glGetFloatv(GL_POINT_SIZE, &pointSize); glGetFloatv(GL_VIEWPORT, viewport); lineWidth /= (float)max(viewport[2] - viewport[0],viewport[3]-viewport[1]) ; // Sets which bounding box to use. if(vparams.isEnabled(VRenderParams::TightenBoundingBox)) exporter->setBoundingBox(parserGL.xmin(),parserGL.ymin(),parserGL.xmax(),parserGL.ymax()) ; else exporter->setBoundingBox(viewport[0],viewport[1],viewport[0]+viewport[2],viewport[1]+viewport[3]) ; exporter->setBlackAndWhite(vparams.isEnabled(VRenderParams::RenderBlackAndWhite)) ; exporter->setClearBackground(vparams.isEnabled(VRenderParams::AddBackground)) ; exporter->setClearColor(clearColor[0],clearColor[1],clearColor[2]) ; exporter->exportToFile(vparams.filename(),primitive_tab,vparams) ; // deletes primitives for(unsigned int i=0;i 10000) throw std::runtime_error("VectorialRender: filename too long.") ; if(_filename != NULL) free(_filename) ; if((_filename = strdup(fn)) == NULL) throw std::runtime_error("could not copy supplied filename. Out of memory ?") ; } void VRenderParams::setOption(VRenderOption opt,bool b) { if(b) _options |= opt ; else _options &= ~opt ; } bool VRenderParams::isEnabled(VRenderOption opt) { return (_options & opt) > 0 ; }