有没有办法在gtk的ui线程以外的线程上运行opengl命令?

时间:2019-07-11 08:11:11

标签: c++ multithreading opengl gtk3

我正在一个需要管道创建和从另一个线程进行gtk眩光渲染的项目中工作。

我正在使用环氧树脂作为gl装载机。我也在Windows系统上使用mingw的gtk +构建。使用示例三角代码,创建管道并使用glarea的realizerender信号进行渲染即可。但是任何其他线程上的gl调用都会导致应用崩溃。

这里是渲染和线程逻辑。我仍然使用realize信号配置管道,但是渲染是在其他线程上完成的。

窗口类

#include "window.h"
#include <thread>
#include <chrono>

namespace M
{

Window::Window()
{
    set_border_width(6);
    set_default_size(640, 480);

    _box.set_spacing(6);
    add(_box);

    _box.pack_end(ngl, Gtk::PACK_EXPAND_WIDGET); // ngl : the GLArea variable

    show_all();

    thread = std::thread( [this] { render(); } );
}

void Window::render()
{
    using namespace std::chrono_literals;
    std::this_thread::sleep_for(5s);

    ngl.renderTri();
}

}

GLArea类

#include "glarea.h"

namespace M
{

GLArea::GLArea()
    : _points(0),
      _colors(0),
      _matrix(0),
      _isButton3Pressed(false),
      _isKeyWPressed(false),
      _isKeyAPressed(false),
      _isKeySPressed(false),
      _isKeyDPressed(false)
{
    set_has_window(false);

    // It is important to explicitely allow events on the GLArea!
    _glArea.add_events(Gdk::POINTER_MOTION_MASK
            | Gdk::BUTTON_PRESS_MASK
            | Gdk::BUTTON_RELEASE_MASK
            | Gdk::KEY_PRESS_MASK
            | Gdk::KEY_RELEASE_MASK);

    pack_end(_glArea, Gtk::PACK_EXPAND_WIDGET);

    _glArea.signal_realize().connect(
            sigc::mem_fun(*this, &GLArea::realize));
    // It is important that the unrealize signal calls our handler to clean up
    // GL resources *before* the default unrealize handler is called, hence the
    // "false".
    _glArea.signal_unrealize().connect(
            sigc::mem_fun(*this, &GLArea::unrealize), false);
    /*_glArea.signal_render().connect(
            sigc::mem_fun(*this, &GLArea::render));*/

    _glArea.signal_key_press_event().connect(
            sigc::mem_fun(*this, &GLArea::on_key_press_event), false);
    _glArea.signal_key_release_event().connect(
            sigc::mem_fun(*this, &GLArea::on_key_release_event), false);

    // Grab the focus to get all key events no matter what!
    _glArea.set_can_focus(true);
    _glArea.grab_focus();

    show_all();
}

GLArea::~GLArea()
{
}

void GLArea::renderTri()
{
    while(true)
    {
        GLArea::render();
        _glArea.queue_draw();
    }
}

bool GLArea::render()
{
    try {

    _glArea.make_current();
        _glArea.throw_if_error();

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        //draw();
        if(_isKeyWPressed) {
            _matrix[13] += 0.01;
        }
        if(_isKeyAPressed) {
            _matrix[12] -= 0.01;
        }
        if(_isKeySPressed) {
            _matrix[13] -= 0.01;
        }
        if(_isKeyDPressed) {
            _matrix[12] += 0.01;
        }

        glUniformMatrix4fv(_matrixLocation, 1, GL_FALSE, _matrix);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        return true;
    } catch(const Gdk::GLError &error) {
        std::cerr
            << error_string()
            << "Something went wrong in the render callback\n\t"
            << "\n\tDomain: " << error.domain()
            << "\n\tCode: " << error.code()
            << "\n\tWhat: " << error.what()
            << std::endl;
        return false;
    }
}
}

完整的原始样本可以在这里找到。 https://github.com/mschwan/glarea-animation

我希望显示三角形,或者如果出现任何gl错误或警告,则将其打印出来,但是出现分段错误。 [信息]实现GL上下文         英特尔(R)高清显卡4400         3.2.0-版本20.19.15.4963 分割错误

0 个答案:

没有答案