Skip to content

Commit 9cbbf1f

Browse files
committed
Coding - move Qt FBO wrapping into OcctGlTools
1 parent 20af30f commit 9cbbf1f

4 files changed

Lines changed: 113 additions & 152 deletions

File tree

occt-qopenglwidget/OcctQOpenGLWidgetViewer.cpp

Lines changed: 6 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,6 @@
2424
#include <BRepPrimAPI_MakeBox.hxx>
2525
#include <Message.hxx>
2626
#include <OpenGl_GraphicDriver.hxx>
27-
#include <OpenGl_FrameBuffer.hxx>
28-
29-
//! OpenGL FBO subclass for wrapping FBO created by Qt using GL_RGBA8
30-
//! texture format instead of GL_SRGB8_ALPHA8.
31-
//! This FBO is set to OpenGl_Context::SetDefaultFrameBuffer() as a final target.
32-
//! Subclass calls OpenGl_Context::SetFrameBufferSRGB() with sRGB=false flag,
33-
//! which asks OCCT to disable GL_FRAMEBUFFER_SRGB and apply sRGB gamma correction manually.
34-
class OcctQtFrameBuffer : public OpenGl_FrameBuffer
35-
{
36-
DEFINE_STANDARD_RTTI_INLINE(OcctQtFrameBuffer, OpenGl_FrameBuffer)
37-
public:
38-
//! Empty constructor.
39-
OcctQtFrameBuffer() {}
40-
41-
//! Make this FBO active in context.
42-
virtual void BindBuffer(const Handle(OpenGl_Context)& theGlCtx) override
43-
{
44-
OpenGl_FrameBuffer::BindBuffer(theGlCtx);
45-
theGlCtx->SetFrameBufferSRGB(true, false);
46-
}
47-
48-
//! Make this FBO as drawing target in context.
49-
virtual void BindDrawBuffer(const Handle(OpenGl_Context)& theGlCtx) override
50-
{
51-
OpenGl_FrameBuffer::BindDrawBuffer(theGlCtx);
52-
theGlCtx->SetFrameBufferSRGB(true, false);
53-
}
54-
55-
//! Make this FBO as reading source in context.
56-
virtual void BindReadBuffer(const Handle(OpenGl_Context)& theGlCtx) override
57-
{
58-
OpenGl_FrameBuffer::BindReadBuffer(theGlCtx);
59-
}
60-
};
6127

6228
// ================================================================
6329
// Function : OcctQOpenGLWidgetViewer
@@ -375,12 +341,9 @@ void OcctQOpenGLWidgetViewer::paintGL()
375341
if (myView.IsNull() || myView->Window().IsNull())
376342
return;
377343

378-
Aspect_Drawable aNativeWin = (Aspect_Drawable)winId();
379-
#ifdef _WIN32
380-
HDC aWglDevCtx = wglGetCurrentDC();
381-
HWND aWglWin = WindowFromDC(aWglDevCtx);
382-
aNativeWin = (Aspect_Drawable)aWglWin;
383-
#endif
344+
Graphic3d_Vec2i aViewSizeOld; myView->Window()->Size(aViewSizeOld.x(), aViewSizeOld.y());
345+
346+
const Aspect_Drawable aNativeWin = OcctGlTools::GetGlNativeWindow((Aspect_Drawable)winId());
384347
if (myView->Window()->NativeHandle() != aNativeWin)
385348
{
386349
// workaround window recreation done by Qt on monitor (QScreen) disconnection
@@ -389,51 +352,18 @@ void OcctQOpenGLWidgetViewer::paintGL()
389352
return;
390353
}
391354

