2 // File : VTKViewer_RenderWindow.cxx
3 // Created : Wed Mar 20 11:34:28 2002
4 // Author : Nicolas REJNERI
7 // Copyright : Open CASCADE 2002
10 #include "VTKViewer_RenderWindow.h"
11 #include "utilities.h"
12 #include "QAD_Settings.h"
13 #include "QAD_Config.h"
14 #include "QAD_Desktop.h"
15 #include "QAD_Study.h"
16 #include "QAD_Tools.h"
17 #include "SALOME_Selection.h"
19 #include <qcolordialog.h>
25 #include <vtkRenderWindowInteractor.h>
35 VTKViewer_RenderWindow::VTKViewer_RenderWindow(QWidget *parent, const char *name) :
36 QGLWidget(parent, name)
38 mInitialized = false ;
39 //NRI - 22/02/2002 setFocusPolicy(QWidget::StrongFocus) ;
40 //NRI - comment rev 1.6 - setFocus();
43 VTKViewer_RenderWindow::~VTKViewer_RenderWindow() {
44 this->ReferenceCount-- ;
47 void VTKViewer_RenderWindow::PrintSelf(ostream& os, vtkIndent indent) {
48 this->vtkRenderWindow::PrintSelf(os, indent);
50 QGLFormat myFormat = this->format() ;
51 os << indent << "qGLVersion: " << qGLVersion() << endl ;
52 os << indent << "doubleBuffer: " << myFormat.doubleBuffer() << endl ;
53 os << indent << "depth: " << myFormat.depth() << endl ;
54 os << indent << "rgba: " << myFormat.rgba() << endl ;
55 os << indent << "alpha: " << myFormat.alpha() << endl ;
56 os << indent << "accum: " << myFormat.accum() << endl ;
57 os << indent << "stencil: " << myFormat.stencil() << endl ;
58 os << indent << "stereo: " << myFormat.stereo() << endl ;
59 os << indent << "directRendering: " << myFormat.directRendering() << endl ;
62 void VTKViewer_RenderWindow::Start(void) {
64 // Initialize the QGLWidget part of the widget if it has not
65 // been initialized so far.
67 if( ! this->mInitialized ) {
68 this->WindowInitialize() ;
73 // End the rendering process and display the image.
74 void VTKViewer_RenderWindow::Frame(void) {
76 if( (! this->AbortRender) && // the render is not being aborted
77 (! autoBufferSwap() ) && // buffers are not switched automatically
78 doubleBuffer() && // double buffering is enabled on QGLWidget side
79 this->vtkRenderWindow::DoubleBuffer && // double buffering is enabled on VTK side
80 this->SwapBuffers ) { // VTK wants us to swap buffers
81 QGLWidget::swapBuffers() ;
84 void* VTKViewer_RenderWindow::GetGenericDisplayId() {
85 return ((void*)x11Display());
88 void* VTKViewer_RenderWindow::GetGenericWindowId() {
89 return ((void*)winId());
92 void* VTKViewer_RenderWindow::GetGenericContext() {
93 return ((void*)(this->context())->currentContext());
96 // Initialize the window for rendering.
97 void VTKViewer_RenderWindow::WindowInitialize(void) {
98 if( ! this->mInitialized ) {
99 this->initializeGL() ;
100 this->MakeCurrent() ;
102 vtkDebugMacro(<< " glMatrixMode ModelView\n");
103 glMatrixMode( GL_MODELVIEW );
105 vtkDebugMacro(<< " zbuffer enabled\n");
106 glDepthFunc( GL_LEQUAL );
107 glEnable( GL_DEPTH_TEST );
109 vtkDebugMacro(" texture stuff\n");
110 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
112 // initialize blending for transparency
113 vtkDebugMacro(<< " blend func stuff\n");
114 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
117 if (this->PointSmoothing)
119 glEnable(GL_POINT_SMOOTH);
123 glDisable(GL_POINT_SMOOTH);
126 if (this->LineSmoothing)
128 glEnable(GL_LINE_SMOOTH);
132 glDisable(GL_LINE_SMOOTH);
135 if (this->PolygonSmoothing)
137 glEnable(GL_POLYGON_SMOOTH);
141 glDisable(GL_POLYGON_SMOOTH);
144 glEnable( GL_NORMALIZE );
145 glAlphaFunc(GL_GREATER,0);
152 void VTKViewer_RenderWindow::SetFullScreen(int arg) {
154 // We do not need to do anything if the FullScreen mode
155 // is already set to the specified value.
157 if( this->FullScreen == arg ) return ;
160 // :TODO: Fri Apr 21 16:41:06 2000 Pagey
161 // This is not implemented in QGLWidget yet. Hence, we
164 vtkDebugMacro(<< " QGLWidget::SetFullScreen() not supported by QGLWidget yet.\n") ;
167 void VTKViewer_RenderWindow::WindowRemap(void) {
169 // :TODO: Fri Apr 21 16:44:35 2000 Pagey
170 // I am not sure why we would ever need to do this under Qt.
171 // Hence, I have not done anything here yet.
173 vtkDebugMacro(<< " QGLWidget::WindowRemap() not supported by QGLWidget yet.\n") ;
176 void VTKViewer_RenderWindow::PrefFullScreen(void) {
178 // :TODO: Fri Apr 21 16:46:30 2000 Pagey
179 // Since, SetFullScreen() is not supported yet, this is useless.
181 vtkDebugMacro(<< " QGLWidget::PrefFullScreen() not supported by QGLWidget yet.\n") ;
184 void VTKViewer_RenderWindow::SetSize(int w, int h) {
185 if ((this->Size[0] != w)||(this->Size[1] != h)) {
191 if( this->Interactor ) {
192 this->Interactor->SetSize(w, h) ;
195 // if we arent mappen then just set the ivars
200 glViewport( 0, 0, (GLint)w, (GLint)h ) ;
203 void VTKViewer_RenderWindow::StereoUpdate() {
205 // :NOTE: Fri Apr 21 16:55:32 2000 Pagey
206 // This routine is taken directly from vtkOpenGLRenderWindow.cxx.
207 // I am not sure what it does. Hope it works.
209 if (this->StereoRender && (!this->StereoStatus))
211 switch (this->StereoType)
213 case VTK_STEREO_CRYSTAL_EYES:
217 case VTK_STEREO_RED_BLUE:
219 this->StereoStatus = 1;
223 else if ((!this->StereoRender) && this->StereoStatus)
225 switch (this->StereoType)
227 case VTK_STEREO_CRYSTAL_EYES:
229 this->StereoStatus = 0;
232 case VTK_STEREO_RED_BLUE:
234 this->StereoStatus = 0;
240 unsigned char *VTKViewer_RenderWindow::GetPixelData(int x1, int y1, int x2, int y2, int front) {
242 // :NOTE: Fri Apr 21 16:58:53 2000 Pagey
243 // This routine is taken directly from vtkOpenGLRenderWindow.cxx.
244 // I am not sure what it does. Hope it works.
248 unsigned char *data = NULL;
250 // set the current window
277 glReadBuffer(GL_FRONT);
281 glReadBuffer(GL_BACK);
284 data = new unsigned char[(x_hi - x_low + 1)*(y_hi - y_low + 1)*3];
287 // We need to read the image data one row at a time and convert it
288 // from RGBA to RGB to get around a bug in Sun OpenGL 1.1
290 unsigned char *buffer;
291 unsigned char *p_data = NULL;
293 buffer = new unsigned char [4*(x_hi - x_low + 1)];
295 for (yloop = y_low; yloop <= y_hi; yloop++)
297 // read in a row of pixels
298 glReadPixels(x_low,yloop,(x_hi-x_low+1),1,
299 GL_RGBA, GL_UNSIGNED_BYTE, buffer);
300 for (xloop = 0; xloop <= x_hi-x_low; xloop++)
302 *p_data = buffer[xloop*4]; p_data++;
303 *p_data = buffer[xloop*4+1]; p_data++;
304 *p_data = buffer[xloop*4+2]; p_data++;
310 // If the Sun bug is ever fixed, then we could use the following
311 // technique which provides a vast speed improvement on the SGI
313 // Calling pack alignment ensures that we can grab the any size window
314 glPixelStorei( GL_PACK_ALIGNMENT, 1 );
315 glReadPixels(x_low, y_low, x_hi-x_low+1, y_hi-y_low+1, GL_RGB,
316 GL_UNSIGNED_BYTE, data);
322 void VTKViewer_RenderWindow::SetPixelData(int x1, int y1, int x2, int y2,
323 unsigned char *data, int front) {
326 // :NOTE: Fri Apr 21 17:00:16 2000 Pagey
327 // This routine is taken directly from vtkOpenGLRenderWindow.cxx.
328 // I am not sure what it does. Hope it works.
333 // set the current window
338 glDrawBuffer(GL_FRONT);
342 glDrawBuffer(GL_BACK);
369 // We need to read the image data one row at a time and convert it
370 // from RGBA to RGB to get around a bug in Sun OpenGL 1.1
372 unsigned char *buffer;
373 unsigned char *p_data = NULL;
375 buffer = new unsigned char [4*(x_hi - x_low + 1)];
377 // now write the binary info one row at a time
380 for (yloop = y_low; yloop <= y_hi; yloop++)
382 for (xloop = 0; xloop <= x_hi - x_low; xloop++)
384 buffer[xloop*4] = *p_data; p_data++;
385 buffer[xloop*4+1] = *p_data; p_data++;
386 buffer[xloop*4+2] = *p_data; p_data++;
387 buffer[xloop*4+3] = 0xff;
389 /* write out a row of pixels */
390 glMatrixMode( GL_MODELVIEW );
393 glMatrixMode( GL_PROJECTION );
396 glRasterPos3f( (2.0 * (GLfloat)(x_low) / this->Size[0] - 1),
397 (2.0 * (GLfloat)(yloop) / this->Size[1] - 1),
399 glMatrixMode( GL_PROJECTION );
401 glMatrixMode( GL_MODELVIEW );
404 glDrawPixels((x_hi-x_low+1),1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
408 // If the Sun bug is ever fixed, then we could use the following
409 // technique which provides a vast speed improvement on the SGI
411 // now write the binary info
412 glMatrixMode( GL_MODELVIEW );
415 glMatrixMode( GL_PROJECTION );
418 glRasterPos3f( (2.0 * (GLfloat)(x_low) / this->Size[0] - 1),
419 (2.0 * (GLfloat)(y_low) / this->Size[1] - 1),
421 glMatrixMode( GL_PROJECTION );
423 glMatrixMode( GL_MODELVIEW );
426 glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
428 glDrawPixels((x_hi-x_low+1), (y_hi - y_low + 1),
429 GL_RGB, GL_UNSIGNED_BYTE, data);
434 float *VTKViewer_RenderWindow::GetRGBAPixelData(int x1, int y1, int x2, int y2, int front)
437 // :NOTE: Fri Apr 21 17:00:16 2000 Pagey
438 // This routine is taken directly from VTKViewer_RenderWindow.cxx.
439 // I am not sure what it does. Hope it works.
446 // set the current window
473 glReadBuffer(GL_FRONT);
477 glReadBuffer(GL_BACK);
480 width = abs(x_hi - x_low) + 1;
481 height = abs(y_hi - y_low) + 1;
483 data = new float[ (width*height*4) ];
485 glReadPixels( x_low, y_low, width, height, GL_RGBA, GL_FLOAT, data);
490 void VTKViewer_RenderWindow::SetRGBAPixelData(int x1, int y1, int x2, int y2,
491 float *data, int front, int blend)
494 // :NOTE: Fri Apr 21 17:00:16 2000 Pagey
495 // This routine is taken directly from VTKViewer_RenderWindow.cxx.
496 // I am not sure what it does. Hope it works.
502 // set the current window
507 glDrawBuffer(GL_FRONT);
511 glDrawBuffer(GL_BACK);
536 width = abs(x_hi-x_low) + 1;
537 height = abs(y_hi-y_low) + 1;
539 /* write out a row of pixels */
540 glMatrixMode( GL_MODELVIEW );
543 glMatrixMode( GL_PROJECTION );
546 glRasterPos3f( (2.0 * (GLfloat)(x_low) / this->Size[0] - 1),
547 (2.0 * (GLfloat)(y_low) / this->Size[1] - 1),
549 glMatrixMode( GL_PROJECTION );
551 glMatrixMode( GL_MODELVIEW );
557 glDrawPixels( width, height, GL_RGBA, GL_FLOAT, data);
562 glDrawPixels( width, height, GL_RGBA, GL_FLOAT, data);
566 float *VTKViewer_RenderWindow::GetZbufferData( int x1, int y1, int x2, int y2 )
571 float *z_data = NULL;
573 // set the current window
598 width = abs(x2 - x1)+1;
599 height = abs(y2 - y1)+1;
601 z_data = new float[width*height];
603 glReadPixels( x_low, y_low,
605 GL_DEPTH_COMPONENT, GL_FLOAT,
611 void VTKViewer_RenderWindow::SetZbufferData( int x1, int y1, int x2, int y2,
618 // set the current window
643 width = abs(x2 - x1)+1;
644 height = abs(y2 - y1)+1;
646 glMatrixMode( GL_MODELVIEW );
649 glMatrixMode( GL_PROJECTION );
652 glRasterPos2f( 2.0 * (GLfloat)(x_low) / this->Size[0] - 1,
653 2.0 * (GLfloat)(y_low) / this->Size[1] - 1);
654 glMatrixMode( GL_PROJECTION );
656 glMatrixMode( GL_MODELVIEW );
659 glDrawPixels( width, height, GL_DEPTH_COMPONENT, GL_FLOAT, buffer);
663 void VTKViewer_RenderWindow::MakeCurrent() {
664 if( this->mInitialized ) {
665 //const QGLContext* current = this->context()->currentContext();
671 void VTKViewer_RenderWindow::initializeGL() {
672 if ( ! this->mInitialized ) {
674 // Construct a format which is similar to the
675 // format set by vtkOpenGLRenderWindow.cxx
678 if( this->vtkRenderWindow::DoubleBuffer ) {
679 myFormat.setDoubleBuffer(true) ;
681 myFormat.setDoubleBuffer(false) ;
683 if( this->StereoCapableWindow ) {
684 myFormat.setStereo(true) ;
686 myFormat.setStereo(false) ;
688 myFormat.setRgba(true) ;
689 myFormat.setDepth(true) ;
690 myFormat.setDirectRendering(true) ;
692 setFormat(myFormat) ;
694 glClearColor(0.0, 0.0, 0.0, 0.0) ;
695 this->mInitialized = true ;
697 setMouseTracking(true);
701 void VTKViewer_RenderWindow::paintGL() {
705 void VTKViewer_RenderWindow::resizeGL(int w, int h) {
709 void VTKViewer_RenderWindow::setContext( QGLContext *context,
710 const QGLContext *shareContext,
711 bool deleteOldContex ) {
712 mInitialized = false ;
713 QGLWidget::setContext(context, shareContext, deleteOldContex) ;
716 void VTKViewer_RenderWindow::mouseMoveEvent( QMouseEvent *event ) {
717 emit MouseMove(event) ;
720 void VTKViewer_RenderWindow::mousePressEvent( QMouseEvent *event ) {
721 //NRI - comment rev 1.6 - setFocus() ;
723 // Emit a ButtonPressed signal for all mouse presses.
725 emit ButtonPressed(event) ;
727 // Emit a signal for the button which was pressed.
729 switch(event->button()) {
731 emit LeftButtonPressed(event) ;
734 emit MiddleButtonPressed(event) ;
737 if ( event->state() == Qt::ControlButton ) {
738 emit RightButtonPressed(event) ;
740 QPopupMenu* popup = createPopup();
742 QAD_Tools::checkPopup( popup );
743 if ( popup->count()>0 ) {
744 popup->exec( QCursor::pos() );
757 void VTKViewer_RenderWindow::mouseReleaseEvent( QMouseEvent *event ) {
759 // Emit a ButtonPressed signal for all mouse releases.
761 emit ButtonReleased(event) ;
763 // Emit a signal for the the mouse button which was
766 switch(event->button()) {
768 emit LeftButtonReleased(event) ;
771 emit MiddleButtonReleased(event) ;
774 emit RightButtonReleased(event) ;
782 void VTKViewer_RenderWindow::keyPressEvent (QKeyEvent * event) {
784 // Let the interactor handle this.
786 emit KeyPressed(event) ;
792 void VTKViewer_RenderWindow::onCreatePopup()
795 QAD_Desktop* Desktop = (QAD_Desktop*) QAD_Application::getDesktop();
796 QAD_Study* myActiveStudy = Desktop->getActiveStudy();
797 SALOME_Selection* Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
800 QString theParent("Viewer");
803 Desktop->definePopup( theContext, theParent, theObject );
804 Desktop->createPopup( myPopup, theContext, theParent, theObject);
805 Desktop->customPopup( myPopup, theContext, theParent, theObject );
807 // if (Sel->IObjectCount() == 0 && myPopup->count()<1) {
808 if ( myPopup->count() > 0 )
809 myIDs.append ( myPopup->insertSeparator() );
811 myIDs.append ( id = myPopup->insertItem (tr ("MEN_VP3D_CHANGEBGR")) );
812 QAD_ASSERT ( myPopup->connectItem ( id, this, SLOT(onChangeBackgroundColor())) );
818 void VTKViewer_RenderWindow::onChangeBackgroundColor()
820 float red, green, blue;
823 vtkRendererCollection * theRenderers = GetRenderers();
824 theRenderers->InitTraversal();
825 vtkRenderer * theRenderer = theRenderers->GetNextItem();
826 theRenderer->GetBackground(backint);
828 QColor selColor = QColorDialog::getColor ( QColor(int(backint[0]*255), int(backint[1]*255), int(backint[2]*255)), NULL );
829 if ( selColor.isValid() ) {
830 theRenderer->SetBackground( selColor.red()/255., selColor.green()/255., selColor.blue()/255. );
831 QAD_CONFIG->addSetting( "VTKViewer:BackgroundColorRed", selColor.red() );
832 QAD_CONFIG->addSetting( "VTKViewer:BackgroundColorGreen", selColor.green() );
833 QAD_CONFIG->addSetting( "VTKViewer:BackgroundColorBlue", selColor.blue() );