C++ 如何将gtkmm与EGL一起使用

C++ 如何将gtkmm与EGL一起使用,c++,gtk,C++,Gtk,我发现了一篇关于如何将EGL与GTK结合使用的博客文章。然而,我在我的项目中使用gtkmm,因此我需要找到如何使用它 我需要找到这些函数: 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 gdk_x11_display_get

我发现了一篇关于如何将EGL与GTK结合使用的博客文章。然而,我在我的项目中使用gtkmm,因此我需要找到如何使用它

我需要找到这些函数:

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
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
关于gtkmm。他们的gtkmm可能返回类实例,所以我需要弄清楚如何获得这些类指向的C对象

如果我们这样做,我们来看一个例子:

Display*    gdk_x11_display_get_xdisplay ()
它返回一个
显示*
。同时,在中,我们看到
gobj()
返回C对象
GdkDisplay*

GdkDisplay*     gobj ()
这不是同一个对象

那么,如何找到这些函数的gtkmm版本呢

更新2:

根据评论中的建议,我给出了一个最小的可复制示例:

#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);
}
有些东西仍然不符合我根据

GTK+内部的OpenGL支持需要核心GL配置文件,因此在OpenGL 3.2及更高版本之前,它不会与固定管道API一起工作。这意味着您将无法使用像glRotatef()或glBegin()/glEnd()对之类的API,或者任何类似的东西

因此,您需要切换到使用可编程管道(即着色器,以及所有必要的工具),以便使用Gtk::GLArea小部件

我需要找到这些函数:

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
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
关于gtkmm

其中一些在gtkmm中很容易找到包装。毕竟,有一个命名系统。名为“
GTK”的GTK函数__
  • 这会导致X11交互。我不知道GDK的“X11”部分的C++包装器。所以您可能需要知道几个类似的命名类。例如,<>代码> GTK::窗口< /C> >和<>代码> GDK::窗口是不同的类。和

    GdkDisplay
    是不同的类。(特别是,
    Display
    不是GTK的一部分,也不是GDK的一部分;它是X11的一部分。)

    根据系统的工作方式(这意味着我没有测试过),以下几行应该是从gtkmm调用GDK的X11交互函数的一种方式。这些假设变量已声明为
    Gtk::GLArea GLArea
    ,例如示例代码中的数据成员

    gdk_x11_display_get_xdisplay(glArea.get_display()->gobj());
    gdk_x11_window_get_xid(glArea.get_window()->gobj());
    

    get\u display
    方法返回一个指向
    Gdk::display
    的智能指针。调用指向对象的方法会产生一个
    GdkDisplay*
    ,然后可以将该指针馈送到
    Gdk\u x11\u display\u get\u xdisplay
    。类似地,
    get\u window
    返回指向
    Gdk::window
    的智能指针,可以进行转换d指向指向
    gdk_x11_window\u get_xid的C对象的指针这有点让人困惑,但是有一个gtkmm
    gdk::Display
    类,它不同于来自x11的
    Display
    类型。调用
    gobj()
    Gdk::Display
    对象上的
    GdkDisplay
    指针,您可以将其传递到
    Gdk\u x11\u Display\u get\u xdisplay()
    以获取(x11)
    Display
    指针。@为什么要从我的程序中获取
    Gdk::Display
    ?GTK::Widget不从Display继承。GTK::Window也不从Display继承。
    GTK::Widget
    GTK::Window
    都提供了
    get\u Display()
    用于获取
    Gdk::Display
    的方法@whydoubt
    eglGetDisplay((eglnativedisplayte)Gdk_x11_Display_get_xdisplay(gtk_widget_get_Display(widget));
    这一行需要
    GTKWidget*小部件
    。如果我做
    gobj()
    在我的gtk小部件上,然后静态转换为
    GTKWidget*
    gtk::widget::gobj()
    返回
    GtkWidget*
    如中所示,我按照您所说的做了。请查看我的更新。我在eglChooseConfig上遇到错误。这些显示不正确。@LucasZanella这是一个新问题。我更新了问题以不使用它们。您能看一看吗?我在eglChooseConfig上遇到错误