392-
// wrap FBO created by QOpenGLWidget
393-
// get context from this (composer) view rather than from arbitrary one
394-
// Handle(OpenGl_GraphicDriver) aDriver =
395-
// Handle(OpenGl_GraphicDriver)::DownCast(myContext->CurrentViewer()->Driver());
396-
// Handle(OpenGl_Context) aGlCtx = aDriver->GetSharedContext();
397-
Handle(OpenGl_Context) aGlCtx = OcctGlTools::GetGlContext(myView);
398-
Handle(OpenGl_FrameBuffer) aDefaultFbo = aGlCtx->DefaultFrameBuffer();
399-
if (aDefaultFbo.IsNull())
400-
{
401-
aDefaultFbo = new OcctQtFrameBuffer();
402-
aGlCtx->SetDefaultFrameBuffer(aDefaultFbo);
403-
}
404-
if (!aDefaultFbo->InitWrapper(aGlCtx))
355+
// wrap FBO created by QOpenGLFramebufferObject
356+
if (!OcctGlTools::InitializeGlFbo(myView))
405357
{
406-
aDefaultFbo.Nullify();
407-
Message::DefaultMessenger()->Send("Default FBO wrapper creation failed", Message_Fail);
408358
QMessageBox::critical(0, "Failure", "Default FBO wrapper creation failed");
409359
QApplication::exit(1);
410360
return;
411361
}
412362

413-
Graphic3d_Vec2i aViewSizeOld;
414-
// don't use QWidget::rect() as it might return misleading information
415-
// const QRect aRect = rect();
416-
// Graphic3d_Vec2i aViewSizeNew(aRect.right() - aRect.left(), aRect.bottom() - aRect.top());
417-
const Graphic3d_Vec2i aViewSizeNew = aDefaultFbo->GetVPSize();
418-
Handle(Aspect_NeutralWindow) aWindow = Handle(Aspect_NeutralWindow)::DownCast(myView->Window());
419-
aWindow->Size(aViewSizeOld.x(), aViewSizeOld.y());
363+
Graphic3d_Vec2i aViewSizeNew; myView->Window()->Size(aViewSizeNew.x(), aViewSizeNew.y());
420364
if (aViewSizeNew != aViewSizeOld)
421-
{
422-
aWindow->SetSize(aViewSizeNew.x(), aViewSizeNew.y());
423-
myView->MustBeResized();
424-
myView->Invalidate();
425365
dumpGlInfo(true, false);
426366

427-
#if (OCC_VERSION_HEX >= 0x070700)
428-
for (const Handle(V3d_View)& aSubviewIter : myView->Subviews())
429-
{
430-
aSubviewIter->MustBeResized();
431-
aSubviewIter->Invalidate();
432-
aDefaultFbo->SetupViewport(aGlCtx);
433-
}
434-
#endif
435-
}
436-
437367
// reset global GL state from Qt before redrawing OCCT
438368
OcctGlTools::ResetGlStateBeforeOcct(myView);
439369

occt-qt-tools/OcctGlTools.cpp

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,39 @@
1313
#include <OpenGl_View.hxx>
1414
#include <OpenGl_Window.hxx>
1515

16+
//! OpenGL FBO subclass for wrapping FBO created by Qt using GL_RGBA8
17+
//! texture format instead of GL_SRGB8_ALPHA8.
18+
//! This FBO is set to OpenGl_Context::SetDefaultFrameBuffer() as a final target.
19+
//! Subclass calls OpenGl_Context::SetFrameBufferSRGB() with sRGB=false flag,
20+
//! which asks OCCT to disable GL_FRAMEBUFFER_SRGB and apply sRGB gamma correction manually.
21+
class OcctQtFrameBuffer : public OpenGl_FrameBuffer
22+
{
23+
DEFINE_STANDARD_RTTI_INLINE(OcctQtFrameBuffer, OpenGl_FrameBuffer)
24+
public:
25+
//! Empty constructor.
26+
OcctQtFrameBuffer() {}
27+
28+
//! Make this FBO active in context.
29+
virtual void BindBuffer(const Handle(OpenGl_Context)& theGlCtx) override
30+
{
31+
OpenGl_FrameBuffer::BindBuffer(theGlCtx);
32+
theGlCtx->SetFrameBufferSRGB(true, false);
33+
}
34+
35+
//! Make this FBO as drawing target in context.
36+
virtual void BindDrawBuffer(const Handle(OpenGl_Context)& theGlCtx) override
37+
{
38+
OpenGl_FrameBuffer::BindDrawBuffer(theGlCtx);
39+
theGlCtx->SetFrameBufferSRGB(true, false);
40+
}
41+
42+
//! Make this FBO as reading source in context.
43+
virtual void BindReadBuffer(const Handle(OpenGl_Context)& theGlCtx) override
44+
{
45+
OpenGl_FrameBuffer::BindReadBuffer(theGlCtx);
46+
}
47+
};
48+
1649
// ================================================================
1750
// Function : GetGlContext
1851
// ================================================================
@@ -23,18 +56,27 @@ Handle(OpenGl_Context) OcctGlTools::GetGlContext(const Handle(V3d_View)& theView
2356
}
2457

