00001
00002 #include "TridGLFrame.h"
00003 #include "TridPage.h"
00004 #include "TridSketches.h"
00005 #include "TridOpenGLGlobal.h"
00006 #include "TridControl.h"
00007 #include "MessageService/MsgService.h"
00008
00009 #include "TROOT.h"
00010 #include "TSystem.h"
00011 #include "TGX11.h"
00012 #include "TVirtualX.h"
00013 #include "KeySymbols.h"
00014
00015 #include <GL/gl.h>
00016 #include <GL/glx.h>
00017 #include <GL/glu.h>
00018 #include "glf.h"
00019 #include <iostream>
00020 #include <sys/time.h>
00021 #include <string>
00022 #include <cmath>
00023
00024 #ifdef USE_ASIMAGE
00025 extern "C" {
00026
00027 #undef __GNUC__
00028 #undef DEBUG
00029 #undef LOCAL_DEBUG
00030 #undef DEBUG_ALL
00031 # include "afterbase.h"
00032 # include "afterimage.h"
00033 }
00034 #endif
00035
00036 using namespace std;
00037
00038 CVSID("$Id: TridGLFrame.cxx,v 1.31 2007/09/14 14:12:19 tagg Exp $");
00039
00043
00044 class TridGLFrameWindowHandler : public TGUnknownWindowHandler
00045 {
00046 public:
00047 TridGLFrame* fGLFrame;
00048 Window fWindow;
00049 TridGLFrameWindowHandler( TridGLFrame* glframe, Window whichWindow)
00050 {
00051 fGLFrame = glframe;
00052 fWindow = whichWindow;
00053 };
00054 virtual ~TridGLFrameWindowHandler() {};
00055
00056 virtual Bool_t HandleEvent(Event_t *event)
00057 {
00058 if((Window)(event->fWindow) == fWindow) {
00059 return fGLFrame->HandleEvent(event);
00060 }
00061 return false;
00062 }
00063
00064 private:
00065 TridGLFrameWindowHandler() {};
00066 };
00067
00068
00072
00073 TridGLFrame::TridGLFrame(TridPage* tp, TGWindow& parent, TridControl* tc,
00074 const TridPOV& min,
00075 const TridPOV& max )
00076 : TGFrame(&parent, 400, 300),
00077 fTridControl(tc),
00078 fAnimTimeMin(-1e99), fAnimTimeMax(1e99)
00079 {
00080 fTridPage = tp;
00081 fMainFrame = dynamic_cast<const TGMainFrame*>(GetMainFrame());
00082
00083 gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
00084 kButtonPressMask | kButtonReleaseMask,
00085 kNone, kNone);
00086
00087 gVirtualX->SelectInput(fId, kKeyPressMask | kExposureMask | kPointerMotionMask |
00088 kStructureNotifyMask);
00089
00090
00091 fDrawContext = NULL;
00092
00093 Resize(GetDefaultSize());
00094 fWidth = GetWidth();
00095 fHeight = GetHeight();
00096 fAspectRatio = double(fWidth)/double(fHeight);
00097 MSG("TriD",Msg::kDebug) << "Initial GLFrame size: " << fWidth << " " << fHeight << endl;
00098 Layout();
00099
00100 DeleteSketches();
00101
00102
00103 SetupOpenGL();
00104
00105
00106 SetPOV();
00107
00108
00109 fPOVMin.Copy(min);
00110 fPOVMax.Copy(max);
00111
00112
00113
00114
00115 fButton = 0;
00116
00117
00118 Update();
00119 MSG("TriD",Msg::kDebug) << "TridGLFrame constructor. Window ID is " << fId << endl;
00120 }
00121
00122
00123
00124 TridGLFrame::~TridGLFrame( void )
00125 {
00126 if(fDrawContext) {
00127 glXDestroyContext(fDrawContext->fDisplay,fDrawContext->fglxContext);
00128 XUnmapWindow(fDrawContext->fDisplay, fDrawContext->fWindow);
00129 XDestroyWindow(fDrawContext->fDisplay, fDrawContext->fWindow);
00130 gClient->RemoveUnknownWindowHandler(fDrawContext->fHandler);
00131 delete fDrawContext->fHandler;
00132 delete fDrawContext;
00133 }
00134 MSG("TriD",Msg::kDebug) << "TridGLFrame destructor." << endl;
00135 }
00136
00137 void TridGLFrame::SetupOpenGL( void )
00138 {
00139
00140
00141 TridOpenGLGlobal::Instance().GlfLoadFont();
00142
00143
00144
00145 fDrawContext = CreateDrawContext();
00146
00147 glXMakeCurrent(fDrawContext->fDisplay, fDrawContext->fWindow, fDrawContext->fglxContext);
00148
00149
00150 glMatrixMode(GL_PROJECTION);
00151 glLoadIdentity();
00152 SetupProjection();
00153 }
00154
00155 TridGLFrame::DrawContext* TridGLFrame::CreateDrawContext(Int_t x, Int_t y, Int_t width, Int_t height)
00156 {
00157 if(width <0 ) width = fWidth;
00158 if(height <0 ) height = fHeight;
00159
00160
00161
00162
00163 DrawContext* dc = new DrawContext;
00164
00165 dc->fX = x;
00166 dc->fY = y;
00167 dc->fWidth = width;
00168 dc->fHeight = height;
00169
00170
00171 dc->fDisplay = (Display *) gVirtualX->GetDisplay();
00172
00173 static int dblBuf[] = {
00174 GLX_DOUBLEBUFFER,
00175 GLX_RGBA, GLX_DEPTH_SIZE, 16,
00176 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
00177 None
00178 };
00179 static int *snglBuf = &dblBuf[1];
00180
00181 dc->fxVisInfo = glXChooseVisual(dc->fDisplay, DefaultScreen(dc->fDisplay), dblBuf);
00182 if (dc->fxVisInfo == 0)
00183 dc->fxVisInfo = glXChooseVisual(dc->fDisplay, DefaultScreen(dc->fDisplay), snglBuf);
00184
00185 if (dc->fxVisInfo == 0)
00186 MSG("TriD",Msg::kDebug) << "InitGLWindow: Error! Barf! No good visual" << endl;
00187
00188
00189 dc->fglxContext = glXCreateContext(dc->fDisplay, dc->fxVisInfo, None, GL_TRUE);
00190 if(dc->fglxContext == 0) {
00191 MSG("TriD",Msg::kInfo) << "OpenGL: DRI unavailable; using indirect renderinging." << endl;
00192 dc->fglxContext = glXCreateContext(dc->fDisplay, dc->fxVisInfo, None, GL_FALSE);
00193 }
00194
00195
00196
00197 int xval, yval;
00198 unsigned int wval, hval, border, depth;
00199 Window root, wind = (Window) GetId();
00200 XGetGeometry(dc->fDisplay, wind, &root, &xval, &yval, &wval, &hval, &border, &depth);
00201
00202
00203 ULong_t mask;
00204 XSetWindowAttributes attr;
00205
00206 attr.background_pixel = 0;
00207 attr.border_pixel = 0;
00208 attr.colormap = XCreateColormap(dc->fDisplay, root, dc->fxVisInfo->visual, AllocNone);
00209 attr.event_mask = NoEventMask;
00210 attr.backing_store = Always;
00211 attr.bit_gravity = NorthWestGravity;
00212 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask |
00213 CWBackingStore | CWBitGravity;
00214
00215 dc->fWindow = XCreateWindow(dc->fDisplay, wind,
00216 xval + x, yval + y, width, height,
00217 0, dc->fxVisInfo->depth, InputOutput,
00218 dc->fxVisInfo->visual, mask, &attr);
00219
00220 XMapWindow(dc->fDisplay, dc->fWindow);
00221
00222
00223 MSG("TriD",Msg::kDebug) << "GL window is " << dc->fWindow << endl;
00224 dc->fHandler = new TridGLFrameWindowHandler(this,dc->fWindow);
00225 gClient->AddUnknownWindowHandler(dc->fHandler);
00226
00227
00228
00229 XSelectInput(dc->fDisplay, dc->fWindow, ExposureMask );
00230 glXMakeCurrent(dc->fDisplay, dc->fWindow, dc->fglxContext);
00231
00232
00233
00234 return dc;
00235 }
00236
00237
00238 Bool_t TridGLFrame::HandleMotion( int button, int startx, int starty, int stopx, int stopy )
00239 {
00240 int delx, dely;
00241 delx = stopx-startx;
00242 dely = stopy-starty;
00243
00244
00245 if(fButton == 0 ) {
00246
00247 UInt_t name = Pick(stopx,stopy);
00248 if(name!=fPicked) {
00249 fPicked = name;
00250 fTridPage->MouseOver(fPicked);
00251 Update();
00252 return true;
00253 }
00254 } else if( button == kButton1 ) {
00255
00256 if(abs(delx) + abs(dely)>0){
00257 fPOV.fPhi += ((float)delx)/((float)fDrawContext->fWidth)*400.;
00258 fPOV.fTheta += ((float)dely)/((float)fDrawContext->fHeight)*400.;
00259 fPOV.Push();
00260 Update();
00261 return true;
00262 }
00263 } else if( button == kButton2 ) {
00264
00265 if(abs(delx) + abs(dely)>0){
00266 float sdx = (float)(startx - (fDrawContext->fWidth/2.));
00267 float sdy = (float)(starty - (fDrawContext->fHeight/2.));
00268 float dot = sdx*delx + sdy*dely;
00269 dot = dot/sqrt(sdy*sdy+sdx*sdx);
00270
00271 fPOV.fDist -= dot*100/(double)(fDrawContext->fWidth);
00272 fPOV.PushIfChanged();
00273 Update();
00274 return true;
00275 }
00276 } else if( button == kButton3 ) {
00277
00278 if(abs(delx) + abs(dely)>0){
00279
00280
00281 GLfloat z;
00282 GLdouble x1, y1, z1;
00283 GLdouble x2, y2, z2;
00284 GLdouble model[16];
00285 GLdouble proj[16];
00286 GLint view[4];
00287 glGetDoublev(GL_MODELVIEW_MATRIX, model);
00288 glGetDoublev(GL_PROJECTION_MATRIX, proj);
00289 glGetIntegerv(GL_VIEWPORT, view);
00290
00291 glReadPixels(startx, fHeight-starty, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
00292 gluUnProject(startx, fHeight-starty, z, model, proj, view, &x1, &y1, &z1);
00293 gluUnProject(stopx, fHeight-stopy, z, model, proj, view, &x2, &y2, &z2);
00294
00295 MSG("TriD",Msg::kDebug) << "Panning. ReadPixel z is " << z << endl;
00296
00297
00298 fPOV.fx -= x2-x1;
00299 fPOV.fy -= y2-y1;
00300 fPOV.fz -= z2-z1;
00301
00302 fPOV.Push();
00303 Update();
00304 return true;
00305 }
00306 }
00307 return true;
00308 }
00309
00310
00311 Bool_t TridGLFrame::HandleMotion(Event_t* ev)
00312 {
00313 HandleMotion(fButton, fMouseLast_x, fMouseLast_y, ev->fX, ev->fY );
00314
00315 fButtonTraveled += abs(ev->fX - fMouseLast_x) + abs(ev->fY - fMouseLast_y);
00316
00317 fMouseLast_x = ev->fX;
00318 fMouseLast_y = ev->fY;
00319
00320 return true;
00321 }
00322
00323 Bool_t TridGLFrame::HandleButton(Event_t *ev)
00324 {
00325
00326 if((ev->fCode == kButton1) || (ev->fCode == kButton2) || (ev->fCode == kButton3) ){
00327 if (ev->fType == kButtonPress) {
00328 fMouseLast_x = fMouseStart_x = ev->fX;
00329 fMouseLast_y = fMouseStart_y = ev->fY;
00330 fButtonTraveled = 0;
00331 fButton = ev->fCode;
00332 }
00333 else if (ev->fType == kButtonRelease) {
00334 if((fButtonTraveled<5)&&(fButton==kButton1)) {
00335
00336 UInt_t name = Pick(fMouseStart_x,fMouseStart_y);
00337 if(name>0) fTridPage->MouseClick(name);
00338 } else {
00339
00340 fPOV.PushIfChanged();
00341 }
00342 fButton = 0;
00343 }
00344 }
00345
00346 else if(ev->fCode == kButton4) {
00347 if (ev->fType == kButtonPress) {
00348
00349 fPOV.fDist -=1; fPOV.PushIfChanged();
00350 Update();
00351 }
00352 }
00353 else if(ev->fCode == kButton5) {
00354 if (ev->fType == kButtonPress) {
00355
00356 fPOV.fDist +=1; fPOV.PushIfChanged();
00357 Update();
00358 }
00359 }
00360
00361
00362 return true;
00363 }
00364
00365 Bool_t TridGLFrame::HandleKey(Event_t *ev)
00366 {
00367 if (ev->fType == kGKeyPress) {
00368 UInt_t keysym;
00369 char str[2];
00370 gVirtualX->LookupString(ev,(char*)str,sizeof(str),keysym);
00371 switch((EKeySym)keysym) {
00372 case kKey_q:
00373 fPOV.fz +=0.1;
00374 break;
00375 case kKey_a:
00376 fPOV.fz -=0.1;
00377 break;
00378 case kKey_w:
00379 fPOV.fy +=0.1;
00380 break;
00381 case kKey_s:
00382 fPOV.fy-= 0.1;
00383 break;
00384 case kKey_e:
00385 fPOV.fx+= 0.1;
00386 break;
00387 case kKey_d:
00388 fPOV.fx-= 0.1;
00389 break;
00390 case kKey_Up:
00391
00392 fPOV.fDist -= 1;
00393 break;
00394 case kKey_Down:
00395
00396 fPOV.fDist += 1;
00397 break;
00398 case kKey_Left:
00399 fPOV.fPhi += 1;
00400 break;
00401 case kKey_Right:
00402 fPOV.fPhi -= 1;
00403 break;
00404 default:
00405 break;
00406 }
00407 }
00408
00409 fPOV.PushIfChanged();
00410 Update();
00411 return true;
00412 }
00413
00414 Bool_t TridGLFrame::HandleContainerExpose(Event_t *ev)
00415 {
00416
00417
00418 if (ev->fCount == 0)
00419 Update();
00420
00421 return kTRUE;
00422 }
00423
00424 Bool_t TridGLFrame::HandleExpose(Event_t *ev)
00425 {
00426
00427
00428 if (ev->fCount == 0)
00429 Update();
00430
00431 return kTRUE;
00432 }
00433
00434 Bool_t TridGLFrame::HandleConfigureNotify(Event_t* ev)
00435 {
00436
00437 fDrawContext->fWidth = fWidth = ev->fWidth;
00438 fDrawContext->fHeight = fHeight = ev->fHeight;
00439 fAspectRatio = double(fWidth)/double(fHeight);
00440 Layout();
00441 ResizeViewport();
00442 Update();
00443 return kTRUE;
00444 }
00445
00446 void TridGLFrame::ResizeViewport()
00447 {
00448 int xval, yval;
00449 unsigned int wval, hval, border, depth;
00450 Window root, wind = (Window) GetId();
00451 XGetGeometry(fDrawContext->fDisplay, wind, &root, &xval, &yval, &wval, &hval, &border, &depth);
00452 XMoveWindow(fDrawContext->fDisplay, fDrawContext->fWindow, xval + fDrawContext->fX, yval + fDrawContext->fY);
00453
00454 XResizeWindow(fDrawContext->fDisplay, fDrawContext->fWindow, fDrawContext->fWidth, fDrawContext->fHeight);
00455 glXMakeCurrent(fDrawContext->fDisplay, fDrawContext->fWindow, fDrawContext->fglxContext);
00456 glViewport(0, 0, (GLint) fDrawContext->fWidth, (GLint) fDrawContext->fHeight);
00457
00458
00459 glMatrixMode (GL_PROJECTION);
00460 glLoadIdentity ();
00461 SetupProjection();
00462 }
00463
00464
00468
00469 unsigned int TridGLFrame::Pick( int x, int y )
00470 {
00471 const int BUFSIZE =512;
00472 static GLuint selectBuf[BUFSIZE];
00473 GLint hits;
00474 GLint viewport[4];
00475
00476 glXMakeCurrent(fDrawContext->fDisplay, fDrawContext->fWindow, fDrawContext->fglxContext);
00477
00478
00479 glGetIntegerv (GL_VIEWPORT, viewport);
00480
00481
00482 glSelectBuffer (BUFSIZE, selectBuf);
00483
00484
00485 glRenderMode (GL_SELECT);
00486
00487
00488 glInitNames();
00489 glPushName(0);
00490
00491
00492
00493
00494 glMatrixMode (GL_PROJECTION);
00495 glPushMatrix ();
00496 glLoadIdentity ();
00497
00498 gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y),
00499 4.0, 4.0, viewport);
00500 SetupProjection();
00501 TransformToPOV();
00502 DrawObjects();
00503
00504
00505 glMatrixMode(GL_PROJECTION);
00506 glPopMatrix();
00507
00508
00509 glFlush();
00510 hits = glRenderMode(GL_RENDER);
00511
00512
00513 GLuint* ptr = (GLuint *) selectBuf;
00514 unsigned int bestName = 0;
00515 float bestZ = 99;
00516
00517 for(int i=0;i<hits;i++) {
00518 unsigned int numNames = *ptr;
00519 ptr++;
00520 float z1 = float(*(ptr))/0x7fffffff;
00521 ptr++;
00522 float z2 = float(*(ptr))/0x7fffffff;
00523 ptr++;
00524 for(unsigned int j=0; j<numNames; j++) {
00525 unsigned int name = *ptr;
00526 ptr++;
00527 if(((z1+z2)<bestZ) && (name>0)) { bestName = name; bestZ = z1+z2; };
00528 }
00529 }
00530 return bestName;
00531 }
00532
00533
00534
00535
00539
00540 void TridGLFrame::Update( void )
00541 {
00542
00543
00544 struct timeval timestart,timeend;
00545 gettimeofday(×tart,0);
00546
00547
00548
00549 glXMakeCurrent(fDrawContext->fDisplay, fDrawContext->fWindow, fDrawContext->fglxContext);
00550
00551
00552 ClearViewport();
00553 TransformToPOV();
00554 SetupOptions();
00555 SetupLighting();
00556 DrawObjects();
00557 DrawHUD(fHUDText.c_str());
00558
00559 glFlush();
00560 SwapBuffers();
00561
00562 gettimeofday(&timeend,0);
00563
00564 fFrameTime = (timeend.tv_sec - timestart.tv_sec) +
00565 (timeend.tv_usec - timestart.tv_usec) * 0.000001;
00566 }
00567
00568 void TridGLFrame::SetupProjection( void )
00569 {
00570 gluPerspective(30.0f,(GLfloat)fDrawContext->fWidth/(GLfloat)fDrawContext->fHeight,0.1f,100.0f);
00571 }
00572
00573 void TridGLFrame::ClearViewport()
00574 {
00575 TVector3 bg = fTridControl->GetBackgroundColor();
00576 glClearColor(bg.x(),bg.y(),bg.y(),0.0);
00577 glClearDepth(1.0);
00578 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00579 }
00580
00581 void TridGLFrame::TransformToPOV( void )
00582 {
00583
00584 NormalizeAndClipPOV();
00585
00586
00587 glMatrixMode(GL_MODELVIEW);
00588
00589
00590 glLoadIdentity();
00591
00592
00593 glTranslatef(0.0f,0.0f,-fPOV.GetDist());
00594
00595
00596 glRotatef(fPOV.GetTheta(),1.0f,0.0f,0.0f);
00597 if(fPOV.GetPhi()!=0)
00598 glRotatef(fPOV.GetPhi() ,0.0f,1.0f,0.0f);
00599
00600
00601 glTranslatef(-fPOV.GetX(), -fPOV.GetY(), -fPOV.GetZ());
00602 }
00603
00604 void TridGLFrame::SetupOptions( )
00605 {
00606
00607 glShadeModel(GL_SMOOTH);
00608 glEnable(GL_DEPTH_TEST);
00609
00610 glEnable(GL_LINE_SMOOTH);
00611 glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
00612 }
00613
00614 void TridGLFrame::SetupLighting( Bool_t lighting_on )
00615 {
00616 lighting_on = false;
00617 if(!lighting_on) {
00618 glDisable(GL_LIGHTING);
00619 glEnable(GL_COLOR_MATERIAL);
00620 } else {
00621
00622
00623 glEnable(GL_COLOR_MATERIAL);
00624
00625 glEnable(GL_LIGHTING);
00626
00627
00628
00629
00630 float Light_Ambient0[]= { 0.3f, 0.3f, 0.3f, 1.0f };
00631 float Light_Diffuse0[]= { 1.2f, 1.2f, 1.2f, 1.0f };
00632 float Light_Position0[]= { 0.0f, 8.0f, 12.0f, 1.0f };
00633 glLightfv(GL_LIGHT0, GL_POSITION, Light_Position0);
00634 glLightfv(GL_LIGHT0, GL_AMBIENT, Light_Ambient0);
00635 glLightfv(GL_LIGHT0, GL_DIFFUSE, Light_Diffuse0);
00636 glEnable (GL_LIGHT0);
00637
00638
00639 float Light_Ambient1[]= { 0.3f, 0.3f, 0.3f, 1.0f };
00640 float Light_Diffuse1[]= { 1.2f, 1.2f, 1.2f, 1.0f };
00641 float Light_Position1[]= { 0.0f, 8.0f, 0.0f, 1.0f };
00642 glLightfv(GL_LIGHT1, GL_POSITION, Light_Position1);
00643 glLightfv(GL_LIGHT1, GL_AMBIENT, Light_Ambient1);
00644 glLightfv(GL_LIGHT1, GL_DIFFUSE, Light_Diffuse1);
00645 glEnable (GL_LIGHT1);
00646 }
00647 }
00648
00649
00650 void TridGLFrame::DrawObjects( )
00651 {
00652 glMatrixMode(GL_MODELVIEW);
00653 TridSketchListItr itr = GetIterator();
00654 TridSketch* sketch;
00655 fNumSketches = 0;
00656 fNumSketchesDrawn = 0;
00657
00658 const double opaque_thresh = 0.99;
00659
00660
00661 itr.Reset();
00662 while( (sketch = itr.Next()) ){
00663 fNumSketches++;
00664 if(sketch->GetTransparency()>=opaque_thresh) {
00665 Bool_t drawn = sketch->Draw(fAnimTimeMin, fAnimTimeMax);
00666 if(drawn) fNumSketchesDrawn++;
00667 }
00668 }
00669
00670
00671 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00672 glEnable(GL_BLEND);
00673 glDepthMask(GL_FALSE);
00674
00675 std::map<double,TridSketch*> sortedSketches;
00676 std::map<double,TridSketch*>::iterator sortItr;
00677
00678 double modelViewMatrix[16];
00679 glGetDoublev(GL_MODELVIEW_MATRIX, modelViewMatrix);
00680
00681 itr.Reset();
00682 while( (sketch = itr.Next()) ){
00683 if(sketch->GetTransparency()<opaque_thresh) {
00684 double z = sketch->ComputeApparentZ(modelViewMatrix);
00685 sortedSketches[z]=sketch;
00686 }
00687 }
00688
00689 for(sortItr = sortedSketches.begin(); sortItr!=sortedSketches.end(); sortItr++)
00690 {
00691 sketch = sortItr->second;
00692 Bool_t drawn = sketch->Draw(fAnimTimeMin, fAnimTimeMax);
00693 if(drawn) fNumSketchesDrawn++;
00694 }
00695
00696 glDepthMask(GL_TRUE);
00697
00698 }
00699
00700
00701 void TridGLFrame::DrawHUD( const char* text )
00702 {
00703
00704
00705
00706
00707
00708
00709
00710
00711 glMatrixMode(GL_PROJECTION);
00712 glPushMatrix();
00713 glLoadIdentity();
00714
00715 float yHeight = 1;
00716 if(fWidth>0) yHeight = (float)fHeight/(float)fWidth;
00717 gluOrtho2D(-1.0,1.0,-yHeight,yHeight);
00718
00719 glMatrixMode(GL_MODELVIEW);
00720 glPushMatrix();
00721 glLoadIdentity();
00722 glTranslatef(-0.99,-yHeight+0.02,0);
00723
00724
00725
00726 glDisable(GL_TEXTURE_2D);
00727 glDisable(GL_LIGHTING);
00728 glDisable(GL_DEPTH_TEST);
00729
00730 glLoadName(0);
00731 glfStringCentering(GL_FALSE);
00732 glfSetRotateAngle(0.0f);
00733 glfStringDirection(GL_LEFT);
00734
00735 glScalef(0.02,0.02,0.01);
00736
00737 char buff[500];
00738 if(strlen(text)==0) {
00739 glColor4f(1.0f, 0.2f, 0.2f, 0.75f);
00740 sprintf(buff," (%3.1f,%3.1f,%4.1f) D:%4.1f Th:%3f Phi:%3f Pick: %d Render: %fs Objects: %d/%d",
00741 fPOV.GetX(),fPOV.GetY(),fPOV.GetZ(),
00742 fPOV.GetDist(),fPOV.GetTheta(),fPOV.GetPhi(),fPicked,
00743 fFrameTime,
00744 fNumSketchesDrawn,fNumSketches);
00745 } else {
00746 glColor4f(1.0f, 0.9f, 0.9f, 0.75f);
00747 strncpy(buff,text,500);
00748 }
00749 glfDrawSolidString(buff);
00750
00751 glMatrixMode(GL_MODELVIEW);
00752 glPopMatrix();
00753 glMatrixMode(GL_PROJECTION);
00754 glPopMatrix();
00755
00756 }
00757
00758 void TridGLFrame::SwapBuffers()
00759 {
00760
00761
00762 glXSwapBuffers(fDrawContext->fDisplay, fDrawContext->fWindow);
00763 if (!glXIsDirect(fDrawContext->fDisplay, fDrawContext->fglxContext)) {
00764 glFinish();
00765 }
00766
00767
00768 GLenum error;
00769 while ((error = glGetError()) != GL_NO_ERROR) cerr << "SwapBuffers error. GL error: " <<gluErrorString(error) << endl;
00770 }
00771
00772
00773 void TridGLFrame::SetPOV( float x, float y, float z, float distance, float theta, float phi)
00774 {
00775
00776
00777
00778
00779 fPOV.Set(x,y,z,distance,theta,phi);
00780 fPOV.Push();
00781 }
00782
00783 void TridGLFrame::SetPOV( const TridPOV& in )
00784 {
00785
00786
00787
00788
00789 fPOV.Copy(in);
00790 fPOV.Push();
00791 }
00792
00793 void TridGLFrame::SetMinPOV( const TridPOV& in )
00794 {
00795 fPOVMin.Copy(in);
00796 }
00797
00798 void TridGLFrame::SetMaxPOV( const TridPOV& in )
00799 {
00800 fPOVMin.Copy(in);
00801 }
00802
00803 void TridGLFrame::NormalizeAndClipPOV( void )
00804 {
00805
00806 fPOV.fPhi = fmod(fPOV.fPhi+540.,360) - 180;
00807
00808 if(fPOV.fx < fPOVMin.fx) fPOV.fx = fPOVMin.fx;
00809 if(fPOV.fy < fPOVMin.fy) fPOV.fy = fPOVMin.fy;
00810 if(fPOV.fz < fPOVMin.fz) fPOV.fz = fPOVMin.fz;
00811 if(fPOV.fDist < fPOVMin.fDist) fPOV.fDist = fPOVMin.fDist;
00812 if(fPOV.fTheta < fPOVMin.fTheta) fPOV.fTheta = fPOVMin.fTheta;
00813 if(fPOV.fPhi < fPOVMin.fPhi) fPOV.fPhi = fPOVMin.fPhi;
00814
00815 if(fPOV.fx > fPOVMax.fx) fPOV.fx = fPOVMax.fx;
00816 if(fPOV.fy > fPOVMax.fy) fPOV.fy = fPOVMax.fy;
00817 if(fPOV.fz > fPOVMax.fz) fPOV.fz = fPOVMax.fz;
00818 if(fPOV.fDist > fPOVMax.fDist) fPOV.fDist = fPOVMax.fDist;
00819 if(fPOV.fTheta > fPOVMax.fTheta) fPOV.fTheta = fPOVMax.fTheta;
00820 if(fPOV.fPhi > fPOVMax.fPhi) fPOV.fPhi = fPOVMax.fPhi;
00821 }
00822
00823
00824 void TridGLFrame::Print(const char* filename, const char* text)
00825 {
00826
00827
00828 #ifdef USE_RAWDUMP
00829
00830
00831
00832
00833
00834
00835 glXMakeCurrent(fDrawContext->fDisplay, fDrawContext->fWindow, fDrawContext->fglxContext);
00836
00837 ClearViewport();
00838 TransformToPOV();
00839 SetupOptions();
00840 SetupLighting();
00841 DrawObjects();
00842 DrawHUD(text);
00843 glFlush();
00844
00845 std::string rawfile = filename;
00846 rawfile += ".raw";
00847 RawDump(rawfile.c_str());
00848
00849 const char* cmd = Form("convert -depth 8 -size %dx%d rgb:%s %s",
00850 fWidth, fHeight,
00851 rawfile.c_str(), filename);
00852 int retval = gSystem->Exec(cmd);
00853 if(retval) {
00854 MSG("TriD",Msg::kWarning) << "'convert' command failed. Raw file dumped: " << rawfile.c_str() << endl;
00855 } else {
00856
00857 gSystem->Unlink(rawfile.c_str());
00858 }
00859 return;
00860 #endif
00861
00862
00863 #ifdef USE_ASIMAGE
00864 const char* dir = gSystem->DirName(filename);
00865 const char* file = gSystem->BaseName(filename);
00866 ASImageFileTypes atype = ASIT_Gif;
00867
00868 const char* suffix = file + strlen(file) -2;
00869 while(suffix>=file) {
00870 if(suffix[0]=='.') { suffix++; break; }
00871 suffix--;
00872 }
00873
00874 if(strcmp(suffix,"xpm")==0) atype = ASIT_Xpm;
00875 if(strcmp(suffix,"png")==0) atype = ASIT_Png;
00876 if(strcmp(suffix,"jpg")==0) atype = ASIT_Jpeg;
00877 if(strcmp(suffix,"jpeg")==0) atype = ASIT_Jpeg;
00878 if(strcmp(suffix,"gif")==0) atype = ASIT_Gif;
00879 if(strcmp(suffix,"tiff")==0) atype = ASIT_Tiff;
00880
00881
00882 XImage* ximage = XGetImage(fDrawContext->fDisplay,
00883 fDrawContext->fWindow,
00884 fDrawContext->fX,
00885 fDrawContext->fY,
00886 fDrawContext->fWidth,
00887 fDrawContext->fHeight,
00888 XAllPlanes(), ZPixmap);
00889 if(ximage==NULL) {
00890 MSG("TriD",Msg::kWarning) << "Error in Print() - Couldn't make the XImage! " << endl;
00891 return;
00892 }
00893
00894 Int_t screen = gVirtualX->GetScreen();
00895 Int_t depth = gVirtualX->GetDepth();
00896 Visual *vis = (Visual*) gVirtualX->GetVisual();
00897 Colormap cmap = (Colormap) gVirtualX->GetColormap();
00898 ASVisual* asv = create_asvisual_for_id(fDrawContext->fDisplay,
00899 screen, depth,
00900 XVisualIDFromVisual(vis),
00901 cmap, 0);
00902 if(asv==0) {
00903 MSG("TriD",Msg::kWarning) << "Couldn't make the ASVisual! " << endl;
00904 return;
00905 }
00906
00907 ASImage* asimage = ximage2asimage(asv, ximage, 10);
00908 if(asimage==0) {
00909 cout << "Couldn't make the ASImage! " << endl;
00910 return;
00911 }
00912 ASImageExportParams parms;
00913 switch (atype) {
00914 case ASIT_Xpm:
00915 parms.xpm.type = atype;
00916 parms.xpm.flags = EXPORT_ALPHA;
00917 parms.xpm.dither = 4;
00918 parms.xpm.opaque_threshold = 127;
00919 parms.xpm.max_colors = 512;
00920 break;
00921 case ASIT_Png:
00922 parms.png.type = atype;
00923 parms.png.flags = EXPORT_ALPHA;
00924 parms.png.compression = 50;
00925 break;
00926 case ASIT_Jpeg:
00927 parms.jpeg.type = atype;
00928 parms.jpeg.flags = 0;
00929 parms.jpeg.quality = ASIMAGE_QUALITY_GOOD;
00930 break;
00931 case ASIT_Gif:
00932 parms.gif.type = atype;
00933 parms.gif.flags = EXPORT_ALPHA;
00934 parms.gif.dither = 0;
00935 parms.gif.opaque_threshold = 0;
00936 break;
00937 case ASIT_Tiff:
00938 parms.tiff.type = atype;
00939 parms.tiff.flags = EXPORT_ALPHA;
00940 parms.tiff.rows_per_strip = 0;
00941 parms.tiff.compression_type = TIFF_COMPRESSION_JPEG;
00942 parms.tiff.jpeg_quality = 100;
00943 parms.tiff.opaque_threshold = 0;
00944 break;
00945 default:
00946 return;
00947 }
00948
00949 if(
00950 ASImage2file( asimage, dir, file,
00951 atype, &parms )
00952 )
00953 MSG("TriD",Msg::kInfo) << "Wrote file " << file << endl;
00954 else
00955 MSG("TriD",Msg::kWarning) << "Write failed!" << endl;
00956
00957
00958 if(asimage) destroy_asimage(&asimage);
00959 if(ximage) XDestroyImage(ximage);
00960
00961 return;
00962 #endif
00963
00964 #ifdef USE_WRITEGIF
00965
00974
00975 Int_t wid = gVirtualX->OpenPixmap(fWidth,fHeight);
00976 gVirtualX->SelectWindow(wid);
00977 Window_t winid = gVirtualX->GetWindowID(wid);
00978
00979 static int snglBuf[] = {
00980 GLX_RGBA, GLX_DEPTH_SIZE, 16,
00981 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
00982 None
00983 };
00984
00985 Display* display = (Display *) gVirtualX->GetDisplay();
00986 XVisualInfo* xvisinfo = glXChooseVisual(display, DefaultScreen(display), snglBuf);
00987
00988 if (xvisinfo == 0)
00989 cout << "InitGLWindow: Error! Barf! No good visual" << endl;
00990
00991 GLXContext glxContext = glXCreateContext(display, xvisinfo, None, GL_FALSE);
00992
00993 GLXPixmap glxPixmap = glXCreateGLXPixmap( display, xvisinfo, (Pixmap) winid);
00994
00995 glXMakeCurrent(display, glxPixmap, glxContext );
00996 glViewport(0, 0, (GLint) fWidth, (GLint) fHeight);
00997 glMatrixMode(GL_PROJECTION);
00998 glLoadIdentity();
00999 SetupProjection();
01000
01001 ClearViewport();
01002 TransformToPOV();
01003
01004
01005 glShadeModel(GL_FLAT);
01006 glDisable(GL_BLEND);
01007 SetupLighting(false);
01008
01009 DrawObjects();
01010 glFlush();
01011
01012 if (gVirtualX->WriteGIF(filename)) {
01013 cout << "Snap taken:" << filename << endl;
01014 } else {
01015 cout << "TVirtualX::WriteGIF() failed!" << endl;
01016 }
01017
01018 glXDestroyGLXPixmap(display, glxPixmap);
01019 gVirtualX->ClosePixmap();
01020 glXDestroyContext( display, glxContext );
01021
01022 return;
01023 #endif
01024
01025 }
01026
01027
01028
01029 int TridGLFrame::RawDump(const char* filename)
01030 {
01031
01032
01033
01034
01035
01036 int i,j;
01037 FILE *fptr;
01038 unsigned char *image;
01039
01040
01041
01042 if ((image = (unsigned char*) malloc(3*fWidth*fHeight*sizeof(char))) == NULL) {
01043 fprintf(stderr,"Failed to allocate memory for image\n");
01044 return 1;
01045 }
01046
01047 glPixelStorei(GL_PACK_ALIGNMENT,1);
01048
01049
01050 if ((fptr = fopen(filename,"w")) == NULL) {
01051 fprintf(stderr,"Failed to open file for window dump\n");
01052 return 1;
01053 }
01054
01055
01056 glReadBuffer(GL_BACK_LEFT);
01057 glReadPixels(0,0,fWidth,fHeight,GL_RGB,GL_UNSIGNED_BYTE,image);
01058
01059
01060
01061 for (j=fHeight-1;j>=0;j--) {
01062 for (i=0;i<(int)fWidth;i++) {
01063 fputc(image[3*j*fWidth+3*i+0],fptr);
01064 fputc(image[3*j*fWidth+3*i+1],fptr);
01065 fputc(image[3*j*fWidth+3*i+2],fptr);
01066 }
01067 }
01068 fclose(fptr);
01069
01070
01071 free(image);
01072 return 0;
01073 }