00001
00002
00003
00004
00005
00006 #include <QGLFormat>
00007 #include <QCloseEvent>
00008 #include <QDesktopWidget>
00009 #include <QSplashScreen>
00010 #include <QFileDialog>
00011 #include <QFile>
00012 #include <QFileInfo>
00013 #include <QMessageBox>
00014 #include "vstudio.h"
00015 #include "CSettings.h"
00016 #include "CShaderEditor.h"
00017 #include "VStudioRenderer.h"
00018 #include "CProperties.h"
00019 #include "Volume.h"
00020 #include "Math/TVector2.h"
00021
00022
00023
00024
00025
00026
00027 CConsole * ptrConsole;
00028
00029
00030
00031
00032
00033
00034 VStudio::VStudio(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent,flags)
00035 {
00036 pSplash = NULL;
00037 pConsole = NULL;
00038 pVStudioSettings = NULL;
00039 pRenderer = NULL;
00040 pShaderEditor = NULL;
00041 pProperties = NULL;
00042 pSceneVolume = NULL;
00043 pSceneProgram = NULL;
00044 pSceneVolumeStatistics = NULL;
00045 currentSceneFileName = "";
00046 askedforSave = false;
00047 }
00048
00049
00050 void VStudio::Destroy()
00051 {
00052 delete pSplash;
00053 delete pConsole;
00054 delete pVStudioSettings;
00055 pSceneVolume = NULL;
00056 pSceneProgram = NULL;
00057 pSceneVolumeStatistics = NULL;
00058 }
00059
00060
00061
00062
00063
00064 CreateResult VStudio::Create()
00065 {
00066
00067 QSettings::setPath(QSettings::IniFormat,QSettings::UserScope,"./");
00068 pVStudioSettings = new CSettings("settings.ini",this);
00069
00070
00071 pVStudioSettings->SetGetCreateSettings();
00072 pVStudioSettings->SetGetPropertiesSettings();
00073
00074
00075 pConsole = new CConsole();
00076
00077 ptrConsole = pConsole;
00078
00079
00080 pSplash = new QSplashScreen();
00081 pSplash->setPixmap(QPixmap(pVStudioSettings->value("APPCREATE/splashImage").toString()));
00082
00083 if(pVStudioSettings->value("APPCREATE/splashShow").toBool())
00084 {
00085 pSplash->show();
00086 }
00087
00088 pSplash->showMessage("Checking OpenGL",Qt::AlignLeft,Qt::white);
00089
00090
00091 if(CheckOpenGL())
00092 {
00093 pSplash->showMessage("Setting Up User Interface",Qt::AlignLeft,Qt::black);
00094
00095 if(SetupUI())
00096 {
00097 pSplash->showMessage("Setting up Connections",Qt::AlignLeft,Qt::black);
00098
00099 if(SetupConnections())
00100 {
00101
00102 pSceneProgram = new CGLProgram();
00103 pSceneProgram->SetRenderer(pRenderer);
00104
00105
00106 pMipProgram = new CGLProgram();
00107 pMipProgram->SetRenderer(pRenderer);
00108
00109 CShaderFile vsfile(NULL);
00110 vsfile.load(pVStudioSettings->value("MIP/VERTEX_SHADER").toString());
00111
00112 CShaderFile fsfile(NULL);
00113 fsfile.load(pVStudioSettings->value("MIP/FRAGMENT_SHADER").toString());
00114
00115 uint vid = pMipProgram->CreateShader(VERTEX_SHADER);
00116 uint fid = pMipProgram->CreateShader(FRAGMENT_SHADER);
00117
00118 std::string vSource = vsfile.toPlainText().toStdString();
00119 const char * vcSource = vSource.c_str();
00120 pMipProgram->Compile(vid,&vcSource,1);
00121
00122 std::string fSource = fsfile.toPlainText().toStdString();
00123 const char * fcSource = fSource.c_str();
00124 pMipProgram->Compile(fid,&fcSource,1);
00125
00126 pMipProgram->AttachShader(vid);
00127 pMipProgram->AttachShader(fid);
00128
00129 if(pMipProgram->Link())
00130 {
00131
00132 }
00133
00134
00135
00136 pRenderer->SetLight(pProperties->GetLight());
00137
00138
00139 if(!pVStudioSettings->value("APPCREATE/validatorPath").toString().isNull()){
00140 pShaderEditor->setValidatorPath(pVStudioSettings->value("APPCREATE/validatorPath").toString());
00141 }
00142
00143
00144 if(!pVStudioSettings->value("APPCREATE/editorPath").toStringList().isEmpty()){
00145 QStringList list = pVStudioSettings->value("APPCREATE/editorPath").toStringList();
00146 QString path = list.first();list.removeFirst();
00147 pShaderEditor->setEditor(path,list);
00148 }
00149
00150
00151 QStringList recent = pVStudioSettings->GetRecentFiles();
00152 for(int i = 0; i < recent.size() ; i++){
00153 if(!recent[i].isEmpty()){
00154 if(QFileInfo(recent[i]).exists()){
00155 AddRecent(recent[i]);
00156 }
00157 }
00158 }
00159
00160
00161 QString sceneFileName = pVStudioSettings->value("APPCREATE/sceneAtStartup").toString();
00162 if(!sceneFileName.isEmpty()){
00163 if(QFile::exists(sceneFileName)){
00164 pSplash->showMessage("Opening Startup Scene",Qt::AlignLeft,Qt::black);
00165 OpenScene(sceneFileName);
00166 }
00167 }
00168 pSplash->showMessage("Starting!",Qt::AlignLeft,Qt::black);
00169
00170
00171 if(pVStudioSettings->value("APPCREATE/splashShow").toBool()){
00172 Sleep(pVStudioSettings->value("APPCREATE/splashTime").toInt());
00173 }
00174
00175 pSplash->finish(this);
00176 }
00177 }
00178 }
00179
00180
00181 if(mCreateMessages.empty())
00182 {
00183 return CREATE_SUCCESS;
00184 }
00185 else
00186 {
00187 if(mCreateMessages.find(CREATE_ERROR)!= mCreateMessages.end())
00188 {
00189 return CREATE_ERROR;
00190 }
00191 else
00192 {
00193 return CREATE_WARNING;
00194 }
00195 }
00196 }
00197
00198
00199
00200
00201
00202 bool VStudio::CheckOpenGL()
00203 {
00204
00205 if(!QGLFormat::hasOpenGL())
00206 {
00207 insertCreateMessage(CREATE_ERROR,"System has no Support for OpenGL");
00208 return false;
00209 }
00210
00211
00212 QGLFormat requestFormat(QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba);
00213 requestFormat.setDepthBufferSize(32);
00214
00215
00216 pRenderer = new VStudioRenderer(this,requestFormat,this);
00217
00218 OpenGLInfo glInfo;
00219 if(!pRenderer->GetOpenglInfo(glInfo))
00220 {
00221 insertCreateMessage(CREATE_ERROR,"Some required OpenGL Features are not available");
00222 return false;
00223 }
00224 else
00225 {
00226 return true;
00227 }
00228 }
00229
00230
00231
00232
00233
00234 bool VStudio::SetupUI()
00235 {
00236
00237 ui.setupUi(this);
00238
00239
00240 QHBoxLayout *layoutGL = new QHBoxLayout();
00241 layoutGL->setMargin(5);
00242 layoutGL->addWidget(pRenderer);
00243 pRenderer->setMinimumSize(400,300);
00244 pRenderer->setGeometry(0,0,400,500);
00245 pRenderer->sizeHint();
00246 ui.containerGL->setLayout(layoutGL);
00247
00248
00249 QHBoxLayout *layoutSH = new QHBoxLayout();
00250 layoutSH->setMargin(0);
00251 pShaderEditor = new CShaderEditor(this,this);
00252 layoutSH->addWidget(pShaderEditor);
00253 ui.containerShader->setLayout(layoutSH);
00254
00255
00256 QHBoxLayout *layoutPR = new QHBoxLayout();
00257 layoutPR->setMargin(0);
00258 pProperties = new CProperties(*pVStudioSettings,this);
00259 layoutPR->addWidget(pProperties);
00260 pProperties->setMinimumSize(400,250);
00261 ui.containerProperties->setLayout(layoutPR);
00262
00263
00264 QDesktopWidget *pDesktop = QApplication::desktop();
00265
00266 word applicationWidth = pDesktop->availableGeometry(pDesktop->primaryScreen()).width();
00267 word applicationHeight = pDesktop->availableGeometry(pDesktop->primaryScreen()).height();
00268
00269 this->setGeometry(100,100,applicationWidth-200,applicationHeight-200);
00270 this->updateGeometry();
00271
00272
00273 ui.actionOpen_Recent->setDisabled(true);
00274
00275
00276 this->setWindowTitle("new Scene");
00277
00278 return true;
00279 }
00280
00281
00282
00283
00284 bool VStudio::SetupConnections()
00285 {
00286
00287 if(!connect(pConsole,SIGNAL(LogStatusChange(int,bool)),this,SLOT(LogStatusChange(int,bool)))){
00288 return false;
00289 }
00290 pConsole->SetLogStatus(LOG_OPENGL,pVStudioSettings->value("logOpenGL").toBool());
00291 pConsole->SetLogStatus(LOG_OPENGL_ALL,pVStudioSettings->value("logOpenGLAll").toBool());
00292
00293
00294 if(!connect(pRenderer,SIGNAL(Maximize()),this,SLOT(MaximizeRenderer()))){
00295 return false;
00296 }
00297 }
00298
00299
00300
00301
00302
00303 void VStudio::LogStatusChange(int what,bool tf){
00304 switch(what){
00305 case LOG_OPENGL:
00306 pRenderer->EnableLog(tf);
00307 break;
00308 }
00309 }
00310
00311 void VStudio::MaximizeRenderer()
00312 {
00313 static bool maximized = false;
00314 if(!maximized){
00315 ui.containerShader->setVisible(false);
00316 ui.containerProperties->setVisible(false);
00317 maximized = true;
00318 }else{
00319 ui.containerShader->setVisible(true);
00320 ui.containerProperties->setVisible(true);
00321 maximized = false;
00322 }
00323 }
00324
00325
00326
00327
00328
00329
00330 void VStudio::showEvent(QShowEvent *event)
00331 {
00332 QWidget::showEvent(event);
00333
00334 this->activateWindow();
00335
00336 if(pConsole->windowState() != Qt::WindowMinimized && pVStudioSettings->value("APPCREATE/consoleAtStartup").toBool()){
00337 pConsole->show();
00338 }
00339 }
00340
00341
00342 void VStudio::changeEvent(QEvent *event)
00343 {
00344 switch(event->type()){
00345 case QEvent::WindowStateChange:
00346 if(this->isMinimized()){
00347 pConsole->setWindowState(Qt::WindowMinimized);
00348 }
00349 }
00350 QWidget::changeEvent(event);
00351 }
00352
00353
00354 void VStudio::closeEvent(QCloseEvent *event)
00355 {
00356 if(!currentSceneFileName.isEmpty()){
00357 if(askedforSave){
00358 event->accept();
00359 }else{
00360 if(!AskSave()){
00361 event->ignore();
00362 }else{
00363 SaveApp();
00364 event->accept();
00365 }
00366 }
00367 }else{
00368 SaveApp();
00369 event->accept();
00370 }
00371 }
00372
00373
00374
00375
00376
00377
00378 void VStudio::on_actionExit_triggered()
00379 {
00380 if(!currentSceneFileName.isEmpty()){
00381 if(AskSave()){
00382 askedforSave = true;
00383 SaveApp();
00384 qApp->closeAllWindows();
00385 }
00386 }else{
00387 SaveApp();
00388 qApp->closeAllWindows();
00389 }
00390 }
00391
00392
00393 void VStudio::on_actionVolume_triggered()
00394 {
00395 QString volumeDirectory;
00396
00397 if(pSceneVolume){
00398 volumeDirectory = QFileInfo(pSceneVolume->GetFileName().c_str()).filePath();
00399 }else{
00400 volumeDirectory = "../DATA/VolumeData";
00401 }
00402
00403 QString filename = QFileDialog::getOpenFileName(this,"Import Volume",volumeDirectory,"Supported (*.vol8;*.vol12;*.vol16;*.dat)");
00404 if(!filename.isNull())
00405 {
00406
00407 LoadVolume(filename);
00408 }
00409 }
00410
00411
00412 bool VStudio::AskSave()
00413 {
00414 QMessageBox questionSave("Question","Do you want to save the scene ?",QMessageBox::NoIcon,QMessageBox::Yes|QMessageBox::Default,QMessageBox::No,QMessageBox::Cancel,this);
00415 switch(questionSave.exec())
00416 {
00417 case QMessageBox::Yes :
00418 if(!currentSceneFileName.isEmpty()){
00419 on_actionSave_triggered();
00420 }else{
00421 on_actionSave_As_triggered();
00422 }
00423 return true;
00424
00425 case QMessageBox::No : return true;
00426 case QMessageBox::Cancel : return false;
00427 }
00428 return false;
00429 }
00430
00431
00432 void VStudio::on_actionSave_triggered()
00433 {
00434 if(currentSceneFileName.isEmpty()){
00435 on_actionSave_As_triggered();
00436 }else{
00437 SaveScene(currentSceneFileName);
00438 }
00439 }
00440
00441
00442 void VStudio::on_actionSave_As_triggered()
00443 {
00444 QString saveDirectory = currentSceneFileName.isEmpty() ? "../Data/Scenes" : QFileInfo(currentSceneFileName).filePath();
00445 QString fileName = QFileDialog::getSaveFileName(this,"Save As",saveDirectory,"(*.vst)");
00446 if(!fileName.isNull()){
00447 SaveScene(fileName);
00448 }
00449 }
00450
00451
00452 void VStudio::on_actionOpen_triggered()
00453 {
00454
00455 if(!currentSceneFileName.isEmpty()){
00456 if(!AskSave()){
00457 return;
00458 }
00459 }
00460
00461
00462 QString openDirectory = currentSceneFileName.isEmpty() ? "../Data/Scenes" : QFileInfo(currentSceneFileName).filePath();
00463 QString fileName = QFileDialog::getOpenFileName(this,"Open",openDirectory,"(*.vst)");
00464 if(!fileName.isEmpty())
00465 {
00466 OpenScene(fileName);
00467 }
00468 }
00469
00470
00471 void VStudio::on_actionOpen_Recent_triggered()
00472 {
00473
00474 if(!currentSceneFileName.isEmpty()){
00475 if(!AskSave()){
00476 return;
00477 }
00478 }
00479
00480
00481 QAction *action = qobject_cast<QAction *>(sender());
00482 if(action){
00483 if(QFile().exists(action->data().toString())){
00484 OpenScene(action->data().toString());
00485 }else{
00486 pConsole->Log(QString("Opening Scene: " + action->data().toString() + " failed"),MAIN_THREAD);
00487 }
00488 }
00489 }
00490
00491
00492 void VStudio::on_actionConsole_triggered()
00493 {
00494 pConsole->showNormal();
00495 }
00496
00497
00498 void VStudio::on_actionApply_Vertex_Shader_triggered()
00499 {
00500 pShaderEditor->OpenAndApplyVertex();
00501 }
00502
00503
00504 void VStudio::on_actionApply_Fragment_Shader_triggered()
00505 {
00506 pShaderEditor->OpenAndApplyFragment();
00507 }
00508
00509
00510 void VStudio::on_actionExport_triggered(){}
00511
00512
00513
00514
00515
00516
00517 void VStudio::LoadVolume( QString fileName )
00518 {
00519
00520 TSmartPointer<CVolume> newVolume = new CVolume(fileName.toStdString());
00521
00522 pConsole->Log(QString("Loading Volume: " + fileName),MAIN_THREAD);
00523
00524 if(newVolume->Create(pSceneProgram,
00525 pProperties->renderMode,
00526 pProperties->fboSize,
00527 pProperties->stepSize,
00528 pProperties->maxSamples,
00529 pProperties->applyNoise,
00530 pProperties->minClip,
00531 pProperties->shadowEnable,
00532 pProperties->shadowQuality,
00533 pProperties->shadowTreshold))
00534 {
00535
00536 pSceneVolume = newVolume;
00537
00538
00539 CVolumeStatistics * newVS = new CVolumeStatistics (pSceneVolume->GetVolumeDataInfo());
00540 CVolumeStatistics * oldVS = pSceneVolumeStatistics;
00541 pSceneVolumeStatistics = newVS;
00542
00543
00544 if(oldVS){oldVS = NULL;}
00545
00546
00547 pProperties->SetVolumeStatistics(pSceneVolumeStatistics);
00548
00549
00550 pSceneVolume->AddTransferProperty(pProperties->GetGradientTransfer());
00551 pSceneVolume->AddTransferProperty(pProperties->GetDensityTransfer());
00552
00553
00554 pSceneVolume->SetLight(pProperties->GetLight());
00555
00556
00557 pRenderer->SetVolume(pSceneVolume);
00558
00559 pProperties->Update();
00560 pRenderer->Update();
00561 return;
00562 }
00563
00564
00565 newVolume = NULL;
00566 pProperties->SetActive(false);
00567
00568 pConsole->Log(QString("Loading Volume: " + fileName + "failed"),MAIN_THREAD);
00569 }
00570
00571
00572 void VStudio::OpenScene(QString fileName)
00573 {
00574 currentSceneFileName = fileName;
00575
00576 pConsole->Log(QString("Opening Scene: " + fileName + " success"),MAIN_THREAD);
00577
00578 QSettings::setPath(QSettings::IniFormat,QSettings::UserScope,QFileInfo(fileName).absolutePath());
00579 QSettings openFile(fileName,QSettings::IniFormat);
00580
00581
00582 if(pSceneVolume)
00583 {
00584
00585 pRenderer->SetVolume(NULL);
00586
00587 pSceneVolume = NULL;
00588 }
00589
00590
00591 pProperties->OpenState(openFile);
00592
00593
00594 pShaderEditor->OpenState(openFile);
00595
00596
00597 pRenderer->OpenState(openFile);
00598
00599
00600 AddRecent(QDir(".").relativeFilePath(fileName));
00601
00602
00603 this->setWindowTitle(currentSceneFileName);
00604
00605
00606 LoadVolume(openFile.value("Volume").toString());
00607
00608
00609 if(pSceneVolume)
00610 {
00611 bool readOK = true;
00612 double rotX = openFile.value("VolumeRotX").toDouble(&readOK);
00613 double rotY = openFile.value("VolumeRotY").toDouble(&readOK);
00614
00615 if(readOK)
00616 {
00617 pSceneVolume->SetOrientation(rotX,rotY);
00618 }
00619 }
00620 }
00621
00622
00623 void VStudio::SaveScene(QString fileName)
00624 {
00625 currentSceneFileName = fileName;
00626
00627 pConsole->Log(QString("Saving Scene: " + currentSceneFileName),MAIN_THREAD);
00628
00629 QSettings::setPath(QSettings::IniFormat,QSettings::UserScope,QFileInfo(fileName).absolutePath());
00630 QSettings saveFile(fileName,QSettings::IniFormat);
00631
00632
00633 saveFile.clear();
00634
00635
00636 if(pSceneVolume){
00637 saveFile.setValue("Volume",QDir(".").relativeFilePath(QString().fromStdString(pSceneVolume->GetFileName())));
00638 }
00639
00640
00641 if(pSceneVolume)
00642 {
00643 CVector2f ori = pSceneVolume->GetOrientation();
00644 saveFile.setValue("VolumeRotX",ori.m_X);
00645 saveFile.setValue("VolumeRotY",ori.m_Y);
00646 }
00647
00648
00649 pProperties->SaveState(saveFile);
00650
00651
00652 pShaderEditor->SaveState(saveFile);
00653
00654
00655 pRenderer->SaveState(saveFile);
00656
00657
00658 AddRecent(QDir(".").relativeFilePath(fileName));
00659
00660
00661 this->setWindowTitle(fileName);
00662
00663 }
00664
00665
00666 void VStudio::AddRecent(QString sceneFileName)
00667 {
00668
00669 QMenu *recentMenu;
00670 if(!ui.actionOpen_Recent->menu()){
00671 recentMenu = new QMenu(this);
00672 ui.actionOpen_Recent->setMenu(recentMenu);
00673 }else{
00674 recentMenu = ui.actionOpen_Recent->menu();
00675 }
00676
00677
00678 for(int i = 0 ; i < recentActions.size() ; i++ ){
00679 if(recentActions.at(i)->data().toString().compare(sceneFileName) == 0){
00680 return;
00681 }
00682 }
00683
00684
00685 QAction * newRecentAction = new QAction(sceneFileName,this);
00686 newRecentAction->setData(sceneFileName);
00687 connect(newRecentAction,SIGNAL(triggered()),this,SLOT(on_actionOpen_Recent_triggered()));
00688
00689 if(recentActions.size() < 5){
00690 recentActions.enqueue(newRecentAction);
00691 recentMenu->addAction(newRecentAction);
00692 }else{
00693 if(!recentActions.isEmpty()){
00694 recentMenu->removeAction(recentActions.dequeue());
00695 }
00696 recentActions.enqueue(newRecentAction);
00697 recentMenu->addAction(newRecentAction);
00698 }
00699
00700
00701 ui.actionOpen_Recent->setEnabled(true);
00702 }
00703
00704
00705 void VStudio::SaveApp()
00706 {
00707
00708 QStringList list;
00709 if(recentActions.size()){
00710 for(int i = 0 ; i < recentActions.size() ; i++){
00711 list << recentActions[i]->data().toString();
00712 }
00713 pVStudioSettings->SetRecentFiles(list);
00714 }
00715 }
00716
00717
00718 void VStudio::SaveImage( QImage & img )
00719 {
00720 QString snapPath("../Data/SnapShots");
00721 QString savePath;
00722
00723 if(currentSceneFileName.isEmpty()){
00724 savePath = snapPath;
00725 }else{
00726 QString baseName = QFileInfo(currentSceneFileName).completeBaseName();
00727 savePath = snapPath.append("/").append(baseName);
00728 }
00729
00730 QDir saveDir(snapPath);
00731 if(!saveDir.exists()){
00732 QDir("./").mkpath(savePath);
00733 }
00734
00735 QStringList filters;filters << "*.bmp";
00736 int numImg = saveDir.entryList(filters).count();
00737
00738 savePath.append("/snap").append(QString().setNum(numImg)).append(".bmp");
00739 img.save(savePath);
00740
00741 pConsole->Log(QString("Snapshot saved: " + savePath),MAIN_THREAD);
00742 }
00743
00744
00745 bool VStudio::RenderMIP( bool tf )
00746 {
00747 if(pSceneVolume)
00748 {
00749 if(tf)
00750 {
00751 pShaderEditor->setDisabled(true);
00752 pSceneVolume->SwitchProgram(pMipProgram);
00753 return true;
00754 }
00755 else
00756 {
00757 pShaderEditor->setDisabled(false);
00758 pSceneVolume->SwitchProgram(pSceneProgram);
00759 return true;
00760 }
00761 }
00762
00763 return false;
00764 }
00765
00766 void VStudio::ResetScene(){}
00767
00768
00769
00770