00001
00002
00003
00004
00005
00006 #include <QMenu>
00007 #include <QContextMenuEvent>
00008 #include <QApplication>
00009 #include <QColorDialog>
00010
00011 #include "glew.h"
00012 #include "gl/glu.h"
00013 #pragma comment(lib,"OpenGL32.lib")
00014 #pragma comment(lib,"glu32.lib")
00015 #pragma comment(lib,"glew32.lib")
00016
00017 #include "VStudioRenderer.h"
00018 #include "vstudio.h"
00019
00020
00021
00022
00023
00024
00025 VStudioRenderer::VStudioRenderer(VStudio * const control,QGLFormat & requestFormat,QWidget *parent):CGLSurface(requestFormat,parent),pControl(control)
00026 {
00027 bDoLog = false;
00028 oldVolume = NULL;
00029 pRenderVolume = NULL;
00030
00031
00032 spCam = new CCamera();
00033
00034
00035 spCamControl = new CSceneCtrl();
00036 spCamControl->Enable(spCam);
00037 registerInputHandler((ICamCtrl*)spCamControl);
00038
00039
00040 EnableThread(true);
00041
00042
00043 contextMenu = new QMenu(this);
00044 transformMC = contextMenu->addAction("Transform Model",this,SLOT(ToggleTransform()));
00045 showLightA = contextMenu->addAction("Show Light",this,SLOT(ShowLight()));
00046 showPerformanceA = contextMenu->addAction("Show Performance Overlay",this,SLOT(ShowPerformance()));
00047 setBGColorA = contextMenu->addAction("Set Background Color",this,SLOT(SelectBGColor()));
00048 snapShotA = contextMenu->addAction("Save Snapshot",this,SLOT(SaveSnapshot()));
00049 enableThreadA = contextMenu->addAction("Disable Threaded Rendering",this,SLOT(ToggleThread()));
00050 transformMC->setEnabled(false);
00051 enableThreadA->setEnabled(false);
00052
00053
00054 bgColor = QColor(0,0,0,255);
00055 showPerf = false;
00056 perfOverlay = new PerformanceOverlay();
00057 bTransformModel = false;
00058
00059 bHighQuality = false;
00060 }
00061
00062
00063 VStudioRenderer::~VStudioRenderer()
00064 {
00065 spCamControl = NULL;
00066 spCam = NULL;
00067 spLight = NULL;
00068 pRenderVolume = NULL;
00069 delete perfOverlay;
00070 }
00071
00072
00073 void VStudioRenderer::OpenState(QSettings & openFile)
00074 {
00075 openFile.beginGroup("CAMERA");
00076
00077 QRectF defaultPos(0,0,6,-1);
00078 QRectF defaultRot(0,0,0,-1);
00079 float defaultFOV = openFile.value("fov",50.0).toDouble();
00080
00081 QRectF camPos = openFile.value("pos",defaultPos).value<QRectF>();openFile.setValue("pos",camPos);
00082 QRectF camRot = openFile.value("rot",defaultRot).value<QRectF>();openFile.setValue("rot",camRot);
00083
00084 spCamControl->SetPos(CVector3f(camPos.left(),camPos.top(),camPos.width()));
00085 spCamControl->SetRot(CVector3f(camRot.left(),camRot.top(),camRot.width()));
00086 spCamControl->SetFOV(defaultFOV);
00087 openFile.endGroup();
00088
00089 openFile.beginGroup("DISPLAY");
00090 QColor defaultColor("black");
00091 bgColor = openFile.value("bgColor",defaultColor).value<QColor>();openFile.setValue("bgColor",bgColor);
00092
00093 SetBGColor(bgColor.redF(),bgColor.greenF(),bgColor.blueF(),bgColor.alphaF());
00094
00095 showPerf = openFile.value("showPerformance",false).toBool();openFile.setValue("showPerformance",showPerf);
00096
00097 if(showPerf){ShowPerformance();}
00098 openFile.endGroup();
00099 }
00100
00101
00102 void VStudioRenderer::SaveState(QSettings & saveFile)
00103 {
00104 saveFile.beginGroup("CAMERA");
00105 CVector3f *camPV = spCamControl->GetPos();
00106 QRectF camPos;camPos.setLeft(camPV->m_X);camPos.setTop(camPV->m_Y);camPos.setWidth(camPV->m_Z);camPos.setHeight(-1.0);
00107 CVector3f *camRV = spCamControl->GetRot();
00108 QRectF camRot;camRot.setLeft(camRV->m_X);camRot.setTop(camRV->m_Y);camRot.setWidth(camRV->m_Z);camRot.setHeight(-1.0);
00109 saveFile.setValue("pos",camPos);
00110 saveFile.setValue("rot",camRot);
00111 saveFile.setValue("fov",spCamControl->GetFOV());
00112 saveFile.endGroup();
00113
00114 saveFile.beginGroup("DISPLAY");
00115 saveFile.setValue("bgColor",bgColor);
00116 saveFile.setValue("showPerformance",showPerf);
00117 saveFile.endGroup();
00118 }
00119
00120
00121 bool VStudioRenderer::GetOpenglInfo(OpenGLInfo & glInfo)
00122 {
00123 if(!this->context()->isValid())
00124 {
00125 return false;
00126 }
00127 else
00128 {
00129 lockGLContext();
00130
00131
00132 bool versionOk = false;
00133 const char * versGLstr = (const char*)glGetString(GL_VERSION);
00134 if(!((versGLstr == NULL) || (sscanf(versGLstr,"%d.%d",&glInfo.gl_VersionMajor,&glInfo.gl_VersionMinor) != 2))){
00135 if(glInfo.gl_VersionMajor >= 2){
00136 const char * versGLSLstr = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
00137 if(!((versGLSLstr == NULL) || (sscanf(versGLSLstr,"%d.%d",&glInfo.glsl_VersionMajor,&glInfo.glsl_VersionMinor) != 2))){
00138 versionOk = true;
00139 }
00140 }
00141 }
00142 if(!versionOk)return false;
00143
00144
00145 GLenum err = glewInit();
00146 if (GLEW_OK != err)
00147 {
00148 const GLubyte *b = glewGetErrorString(err);
00149 return false;
00150 }
00151
00152
00153 if(!GLEW_EXT_framebuffer_object){
00154 return false;
00155 }
00156
00157 unlockGLContext();
00158
00159 return true;
00160 }
00161 }
00162
00163
00164 void VStudioRenderer::SetVolume(TSmartPointer<CVolume> volume)
00165 {
00166 lockGLContext();
00167
00168 if(oldVolume)
00169 {
00170 oldVolume->DestroyOpenGL();
00171 oldVolume = NULL;
00172 pRenderVolume = NULL;
00173 }
00174 if(volume)
00175 {
00176 if(volume->CreateOpenGL())
00177 {
00178 oldVolume = pRenderVolume = volume;
00179 transformMC->setEnabled(true);
00180 }
00181 else
00182 {
00183 oldVolume = pRenderVolume = NULL;
00184 onLOG("SetVolume failed in volume->CreateOpenGL()");
00185 }
00186 }
00187
00188 unlockGLContext();
00189 }
00190
00191 void VStudioRenderer::SetLight(TSmartPointer<CLight> light)
00192 {
00193 spLight = light;
00194 }
00195
00196 void VStudioRenderer::SetBGColor(float r,float g,float b,float a)
00197 {
00198 lockGLContext();
00199 glClearColor(r,g,b,a);
00200 unlockGLContext();
00201 }
00202
00203
00204
00205
00206
00207 void VStudioRenderer::onInitialize()
00208 {
00209 glClearColor(bgColor.redF(),bgColor.greenF(),bgColor.blueF(),bgColor.alphaF());
00210 glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
00211 glEnable(GL_DEPTH_TEST);
00212 glEnable(GL_CULL_FACE);
00213 glShadeModel(GL_SMOOTH);
00214 }
00215
00216 void VStudioRenderer::onResize()
00217 {
00218 glViewport(0,0,viewportWidth,viewportHeight);
00219 spCam->SetAspect((float)viewportWidth/viewportHeight);
00220
00221 if(pRenderVolume)
00222 {
00223 pRenderVolume->ViewAspectChange((float)viewportWidth/viewportHeight);
00224 }
00225 }
00226
00227 void VStudioRenderer::onDraw()
00228 {
00229
00230 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00231
00232
00233 if(!bTransformModel)
00234 {
00235 spCamControl->Update();
00236 }
00237
00238 spCam->UpdateView();
00239 spCam->UpdateTransForm();
00240
00241
00242 RenderScene();
00243
00244
00245 this->swapBuffers();
00246
00247 if(bHighQuality)
00248 {
00249 bHighQuality = false;
00250 pControl->GetVolume()->SetHighQuality(false);
00251 QImage snap = this->grabFrameBuffer();
00252 pControl->SaveImage(snap);
00253 }
00254 }
00255
00256 void VStudioRenderer::onOverlayDraw(QPainter * painter)
00257 {
00258
00259 painter->begin(this);
00260
00261
00262 glMatrixMode(GL_PROJECTION);
00263 glPushMatrix();
00264 glMatrixMode(GL_MODELVIEW);
00265 glPushMatrix();
00266 glPushAttrib(GL_ALL_ATTRIB_BITS);
00267
00268
00269 onInitialize();
00270
00271
00272 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00273
00274
00275 if(!bTransformModel)
00276 {
00277 spCamControl->Update();
00278 }
00279 spCam->ForceUpdateView();
00280 spCam->ForceUpdateTransform();
00281
00282
00283 RenderScene();
00284
00285
00286 glMatrixMode(GL_PROJECTION);
00287 glPopMatrix();
00288 glMatrixMode(GL_MODELVIEW);
00289 glPopMatrix();
00290 glPopAttrib();
00291
00292
00293 RenderOverlay(painter);
00294
00295
00296 painter->end();
00297
00298 if(bHighQuality)
00299 {
00300 bHighQuality = false;
00301 pControl->GetVolume()->SetHighQuality(false);
00302 QImage snap = this->grabFrameBuffer();
00303 pControl->SaveImage(snap);
00304 }
00305 }
00306
00307 void VStudioRenderer::RenderScene()
00308 {
00309
00310 if(pRenderVolume)pRenderVolume->Render();
00311
00312
00313 if(spLight)if(spLight->bShow)spLight->Draw();
00314
00315
00316
00317
00318 if(bDoLog)
00319 {
00320 ReportErrors();
00321 }
00322 }
00323
00324 void VStudioRenderer::RenderOverlay( QPainter * painter )
00325 {
00326 perfOverlay->IncFrame();
00327 perfOverlay->Draw(painter);
00328 }
00329
00330 void VStudioRenderer::onFinishRendering()
00331 {
00332 if(pRenderVolume)
00333 {
00334 pRenderVolume->DestroyOpenGL();
00335 }
00336 }
00337
00338 void VStudioRenderer::onLOG(QString &what)
00339 {
00340 pControl->GetConsole().Log(what,MAIN_THREAD);
00341 }
00342
00343 void VStudioRenderer::onLOG(const char * what)
00344 {
00345 pControl->GetConsole().Log(what,MAIN_THREAD);
00346 }
00347
00348 void VStudioRenderer::contextMenuEvent( QContextMenuEvent * event)
00349 {
00350 if(QApplication::keyboardModifiers().testFlag(Qt::ControlModifier))
00351 {
00352 if(event->reason() == QContextMenuEvent::Mouse)
00353 {
00354 if(spLight->bShow){
00355 showLightA->setText("HideLight");
00356 }else{
00357 showLightA->setText("ShowLight");
00358 }
00359 contextMenu->exec(event->globalPos());
00360 }
00361 }
00362 }
00363
00364 void VStudioRenderer::keyPressEvent(QKeyEvent *event)
00365 {
00366 if(event->key() == Qt::Key_Alt)
00367 {
00368 registerInputHandler((IInputHandler*)spLight);
00369 backupHeadLight = spLight->bHeadLight;
00370 spLight->SetHeadLight(false);
00371 Update();
00372 }
00373 event->accept();
00374 }
00375
00376 void VStudioRenderer::keyReleaseEvent(QKeyEvent *event)
00377 {
00378 if(event->key() == Qt::Key_Alt)
00379 {
00380 registerInputHandler((IInputHandler*)spCamControl);
00381 spLight->SetHeadLight(backupHeadLight);
00382 Update();
00383 }
00384 event->accept();
00385 }
00386
00387 void VStudioRenderer::mouseDoubleClickEvent(QMouseEvent * event)
00388 {
00389 emit Maximize();
00390 }
00391
00392
00393
00394
00395 void VStudioRenderer::ShowLight()
00396 {
00397 if(showLightA->text().startsWith("Show"))
00398 {
00399 spLight->Show(true);
00400 showLightA->setText("Hide Light");
00401 }
00402 else
00403 {
00404 spLight->Show(false);
00405 showLightA->setText("Show Light");
00406 }
00407 }
00408
00409 void VStudioRenderer::SelectBGColor()
00410 {
00411 bgColor = QColorDialog::getColor(); if(!bgColor.isValid()) return;
00412 SetBGColor(bgColor.redF(),bgColor.greenF(),bgColor.blueF(),bgColor.alphaF());
00413 }
00414
00415 void VStudioRenderer::ShowPerformance()
00416 {
00417 if(showPerformanceA->text().startsWith("Show"))
00418 {
00419 lockGLContext();
00420 spCam->ForceUpdateView();
00421 spCam->ForceUpdateTransform();
00422 unlockGLContext();
00423
00424 perfOverlay->Reset();
00425 StartAnimate(10);
00426 EnableOverlay(true);
00427 showPerformanceA->setText("Hide Performance Overlay");
00428 }
00429 else
00430 {
00431 lockGLContext();
00432 spCam->ForceUpdateView();
00433 spCam->ForceUpdateTransform();
00434 unlockGLContext();
00435 EndAnimate();
00436 EnableOverlay(false);
00437 showPerformanceA->setText("Show Performance Overlay");
00438 }
00439 }
00440
00441 void VStudioRenderer::SaveSnapshot()
00442 {
00443 pControl->GetVolume()->SetHighQuality(true);
00444 bHighQuality = true;
00445 Update();
00446 }
00447
00448 void VStudioRenderer::ToggleThread()
00449 {
00450
00451 }
00452
00453 void VStudioRenderer::ToggleTransform()
00454 {
00455 if(transformMC->text().compare("Transform Model") == 0)
00456 {
00457 bTransformModel = true;
00458 registerInputHandler((IInputHandler*)pRenderVolume);
00459 transformMC->setText("Transform Camera");
00460 }
00461 else
00462 {
00463 registerInputHandler((IInputHandler*)spCamControl);
00464 bTransformModel = false;
00465 transformMC->setText("Transform Model");
00466 }
00467 update();
00468 }
00469
00470 void VStudioRenderer::onAnimate()
00471 {
00472 static int timerCount = 0;
00473 timerCount+=10;
00474
00475 if(timerCount == 1000){
00476 perfOverlay->SetFps();
00477 timerCount = 0;
00478 }
00479 Update();
00480 }
00481
00482
00483
00484
00485 void VStudioRenderer::ReportErrors()
00486 {
00487 GLenum eGlError = glGetError();
00488 while(eGlError != GL_NO_ERROR)
00489 {
00490 pControl->GetConsole().Log(QString("OpenGL-Error: ").append((const char *)gluErrorString(eGlError)),OPENGL_THREAD);
00491 eGlError = glGetError();
00492 }
00493 }