Reputation: 1850
I found this blog post that has an example on how to use EGL with GTK. However I use gtkmm on my project, therefore I need to find how to do things with it
I need to find these functions:
gdk_x11_display_get_xdisplay
gtk_widget_get_display
gdk_x11_window_get_xid
gtk_widget_get_window
gtk_widget_get_allocated_width
gtk_widget_get_allocated_height
on gtkmm. Their gtkmm probably return class instances, so I need to figure out how to get the C object these classes point to as well
If we look at the GTK functions, let's see an example:
Display* gdk_x11_display_get_xdisplay ()
It returns a Display*
. Meanwhile, in the gtkmm for Display we see that gobj()
returns the C object GdkDisplay*
:
GdkDisplay* gobj ()
which is not the same object.
So, how to find the gtkmm versions of these functions?
UPDATE2:
based on the suggestions in the comment, I made a minimal reproducible example:
#include <iostream>
#include <gtkmm.h>
#include <epoxy/gl.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GL/gl.h>
class MyOpenGLArea : public Gtk::Window
{
public:
MyOpenGLArea()
{
set_title("Test");
set_default_size(640, 360);
add(vBox);
glArea.set_hexpand(true);
glArea.set_vexpand(true);
glArea.set_auto_render(true);
vBox.add(glArea);
glArea.signal_realize().connect(sigc::mem_fun(*this, &MyOpenGLArea::realize));
glArea.signal_render().connect(sigc::mem_fun(*this, &MyOpenGLArea::render), false);
glArea.show();
vBox.show();
};
public:
Gtk::GLArea glArea;
Gtk::Box vBox{Gtk::ORIENTATION_VERTICAL, false};
void realize()
{
EGLBoolean eglStatus;
EGLConfig eglConfig;
EGLint n_config;
EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
eglDisplay = eglGetDisplay((EGLNativeDisplayType)gdk_x11_display_get_xdisplay(glArea.get_display()->gobj()));
eglStatus = eglInitialize(eglDisplay, NULL, NULL);
if (!eglStatus)
{
printf("Error at eglInitialize\n");
switch (eglStatus)
{
case EGL_BAD_DISPLAY:
printf("EGL_BAD_DISPLAY\n");
break;
case EGL_NOT_INITIALIZED:
printf("EGL_NOT_INITIALIZED\n");
break;
case EGL_FALSE:
printf("EGL_FALSE\n");
break;
}
}
eglStatus = eglChooseConfig(eglDisplay, context_attribs, &eglConfig, 1, &numConfigs);
if (!eglStatus)
{
printf("Error at eglChooseConfig\n");
switch (eglStatus)
{
case EGL_BAD_DISPLAY:
printf("EGL_BAD_DISPLAY\n");
break;
case EGL_BAD_ATTRIBUTE:
printf("EGL_BAD_ATTRIBUTE\n");
break;
case EGL_NOT_INITIALIZED:
printf("EGL_NOT_INITIALIZED\n");
break;
case EGL_BAD_PARAMETER:
printf("EGL_BAD_PARAMETER\n");
break;
case EGL_FALSE:
printf("EGL_FALSE\n");
break;
}
}
};
virtual bool render(const Glib::RefPtr<Gdk::GLContext> &context)
{
glDraw();
glFinish();
return true;
}
void glDraw()
{
}
private:
EGLDisplay eglDisplay;
EGLSurface eglSurface;
EGLContext eglContext;
int numConfigs;
};
int main(int argc, char **argv)
{
auto app = Gtk::Application::create(argc, argv, "");
MyOpenGLArea myOpenGLArea;
return app->run(myOpenGLArea);
}
Here's the output:
libEGL warning: DRI2: failed to authenticate
Error at eglChooseConfig
EGL_FALSE
Something is still not rigth with the display I get
Upvotes: 2
Views: 832
Reputation: 16851
I need to find these functions:
gdk_x11_display_get_xdisplay gtk_widget_get_display gdk_x11_window_get_xid gtk_widget_get_window gtk_widget_get_allocated_width gtk_widget_get_allocated_height
on gtkmm.
Some of these have easy-to-find wrappers in gtkmm. There is a naming system in place, after all. A GTK function named "gtk_<thing>_<action>
" usually corresponds to the <action>
method of the (capitalized) <Thing>
class in the Gtk
namespace – i.e. Gtk::<Thing>::<action>
.
Gtk::Widget::get_display
Gtk::Widget::get_window
Gtk::Widget::get_allocated_width
Gtk::Widget::get_allocated_height
That leaves the X11 interaction. I am not aware of a C++ wrapper for the "x11" portion of GDK, so you might need to mix C and C++ APIs. Just be aware of several similarly-named classes. For example, Gtk::Window
and Gdk::Window
are distinct classes. Also, Display
(without a namespace) and GdkDisplay
are distinct classes. (In particular, Display
is not part of GTK nor of GDK; it is part of X11.)
Based on how the system is supposed to work (meaning that I have not tested this), the following lines should be a way to invoke GDK's X11 interaction functions from gtkmm. These assume a variable has been declared as Gtk::GLArea glArea
, such as the data member from the example code.
gdk_x11_display_get_xdisplay(glArea.get_display()->gobj());
gdk_x11_window_get_xid(glArea.get_window()->gobj());
The get_display
method returns a smart pointer to a Gdk::Display
. Calling the pointed-to object's gobj
method gives a GdkDisplay*
which could then be fed to gdk_x11_display_get_xdisplay
. Similarly, get_window
returns a smart pointer to a Gdk::Window
, which can be converted to a pointer to the C object for gdk_x11_window_get_xid
.
Upvotes: 1
Reputation: 799
According to https://www.bassi.io/articles/2015/02/17/using-opengl-with-gtk/
the OpenGL support inside GTK+ requires core GL profiles, and thus it won’t work with the fixed pipeline API that was common until OpenGL 3.2 and later versions. this means that you won’t be able to use API like glRotatef(), or glBegin()/glEnd() pairs, or any of that stuff.
So you need to switch to using the programmable pipeline (i.e. shaders, and all that entails) in order to get going with the Gtk::GLArea widget.
Upvotes: 1