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::GLArealooks 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::GLAreaincludes some tricky parts like:Aspect_Window(it could be alsoXw_Windowlike in your sample, more generalAspect_NeutralWindowor another subclass).Gtk::GLAreaintoAspect_RenderingContext/OpenGl_Context.Gtk::GLAreafor rendering content intoOpenGl_FrameBuffer.Gtk::GLArea::signal_render().AIS_ViewController).It is important to note, that GTK may be run in different context:
GLXis used for OpenGL.This is default OCCT configuration for Linux;
EGLis used for OpenGL context.OCCT does support
EGLbut as a dedicated configuration as alternative toGLX, 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::GLAreato 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.