How to use gtkmm with EGL

泄露秘密 提交于 2019-12-24 05:06:17

问题


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


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/57797368/how-to-use-gtkmm-with-egl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!