I'm trying to port the code from https://github.com/eryar/occQt to gtkmm, by creating a custom widget and overriding the Gtk::widget::on_realize() method like
void OccView::on_realize() {
// Create Aspect_DisplayConnection
Handle(Aspect_DisplayConnection) display_connection = new Aspect_DisplayConnection();
// Get graphic driver if it exists, otherwise initialize it.
Handle(Graphic3d_GraphicDriver) graphic_driver;
if (!graphic_driver) {
graphic_driver = new OpenGl_GraphicDriver(display_connection);
}
// Get window handle. This returns something suitable for all platforms.
Window x_window = GDK_SURFACE_XID(get_native()->get_surface()->gobj());
// Create window for platform.
Handle(Xw_Window) xw_window = new Xw_Window(display_connection, x_window);
// Create V3dViewer and V3d_View
mViewer = new V3d_Viewer(graphic_driver, Standard_ExtString("viewer3d"));
mView = mViewer->CreateView();
// Set window for the view
mView->SetWindow(xw_window);
if (!xw_window->IsMapped()) {
xw_window->Map();
}
// Create AISInteractiveContext
mContext = new AIS_InteractiveContext(mViewer);
// Set up lights etc
mViewer->SetDefaultLights();
mViewer->SetLightOn();
mView->SetBackgroundColor(Quantity_NOC_BLACK);
mView->MustBeResized();
mView->TriedronDisplay(Aspect_TOTP_LEFT_LOWER, Quantity_NOC_GOLD, 0.08, V3d_ZBUFFER);
mContext->SetDisplayMode(AIS_Shaded, Standard_True);
// Call base method
Gtk::Widget::on_realize();
}
but the Gtk::Window
stays empty after appending the OccView
object. What am I doing wrong? Is there a working example on how to integrate the Opencascade V3d_View
into a Gtk::Widget
, or the gtkmm framework in general?
I haven't used GTK since university, so my experience is pretty basic here.
There are two basic approaches for embedding OpenGL-based viewer into GTK:
Gtk::GLArea
.Your current code tries to follow the first approach used by conventional samples for Qt Widgets and MFC coming with OCCT. I guess it should be feasible, but implies some limitations and issues with mixing GTK widgets, as GTK will not be aware of OpenGL usage.
In contrast, Gtk::GLArea
looks like a "modern" way for embedding OpenGL renderer designed by GTK developers and expected to work transparently.
Therefore, I've tried implementing a Hello-World sample using Gtk::GLArea
(based on a development snapshot of OCCT 7.6.0dev):
https://github.com/gkv311/occt-samples-gtk
I don't bring the whole code of the sample here, as it is quite large in size.
Putting OCCT Viewer into Gtk::GLArea
includes some tricky parts like:
Aspect_Window
(it could be also Xw_Window
like in your sample, more general Aspect_NeutralWindow
or another subclass).Gtk::GLArea
into Aspect_RenderingContext
/OpenGl_Context
.Gtk::GLArea
for rendering content into OpenGl_FrameBuffer
.Gtk::GLArea::signal_render()
.AIS_ViewController
).It is important to note, that GTK may be run in different context:
GLX
is used for OpenGL.EGL
is used for OpenGL context.EGL
but as a dedicated configuration as alternative to GLX
, while GTK handles this in runtime somehow. In addition, OCCT does not (yet) provide any wrapper for a Wayland native window, though it might be not critical for using.Initially I expected Gtk::GLArea
to work natively, but instead a very basic sample (without OCCT viewer) displays artifacts to me (widgets randomly blacked) on Xubuntu 18.04, though it works as expected on Ubuntu 21.04 (within Xorg session). I don't know if it is a bug fixed in GTK implementation, or there is something that should be fixed in a sample to workaround problem on older Linux.