2016-06-28 2 views
2

В настоящее время я пытаюсь получить окно Qt 5 и QOpenGLContext, работающее с GLEW. Да, я знаю, что Qt 5 предоставляет свои собственные функции для OpenGL, но поскольку мой движок рендеринга использует GLEW и поддерживает другие библиотеки окон, встроенный материал Qt не является вариантом.Использование GLEW с Qt 5.x

Теперь, вот что я встал и работает до сих пор:

  1. I к югу классифицироваться QWindow и оснастили его с QOpenGLContext. Контекст успешно инициализирован.

  2. После инициализации QOpenGLContext, я (снова успешно) позвонил glewInit(), чтобы инициализировать GLEW.

  3. Теперь я могу визуализировать геометрию для фреймбуфера по умолчанию точно так же, как и для других оконных фреймворков (точнее, GLFW).

Здесь сложная часть: я использую один из однородных объектов буфера OpenGL для передачи световых данных на GPU. Как только я позвоню glBufferData(), чтобы заполнить его, я получаю ошибку сегментации. При использовании моей реализации на основе GLFW и инициализации контекста все работает нормально. Я знаю, что такого рода поведение можно ожидать для недостаточно инициализированных контекстов OpenGL, но, опять же, настройка QOpenGLContext и вызов glewInit(), похоже, очень хорошо работают.

Вот код, чтобы показать, что я пытаюсь сделать ...

QtWindow::QtWindow(QWindow *parent) 
: QWindow(parent) { 

    setSurfaceType(QWindow::OpenGLSurface); 

    QSurfaceFormat format; 
    format.setVersion(4,5); 
    format.setOption(QSurfaceFormat::DeprecatedFunctions); 
    format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); 
    format.setProfile(QSurfaceFormat::CoreProfile); 

    setFormat(format); 

} 

Этого должно быть достаточно, чтобы в дальнейшем получить контекст формата я хочу. Теперь, как раз перед первым кадром оказывается, я создал контекст и GLEW ...

void QtWindow::init_context() { 

    if (!initialized_) { 
    context_handler_.init(this); 
    initialized_ = true; 

    glewExperimental = GL_TRUE; 
    auto e = glewInit(); 
    if (e != GLEW_OK) { 
     std::cout << "Failed to initialize glew: " 
       << glewGetErrorString(e) << std::endl; 
    } 

    glGetError(); 

    } 

} 

я использую небольшой вспомогательный класс для инициализации QOpenGLContext как мне нужно, чтобы предотвратить Qt из не-определений GLEW макросов:

void QtContextHandler::init(QWindow* parent) { 
    if (!qt_context_) { 
    qt_context_ = new QOpenGLContext(parent); 
    qt_context_->setFormat(parent->requestedFormat()); 

    if (qt_context_->create()) { 
     auto format(qt_context_->format()); 
     std::cout << "Initialized Qt OpenGL context " 
       << format.majorVersion() << "." 
       << format.minorVersion() << " successfully." 
       << std::endl; 


     qt_context_->makeCurrent(parent); 
    } else { 
     std::cout << "Failed to initialize Qt OpenGL context!" 
       << std::endl; 
    } 

    } 
} 

Вот что я делаю для настройки подсветки UBO и сбоя при инициализации OpenGL, как показано выше. Я использую oglplus как GL обертке, но так как она оборачивает функции OpenGL довольно плотно, вы должны получить идею:

ubo_.Bind(ogl::Buffer::Target::Uniform); 

oglplus::Buffer::Data(oglplus::Buffer::Target::Uniform, sizeof(data), &data, oglplus::BufferUsage::DynamicDraw); 

Кто-нибудь пробовал аналогичные подходы и могут поделиться своим опытом? Я был бы признателен за любую помощь, поскольку я застрял, пытаясь понять, что я делаю неправильно. Опять же: инициализация работает нормально, и я даже могу создавать VBOs/VAOs/IBOs для рендеринга сеток! Только создание UBO вызывает ошибку сегментации.

EDIT:

Хорошо, вот некоторые новые идеи. Прежде всего, ошибка сегментации возникает только в том случае, если загруженные данные превышают определенный размер (~ 90 байтов). Другими словами, я могу визуализировать сцену с созданным Qt контекстом, используя только один настраиваемый источник света. Однако при запросе GL_MAX_UNIFORM_BLOCK_SIZE драйвер говорит мне, что 64 КБ доступны для однородных блоков (то же самое относится к контекстам, созданным в GLFW). Кто-нибудь имеет представление о том, что может пойти не так?

+1

Вы говорите, что как только вы используете 'glBufferData', вы получаете ошибку seg. Вы проверили, что 'glBufferData' не является нулевым в этот момент? –

+0

@ G.M. Да, я проверил это. Любопытно, что я попытался загрузить некоторые фиктивные данные, например: 'std :: array d = {0,1,2,3,4,5,6,7,8,9}' и 'ogl :: Buffer :: Data (ogl :: Buffer :: Target :: Uniform, sizeof (d), & d, ogl :: BufferUsage :: DynamicDraw); и он отлично работал (за исключением неожиданного поведения на стороне шейдера, очевидно). У меня возникает ощущение, что типы данных, которые я использую для световых данных, перепутались или что-то в этом роде. –

ответ

1

Хорошо, на случай, если кто-либо столкнется с аналогичными трудностями: мне удалось заставить его работать, загрузив данные UBO с помощью glBufferStorage вместо glBufferData. Первый используется для создания буферов неизменяемого размера, что достаточно для моих целей. Тем не менее, я не знаю, что пошло не так с glBufferData и является ли это ошибкой в ​​Qt или я неправильно инициализировал контекст.

+0

Вы уже пробовали это с более поздними версиями Qt? (Эта тема была написана год назад (2016) сейчас 2017). –

Смежные вопросы