00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 #include "qglviewer.h"
00024 
00025 #ifndef NO_VECTORIAL_RENDER
00026 # if QT_VERSION >= 0x040000
00027 #  include "ui_VRenderInterface.h"
00028 # else
00029 #  include <qcheckbox.h>
00030 #  include <qcombobox.h>
00031 #  include "VRenderInterface.Qt3.h"
00032 # endif
00033 # include "VRender/VRender.h"
00034 #endif
00035 
00036 #if QT_VERSION >= 0x040000
00037 # include "ui_ImageInterface.h"
00038 #else
00039 # include <qspinbox.h>
00040 # include <qcheckbox.h>
00041 # include "ImageInterface.Qt3.h"
00042 #endif
00043 
00044 
00045 #if QT_VERSION < 0x040000
00046 # include <qimage.h>
00047 #else
00048 # include <QImageWriter>
00049 #endif
00050 
00051 #include <qfileinfo.h>
00052 #include <qfiledialog.h>
00053 #include <qmessagebox.h>
00054 #include <qapplication.h>
00055 #include <qmap.h>
00056 #include <qinputdialog.h>
00057 #include <qprogressdialog.h>
00058 #include <qcursor.h>
00059 
00060 using namespace std;
00061 
00063 
00064 static QString formats;
00065 
00066 static QMap<QString, QString> Qtformat;
00067 
00068 static QMap<QString, QString> FDFormatString;
00069 
00070 static QMap<QString, QString> extension;
00071 
00072 
00074 void QGLViewer::setSnapshotFileName(const QString& name)
00075 {
00076 #if QT_VERSION >= 0x040000
00077   snapshotFileName_ = QFileInfo(name).absoluteFilePath();
00078 #else
00079   snapshotFileName_ = QFileInfo(name).absFilePath();
00080 #endif
00081 }
00082 
00083 #ifndef DOXYGEN
00084 const QString& QGLViewer::snapshotFilename() const
00085 {
00086   qWarning("snapshotFilename is deprecated. Use snapshotFileName() (uppercase N) instead.");
00087   return snapshotFileName();
00088 }
00089 #endif
00090 
00091 
00097 bool QGLViewer::openSnapshotFormatDialog()
00098 {
00099   bool ok = false;
00100 #if QT_VERSION >= 0x040000
00101   QStringList list = formats.split(";;", QString::SkipEmptyParts);
00102   int current = list.indexOf(FDFormatString[snapshotFormat()]);
00103   QString format = QInputDialog::getItem(this, "Snapshot format", "Select a snapshot format", list, current, false, &ok);
00104 #else
00105   QStringList list = QStringList::split(";;", formats);
00106   int current = list.findIndex(FDFormatString[snapshotFormat()]);
00107   QString format = QInputDialog::getItem("Snapshot format", "Select a snapshot format", list, current, false, &ok, this);
00108 #endif
00109   if (ok)
00110     setSnapshotFormat(Qtformat[format]);
00111   return ok;
00112 }
00113 
00114 
00115 
00116 
00117 void QGLViewer::initializeSnapshotFormats()
00118 {
00119 #if QT_VERSION >= 0x040000
00120   QList<QByteArray> list = QImageWriter::supportedImageFormats();
00121   QStringList formatList;
00122   for (int i=0; i < list.size(); ++i)
00123     formatList << QString(list.at(i).toUpper());
00124 #else
00125   QStringList formatList = QImage::outputFormatList();
00126 #endif
00127   
00128   
00129   
00130   
00131 
00132 #ifndef NO_VECTORIAL_RENDER
00133   
00134   formatList += "EPS";
00135   formatList += "PS";
00136   formatList += "XFIG";
00137 #endif
00138 
00139   
00140   
00141   QStringList QtText, MenuText, Ext;
00142   QtText += "JPEG";     MenuText += "JPEG (*.jpg)";             Ext += "jpg";
00143   QtText += "PNG";      MenuText += "PNG (*.png)";              Ext += "png";
00144   QtText += "EPS";      MenuText += "Encapsulated Postscript (*.eps)";  Ext += "eps";
00145   QtText += "PS";       MenuText += "Postscript (*.ps)";        Ext += "ps";
00146   QtText += "PPM";      MenuText += "24bit RGB Bitmap (*.ppm)"; Ext += "ppm";
00147   QtText += "BMP";      MenuText += "Windows Bitmap (*.bmp)";   Ext += "bmp";
00148   QtText += "XFIG";     MenuText += "XFig (*.fig)";             Ext += "fig";
00149 
00150 #if QT_VERSION < 0x030000
00151   QStringList::Iterator itText = QtText.begin();
00152   QStringList::Iterator itMenu = MenuText.begin();
00153   QStringList::Iterator itExt  = Ext.begin();
00154 #else
00155   QStringList::iterator itText = QtText.begin();
00156   QStringList::iterator itMenu = MenuText.begin();
00157   QStringList::iterator itExt  = Ext.begin();
00158 #endif
00159   while (itText != QtText.end())
00160     {
00161       
00162       if (formatList.contains((*itText)))
00163         {
00164           
00165           if (formats.isEmpty())
00166             setSnapshotFormat(*itText);
00167           else
00168             formats += ";;";
00169           formats += (*itMenu);
00170           Qtformat[(*itMenu)]  = (*itText);
00171           FDFormatString[(*itText)]  = (*itMenu);
00172           extension[(*itText)] = (*itExt);
00173         }
00174       
00175       itText++;
00176       itMenu++;
00177       itExt++;
00178     }
00179 }
00180 
00181 
00182 static bool checkFileName(QString& fileName, QWidget* widget, const QString& snapshotFormat)
00183 {
00184   if (fileName.isEmpty())
00185     return false;
00186 
00187   
00188   QFileInfo info(fileName);
00189 
00190 #if QT_VERSION >= 0x040000
00191   if (info.suffix().isEmpty())
00192 #else
00193   if (info.extension(false).isEmpty())
00194 #endif
00195     {
00196       
00197       if (fileName.right(1) != ".")
00198         fileName += ".";
00199       fileName += extension[snapshotFormat];
00200       info.setFile(fileName);
00201     }
00202 #if QT_VERSION >= 0x040000
00203   else if (info.suffix() != extension[snapshotFormat])
00204 #else
00205   else if (info.extension(false) != extension[snapshotFormat])
00206 #endif
00207     {
00208       
00209 #if QT_VERSION >= 0x040000
00210       QString modifiedName = info.absolutePath() + '/' + info.baseName() + "." + extension[snapshotFormat];
00211 #else
00212 # if QT_VERSION >= 0x030000
00213       QString modifiedName = info.dirPath() + '/' + info.baseName(true) + '.' + extension[snapshotFormat];
00214 # else
00215       QString modifiedName = info.dirPath() + '/' + info.baseName() + '.' + extension[snapshotFormat];
00216 # endif
00217 #endif
00218       QFileInfo modifInfo(modifiedName);
00219       int i=(QMessageBox::warning(widget,"Wrong extension",
00220                                   info.fileName()+" has a wrong extension.\nSave as "+modifInfo.fileName()+" instead ?",
00221                                   QMessageBox::Yes,
00222                                   QMessageBox::No,
00223                                   QMessageBox::Cancel));
00224       if (i==QMessageBox::Cancel)
00225         return false;
00226 
00227       if (i==QMessageBox::Yes)
00228         {
00229           fileName = modifiedName;
00230           info.setFile(fileName);
00231         }
00232     }
00233 
00234   return true;
00235 }
00236 
00237 #ifndef NO_VECTORIAL_RENDER
00238 
00239 void drawVectorial(void* param)
00240 {
00241   ( (QGLViewer*) param )->drawVectorial();
00242 }
00243 
00244 #ifndef DOXYGEN
00245 class ProgressDialog
00246 {
00247 public:
00248   static void showProgressDialog(QGLWidget* parent);
00249   static void updateProgress(float progress, const QString& stepString);
00250   static void hideProgressDialog();
00251 
00252 private:
00253   static QProgressDialog* progressDialog;
00254 };
00255 
00256 QProgressDialog* ProgressDialog::progressDialog = NULL;
00257 
00258 void ProgressDialog::showProgressDialog(QGLWidget* parent)
00259 {
00260   progressDialog = new QProgressDialog(parent);
00261 #if QT_VERSION >= 0x040000
00262   progressDialog->setWindowTitle("Image rendering progress");
00263 #else
00264   progressDialog->setCaption("Image rendering progress");
00265 #endif
00266   progressDialog->setMinimumSize(300, 40);
00267   progressDialog->setCancelButton(NULL);
00268   progressDialog->show();
00269 }
00270 
00271 void ProgressDialog::updateProgress(float progress, const QString& stepString)
00272 {
00273 #if QT_VERSION >= 0x040000
00274   progressDialog->setValue(int(progress*100));
00275 #else
00276   progressDialog->setProgress(int(progress*100));
00277 #endif
00278   QString message(stepString);
00279   if (message.length() > 33)
00280     message = message.left(17) + "..." + message.right(12);
00281   progressDialog->setLabelText(message);
00282   progressDialog->update();
00283   qApp->processEvents();
00284 }
00285 
00286 void ProgressDialog::hideProgressDialog()
00287 {
00288   progressDialog->close();
00289   delete progressDialog;
00290   progressDialog = NULL;
00291 }
00292 
00293 #if QT_VERSION >= 0x040000
00294 class VRenderInterface: public QDialog, public Ui::VRenderInterface
00295 {
00296  public: VRenderInterface(QWidget *parent) : QDialog(parent) { setupUi(this); }
00297 };
00298 #endif
00299 
00300 #endif
00301 
00302 
00303 
00304 static int saveVectorialSnapshot(const QString& fileName, QGLWidget* widget, const QString& snapshotFormat)
00305 {
00306   static VRenderInterface* VRinterface = NULL;
00307 
00308   if (!VRinterface)
00309 #if QT_VERSION >= 0x030000
00310     VRinterface = new VRenderInterface(widget);
00311 #else
00312     VRinterface = new VRenderInterface(widget, "", true); 
00313 #endif
00314 
00315   
00316   
00317   if (snapshotFormat == "XFIG")
00318     {
00319       VRinterface->tightenBBox->setEnabled(false);
00320       VRinterface->colorBackground->setEnabled(false);
00321     }
00322   else
00323     {
00324       VRinterface->tightenBBox->setEnabled(true);
00325       VRinterface->colorBackground->setEnabled(true);
00326     }
00327 
00328   if (VRinterface->exec() == QDialog::Rejected)
00329     return -1;
00330 
00331   vrender::VRenderParams vparams;
00332   vparams.setFilename(fileName);
00333 
00334   if (snapshotFormat == "EPS")  vparams.setFormat(vrender::VRenderParams::EPS);
00335   if (snapshotFormat == "PS")   vparams.setFormat(vrender::VRenderParams::PS);
00336   if (snapshotFormat == "XFIG") vparams.setFormat(vrender::VRenderParams::XFIG);
00337 
00338   vparams.setOption(vrender::VRenderParams::CullHiddenFaces, !(VRinterface->includeHidden->isChecked()));
00339   vparams.setOption(vrender::VRenderParams::OptimizeBackFaceCulling, VRinterface->cullBackFaces->isChecked());
00340   vparams.setOption(vrender::VRenderParams::RenderBlackAndWhite, VRinterface->blackAndWhite->isChecked());
00341   vparams.setOption(vrender::VRenderParams::AddBackground, VRinterface->colorBackground->isChecked());
00342   vparams.setOption(vrender::VRenderParams::TightenBoundingBox, VRinterface->tightenBBox->isChecked());
00343 
00344 #if QT_VERSION >= 0x040000
00345   switch (VRinterface->sortMethod->currentIndex())
00346 #else
00347   switch (VRinterface->sortMethod->currentItem())
00348 #endif
00349     {
00350     case 0: vparams.setSortMethod(vrender::VRenderParams::NoSorting);           break;
00351     case 1: vparams.setSortMethod(vrender::VRenderParams::BSPSort);             break;
00352     case 2: vparams.setSortMethod(vrender::VRenderParams::TopologicalSort);     break;
00353     case 3: vparams.setSortMethod(vrender::VRenderParams::AdvancedTopologicalSort);     break;
00354     default:
00355       qWarning("VRenderInterface::saveVectorialSnapshot: Unknown SortMethod");
00356     }
00357 
00358   vparams.setProgressFunction(&ProgressDialog::updateProgress);
00359   ProgressDialog::showProgressDialog(widget);
00360   widget->makeCurrent();
00361   widget->raise();
00362   vrender::VectorialRender(drawVectorial, (void*) widget, vparams);
00363   ProgressDialog::hideProgressDialog();
00364 #if QT_VERSION < 0x030000
00365   widget->setCursor(Qt::arrowCursor);
00366 #else
00367   widget->setCursor(QCursor(Qt::ArrowCursor));
00368 #endif
00369 
00370   
00371   return 0;
00372 }
00373 #endif // NO_VECTORIAL_RENDER
00374 
00375 
00376 #if QT_VERSION >= 0x040000
00377 class ImageInterface: public QDialog, public Ui::ImageInterface
00378 {
00379  public: ImageInterface(QWidget *parent) : QDialog(parent) { setupUi(this); }
00380 };
00381 #endif
00382 
00383 
00384 
00385 
00386 bool QGLViewer::saveImageSnapshot(const QString& fileName)
00387 {
00388   static ImageInterface* imageInterface = NULL;
00389 
00390   if (!imageInterface)
00391 #if QT_VERSION >= 0x030000
00392     imageInterface = new ImageInterface(this);
00393 #else
00394     imageInterface = new ImageInterface(this, "", true);  
00395 #endif
00396 
00397   
00398   if ((imageInterface->imgWidth->value() == 1) && (imageInterface->imgHeight->value() == 1))
00399     {
00400       imageInterface->imgWidth->setValue(width());
00401       imageInterface->imgHeight->setValue(height());
00402     }
00403 
00404   imageInterface->imgQuality->setValue(snapshotQuality());
00405 
00406   if (imageInterface->exec() == QDialog::Rejected)
00407     return true;
00408 
00409   
00410   qApp->processEvents();
00411   
00412   setSnapshotQuality(imageInterface->imgQuality->value());
00413   
00414   QColor previousBGColor = backgroundColor();
00415   if (imageInterface->whiteBackground->isChecked())
00416     setBackgroundColor(Qt::white);
00417 
00418   QSize finalSize(imageInterface->imgWidth->value(), imageInterface->imgHeight->value());
00419 
00420   double oversampling = imageInterface->oversampling->value();
00421   QSize subSize(int(this->width()/oversampling), int(this->height()/oversampling));
00422 
00423   double aspectRatio = width() / static_cast<double>(height());
00424   double newAspectRatio = finalSize.width() / static_cast<double>(finalSize.height());
00425 
00426   double zNear = camera()->zNear();
00427   double zFar = camera()->zFar();
00428 
00429   double xMin, yMin;
00430   bool expand = imageInterface->expandFrustum->isChecked();
00431   if (camera()->type() == qglviewer::Camera::PERSPECTIVE)
00432     if ((expand && (newAspectRatio>aspectRatio)) || (!expand && (newAspectRatio<aspectRatio)))
00433       {
00434         yMin = zNear * tan(camera()->fieldOfView() / 2.0);
00435         xMin = newAspectRatio * yMin;
00436       }
00437     else
00438       {
00439         xMin = zNear * tan(camera()->fieldOfView() / 2.0) * aspectRatio;
00440         yMin = xMin / newAspectRatio;
00441       }
00442   else
00443     {
00444       camera()->getOrthoWidthHeight(xMin, yMin);
00445       if ((expand && (newAspectRatio>aspectRatio)) || (!expand && (newAspectRatio<aspectRatio)))
00446         xMin = newAspectRatio * yMin;
00447       else
00448         yMin = xMin / newAspectRatio;
00449     }
00450   
00451 #if QT_VERSION >= 0x040000
00452   QImage image(finalSize.width(), finalSize.height(), QImage::Format_ARGB32);
00453 #else
00454   QImage image(finalSize.width(), finalSize.height(), 32);
00455 #endif
00456 
00457   if (image.isNull())
00458     {
00459       QMessageBox::warning(this, "Image saving error",
00460                            "Unable to create resulting image",
00461                            QMessageBox::Ok, QMessageBox::NoButton);
00462       return false;
00463     }
00464 
00465   
00466   
00467 
00468   double scaleX = subSize.width() / static_cast<double>(finalSize.width());
00469   double scaleY = subSize.height() / static_cast<double>(finalSize.height());
00470 
00471   double deltaX = 2.0 * xMin * scaleX;
00472   double deltaY = 2.0 * yMin * scaleY;
00473 
00474   int nbX = finalSize.width() / subSize.width();
00475   int nbY = finalSize.height() / subSize.height();
00476 
00477   
00478   if (nbX * subSize.width() < finalSize.width())
00479     nbX++;
00480   if (nbY * subSize.height() < finalSize.height())
00481     nbY++;
00482 
00483   makeCurrent();
00484 
00485   
00486   
00487   tileRegion_ = new TileRegion();
00488   double tileXMin, tileWidth, tileYMin, tileHeight;
00489   if ((expand && (newAspectRatio>aspectRatio)) || (!expand && (newAspectRatio<aspectRatio)))
00490     {
00491       double tileTotalWidth = newAspectRatio * height();
00492       tileXMin = (width() - tileTotalWidth) / 2.0;
00493       tileWidth = tileTotalWidth * scaleX;
00494       tileYMin = 0.0;
00495       tileHeight = height() * scaleY;
00496       tileRegion_->textScale = 1.0 / scaleY;
00497     }
00498   else
00499     {
00500       double tileTotalHeight = width() / newAspectRatio;
00501       tileYMin = (height() - tileTotalHeight) / 2.0;
00502       tileHeight = tileTotalHeight * scaleY;
00503       tileXMin = 0.0;
00504       tileWidth = width() * scaleX;
00505       tileRegion_->textScale = 1.0 / scaleX;
00506     }
00507 
00508   int count=0;
00509   for (int i=0; i<nbX; i++)
00510     for (int j=0; j<nbY; j++)
00511       {
00512         preDraw();
00513 
00514         
00515         glMatrixMode(GL_PROJECTION);
00516         glLoadIdentity();
00517         if (camera()->type() == qglviewer::Camera::PERSPECTIVE)
00518           glFrustum(-xMin + i*deltaX, -xMin + (i+1)*deltaX, yMin - (j+1)*deltaY, yMin - j*deltaY, zNear, zFar);
00519         else
00520           glOrtho(-xMin + i*deltaX, -xMin + (i+1)*deltaX, yMin - (j+1)*deltaY, yMin - j*deltaY, zNear, zFar);
00521         glMatrixMode(GL_MODELVIEW);
00522 
00523         tileRegion_->xMin = tileXMin + i * tileWidth;
00524         tileRegion_->xMax = tileXMin + (i+1) * tileWidth;
00525         tileRegion_->yMin = tileYMin + j * tileHeight;
00526         tileRegion_->yMax = tileYMin + (j+1) * tileHeight;
00527 
00528         draw();
00529         postDraw();
00530 
00531         
00532         
00533 
00534         QImage snapshot = grabFrameBuffer(true);
00535 
00536         
00537         
00538         
00539         
00540 
00541 #if QT_VERSION >= 0x040000
00542         QImage subImage = snapshot.scaled(subSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
00543 #else
00544 # if QT_VERSION >= 0x030000
00545         QImage subImage = snapshot.scale(subSize, QImage::ScaleFree);
00546 # else
00547         QImage subImage = snapshot.smoothScale(subSize.width(), subSize.height());
00548 # endif
00549 #endif
00550 
00551         
00552         for (int ii=0; ii<subSize.width(); ii++)
00553           {
00554             int fi = i*subSize.width() + ii;
00555             if (fi == image.width())
00556               break;
00557             for (int jj=0; jj<subSize.height(); jj++)
00558               {
00559                 int fj = j*subSize.height() + jj;
00560                 if (fj == image.height())
00561                   break;
00562                 image.setPixel(fi, fj, subImage.pixel(ii,jj));
00563               }
00564           }
00565         count++;
00566       }
00567   
00568 #if QT_VERSION >= 0x040000
00569   bool saveOK = image.save(fileName, snapshotFormat().toLatin1().constData(), snapshotQuality());
00570 #else
00571   bool saveOK = image.save(fileName, snapshotFormat(), snapshotQuality());
00572 #endif
00573 
00574   
00575 
00576   
00577   
00578   
00579   
00580   
00581 
00582   delete tileRegion_;
00583   tileRegion_ = NULL;
00584 
00585   if (imageInterface->whiteBackground->isChecked())
00586     setBackgroundColor(previousBGColor);
00587 
00588   return saveOK;
00589 }
00590 
00591 
00641 void QGLViewer::saveSnapshot(bool automatic, bool overwrite)
00642 {
00643   
00644   if (snapshotFileName().isEmpty() || !automatic)
00645     {
00646       QString fileName;
00647 #if QT_VERSION < 0x030000
00648       if (openSnapshotFormatDialog())
00649         fileName = QFileDialog::getSaveFileName(snapshotFileName(), FDFormatString[snapshotFormat()]+";;All files (*.*)", this, "Save dialog");
00650       else
00651         return;
00652 #else
00653       QString selectedFormat = FDFormatString[snapshotFormat()];
00654 # if QT_VERSION >= 0x040000
00655       fileName = QFileDialog::getSaveFileName(this, "Choose a file name to save under", snapshotFileName(), formats, &selectedFormat,
00656                                               overwrite?QFileDialog::DontConfirmOverwrite:QFlag(0));
00657 # else
00658       fileName = QFileDialog::getSaveFileName(snapshotFileName(), formats, this,
00659                                               "Save Snapshot dialog", "Choose a file name to save under", &selectedFormat);
00660 # endif
00661       setSnapshotFormat(Qtformat[selectedFormat]);
00662 #endif
00663 
00664       if (checkFileName(fileName, this, snapshotFormat()))
00665         setSnapshotFileName(fileName);
00666       else
00667         return;
00668     }
00669 
00670   QFileInfo fileInfo(snapshotFileName());
00671 
00672   if ((automatic) && (snapshotCounter() >= 0))
00673     {
00674       
00675       const QString baseName = fileInfo.baseName();
00676       QString count;
00677       count.sprintf("%.04d", snapshotCounter_++);
00678       QString suffix;
00679 #if QT_VERSION >= 0x040000
00680       suffix = fileInfo.suffix();
00681       if (suffix.isEmpty())
00682         suffix = extension[snapshotFormat()];
00683       fileInfo.setFile(fileInfo.absolutePath()+ '/' + baseName + '-' + count + '.' + suffix);
00684 #else      
00685       suffix = fileInfo.extension();
00686       if (suffix.isEmpty())
00687         suffix = extension[snapshotFormat()];
00688       fileInfo.setFile(fileInfo.dirPath()+ '/' + baseName + '-' + count + '.' + suffix);
00689 #endif
00690 
00691       if (!overwrite)
00692         while (fileInfo.exists())
00693           {
00694             count.sprintf("%.04d", snapshotCounter_++);
00695 #if QT_VERSION >= 0x040000
00696             fileInfo.setFile(fileInfo.absolutePath() + '/' +baseName + '-' + count + '.' + fileInfo.suffix());
00697 #else
00698             fileInfo.setFile(fileInfo.dirPath() + '/' + baseName + '-' + count + '.' + fileInfo.extension());
00699 #endif
00700           }
00701     }
00702 
00703 #if QT_VERSION < 0x040000
00704   if ((fileInfo.exists()) && (!overwrite) &&
00705       (QMessageBox::warning(this,"Overwrite file ?",
00706                             "File "+fileInfo.fileName()+" already exists.\nOverwrite ?",
00707                             QMessageBox::Yes,
00708                             QMessageBox::Cancel) == QMessageBox::Cancel))
00709       return;
00710 #endif
00711   
00712   bool saveOK;
00713 #ifndef NO_VECTORIAL_RENDER
00714   if ( (snapshotFormat() == "EPS") || (snapshotFormat() == "PS") || (snapshotFormat() == "XFIG") )
00715       
00716       saveOK = (saveVectorialSnapshot(fileInfo.filePath(), this, snapshotFormat()) <= 0);
00717   else
00718 #endif
00719     if (automatic)
00720         {
00721       QImage snapshot = frameBufferSnapshot();
00722 #if QT_VERSION >= 0x040000
00723     saveOK = snapshot.save(fileInfo.filePath(), snapshotFormat().toLatin1().constData(), snapshotQuality());
00724 #else
00725     saveOK = snapshot.save(fileInfo.filePath(), snapshotFormat(), snapshotQuality());
00726 #endif
00727         }
00728         else
00729           saveOK = saveImageSnapshot(fileInfo.filePath());
00730 
00731   if (!saveOK)
00732     QMessageBox::warning(this, "Snapshot problem", "Unable to save snapshot in\n"+fileInfo.filePath());
00733 }
00734 
00735 QImage QGLViewer::frameBufferSnapshot()
00736 {
00737       
00738       makeCurrent();
00739       raise();
00740       
00741       
00742       
00743       
00744       return grabFrameBuffer(true);
00745 }
00746 
00758 void QGLViewer::saveSnapshot(const QString& fileName, bool overwrite)
00759 {
00760   const QString previousName = snapshotFileName();
00761   const int previousCounter = snapshotCounter();
00762   setSnapshotFileName(fileName);
00763   setSnapshotCounter(-1);
00764   saveSnapshot(true, overwrite);
00765   setSnapshotFileName(previousName);
00766   setSnapshotCounter(previousCounter);
00767 }
00768 
00773 void QGLViewer::snapshotToClipboard()
00774 {
00775         QClipboard *cb = QApplication::clipboard();
00776         cb->setImage(frameBufferSnapshot()); 
00777 }
00778 
00779 #if QT_VERSION < 0x030000
00780 
00781 
00782 QImage QGLViewer::grabFrameBuffer(bool withAlpha)
00783 {
00784   makeCurrent();
00785   QImage res;
00786   int w = width();
00787   int h = height();
00788   if (format().rgba())
00789   {
00790         res = QImage(w, h, 32);
00791         glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, res.bits());
00792         if (QImage::systemByteOrder() == QImage::BigEndian)
00793         {
00794           
00795           uint *p = (uint*)res.bits();
00796           uint *end = p + w*h;
00797           if (withAlpha && format().alpha())
00798           {
00799                 while (p < end)
00800                 {
00801                   uint a = *p << 24;
00802                   *p = (*p >> 8) | a;
00803                   p++;
00804                 }
00805           }
00806           else
00807           {
00808                 while (p < end)
00809                   *p++ >>= 8;
00810           }
00811         }
00812         else
00813         {
00814           
00815           res = res.swapRGB();
00816         }
00817         res.setAlphaBuffer(withAlpha && format().alpha());
00818   }
00819   else
00820   {
00821 #if defined (Q_OS_WIN) || defined (Q_WS_WIN)
00822         res = QImage(w, h, 8);
00823         glReadPixels(0, 0, w, h, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, res.bits());
00824         
00825         
00826         
00827         
00828         
00829         
00830         
00831         
00832 #endif
00833   }
00834 
00835   return res.mirror();
00836 }
00837 
00838 #endif // QT_VERSION < 0x030000