Как вы используете QAbstractOpenGLFunctions в С++?

Я новичок в OpenGL, так что это может быть глупый вопрос. Кажется, я упускаю что-то очевидное. Я не понимаю, как новые классы OpenGL должны быть полезным.

Существуют классы для каждой версии и профиля OpenGL . Эти классы имеют явные методы для всех вызовов OpenGL, поддерживаемых каждой версией. Вот неполный список:

  • QOpenGLFunctions_1_0
  • QOpenGLFunctions_1_1
  • QOpenGLFunctions_1_2
  • QOpenGLFunctions_1_3
  • QOpenGLFunctions_1_4

Я предполагаю, что это будет что-то вроде следующего:

  • запросите видеокарту и спросите, какие версии OpenGL она поддерживает.
  • создать копию класса для самой высокой версии, поддерживаемой с помощью QOpenGLContext::versionFunctions()

Итак, как мне написать код, используя этот класс? Я не могу предсказать, какой объект я получу во время выполнения, не зная точно, на каком оборудовании он будет работать. Базовый класс не содержит методов, поскольку они разные для каждого производного класса. Я мог бы написать гигантский переключатель, но это кажется шагом назад по сравнению с использованием QOpenGLFunctions или простым получением адресов функций вручную.


person Jay    schedule 18.10.2013    source источник
comment
Но вы можете предсказать подмножество OpenGL, которое вы собираетесь использовать, и запросить соответствующую версию. Если в контексте есть надмножество нужных вам функций, все будет в порядке. В противном случае эти объекты не смогут инициализироваться. В то же время: 1) вам не нужно разрешать каждый и каждый адрес процедуры OpenGL, и 2) если вы по какой-то причине попытаетесь использовать функцию, которая не соответствует выбранной вами версии (например, потому что она была введена позже, или потому что это в профиле совместимости, и вы используете ядро) вы получаете приятную ошибку времени компиляции вместо таинственной ошибки времени выполнения.   -  person peppe    schedule 19.10.2013
comment
Я предполагаю, что вы имеете в виду, что можете предсказать версию и профиль, которые вы хотите использовать. Нет никакой гарантии, что это будет на компьютере пользователя. Так что либо вы выбираете версию, и если у них ее нет, вы говорите пользователю, что ему не повезло. Или вы можете написать код для каждой версии и поставить везде тесты, чтобы выбрать правильный код. Это объясняет, почему игры не работают на всех аппаратных средствах.   -  person Jay    schedule 19.10.2013
comment
Это правильно. Вы можете установить какие-то абсолютные минимальные требования (например: OpenGL ›= 2.1 и FBO), а затем динамически проверить, действительно ли у пользователя есть какие-то дополнительные функции (проверив расширения или версию контекста, которую вы получили) — и если да. , используй их. В этом случае эти объекты в Qt предотвратят случайное использование вызовов, отличных от OpenGL 2.1 (поскольку в объекте QOpenGLFunctions_2_1 не будет методов).   -  person peppe    schedule 20.10.2013
comment
Спасибо, это был еще один мой вопрос. Можете ли вы использовать вызовы OpenGL версии 2 и, если они присутствуют, вызовы версии 3 в одной и той же сцене.   -  person Jay    schedule 21.10.2013


Ответы (1)


Полезность этих классов заключается в том, что предыдущий класс QOpenGLFunctions раскрывал только функциональность OpenGL/ES 2.0. Теперь они представили полную функциональность многих версий OpenGL, позволяя вам использовать возможности, предлагаемые только в этих версиях.

Конечно, большинство разработчиков не выбирают версию GL во время выполнения для большинства приложений. Они нацелены на конкретную версию, и для этого отлично подойдут классы Qt.

Если то, что вы ищете, — это способ вызова «общих» методов между различными классами QOpenGLFunctions_*, не зная, какую версию OpenGL вы используете (но при этом даете себе возможность воспользоваться преимуществами конкретных функций «более высокого» версий), почему бы не использовать шаблоны?

Например:

template <class T>
class SomeOpenGLRendering {
public:
    SomeOpenGLRendering(T *openglFunctions) : openglFunctions(openglFunctions) {
        openglFunctions->initializeOpenGLFunctions();
    }

    void renderSomething() {
        openglFunctions->glClear(GL_COLOR_BUFFER_BIT);
    }

private:
    T *openglFunctions;
};

А затем на основе любых критериев, которые вы хотели бы (например, обнаружение оборудования, как вы сказали), создайте нужную версию по мере необходимости:

SomeOpenGLRendering<QOpenGLFunctions_3_2_Core> r(new QOpenGLFunctions_3_2_Core());
r.renderSomething();
person ksimons    schedule 18.10.2013
comment
Вы говорите, что большинство разработчиков не выбирают версию GL во время выполнения для большинства приложений. Как вы можете выбрать конкретную версию, не гарантируя, что аппаратное обеспечение будет иметь эту версию? - person Jay; 18.10.2013
comment
К лучшему или к худшему, вам просто нужно определить минимальные требования, а затем проблема пользователя в том, чтобы получить поддержку, если он хочет запустить ваше приложение. Вот хорошее обсуждение на эту тему: opengl.org/discussion_boards/showthread.php/ - person ksimons; 18.10.2013
comment
ПРИМЕЧАНИЕ: если SomeOpenGLRendering расширяет QObject, вы облажались, поскольку QObject не может быть шаблоном. - person Lennart Rolland; 22.09.2016