首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在EGL中使用gtkmm

如何在EGL中使用gtkmm
EN

Stack Overflow用户
提问于 2019-09-05 01:32:25
回答 2查看 504关注 0票数 2

我找到了博客文章,其中有一个关于如何在GTK中使用EGL的示例。但是我在我的项目中使用了gtkmm,因此我需要找到如何用它来做事情。

我需要找到这些功能:

代码语言:javascript
运行
复制
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对象

如果我们使用查看GTK函数,让我们看看一个例子:

代码语言:javascript
运行
复制
Display*    gdk_x11_display_get_xdisplay ()

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

代码语言:javascript
运行
复制
GdkDisplay*     gobj ()

而不是同一个对象。

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

UPDATE2:

根据评论中的建议,我提出了一个最少可重复的例子:

代码语言:javascript
运行
复制
#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);
}

这是输出:

代码语言:javascript
运行
复制
libEGL warning: DRI2: failed to authenticate
Error at eglChooseConfig
EGL_FALSE

我得到的显示还不够严格。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-13 19:44:19

我需要找到这些功能: 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_<thing>_<action>“的GTK函数通常对应于Gtk命名空间中(大写) <Thing>类的<action>方法-即Gtk::<Thing>::<action>

这就留下了X11交互。我不知道GDK的“C++”部分有一个x11包装器,所以您可能需要使用混合C和C++ API。只要注意几个同名的类就行了。例如,Gtk::WindowGdk::Window是不同的类。另外,Display (没有命名空间)和GdkDisplay是不同的类。(尤其是,Display不是GTK的一部分,也不是GDK的一部分;它是X11的一部分。)

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

代码语言:javascript
运行
复制
gdk_x11_display_get_xdisplay(glArea.get_display()->gobj());
gdk_x11_window_get_xid(glArea.get_window()->gobj());

get_display方法返回指向Gdk::Display的智能指针。调用指向对象的gobj方法将提供一个GdkDisplay*,然后该GdkDisplay*可以输入给gdk_x11_display_get_xdisplay。类似地,get_window返回一个指向Gdk::Window的智能指针,该指针可以转换为指向gdk_x11_window_get_xid的C对象的指针。

票数 1
EN

Stack Overflow用户

发布于 2019-09-12 05:56:22

根据https://www.bassi.io/articles/2015/02/17/using-opengl-with-gtk/

OpenGL在GTK+中的支持需要核心GL配置文件,因此在OpenGL 3.2和更高版本之前,它将无法使用固定的管道API。这意味着您将无法使用glRotatef()或glBegin()/glEnd()对之类的API。

因此,为了使用Gtk::GLArea小部件,您需要切换到使用可编程管道(即着色器和所有所需的内容)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57797368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档