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"
16 #include <QGuiApplication>
17 #include <QPaintEvent>
20 #include <V3d_OrthographicView.hxx>
21 #include <V3d_PerspectiveView.hxx>
22 #include <Visual3d_View.hxx>
25 #include <WNT_Window.hxx>
27 #include <Xw_Window.hxx>
34 Create native view window for CasCade view [ static ]
36 Handle(Aspect_Window) CreateCasWindow( const Handle(V3d_View)& view, WId winId )
38 Aspect_Handle aWindowHandle = (Aspect_Handle)winId;
40 Handle(WNT_Window) viewWindow = new WNT_Window( aWindowHandle );
42 Handle(Aspect_DisplayConnection) aDispConnection = view->Viewer()->Driver()->GetDisplayConnection();
43 Handle(Xw_Window) viewWindow = new Xw_Window( aDispConnection, aWindowHandle );
50 class OpenGLUtils_FrameBuffer
53 OpenGLUtils_FrameBuffer();
54 ~OpenGLUtils_FrameBuffer();
56 bool init( const GLsizei&, const GLsizei& );
73 #define APIENTRYP APIENTRY *
76 #ifndef GL_FRAMEBUFFER_EXT
77 #define GL_FRAMEBUFFER_EXT 0x8D40
80 #ifndef GL_RENDERBUFFER_EXT
81 #define GL_RENDERBUFFER_EXT 0x8D41
84 #ifndef GL_COLOR_ATTACHMENT0_EXT
85 #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
88 #ifndef GL_DEPTH_ATTACHMENT_EXT
89 #define GL_DEPTH_ATTACHMENT_EXT 0x8D00
92 #ifndef GL_FRAMEBUFFER_COMPLETE_EXT
93 #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
96 typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
97 typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
98 typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
99 typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
100 typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
101 typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
102 typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
103 typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
104 typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
105 typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
107 static PFNGLGENFRAMEBUFFERSEXTPROC vglGenFramebuffersEXT = NULL;
108 static PFNGLBINDFRAMEBUFFEREXTPROC vglBindFramebufferEXT = NULL;
109 static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC vglFramebufferTexture2DEXT = NULL;
110 static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC vglCheckFramebufferStatusEXT = NULL;
111 static PFNGLDELETEFRAMEBUFFERSEXTPROC vglDeleteFramebuffersEXT = NULL;
112 static PFNGLGENRENDERBUFFERSEXTPROC vglGenRenderbuffersEXT = NULL;
113 static PFNGLBINDRENDERBUFFEREXTPROC vglBindRenderbufferEXT = NULL;
114 static PFNGLRENDERBUFFERSTORAGEEXTPROC vglRenderbufferStorageEXT = NULL;
115 static PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC vglFramebufferRenderbufferEXT = NULL;
116 static PFNGLDELETERENDERBUFFERSEXTPROC vglDeleteRenderbuffersEXT = NULL;
119 #define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
121 #define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
126 vglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glGenFramebuffersEXT" );
127 vglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)GL_GetProcAddress( "glBindFramebufferEXT" );
128 vglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)GL_GetProcAddress( "glFramebufferTexture2DEXT" );
129 vglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)GL_GetProcAddress( "glCheckFramebufferStatusEXT" );
130 vglDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteFramebuffersEXT" );
131 vglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)GL_GetProcAddress( "glGenRenderbuffersEXT" );
132 vglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)GL_GetProcAddress( "glBindRenderbufferEXT" );
133 vglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)GL_GetProcAddress( "glRenderbufferStorageEXT" );
134 vglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)GL_GetProcAddress( "glFramebufferRenderbufferEXT" );
135 vglDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteRenderbuffersEXT" );
137 bool ok = vglGenFramebuffersEXT && vglBindFramebufferEXT && vglFramebufferTexture2DEXT &&
138 vglCheckFramebufferStatusEXT && vglDeleteFramebuffersEXT && vglGenRenderbuffersEXT &&
139 vglBindRenderbufferEXT && vglRenderbufferStorageEXT && vglFramebufferRenderbufferEXT &&
140 vglDeleteRenderbuffersEXT;
145 static bool IsEXTInitialized = InitializeEXT();
147 OpenGLUtils_FrameBuffer::OpenGLUtils_FrameBuffer()
154 OpenGLUtils_FrameBuffer::~OpenGLUtils_FrameBuffer()
159 bool OpenGLUtils_FrameBuffer::init( const GLsizei& xSize, const GLsizei& ySize )
161 char* ext = (char*)glGetString( GL_EXTENSIONS );
162 if( !IsEXTInitialized ||
163 strstr( ext, "GL_EXT_framebuffer_object" ) == NULL )
165 qDebug( "Initializing OpenGL FrameBuffer extension failed" );
169 // create a texture object
170 glEnable( GL_TEXTURE_2D );
171 glGenTextures( 1, &textureId );
172 glBindTexture( GL_TEXTURE_2D, textureId );
173 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
174 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
175 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, xSize, ySize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
176 glBindTexture( GL_TEXTURE_2D, 0 );
178 // create a renderbuffer object to store depth info
179 vglGenRenderbuffersEXT( 1, &rboId );
180 vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rboId );
181 vglRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, xSize, ySize );
182 vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
184 // create a framebuffer object
185 vglGenFramebuffersEXT( 1, &fboId );
186 vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
188 // attach the texture to FBO color attachment point
189 vglFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0 );
191 // attach the renderbuffer to depth attachment point
192 vglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId );
195 GLenum status = vglCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
198 vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
200 return status == GL_FRAMEBUFFER_COMPLETE_EXT;
203 void OpenGLUtils_FrameBuffer::release()
205 if( !IsEXTInitialized )
208 glDeleteTextures( 1, &textureId );
211 vglDeleteFramebuffersEXT( 1, &fboId );
214 vglDeleteRenderbuffersEXT( 1, &rboId );
218 void OpenGLUtils_FrameBuffer::bind()
220 if( !IsEXTInitialized )
223 vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
226 void OpenGLUtils_FrameBuffer::unbind()
228 if( !IsEXTInitialized )
231 vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
236 //************************************************************************
237 //************************************************************************
238 //************************************************************************
239 XGUI_ViewPort::XGUI_ViewPort(XGUI_ViewWindow* theParent,
240 const Handle(V3d_Viewer)& theViewer,
241 V3d_TypeOfView theType) :
243 myPaintersRedrawing(false)
245 setMouseTracking( true );
246 setBackgroundRole( QPalette::NoRole );
248 // set focus policy to threat QContextMenuEvent from keyboard
249 setFocusPolicy( Qt::StrongFocus );
250 setAttribute( Qt::WA_PaintOnScreen );
251 setAttribute( Qt::WA_NoSystemBackground );
253 if ( theType == V3d_ORTHOGRAPHIC ) {
254 myOrthoView = new V3d_OrthographicView( theViewer );
255 myActiveView = myOrthoView;
258 myPerspView = new V3d_PerspectiveView( theViewer );
259 myActiveView = myPerspView;
261 //setBackground( Qtx::BackgroundData( Qt::black ) ); // set default background
264 //***********************************************
265 XGUI_ViewPort::~XGUI_ViewPort()
269 //***********************************************
270 bool XGUI_ViewPort::mapView( const Handle(V3d_View)& theView)
272 if ( !setWindow( theView ) )
275 if ( !mapped( theView ) ) {
276 theView->SetWindow( myWindow );
277 if ( theView != activeView() )
278 theView->View()->Deactivate();
281 /* create static trihedron (16551: EDF PAL 501) */
282 //OCCViewer_ViewWindow* aVW = dynamic_cast<OCCViewer_ViewWindow*>( parentWidget()->parentWidget()->parentWidget() );
284 // OCCViewer_Viewer* aViewModel = dynamic_cast<OCCViewer_Viewer*>( aVW->getViewManager()->getViewModel() );
285 // if ( aViewModel && aViewModel->isStaticTrihedronDisplayed() ){
286 //theView->ZBufferTriedronSetup();
287 theView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER );
296 //***********************************************
297 bool XGUI_ViewPort::setWindow( const Handle(V3d_View)& theView)
299 if ( !myWindow.IsNull() )
302 if ( theView.IsNull() )
305 attachWindow( theView, CreateCasWindow( theView, winId() ) );
307 myWindow = theView->Window();
308 return !myWindow.IsNull();
311 //***********************************************
312 bool XGUI_ViewPort::mapped( const Handle(V3d_View)& theView) const
314 return ( !theView.IsNull() && theView->View()->IsDefined() );
317 //***********************************************
318 void XGUI_ViewPort::updateBackground()
322 //***********************************************
323 void XGUI_ViewPort::attachWindow( const Handle(V3d_View)& theView, const Handle(Aspect_Window)& theWnd)
325 if (!theView.IsNull()) {
326 theView->SetWindow( theWnd );
331 //***********************************************
332 void XGUI_ViewPort::paintEvent( QPaintEvent* theEvent)
335 /* X11 : map before show doesn't work */
336 if ( !mapped( activeView() ) )
337 mapView( activeView() );
339 if ( !myWindow.IsNull() ) {
340 //QGuiApplication::sync();
341 QRect rc = theEvent->rect();
342 //if ( !myPaintersRedrawing ) {
343 //activeView()->Redraw();
344 activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() );
347 //if ( myPaintersRedrawing ) {
348 // QPainter p( this );
349 // //emit vpDrawExternal( &p );
350 // myPaintersRedrawing = false;
354 //***********************************************
355 void XGUI_ViewPort::resizeEvent( QResizeEvent* )
358 /* Win32 : map before first show to avoid flicker */
359 if ( !mapped( activeView() ) )
360 mapView( activeView() );
362 //QGuiApplication::sync();
363 if ( !activeView().IsNull() )
364 activeView()->MustBeResized();
367 //***********************************************
368 QImage XGUI_ViewPort::dumpView()
370 Handle(V3d_View) view = getView();
374 int aWidth = width();
375 int aHeight = height();
376 //QApplication::syncX();
377 view->Redraw(); // In order to reactivate GL context
380 OpenGLUtils_FrameBuffer aFrameBuffer;
381 if( aFrameBuffer.init( aWidth, aHeight ) )
383 QImage anImage( aWidth, aHeight, QImage::Format_RGB32 );
385 glPushAttrib( GL_VIEWPORT_BIT );
386 glViewport( 0, 0, aWidth, aHeight );
392 aFrameBuffer.unbind();
396 glReadPixels( 0, 0, aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, anImage.bits() );
397 aFrameBuffer.unbind();
399 anImage = anImage.rgbSwapped();
400 anImage = anImage.mirrored();
403 // if frame buffers are unsupported, use old functionality
406 unsigned char* data = new unsigned char[ aWidth*aHeight*4 ];
408 QPoint p = mapFromParent(geometry().topLeft());
410 glReadPixels( p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE,
413 QImage anImage( data, aWidth, aHeight, QImage::Format_ARGB32 );
414 anImage = anImage.mirrored();
415 anImage = anImage.rgbSwapped();