Я работаю над проектом, требующим создания конвейера и выполнения вызовов gtk glarea из другого потока.
Я использую эпоксидную смолу в качестве загрузчика gl. Я также использую сборку mtw gtk + в системе Windows. Использование примера кода треугольника, создание конвейера и рендеринг с использованием сигналов realize
и render
glarea. Но любой вызов 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 контекста
Intel® HD Graphics 4400
3.2.0 - сборка 20.19.15.4963
Ошибка сегментации