Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifdef WIN32
00046 # include <windows.h>
00047 #endif
00048
00049 #ifdef __APPLE__
00050 # include <OpenGL/gl.h>
00051 #else
00052 # include <GL/gl.h>
00053 #endif
00054
00055 #include <stdio.h>
00056 #include <vector>
00057 #include <stdlib.h>
00058 #include <string.h>
00059
00060 #include "VRender.h"
00061 #include "ParserGL.h"
00062 #include "Exporter.h"
00063 #include "SortMethod.h"
00064 #include "Optimizer.h"
00065
00066 using namespace vrender ;
00067 using namespace std ;
00068
00069 void vrender::VectorialRender(RenderCB render_callback, void *callback_params, VRenderParams& vparams)
00070 {
00071 GLfloat *feedbackBuffer = NULL ;
00072 SortMethod *sort_method = NULL ;
00073 Exporter *exporter = NULL ;
00074
00075 try
00076 {
00077 GLint returned = -1 ;
00078
00079 vparams.error() = 0 ;
00080
00081 int nb_renders = 0 ;
00082
00083 vparams.progress(0.0, QGLViewer::tr("Rendering...")) ;
00084
00085 while(returned < 0)
00086 {
00087 if(feedbackBuffer != NULL)
00088 delete[] feedbackBuffer ;
00089
00090 feedbackBuffer = new GLfloat[vparams.size()] ;
00091
00092 if(feedbackBuffer == NULL)
00093 throw std::runtime_error("Out of memory during feedback buffer allocation.") ;
00094
00095 glFeedbackBuffer(vparams.size(), GL_3D_COLOR, feedbackBuffer);
00096 glRenderMode(GL_FEEDBACK);
00097 render_callback(callback_params);
00098 returned = glRenderMode(GL_RENDER);
00099
00100 nb_renders++ ;
00101
00102 if(returned < 0)
00103 vparams.size() *= 2 ;
00104 }
00105
00106 #ifdef A_VOIR
00107 if(SortMethod != EPS_DONT_SORT)
00108 {
00109 GLint depth_bits ;
00110 glGetIntegerv(GL_DEPTH_BITS, &depth_bits) ;
00111
00112 EGALITY_EPS = 2.0/(1 << depth_bits) ;
00113 LINE_EGALITY_EPS = 2.0/(1 << depth_bits) ;
00114 }
00115 #endif
00116 if (returned > vparams.size())
00117 vparams.size() = returned;
00118 #ifdef _VRENDER_DEBUG
00119 cout << "Size = " << vparams.size() << ", returned=" << returned << endl ;
00120 #endif
00121
00122
00123
00124
00125 vector<PtrPrimitive> primitive_tab ;
00126
00127 ParserGL parserGL ;
00128 parserGL.parseFeedbackBuffer(feedbackBuffer,returned,primitive_tab,vparams) ;
00129
00130 if(feedbackBuffer != NULL)
00131 {
00132 delete[] feedbackBuffer ;
00133 feedbackBuffer = NULL ;
00134 }
00135
00136 if(vparams.isEnabled(VRenderParams::OptimizeBackFaceCulling))
00137 {
00138 BackFaceCullingOptimizer bfopt ;
00139 bfopt.optimize(primitive_tab,vparams) ;
00140 }
00141
00142
00143
00144 switch(vparams.sortMethod())
00145 {
00146 case VRenderParams::AdvancedTopologicalSort:
00147 case VRenderParams::TopologicalSort: {
00148 TopologicalSortMethod *tsm = new TopologicalSortMethod() ;
00149 tsm->setBreakCycles(vparams.sortMethod() == VRenderParams::AdvancedTopologicalSort) ;
00150 sort_method = tsm ;
00151 }
00152 break ;
00153
00154 case VRenderParams::BSPSort: sort_method = new BSPSortMethod() ;
00155 break ;
00156
00157 case VRenderParams::NoSorting: sort_method = new DontSortMethod() ;
00158 break ;
00159 default:
00160 throw std::runtime_error("Unknown sorting method.") ;
00161 }
00162
00163 sort_method->sortPrimitives(primitive_tab,vparams) ;
00164
00165
00166
00167 if(vparams.isEnabled(VRenderParams::CullHiddenFaces))
00168 {
00169 VisibilityOptimizer vopt ;
00170 vopt.optimize(primitive_tab,vparams) ;
00171 }
00172
00173 #ifdef A_FAIRE
00174 if(vparams.isEnabled(VRenderParams::OptimizePrimitiveSplit))
00175 {
00176 PrimitiveSplitOptimizer psopt ;
00177 psopt.optimize(primitive_tab) ;
00178 }
00179 #endif
00180
00181
00182 switch(vparams.format())
00183 {
00184 case VRenderParams::EPS: exporter = new EPSExporter() ;
00185 break ;
00186 case VRenderParams::PS: exporter = new PSExporter() ;
00187 break ;
00188 case VRenderParams::XFIG:exporter = new FIGExporter() ;
00189 break ;
00190 #ifdef A_FAIRE
00191 case VRenderParams::SVG: exporter = new SVGExporter() ;
00192 break ;
00193 #endif
00194 default:
00195 throw std::runtime_error("Sorry, this output format is not handled now. Only EPS and PS are currently supported.") ;
00196 }
00197
00198
00199
00200 GLfloat viewport[4],clearColor[4],lineWidth,pointSize ;
00201
00202 glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
00203 glGetFloatv(GL_LINE_WIDTH, &lineWidth);
00204 glGetFloatv(GL_POINT_SIZE, &pointSize);
00205 glGetFloatv(GL_VIEWPORT, viewport);
00206
00207 lineWidth /= (float)max(viewport[2] - viewport[0],viewport[3]-viewport[1]) ;
00208
00209
00210
00211 if(vparams.isEnabled(VRenderParams::TightenBoundingBox))
00212 exporter->setBoundingBox(parserGL.xmin(),parserGL.ymin(),parserGL.xmax(),parserGL.ymax()) ;
00213 else
00214 exporter->setBoundingBox(viewport[0],viewport[1],viewport[0]+viewport[2],viewport[1]+viewport[3]) ;
00215
00216 exporter->setBlackAndWhite(vparams.isEnabled(VRenderParams::RenderBlackAndWhite)) ;
00217 exporter->setClearBackground(vparams.isEnabled(VRenderParams::AddBackground)) ;
00218 exporter->setClearColor(clearColor[0],clearColor[1],clearColor[2]) ;
00219
00220 exporter->exportToFile(vparams.filename(),primitive_tab,vparams) ;
00221
00222
00223
00224 for(unsigned int i=0;i<primitive_tab.size();++i)
00225 delete primitive_tab[i] ;
00226
00227 if(exporter != NULL) delete exporter ;
00228 if(sort_method != NULL) delete sort_method ;
00229 }
00230 catch(exception& e)
00231 {
00232 cout << "Render aborted: " << e.what() << endl ;
00233
00234 if(exporter != NULL) delete exporter ;
00235 if(sort_method != NULL) delete sort_method ;
00236 if(feedbackBuffer != NULL) delete[] feedbackBuffer ;
00237
00238 throw e ;
00239 }
00240 }
00241
00242 VRenderParams::VRenderParams()
00243 {
00244 _options = 0 ;
00245 _format = EPS ;
00246 _filename = "" ;
00247 _progress_function = NULL ;
00248 _sortMethod = BSPSort ;
00249 }
00250
00251 VRenderParams::~VRenderParams()
00252 {}
00253
00254
00255 void VRenderParams::progress(float f, const QString& progress_string)
00256 {
00257 _progress_function(f,progress_string) ;
00258 }
00259
00260 void VRenderParams::setFilename(const QString& filename)
00261 {
00262 _filename = filename;
00263 }
00264
00265 void VRenderParams::setOption(VRenderOption opt,bool b)
00266 {
00267 if(b)
00268 _options |= opt ;
00269 else
00270 _options &= ~opt ;
00271 }
00272
00273 bool VRenderParams::isEnabled(VRenderOption opt)
00274 {
00275 return (_options & opt) > 0 ;
00276 }