В настоящее время я пытаюсь получить окно Qt 5 и QOpenGLContext
, работающее с GLEW. Да, я знаю, что Qt 5 предоставляет свои собственные функции для OpenGL, но поскольку мой движок рендеринга использует GLEW и поддерживает другие библиотеки окон, встроенный материал Qt не является вариантом.Использование GLEW с Qt 5.x
Теперь, вот что я встал и работает до сих пор:
I к югу классифицироваться
QWindow
и оснастили его сQOpenGLContext
. Контекст успешно инициализирован.После инициализации
QOpenGLContext
, я (снова успешно) позвонилglewInit()
, чтобы инициализировать GLEW.Теперь я могу визуализировать геометрию для фреймбуфера по умолчанию точно так же, как и для других оконных фреймворков (точнее, 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). Кто-нибудь имеет представление о том, что может пойти не так?
Вы говорите, что как только вы используете 'glBufferData', вы получаете ошибку seg. Вы проверили, что 'glBufferData' не является нулевым в этот момент? –
@ 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); и он отлично работал (за исключением неожиданного поведения на стороне шейдера, очевидно). У меня возникает ощущение, что типы данных, которые я использую для световых данных, перепутались или что-то в этом роде. –