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