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, QGLViewer::tr("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<PtrPrimitive> 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<primitive_tab.size(); ++i) delete primitive_tab[i] ; if(exporter != NULL) delete exporter ; if(sort_method != NULL) delete sort_method ; } catch(exception& e) { cout << "Render aborted: " << e.what() << endl ; if(exporter != NULL) delete exporter ; if(sort_method != NULL) delete sort_method ; if(feedbackBuffer != NULL) delete[] feedbackBuffer ; throw e ; } }