2 # ifndef GLX_GLXEXT_LEGACY
3 # define GLX_GLXEXT_LEGACY
12 #include "XGUI_ViewPort.h"
13 #include "XGUI_ViewWindow.h"
14 #include "XGUI_Viewer.h"
15 #include "XGUI_Constants.h"
17 #include <QGuiApplication>
18 #include <QPaintEvent>
21 #include <V3d_OrthographicView.hxx>
22 #include <V3d_PerspectiveView.hxx>
23 #include <Visual3d_View.hxx>
26 #include <WNT_Window.hxx>
28 #include <Xw_Window.hxx>
34 static double rx = 0.;
35 static double ry = 0.;
38 static Standard_Boolean zRotation = Standard_False;
43 Create native view window for CasCade view [ static ]
45 Handle(Aspect_Window) CreateCasWindow( const Handle(V3d_View)& view, WId winId )
47 Aspect_Handle aWindowHandle = (Aspect_Handle)winId;
49 Handle(WNT_Window) viewWindow = new WNT_Window( aWindowHandle );
51 Handle(Aspect_DisplayConnection) aDispConnection = view->Viewer()->Driver()->GetDisplayConnection();
52 Handle(Xw_Window) viewWindow = new Xw_Window( aDispConnection, aWindowHandle );
59 class OpenGLUtils_FrameBuffer
62 OpenGLUtils_FrameBuffer();
63 ~OpenGLUtils_FrameBuffer();
65 bool init( const GLsizei&, const GLsizei& );
82 #define APIENTRYP APIENTRY *
85 #ifndef GL_FRAMEBUFFER_EXT
86 #define GL_FRAMEBUFFER_EXT 0x8D40
89 #ifndef GL_RENDERBUFFER_EXT
90 #define GL_RENDERBUFFER_EXT 0x8D41
93 #ifndef GL_COLOR_ATTACHMENT0_EXT
94 #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
97 #ifndef GL_DEPTH_ATTACHMENT_EXT
98 #define GL_DEPTH_ATTACHMENT_EXT 0x8D00
101 #ifndef GL_FRAMEBUFFER_COMPLETE_EXT
102 #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
105 typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
106 typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
107 typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
108 typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
109 typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
110 typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
111 typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
112 typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
113 typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
114 typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
116 static PFNGLGENFRAMEBUFFERSEXTPROC vglGenFramebuffersEXT = NULL;
117 static PFNGLBINDFRAMEBUFFEREXTPROC vglBindFramebufferEXT = NULL;
118 static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC vglFramebufferTexture2DEXT = NULL;
119 static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC vglCheckFramebufferStatusEXT = NULL;
120 static PFNGLDELETEFRAMEBUFFERSEXTPROC vglDeleteFramebuffersEXT = NULL;
121 static PFNGLGENRENDERBUFFERSEXTPROC vglGenRenderbuffersEXT = NULL;
122 static PFNGLBINDRENDERBUFFEREXTPROC vglBindRenderbufferEXT = NULL;
123 static PFNGLRENDERBUFFERSTORAGEEXTPROC vglRenderbufferStorageEXT = NULL;
124 static PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC vglFramebufferRenderbufferEXT = NULL;
125 static PFNGLDELETERENDERBUFFERSEXTPROC vglDeleteRenderbuffersEXT = NULL;
128 #define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
130 #define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
135 vglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glGenFramebuffersEXT" );
136 vglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)GL_GetProcAddress( "glBindFramebufferEXT" );
137 vglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)GL_GetProcAddress( "glFramebufferTexture2DEXT" );
138 vglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)GL_GetProcAddress( "glCheckFramebufferStatusEXT" );
139 vglDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteFramebuffersEXT" );
140 vglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)GL_GetProcAddress( "glGenRenderbuffersEXT" );
141 vglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)GL_GetProcAddress( "glBindRenderbufferEXT" );
142 vglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)GL_GetProcAddress( "glRenderbufferStorageEXT" );
143 vglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)GL_GetProcAddress( "glFramebufferRenderbufferEXT" );
144 vglDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteRenderbuffersEXT" );
146 bool ok = vglGenFramebuffersEXT && vglBindFramebufferEXT && vglFramebufferTexture2DEXT &&
147 vglCheckFramebufferStatusEXT && vglDeleteFramebuffersEXT && vglGenRenderbuffersEXT &&
148 vglBindRenderbufferEXT && vglRenderbufferStorageEXT && vglFramebufferRenderbufferEXT &&
149 vglDeleteRenderbuffersEXT;
154 static bool IsEXTInitialized = InitializeEXT();
156 OpenGLUtils_FrameBuffer::OpenGLUtils_FrameBuffer()
163 OpenGLUtils_FrameBuffer::~OpenGLUtils_FrameBuffer()
168 bool OpenGLUtils_FrameBuffer::init( const GLsizei& xSize, const GLsizei& ySize )
170 char* ext = (char*)glGetString( GL_EXTENSIONS );
171 if( !IsEXTInitialized ||
172 strstr( ext, "GL_EXT_framebuffer_object" ) == NULL )
174 qDebug( "Initializing OpenGL FrameBuffer extension failed" );
178 // create a texture object
179 glEnable( GL_TEXTURE_2D );
180 glGenTextures( 1, &textureId );
181 glBindTexture( GL_TEXTURE_2D, textureId );
182 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
183 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
184 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, xSize, ySize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
185 glBindTexture( GL_TEXTURE_2D, 0 );
187 // create a renderbuffer object to store depth info
188 vglGenRenderbuffersEXT( 1, &rboId );
189 vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rboId );
190 vglRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, xSize, ySize );
191 vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
193 // create a framebuffer object
194 vglGenFramebuffersEXT( 1, &fboId );
195 vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
197 // attach the texture to FBO color attachment point
198 vglFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0 );
200 // attach the renderbuffer to depth attachment point
201 vglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId );
204 GLenum status = vglCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
207 vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
209 return status == GL_FRAMEBUFFER_COMPLETE_EXT;
212 void OpenGLUtils_FrameBuffer::release()
214 if( !IsEXTInitialized )
217 glDeleteTextures( 1, &textureId );
220 vglDeleteFramebuffersEXT( 1, &fboId );
223 vglDeleteRenderbuffersEXT( 1, &rboId );
227 void OpenGLUtils_FrameBuffer::bind()
229 if( !IsEXTInitialized )
232 vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
235 void OpenGLUtils_FrameBuffer::unbind()
237 if( !IsEXTInitialized )
240 vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
245 //************************************************************************
246 //************************************************************************
247 //************************************************************************
248 XGUI_ViewPort::XGUI_ViewPort(XGUI_ViewWindow* theParent,
249 const Handle(V3d_Viewer)& theViewer,
250 V3d_TypeOfView theType) :
252 myPaintersRedrawing(false),
254 myIsAdvancedZoomingEnabled( false )
256 setMouseTracking( true );
257 setBackgroundRole( QPalette::NoRole );
259 // set focus policy to threat QContextMenuEvent from keyboard
260 setFocusPolicy( Qt::StrongFocus );
261 setAttribute( Qt::WA_PaintOnScreen );
262 setAttribute( Qt::WA_NoSystemBackground );
264 if ( theType == V3d_ORTHOGRAPHIC ) {
265 myOrthoView = new V3d_OrthographicView( theViewer );
266 myActiveView = myOrthoView;
269 myPerspView = new V3d_PerspectiveView( theViewer );
270 myActiveView = myPerspView;
272 myActiveView->SetSurfaceDetail(V3d_TEX_ALL);
274 //setBackground( Qtx::BackgroundData( Qt::black ) ); // set default background
277 //***********************************************
278 XGUI_ViewPort::~XGUI_ViewPort()
282 //***********************************************
283 bool XGUI_ViewPort::mapView( const Handle(V3d_View)& theView)
285 if ( !setWindow( theView ) )
288 if ( !mapped( theView ) ) {
289 theView->SetWindow( myWindow );
290 if ( theView != activeView() )
291 theView->View()->Deactivate();
294 /* create static trihedron (16551: EDF PAL 501) */
295 //OCCViewer_ViewWindow* aVW = dynamic_cast<OCCViewer_ViewWindow*>( parentWidget()->parentWidget()->parentWidget() );
297 // OCCViewer_Viewer* aViewModel = dynamic_cast<OCCViewer_Viewer*>( aVW->getViewManager()->getViewModel() );
298 // if ( aViewModel && aViewModel->isStaticTrihedronDisplayed() ){
299 //theView->ZBufferTriedronSetup();
300 theView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER );
309 //***********************************************
310 bool XGUI_ViewPort::setWindow( const Handle(V3d_View)& theView)
312 if ( !myWindow.IsNull() )
315 if ( theView.IsNull() )
318 attachWindow( theView, CreateCasWindow( theView, winId() ) );
320 myWindow = theView->Window();
321 return !myWindow.IsNull();
324 //***********************************************
325 bool XGUI_ViewPort::mapped( const Handle(V3d_View)& theView) const
327 return ( !theView.IsNull() && theView->View()->IsDefined() );
330 //***********************************************
331 void XGUI_ViewPort::updateBackground()
335 //***********************************************
336 void XGUI_ViewPort::attachWindow( const Handle(V3d_View)& theView, const Handle(Aspect_Window)& theWnd)
338 if (!theView.IsNull()) {
339 theView->SetWindow( theWnd );
344 //***********************************************
345 void XGUI_ViewPort::paintEvent( QPaintEvent* theEvent)
348 /* X11 : map before show doesn't work */
349 if ( !mapped( activeView() ) )
350 mapView( activeView() );
352 if ( !myWindow.IsNull() ) {
353 //QGuiApplication::sync();
354 QRect rc = theEvent->rect();
355 //if ( !myPaintersRedrawing ) {
356 //activeView()->Redraw();
357 activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() );
361 //if ( myPaintersRedrawing ) {
362 // QPainter p( this );
363 // //emit vpDrawExternal( &p );
364 // myPaintersRedrawing = false;
368 //***********************************************
369 void XGUI_ViewPort::resizeEvent( QResizeEvent* )
372 /* Win32 : map before first show to avoid flicker */
373 if ( !mapped( activeView() ) )
374 mapView( activeView() );
376 //QGuiApplication::sync();
377 if ( !activeView().IsNull() )
378 activeView()->MustBeResized();
381 //***********************************************
382 QImage XGUI_ViewPort::dumpView(QRect theRect, bool toUpdate)
384 Handle(V3d_View) view = getView();
390 if (theRect.isNull()) {
394 aWidth = theRect.width();
395 aHeight = theRect.height();
397 //QApplication::syncX();
399 OpenGLUtils_FrameBuffer aFrameBuffer;
400 if( aFrameBuffer.init( aWidth, aHeight ) )
402 QImage anImage( aWidth, aHeight, QImage::Format_RGB32 );
404 glPushAttrib( GL_VIEWPORT_BIT );
405 glViewport( 0, 0, aWidth, aHeight );
410 if (theRect.isNull())
413 view->Redraw(theRect.x(), theRect.y(), theRect.width(), theRect.height());
415 aFrameBuffer.unbind();
419 if (theRect.isNull())
420 glReadPixels( 0, 0, aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, anImage.bits() );
422 glReadPixels( theRect.x(), theRect.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, anImage.bits() );
423 aFrameBuffer.unbind();
425 anImage = anImage.rgbSwapped();
426 anImage = anImage.mirrored();
429 // if frame buffers are unsupported, use old functionality
430 unsigned char* data = new unsigned char[ aWidth*aHeight*4 ];
433 if (theRect.isNull()) {
436 p = mapFromParent(geometry().topLeft());
439 view->Redraw(theRect.x(), theRect.y(), theRect.width(), theRect.height());
440 p = theRect.topLeft();
442 glReadPixels( p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, data);
444 QImage anImage( data, aWidth, aHeight, QImage::Format_ARGB32 );
445 anImage = anImage.mirrored();
446 anImage = anImage.rgbSwapped();
452 Inits 'rotation' transformation.
454 void XGUI_ViewPort::startRotation( int x, int y,
455 int theRotationPointType,
456 const gp_Pnt& theSelectedPoint )
458 if ( !activeView().IsNull() ) {
459 switch ( theRotationPointType ) {
461 activeView()->StartRotation( x, y, 0.45 );
467 activeView()->Size(X,Y);
468 rx = Standard_Real(activeView()->Convert(X));
469 ry = Standard_Real(activeView()->Convert(Y));
471 activeView()->Rotate( 0., 0., 0.,
472 theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
475 Quantity_Ratio zRotationThreshold;
476 zRotation = Standard_False;
477 zRotationThreshold = 0.45;
478 if( zRotationThreshold > 0. ) {
479 Standard_Real dx = Abs(sx - rx/2.);
480 Standard_Real dy = Abs(sy - ry/2.);
481 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
482 if( dx > dd || dy > dd ) zRotation = Standard_True;
488 activeView()->DepthFitAll();
493 Rotates the viewport.
495 void XGUI_ViewPort::rotate( int x, int y,
496 int theRotationPointType,
497 const gp_Pnt& theSelectedPoint )
499 if ( !activeView().IsNull() ) {
500 switch ( theRotationPointType ) {
502 activeView()->Rotation( x, y );
507 dz = atan2(Standard_Real(x)-rx/2., ry/2.-Standard_Real(y)) -
508 atan2(sx-rx/2.,ry/2.-sy);
512 dx = (Standard_Real(x) - sx) * M_PI/rx;
513 dy = (sy - Standard_Real(y)) * M_PI/ry;
517 activeView()->Rotate( dx, dy, dz,
518 theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
524 emit vpTransformed( );
526 // setZSize( getZSize() );
530 Resets the viewport after 'rotation'.
532 void XGUI_ViewPort::endRotation()
534 if ( !activeView().IsNull() ) {
535 activeView()->ZFitAll(1.);
536 activeView()->SetZSize(0.);
537 activeView()->Update();
538 emit vpTransformed( );
543 Inits 'zoom' transformation.
545 void XGUI_ViewPort::startZoomAtPoint( int x, int y )
547 if ( !activeView().IsNull()/* && isAdvancedZoomingEnabled() */)
548 activeView()->StartZoomAtPoint( x, y );
552 Centers the viewport.
554 void XGUI_ViewPort::setCenter( int x, int y )
556 if ( !activeView().IsNull() ) {
557 activeView()->Place( x, y, myScale );
558 emit vpTransformed( );
563 Called at 'pan' transformation.
565 void XGUI_ViewPort::pan( int dx, int dy )
567 if ( !activeView().IsNull() ) {
568 activeView()->Pan( dx, dy, 1.0 );
569 emit vpTransformed( );
574 Called at 'window fit' transformation.
576 void XGUI_ViewPort::fitRect( const QRect& rect )
578 if ( !activeView().IsNull() ) {
579 activeView()->WindowFit( rect.left(), rect.top(), rect.right(), rect.bottom() );
580 emit vpTransformed( );
585 Called at 'zoom' transformation.
587 void XGUI_ViewPort::zoom( int x0, int y0, int x, int y )
589 if ( !activeView().IsNull() ) {
590 if ( isAdvancedZoomingEnabled() )
591 activeView()->ZoomAtPoint( x0, y0, x, y );
593 activeView()->Zoom( x0 + y0, 0, x + y, 0 );
594 emit vpTransformed( );