[vtkusers] vtk and gtk on macOS

Langer, Stephen A. (Fed) stephen.langer at nist.gov
Tue Nov 14 14:59:19 EST 2017


Responding to my own message again…

Is it possible that the vtk or gtk+2 coordinate systems are different on different platforms?
On a Mac, using vtk 7.1.1 and Cocoa, the configure callback for the vtk render window inside a gtk widget looks like this:

gboolean OOFCanvas3D::configure(GdkEventConfigure *event) {
   render_window->SetSize(event->width, event->height);
  GtkWidget *topwindow = gtk_widget_get_toplevel(drawing_area);
  assert(topwindow != nullptr);
  int top_height = topwindow->allocation.height;
  render_window->SetPosition(event->x, top_height - event->y - event->height);
  return true;
}

but that doesn't work on Linux (Ubuntu inside VirtualBox, using vtk 7.1.1 and X11), where it has to be this:

gboolean OOFCanvas3D::configure(GdkEventConfigure *event) {
   render_window->SetSize(event->width, event->height);
  render_window->SetPosition(event->x, event->y);
  return true;
}

Both of these do what they should do (on their respective platforms) when the space allocated for the vtk render window is changed.  But it looks like on the Mac the position of the vtk widget is measured from the bottom of the enclosing window while on Linux it's measured from the top!  Can this be true?  What am I missing?

Thanks.

-- Steve


From: vtkusers <vtkusers-bounces at vtk.org> on behalf of "Langer, Stephen A. (Fed)" <stephen.langer at nist.gov>
Date: Tuesday, November 14, 2017 at 2:06 PM
To: "vtkusers at vtk.org" <vtkusers at vtk.org>
Subject: Re: [vtkusers] vtk and gtk on macOS

Just in case someone else is trying to do the same thing and finds this message, the configure callback below is incorrect because gtk and vtk have different ideas about which direction is up.  The call to render_window->SetPosition should be
  GtkWidget *top = gtk_widget_get_toplevel(drawing_area)
 render_window->SetPosition(top->allocation.height- event->y - event->height);

event->y and drawing_area->allocation.y are interchangeable.

-- Steve

From: vtkusers <vtkusers-bounces at vtk.org> on behalf of "Langer, Stephen A. (Fed)" <stephen.langer at nist.gov>
Date: Friday, November 3, 2017 at 10:11 AM
To: David Gobbi <david.gobbi at gmail.com>
Cc: "vtkusers at vtk.org" <vtkusers at vtk.org>
Subject: Re: [vtkusers] vtk and gtk on macOS


HI David --

Thanks for the suggestions, which got me started on the right track.

What seems to work is this (somewhat simplified to eliminate some infrastructure):

// Create gtk widget and vtk window
GtkWidget *drawing_area = gtk_drawing_area_new();
vtkSmartPointer<vtkCocoaRenderWindow> render_window = vtkSmartPointer<vtkCocoaRenderWindow>::New();
// Connect to gtk signals.
g_signal_connect(drawing_area, "realize", realize_callback, ..)
g_signal_connect(drawing_area, "configure_event", configure_callback, …)

// in realize_callback
gtk_widget_realize(drawing_area);
render_window->SetRootWindow(gtk_widget_get_root_window(drawing_area));
GdkWindow gparent = gtk_widget_get_parent_window(drawing_area);
NSView *pid = gdk_quartz_window_get_nsview(gparent);
render_window->SetParentId((void*) pid);

// in configure_callback
// event is a GdkEventConfigure* that's passed in as an argument
// Unlike David's  QWidget example, I do not use the superclass versions of SetSize and SetPosition
render_window->SetSize(event->width, event->height);
render_window->SetPosition(drawing_area->allocation.x, drawing_area->allocation.y);

I also added an expose event callback which just called render_window->Render(), but it doesn't seem to be necessary.

-- Steve

From: David Gobbi <david.gobbi at gmail.com>
Date: Tuesday, October 24, 2017 at 2:56 PM
To: "Langer, Stephen A. (Fed)" <stephen.langer at nist.gov>
Cc: "vtkusers at vtk.org" <vtkusers at vtk.org>
Subject: Re: [vtkusers] vtk and gtk on macOS

Hi Steve,

Here is some code that I use to bind a VTK window to a QWidget.  My guess is that something similar should work with GTK.  I have been using this on OS X with vtkCocoaRenderWindow.

void BindRenderWindow(vtkRenderWindow *window, QWidget *widget)
{
  // Unmap the window if it is already mapped somewhere else.
  if (window->GetMapped()) {
    window->Finalize();
  }
  // Create the connection
  window->SetWindowId(reinterpret_cast<void *>(widget->winId()));
  // Note that we must call the superclass SetSize()/SetPosition()
  // (we just want to set the member variables, with no side-effects)
  window->vtkRenderWindow::SetSize(widget->width(), widget->height());
  window->vtkRenderWindow::SetPosition(widget->x(), widget->y());
  // Prepare for rendering
  if (widget->isVisible()) {
    window->Start();
  }
  // Call SetSize() again, to synchronize the window to the widget
  window->SetSize(widget->width(), widget->height());
}

Some further notes:
1) I disable Qt's paint engine, so that Qt itself doesn't draw in the window.  GTK may be similar.
2) You probably will not need GtkGLExt (for Qt, I didn't have to use QGLWidget).

 - David



On Tue, Oct 24, 2017 at 12:12 PM, Langer, Stephen A. (Fed) <stephen.langer at nist.gov<mailto:stephen.langer at nist.gov>> wrote:
Hi --

Is there a simple way to get vtk to work inside a gtk+2 program on macOS?   If there isn't a simple way, is there a difficult one?

I'm trying to get a program that uses gtk+2 and vtk to work with a modern version of vtk -- I'm upgrading from 5.10.1 to 7.1.1 or 8.0.1.    On Linux, the following code creates a vtk render window and a gtk widget containing it:
    vtkRenderWindow *render_win = vtkRenderWindow::New();
    GtkWidget *drawing_area = gtk_drawing_area_new();
    Display *disp = GDK_DISPLAY();
    render_win->SetDisplayId(disp);
followed eventually by
     XID wid = GDK_WINDOW_XID(drawing_area->window);
     render_win->SetWindowId(wid);
after receiving the gtk "realize" signal on the drawing_area.

On macOS, I'd like to use the Cocoa version of gtk+2 and vtkCocoaRenderWindow, but I can't figure out how to embed the render window into a gtk widget.    All the examples I've found on-line aren't really applicable.

GtkGLExt might be applicable, but it doesn't look like it's being maintained.

An alternative would be to use X11, but native Mac OpenGL doesn't understand X11, so I tried installing mesa from macports , rebuilding vtk with VTK_USE_X instead of VTK_USE_COCOA, and linking to /opt/local/lib instead of /System/Library/Frameworks/OpenGL.framework.  Then I can use the same code as on Linux, but vtk complains about the context not supporting OpenGL 3.2, and then crashes:
  ERROR: In /Users/langer/UTIL/VTK/VTK-7.1.1/Rendering/OpenGL2/vtkTextureObject.cxx, line 440
  vtkTextureObject (0x7f9eafdb1690): failed at glGenTextures 1 OpenGL errors detected
    0 : (1280) Invalid enum

Thanks,
     Steve
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20171114/711037db/attachment.html>


More information about the vtkusers mailing list