Версии OpenGL и gpus - какая там совместимость?

Я пытаюсь понять, как версии видеокарты, версии OpenGL и заголовки API работают вместе. Я читал о разгроме OpenGL 2.0/3.0/3.1 на форумах OpenGL и в других местах, но до сих пор не ясно, как это сработает для меня как разработчика (новичок в OpenGL). (кстати, я использую nVidia в этом вопросе в качестве примера, потому что я покупаю одну из их карт, но, очевидно, я хотел бы быть независимым от производителя программного обеспечения, которое я разрабатываю).

Во-первых, есть графический процессор, который должен поддерживать версию OpenGL. Но напр. У nVidia есть драйверы для старых видеокарт для поддержки OpenGL 3. Означает ли это, что эти драйверы реализуют определенные функции в программном обеспечении для эмуляции новых функций, которых нет в оборудовании?

Затем идут заголовки API. Если я решу написать приложение для OpenGL 3, стоит ли ждать, пока Microsoft выпустит обновленную версию SDK платформы с заголовками, поддерживающими эту версию? Как вы выбираете, какую версию API использовать — через препроцессор, определяемый в коде, или обновление до последней версии SDK платформы просто обновляется до последней версии (не могу себе представить этот последний вариант, но вы никогда не знаете. ..).

Как насчет обратной совместимости? Если я напишу приложение, ориентированное на OpenGL 1.2, смогут ли пользователи, установившие драйверы для своих карт, поддерживающих OpenGL 3, по-прежнему запускать его, или мне следует протестировать функции/поддерживаемую версию карты в моем приложении? Чтение http://developer.nvidia.com/object/opengl_3_driver.html похоже подтверждает что, по крайней мере, для карт nVidia приложения, написанные против 1.2, будут продолжать работать, но это также означает, что другие поставщики могут прекратить поддержку API 1.2. По сути, это поставило бы меня (потенциально) в положение, когда в будущем программное обеспечение не будет работать с последними картами, потому что они больше не поддерживают 1.2. Но если я буду разрабатывать для OpenGL 3 или даже 2 сегодня, я могу исключить пользователей, у которых GPU поддерживает только 1.2.

Мне не нужны причудливые функции в OpenGL - я почти не использую затенение, фиксированный конвейер работает нормально для меня (мое приложение похоже на CAD). На какой версии лучше всего основывать новое приложение с расчетом на то, что это будет долгоживущее приложение с добавочными обновлениями в ближайшие годы?

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


person Roel    schedule 05.06.2009    source источник


Ответы (3)


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

В Visual Studio вы всегда будете связывать свое приложение с opengl32.lib, а opengl32.lib не меняется в разных версиях OpenGL. Вместо этого OpenGL использует wglGetProcAddress() для динамического доступа к расширениям/версиям OpenGL во время выполнения, а не во время компиляции. А именно, если данный драйвер не поддерживает расширение, тогда wglGetProcAddress() вернет NULL во время выполнения, когда будет запрошена процедура этого расширения. Поэтому в вашем коде вам нужно будет реализовать логику, которая обрабатывает случай возврата NULL. В самом простом сценарии вы можете просто вывести сообщение об ошибке и сказать: «Эта функция недоступна, поэтому эта программа будет вести себя…». Или вы можете найти другие альтернативные способы сделать то же самое, но без использования расширения. По большей части вы получите возврат NULL от wglGetProcAddress только в том случае, если ваше приложение работает на старом оборудовании/драйверах, которые не поддерживают версию OpenGL, в которой добавлено расширение, которое вы ищете. Тем не менее, в будущем вы захотите быть в курсе тех вещей, которые более новые версии OpenGL решили устареть. Я не слишком много читал в спецификации 3.1, но, по-видимому, они вводят модель устаревания, при которой старые технологии/расширения могут быть объявлены устаревшими, что откроет дверь для более нового оборудования/драйверов, чтобы они больше не поддерживали устаревшие расширения, и в этом случае wglGetProcAddress снова вернет NULL для этих расширений. Поэтому, если вы вставите логику для обработки возврата NULL в wglGetProcAddress(), вы все равно будете в порядке даже для устаревших расширений. Вам просто может понадобиться реализовать лучшие альтернативы или сделать более новые расширения по умолчанию.

Что касается версионных заголовков API, то изменения в заголовках — это в основном просто изменения, позволяющие получить доступ к новым функциям, возвращаемым wglGetProcAddress(). Поэтому, если вы включаете заголовок API для версии 2, все в порядке, если вам нужны только расширения для OpenGL 2. Если вам нужен доступ к функциям/расширениям, которые были добавлены в версии 3, вы просто замените свою версию. 2 с заголовком версии 3, который просто добавляет некоторые дополнительные определения типов указателей функций, связанные с новыми расширениями, так что при вызове wglGetProcAddress() вы можете привести возвращаемое значение к правильному указателю функции. Пример:

PFNGLGENQUERIESARBPROC glGenQueriesARB = NULL;

...

glGenQueriesARB = (PFNGLGENQUERIESARBPROC)wglGetProcAddress("glGenQueriesARB");