2558
// ================================================================
26-
// Function : InitializeGlWindow
59+
// Function : GetGlNativeWindow
2760
// ================================================================
28-
bool OcctGlTools::InitializeGlWindow(const Handle(V3d_View)& theView,
29-
const Aspect_Drawable theNativeWin,
30-
const Graphic3d_Vec2i& theSize)
61+
Aspect_Drawable OcctGlTools::GetGlNativeWindow(Aspect_Drawable theNativeWin)
3162
{
32-
Aspect_Drawable aNativeWin = theNativeWin;
63+
Aspect_Drawable aNativeWin = (Aspect_Drawable)theNativeWin;
3364
#ifdef _WIN32
3465
HDC aWglDevCtx = wglGetCurrentDC();
3566
HWND aWglWin = WindowFromDC(aWglDevCtx);
3667
aNativeWin = (Aspect_Drawable)aWglWin;
3768
#endif
69+
return aNativeWin;
70+
}
71+
72+
// ================================================================
73+
// Function : InitializeGlWindow
74+
// ================================================================
75+
bool OcctGlTools::InitializeGlWindow(const Handle(V3d_View)& theView,
76+
const Aspect_Drawable theNativeWin,
77+
const Graphic3d_Vec2i& theSize)
78+
{
79+
const Aspect_Drawable aNativeWin = GetGlNativeWindow(theNativeWin);
3880

3981
Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast(theView->Viewer()->Driver());
4082
Handle(OpenGl_Context) aGlCtx = new OpenGl_Context();
@@ -62,6 +104,46 @@ bool OcctGlTools::InitializeGlWindow(const Handle(V3d_View)& theView,
62104
return true;
63105
}
64106

107+
// ================================================================
108+
// Function : InitializeGlFbo
109+
// ================================================================
110+
bool OcctGlTools::InitializeGlFbo(const Handle(V3d_View)& theView)
111+
{
112+
Handle(OpenGl_Context) aGlCtx = OcctGlTools::GetGlContext(theView);
113+
Handle(OpenGl_FrameBuffer) aDefaultFbo = aGlCtx->DefaultFrameBuffer();
114+
if (aDefaultFbo.IsNull())
115+
{
116+
aDefaultFbo = new OcctQtFrameBuffer();
117+
aGlCtx->SetDefaultFrameBuffer(aDefaultFbo);
118+
}
119+
if (!aDefaultFbo->InitWrapper(aGlCtx))
120+
{
121+
aDefaultFbo.Nullify();
122+
Message::DefaultMessenger()->Send("Default FBO wrapper creation failed", Message_Fail);
123+
return false;
124+
}
125+
126+
Graphic3d_Vec2i aViewSizeOld;
127+
const Graphic3d_Vec2i aViewSizeNew = aDefaultFbo->GetVPSize();
128+
Handle(Aspect_NeutralWindow) aWindow = Handle(Aspect_NeutralWindow)::DownCast(theView->Window());
129+
aWindow->Size(aViewSizeOld.x(), aViewSizeOld.y());
130+
if (aViewSizeNew != aViewSizeOld)
131+
{
132+
aWindow->SetSize(aViewSizeNew.x(), aViewSizeNew.y());
133+
theView->MustBeResized();
134+
theView->Invalidate();
135+
#if (OCC_VERSION_HEX >= 0x070700)
136+
for (const Handle(V3d_View)& aSubviewIter : theView->Subviews())
137+
{
138+
aSubviewIter->MustBeResized();
139+
aSubviewIter->Invalidate();
140+
aDefaultFbo->SetupViewport(aGlCtx);
141+
}
142+
#endif
143+
}
144+
return true;
145+
}
146+
65147
// ================================================================
66148
// Function : ResetGlStateBeforeOcct
67149
// ================================================================

occt-qt-tools/OcctGlTools.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,17 @@ class OcctGlTools
1414
//! Return GL context.
1515
static Handle(OpenGl_Context) GetGlContext(const Handle(V3d_View)& theView);
1616

17+
//! Return active native window bound to OpenGL context.
18+
static Aspect_Drawable GetGlNativeWindow(Aspect_Drawable theNativeWin);
19+
20+
//! Initialize native window for OCCT 3D Viewer.
1721
static bool InitializeGlWindow(const Handle(V3d_View)& theView,
1822
const Aspect_Drawable theNativeWin,
1923
const Graphic3d_Vec2i& theSize);
2024

25+
//! Wrap FBO created by QOpenGLFramebufferObject to OCCT 3D Viewer target.
26+
static bool InitializeGlFbo(const Handle(V3d_View)& theView);
27+
2128
//! Cleanup up global GL state after Qt before redrawing OCCT Viewer.
2229
static void ResetGlStateBeforeOcct(const Handle(V3d_View)& theView);
2330

occt-qtquick/OcctQQuickFramebufferViewer.cpp

Lines changed: 13 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -25,40 +25,6 @@
2525
#include <BRepPrimAPI_MakeBox.hxx>
2626
#include <Message.hxx>
2727
#include <OpenGl_GraphicDriver.hxx>
28-
#include <OpenGl_FrameBuffer.hxx>
29-
30-
//! OpenGL FBO subclass for wrapping FBO created by Qt using GL_RGBA8
31-
//! texture format instead of GL_SRGB8_ALPHA8.
32-
//! This FBO is set to OpenGl_Context::SetDefaultFrameBuffer() as a final target.
33-
//! Subclass calls OpenGl_Context::SetFrameBufferSRGB() with sRGB=false flag,
34-
//! which asks OCCT to disable GL_FRAMEBUFFER_SRGB and apply sRGB gamma correction manually.
35-
class OcctQtFrameBuffer : public OpenGl_FrameBuffer
36-
{
37-
DEFINE_STANDARD_RTTI_INLINE(OcctQtFrameBuffer, OpenGl_FrameBuffer)
38-
public:
39-
//! Empty constructor.
40-
OcctQtFrameBuffer() {}
41-
42-
//! Make this FBO active in context.
43-
virtual void BindBuffer(const Handle(OpenGl_Context)& theGlCtx) override
44-
{
45-
OpenGl_FrameBuffer::BindBuffer(theGlCtx);
46-
theGlCtx->SetFrameBufferSRGB(true, false);
47-
}
48-
49-
//! Make this FBO as drawing target in context.
50-
virtual void BindDrawBuffer(const Handle(OpenGl_Context)& theGlCtx) override
51-
{
52-
OpenGl_FrameBuffer::BindDrawBuffer(theGlCtx);
53-
theGlCtx->SetFrameBufferSRGB(true, false);
54-
}
55-
56-
//! Make this FBO as reading source in context.
57-
virtual void BindReadBuffer(const Handle(OpenGl_Context)& theGlCtx) override
58-
{
59-
OpenGl_FrameBuffer::BindReadBuffer(theGlCtx);
60-
}
61-
};
6228

6329
// ================================================================
6430
// Function : OcctQQuickFramebufferViewer
@@ -433,7 +399,6 @@ void OcctQQuickFramebufferViewer::Renderer::synchronize(QQuickFramebufferObject*
433399
myViewer->synchronize(framebufferObject());
434400
}
435401

436-
437402
// ================================================================
438403
// Function : render
439404
// ================================================================
@@ -496,59 +461,36 @@ void OcctQQuickFramebufferViewer::render(QOpenGLFramebufferObject* theFbo)
496461
{
497462
// this method is called from GL rendering thread;
498463
// accessing GUI items is not allowed here!
464+
Standard_Mutex::Sentry aLock(myViewerMutex);
465+
const QQuickWindow* aQWindow = window();
499466
if (theFbo == nullptr || myView.IsNull())
500467
return;
501468

502-
QQuickWindow* aQWindow = window();
503-
Aspect_Drawable aNativeWin = aQWindow != nullptr ? (Aspect_Drawable)aQWindow->winId() : 0;
504-
#ifdef _WIN32
505-
HDC aWglDevCtx = wglGetCurrentDC();
506-
HWND aWglWin = WindowFromDC(aWglDevCtx);
507-
aNativeWin = (Aspect_Drawable)aWglWin;
508-
#endif
509-
510-
Standard_Mutex::Sentry aLock(myViewerMutex);
511-
if (myView->Window().IsNull())
469+
const Aspect_Drawable aNativeWin =
470+
OcctGlTools::GetGlNativeWindow(aQWindow != nullptr ? (Aspect_Drawable)aQWindow->winId() : 0);
471+
const Graphic3d_Vec2i aViewSize(theFbo->size().width(), theFbo->size().height());
472+
if (myView->Window().IsNull()
473+
|| myView->Window()->NativeHandle() != aNativeWin)
512474
{
513475
initializeGL(theFbo);
514476
theFbo->bind();
477+
if (myView->Window().IsNull())
478+
return;
515479
}
516-
else if (myView->Window()->NativeHandle() != aNativeWin)
517-
{
518-
// workaround window recreation done by Qt on monitor (QScreen) disconnection
519-
Message::SendWarning() << "Native window handle has changed by QQuickWindow!";
520-
synchronize(theFbo);
521-
return;
522-
}
480+
481+
Graphic3d_Vec2i aViewSizeOld; myView->Window()->Size(aViewSizeOld.x(), aViewSizeOld.y());
523482

524483
// wrap FBO created by QOpenGLFramebufferObject
525-
Handle(OpenGl_Context) aGlCtx = OcctGlTools::GetGlContext(myView);
526-
Handle(OpenGl_FrameBuffer) aDefaultFbo = aGlCtx->DefaultFrameBuffer();
527-
if (aDefaultFbo.IsNull())
528-
{
529-
aDefaultFbo = new OcctQtFrameBuffer();
530-
aGlCtx->SetDefaultFrameBuffer(aDefaultFbo);
531-
}
532-
if (!aDefaultFbo->InitWrapper(aGlCtx))
484+
if (!OcctGlTools::InitializeGlFbo(myView))
533485
{
534-
aDefaultFbo.Nullify();
535-
Message::DefaultMessenger()->Send("Default FBO wrapper creation failed", Message_Fail);
536486
QMessageBox::critical(0, "Failure", "Default FBO wrapper creation failed");
537487
QApplication::exit(1);
538488
return;
539489
}
540490

541-
Graphic3d_Vec2i aViewSizeOld;
542-
const Graphic3d_Vec2i aViewSizeNew = aDefaultFbo->GetVPSize();
543-
Handle(Aspect_NeutralWindow) aWindow = Handle(Aspect_NeutralWindow)::DownCast(myView->Window());
544-
aWindow->Size(aViewSizeOld.x(), aViewSizeOld.y());
491+
Graphic3d_Vec2i aViewSizeNew; myView->Window()->Size(aViewSizeNew.x(), aViewSizeNew.y());
545492
if (aViewSizeNew != aViewSizeOld)
546-
{
547-
aWindow->SetSize(aViewSizeNew.x(), aViewSizeNew.y());
548-
myView->MustBeResized();
549-
myView->Invalidate();
550493
dumpGlInfo(true, false);
551-
}
552494

553495
// reset global GL state from Qt before redrawing OCCT
554496
OcctGlTools::ResetGlStateBeforeOcct(myView);

0 commit comments

Comments
 (0)