Из моего опыта работы с 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