В приведенном выше примере typedef для PFNGLGENQUERIESARBPROC определяется в заголовках API. Я полагаю, что glGenQueriesARB был добавлен в версии 1.2, поэтому мне понадобятся по крайней мере заголовки API версии 1.2, чтобы получить определение PFNGLGENQUERIESARBPROC. Это действительно все, что делают заголовки.

Еще одна вещь, которую я хочу упомянуть о 3.1. Судя по всему, в версии 3.1 они отказываются от многих функций OpenGL, которые моя компания использовала повсеместно, включая списки отображения, механизмы glBegin/glEnd и режим рендеринга GL_SELECT. Я не очень разбираюсь в деталях, но я не понимаю, как они могут это сделать, не создавая новый opengl32.lib для связи, потому что кажется, что большая часть этой функциональности встроена в opengl32.lib, и недоступно через wglGetProcAddress. Кроме того, собирается ли Microsoft включить этот новый opengl32.lib в свои версии Visual Studio? У меня нет ответа на эти вопросы, но я думаю, что, несмотря на то, что версия 3.1 устарела, эта функциональность будет существовать еще долгое время. Если вы продолжите компоновку с вашим текущим opengl32.lib, он должен продолжать работать почти бесконечно, хотя в какой-то момент вы можете потерять аппаратное ускорение. Подавляющее большинство руководств по OpenGL, доступных в Интернете, используют методы glBegin/glEnd для рисования примитивов. То же самое верно и для GL_SELECT, хотя многие аппаратные средства больше не ускоряют режим рендеринга GL_SELECT. Даже в учебнике opengl.org используются предположительно устаревшие методы glBegin/glEnd. И мне еще предстоит найти руководство по началу работы, в котором используются только функции 3.1, избегая устаревших функций (конечно, если кто-то знает о нем, дайте ссылку на него). В любом случае, хотя кажется, что 3.1 выбросил много старого ради всего нового, я думаю, что старое еще какое-то время будет существовать.

Короче, вот мой совет. Если ваши потребности в OpenGL просты, просто используйте базовую функциональность OpenGL. Массивы вершин поддерживаются в версиях 1.1–3.1, поэтому, если вы ищете максимальное время жизни и начинаете с нуля, вероятно, вам следует использовать именно его. Тем не менее, я считаю, что glBegin/glEnd и списки отображения все еще будут существовать некоторое время, даже несмотря на то, что они устарели в версии 3, поэтому, если вы хотите их использовать, я бы не стал слишком беспокоиться. Я бы избегал режима GL_SELECT для выбора в пользу альтернативного метода. Многие поставщики аппаратного обеспечения считали GL_SELECT устаревшим в течение многих лет, даже несмотря на то, что он стал устаревшим только в версии 3. В нашем приложении мы получаем множество проблем, когда он не работает на картах ATI и интегрированных картах GMA. Впоследствии мы только что реализовали метод выбора с использованием запросов окклюзии, который, похоже, решил проблему. Поэтому, чтобы сделать это правильно с первого раза, избегайте GL_SELECT.

Удачи.

person Anthony Johnson    schedule 06.06.2009

Что касается драйверов, я думаю, что в некоторых случаях недостающая функциональность написана в программном обеспечении. Весь смысл использования OpenGL (кроме ускорения) заключается в том, чтобы писать в API и не заботиться о том, КАК это реализовано.

По моему опыту, вы не объявляете версии OpenGL. Вызовы функций между версиями API не перекрываются. Помните о спецификации, и если, например, вы вызываете метод 2.0, минимальная версия вашего приложения просто станет 2.0. У меня есть приложения для отображения, написанные для OpenGL (глупые старые видеокарты Sun), и они прекрасно работают на новых картах серии nvidia 200.

Я не думаю, что в любом случае можно гарантировать, что API не изменится в будущем; особенно, если вы не контролируете это. Ваше приложение может перестать работать через 10 лет, когда мы перейдем на OpenGL 6.4. Надеюсь, вы написали достаточно хорошее приложение, за обновление которого клиенты будут готовы платить.

person basszero    schedule 05.06.2009

Этот человек, Марк Дж. Килгард, публикует исходный код и документы nVidia по openGL с 90-х годов и делает это от имени одного из двух крупнейших имен в области игрового оборудования.

//------------------------------------------------ ------------------------------------- ... представление о том, что Приложение OpenGL «неправильное», чтобы когда-либо использовать немедленный режим, это слишком усердно. Спецификация OpenGL 3.0 зашла так далеко, что пометила немедленный режим в OpenGL как «устаревший» (что бы это ни значило!); такой экстремизм контрпродуктивен и глуп. Правильный способ поощрять правильное использование API – не пытаться объявить его устаревшим или запретить, а информировать разработчиков о том, как правильно использовать API в конкретных ситуациях.

person Marc Clint Dion    schedule 03.07.2013
comment
В духе обучения разработчиков правильному использованию API в конкретной ситуации я хочу добавить следующее: immediate mode = linear correlation between amount of 'geometry' committed and number of API calls (с ненулевыми накладными расходами). - person Gigi; 19.07.2013