Рис. 1.1, Обзор операций в OpenGL
От конкретных реализаций Open GL не требуется в точности следовать определенному стандартом порядку выполнения операций. Единственное, чего нужно добиваться, - соответствия результатов рендеринга в разных реализациях. Из множества новаторских программных и аппаратных архитектур, которые реализуют OpenGL, ни одна не дает результаты, полностью не соответствующие тому, что изображено на рис. 1.1. Несмотря на это, диаграмма может помочь читателю понять процесс рендеринга в OpenGL в целом, даже если отдельные реализации работают немного иначе.
1.7. Рисование геометрических фигур
Данные для рисования геометрических фигур - точек, линий, многоугольников (в специальной литературе обычно называются графическими примитивами) - изначально хранятся в памяти приложения (см. рис. 1.1, 1). Эта память может быть либо основной оперативной памятью компьютера, либо видеопамятью графического ускорителя - все зависит от последних изменений в OpenGL и кэширования данных в его реализации. В любом случае, это память, содержащая данные о геометрических фигурах, которые приложение собирается рисовать.
1.7.1, Определение геометрических фигур
OpenGL поддерживает следующие графические примитивы: точки, линии, ломаные линии, замкнутые ломаные линии, выпуклые многоугольники, треугольники, множества связных треугольников, множества связанных наподобие веера треугольников, четырехугольники и множества связных четырехугольников.
Существуют три основных способа передачи данных о геометрических фигурах в OpenGL. Метод «вершина за раз» использует gl Begin для начала рисования примитива и gl End - для завершения. Между этими вызовами обычно выполняются команды, которые устанавливают атрибуты вершин - положение вершин, цвет, нормаль, координаты текстуры, вторичный цвет, видимость граней, координаты дымки, - используя функции gl Vertex, gl Col or, gl Normal и gllexCoord. (Существует много разновидностей этих функций, которые позволяют передавать разные типы данных как по значению, так и по ссылке.) Стандарт OpenGL, включая версию OpenG L 1.5, не предусматривает установку пользовательских дан и ых для вершин. Для каждой вершины можно установить только тс параметры, которые определены стандартом.
При использовании метода «вершина за раз» вызов gl Vertex означает конец передачи данных для отдельной вершины, он также может являться маркером окончания описания примитива. После вызова gl Begin и указания типа примитива OpenGL будет считать графический примитив полностью определенным, если команда gl Vertex была вызвана необходимое количество раз. Например, для определения треугольника достаточно задать три вершины посредством трех последовательных вызовов gl Vertex. При определении множества связанных треугольников (triangle strip) первый треугольник задается тремя последовательными вызовами gl Vertex, а каждый последующий вызов gl Vertex определяет дополнительный треугольник1.
Второй метод рисования примитивов основан на использовании массивов вершин. Приложения помещают атрибуты вершин в массивы, запоминают указатели на эти массивы и используют gl DrawArrays, gl Multi DrawArrays, glDrawElements, glMultiOrawElements, glDrawRangeElements илид! Inter!eavedArrays для рисования большого количества примитивов за один раз. Этот метод предпочтительнее, если для приложения критична производительность, - упомянутые функции эффективно передают большое количество данных в OpenGL. gl Begi n/gl End-методы требуют вызова функции для каждого атрибута каждой вершины, так что из-за множественных вызовов функций при рисовании объектов с тысячами вершин время выполнения существенно увеличивается, в то время как использование массивов вершин позволяет обойтись всего одним вызовом. Ко всему прочему предварительная организация данных в массивы позволяет реализациям OpenGL использовать более эффективные алгоритмы для их обработки.