В настоящее время я пытаюсь получить окно Qt 5 и QOpenGLContext
работая с GLEW. Да, я знаю, что Qt 5 предоставляет свои собственные функции-обертки для OpenGL, но, поскольку мой движок рендеринга опирается на GLEW и также поддерживает другие библиотеки окон, встроенные в Qt вещи не подходят.
Теперь вот что я запустил и запустил до сих пор:
Я субкласс QWindow
и оснастил его QOpenGLContext
, Контекст успешно инициализирован.
После инициализации QOpenGLContext
Я (опять успешно) звоню glewInit()
инициализировать GLEW.
Теперь я могу отображать геометрию в стандартный буфер кадров точно так же, как я делаю это для других оконных структур (точнее, GLFW).
Здесь возникает сложная часть: я использую один из объектов единого буфера OpenGL для передачи легких данных в графический процессор. Как только я позвоню 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);
Кто-нибудь пробовал подобные подходы и может поделиться своим опытом? Я был бы признателен за любую помощь, так как я застрял, пытаясь выяснить, что я делаю неправильно. Еще раз: инициализация, кажется, проходит гладко, и я даже могу создавать VBO / VAO / IBO для рендеринга сеток! Только создание UBO вызывает ошибку сегментации.
РЕДАКТИРОВАТЬ:
Хорошо, вот несколько новых идей. Прежде всего, ошибка сегментации возникает только в том случае, если загруженные данные превышают определенный размер (~ 90 байт). Другими словами, я могу визуализировать сцену в контексте, созданном Qt, используя ровно один пользовательский источник света. При запросе GL_MAX_UNIFORM_BLOCK_SIZE
тем не менее, драйвер говорит мне, что 64KB доступны для однородных блоков (то же самое верно для контекстов, созданных GLFW). У кого-нибудь есть идеи о том, что может пойти не так?
Хорошо, на случай, если кто-то столкнется с подобными трудностями: мне удалось заставить его работать, загрузив данные UBO, используя glBufferStorage
вместо glBufferData
, Первый используется для создания буферов неизменного размера, что достаточно для моих целей. Тем не менее, я не знаю, что пошло не так с glBufferData
и является ли это ошибкой в Qt или я неправильно инициализировал контекст.
Других решений пока нет …