Объект GI

From SunFlurry wiki
Jump to: navigation, search
  GI (Объект GI)
Статус разработки: Реализован
Создание объекта: Init

С помощью объекта GI можно получить доступ к графическим возможностям системы по спецификациям OpenGL или подобным. В данный момент поддерживается только OpenGL, в будущем, список возможных спецификаций может быть увеличен. Работа с интерфейсом может происходить двумя способами: с виде объекта на форме (региона окна с графическими возможностями) и в виде объекта в памяти без видимой составляющей. В первом случае, при инициализации объекта необходимо указать идентификатор (Handle) объекта окна (см. Form.Handle). Таким объектом может быть практически любой объект формы (к примеру, текстовое поле или даже кнопка), однако обычно для исключения мигания при перерисовке, желательно использовать объект пустого окна, в котором отсутствует прорисовка пустого фона. Кроме объектов формы системы, можно также использовать объекты окон или сами окна внешних приложений или загружаемых библиотек, если известен их идентификатор (Handle). Визуальный (привязанный к окну) объект GI может работать в двух режимах:

  • Режим обновления экрана системой и запросами на обновление. Используется, когда не требуется большой скорости обновления и количество кадров в секунду не имеет большого значения. Прорисовка GI окна происходит всякий раз, когда оно получает запрос на обновление (для Windows, сообщение WM_PAINT). Периодическую отсылку этих запросов можно осуществить, к примеру, с помощью события OnTimer или внутри цикла исполнения программы, вызывая метод InitiateRedraw. Данный режим рекомендуется, когда в одном окне могут находиться несколько объектов GI, использующие небольшое количество ресурсов или когда не требуется постоянная прорисовка, а только реакция на действия пользователя (не анимированное окно). Пример использования такого режима см. ниже.
  • Режим выделенного цикла обновления. В этом режиме обычно используется бесконечный цикл, внутри которого происходит работа с объектом. Этот цикл можно выполнять, как в отдельном потоке, так и в обычном потоке исполнения программы. Внутри цикла должна присутствовать команда InitiateRedraw, которая и выполняет прорисовку объекта, а также может задерживать выполнение, если включен режим ограничения кадров (см. ниже). Сообщения на обновления в этом случае не создаются, прорисовка окна выполняется непосредственно в момент вызова (правильнее сказать, выполняется помещение команд прорисовки в очередь видеокарты, которая будет заниматься прорисовкой и после окончания выполнения этой команды). Данный режим используется по умолчанию и рекомендуется, когда необходим полный контроль над окном объекта с более точным и ровным количеством обновлений в секунду.

Все функции и константы спецификации OpenGL доступны непосредственно из объекта (причем значения констант можно получить из интерфейса, без инициализации самого объекта), пример: aGI.glClear(aGI.GL_COLOR_BUFFER_BIT or aGI.GL_DEPTH_BUFFER_BIT). Вызов функций оптимизирован и происходит достаточно быстро, однако для сложных сцен может возникнуть необходимость выполнять тысячи и вызовов 60 и более раз в секунду, чтобы успевать за работой графической карты. Каждая команда языков высокого уровня выполняется гораздо медленнее, чем для языков, превращающих программы в машинный код, и нужно выполнить сотни тысяч таких команд в секунду, что может не оставить времени для другой работы внутри цикла прорисовки (обработки нажатия клавиш, движение объектов и пр.). Поэтому подход с прямым вызовом функций OpenGL для полной прорисовки сложных сцен не является оптимальным. Для облегчения ситуации, система оперирует понятиями графический объект и модель графического объекта. Объект GI может содержать произвольное количество графических объектов, которые могут быть как видимыми, так не отображаться на экране, они имеют свои свойства, такие, как идентификатор, координаты, коэффициенты изменения положения, размера и поворота, программы GPU (далее, шейдеры) и пр. Также графические объекты структурированы в дерево графических объектов. При прорисовке сцены, сначала рисуется родитель, затем подчиненные ему объекты, сохраняя все заданные для родителя свойства, типа изменения положения и поворота. Графические объекты удобно искать и удалять с помощью функций группового поиска (к примеру, FindObjectsByIDRange или DeleteObjectRange), изменения свойств объектов или даже их добавление и удаление допускается внутри цикла прорисовки и в событиях цикла и графических объектов.

Графический объект на данный момент может иметь "простую" модель (см. GIModel.Simple) или быть нарисованным в обработчике рисования без какой-либо модели. В будущем планируется добавить другие типы моделей. "Простая" модель представляет собой бинарную очередь обычных команд для прорисовки, сохраненную в буфер, которую система использует всякий раз при необходимости прорисовать графический объект. Так как подобная цепочка команд выполняется на низком уровне машинного кода, а не на высоком уровне языка системы, выполнение проходит гораздо быстрее. "Простая" модель для OpenGL включает практически все необходимые команды рисования вертексов или массивов, манипуляции текстурами, переменными шейдеров и матрицами. Модель создается и изменяется достаточно редко и прорисовка в большинстве кадров выполняется на статической модели, процесс создания модели, поэтому, практически не влияет на скорость прорисовки. Минусом такого подхода является необходимость создавать модель (обычно с помощью Buffer.AddValues), что усложняет читаемость кода, но ее также можно загружать в готовом виде из какого-либо файла ресурса. См. пример создания модели ниже.

Объект GI также оперирует своим набором событий, которые могут быть заданы как для самого объекта, так и для его графических объектов (см. LinkEvent). Доступны события момента начала прорисовки, ввода информации пользователем (нажатия клавиш, движение мыши, получение фокуса и пр.) и изменение размеров всего окна. События удобно использовать для основных объектов или всего окна, задание событий для очень большого числа объектов может замедлить цикл прорисовки.

Одной из важных характеристик объекта GI, является то, насколько часто происходит прорисовка окна и насколько активно объект использует ресурсы компьютера. Объект, являющийся вспомогательным для работы клиента (к примеру, область на форме для показа чертежей или графиков), должен использовать как можно меньше ресурсов, тогда как основной объект (полноэкранное игровое окно), должен использовать максимальное количество ресурсов, необходимое для комфортного отображения информации, но не больше. Объект сделать таким образом, что в режиме ограничения кадров использовать минимальное необходимое количество ресурсов. Для управления режимом используется функция FrameLimiter. Для нахождения узких мест в коде и получения простой статистики потребления ресурсов можно использовать встроенные функции статистики: RenderStats -- для информации по количеству рисуемых кадров в секунду и времени, которое тратит центральный процессор для прорисовки одного кадра; RenderStats2 -- для получения времени, которое тратит видеокарта для прорисовки одного кадра. Сравнительный анализ этих функций может помочь найти и исправить медленное место в программе. Для любой графической спецификации (OpenGL и пр.) также необходимо помнить, что функции получения информации (для OpenGL к примеру glGetString или glGetError, как и другие функции glGet* и не только) дожидаются окончания выполнения очереди команд видеокарты с тем, чтобы получить данные не в произвольный момент очереди, а на момент ее окончания. Таким образом, драйверы видеокарты создают цикл ожидания процессором окончания работы над очередью видеокарты. Этот цикл занимает время и бесполезно нагружает процессор, тем самым сокращая остаток полезного времени для создания кадра процессором. Такие команды могут использоваться для отладки, но в реальной работе их необходимо избегать, либо помещать их в самое начало прорисовки кадра, когда очередь команд все еще пуста.

Важной характеристикой графического окна при работе является перспектива. К примеру, для 3D объектов, необходима перспектива, когда удаленные части рисуемого объекта меньше по размеру, чем те, что ближе к пользователю, для 2D рисунков такая проекция неудобна. Для изменения перспективы в системе используется как функция WorldPerspective, которая позволяет использовать оба режима, так и функция TextWorldPerspective, включающая или отключающая "текстовую" проекцию, когда графическая точка видеокарты будет совпадать по размеру с физической точкой экрана. Текстовую проекцию можно включать, к примеру, чтобы вывести текст, знаки и картинки поверх общей прорисованной сцены, с тем, чтобы потом ее выключить. В "текстовом" режиме верхняя левая точка экрана совпадает с координатой (0,0) и увеличение координаты по y адресует последовательность точек сверху вниз, когда как в обычном режиме координата (0,0) обычно находится в середине экрана (окна), и увеличение координаты по y адресует последовательность точек внизу вверх. Также для 3D перспективы существует возможность захвата окном курсора мыши и использование режима, когда вращение объектов мышью не приводит к ее выходу за пределы рабочего окна (функции MouseMode, CaptureMouse, ReleaseMouse). Эти вспомогательные функции могут быть полезными при работе с мышью в графических окнах.

Для анимации и других процессов, связанных с работой с объектом GI свойственно использовать реальное время, как ориентир. Система использует встроенный атрибут количества секунд, прошедших с прорисовки первого кадра объекта (WorldTime). Значение представляет собой вещественное число, полученное из таймера высокой точности (dbgHRPCCurrent), либо встроенных часов компьютера, если первый отсутствует. Разработчики могут использовать другие источники получения времени, однако атрибут WorldTime обычно более удобен по следующим соображениям: отсчет времени начинается с нуля, нет необходимости в дополнительных вычислениях; атрибут позволяет не только получать, но и обновлять время (к примеру, после загрузки состояния); атрибут обновляется только в начале последовательности цикла прорисовки (см. ниже), поэтому, для одного кадра при работе с ним внутри рабочего потока атрибут будет отдавать одно и то же значение (нет необходимости запоминать начальное время кадра), для получения значения атрибута из других потоков рекомендуется использовать безопасный атрибут WorldTimeSafe; значение атрибута доступно, как стандартная переменная в любых шейдерных программах системы, и как команда в простых моделях визуальных объектов (то есть, не требует дополнительной работы для установки переменных).

Одна из проблем работы напрямую с графическими спецификациями (OpenGL не исключение), это то, что без дополнительных библиотек, невозможно удобно вывести текст (получение отдельных символов из большой текстуры не самый лучший метод по многим причинам). Система обладает встроенным генератором текста (функция RenderText), который автоматически создает текстуры в памяти получая изображение с помощью возможностей операционной системы, и после этого использует такие текстуры для быстрого вывода текста на экран. Такой подход обладает очевидными преимуществами: возможно использовать произвольные шрифты системы (как и новые), работа с юникодом, система сама следит за появлением новых символов и добавлением их на текстуру, возможно использовать все свойства текста операционной системы, встроенные возможности использования тени, шейдера для контура, как и произвольного шейдера. Текстуры для работы с текстом можно подготовить заранее с помощью функции PrerenderText или очистить в любой момент работы (для освобождения места) с помощью функции FreeTextBuffers, также можно использовать функцию для получения размером выводимого текста TextWidthAndHeight.

Для использования шейдеров в системе практикуется модель, сходная с OpenGL. Шейдеры делятся на типы (см. ShaderAdd) и группируются в программы (см. ShaderProgramAdd), которые, в свою очередь, могут быть использованы в моменты выполнения рисования (см. ShaderProgramUse). В шейдерам (программах GPU) часто используются переменные, значение которых необходимо получать из внешней программы. Переменные в системе должны быть добавлены к объекту шейдера с указанием ее типа и свойств. При создании программы из нескольких шейдеров, этой программе становится доступен список переменных, используемых в ее шейдерах. Установка значений этих переменных выполняется только для программ, а не для отдельных шейдеров (см. ShaderProgramSetVariable). Однажды заданная переменная сохраняет свое значение для определенной программы до тех пор, пока ее значение снова не будет изменено. Также для разных программ одинаковые по имени переменные из одних и тех же шейдеров будут иметь разные значения. Иными словами, несмотря на то, что переменная задается в тексте шейдера, ее значение существует только на уровне программ. Система позволяет указывать имена переменных, отсутствующих в тексте шейдера, вызов изменения значения таких переменных будет просто пропущен. Система также задает ограниченное количество "стандартных" переменных, которые она будет заполнять самостоятельно в моменты использования программы шейдера. Для разработчика достаточно указать определенное имя и тип переменной при создании шейдера, значение будет заполнено системой автоматически. Ниже дана таблица доступных на данный момент стандартных переменных:

Наименование переменной Тип переменной Применение Описание
u_time float Любые шейдеры Значение представляет собой текущее время кадра, см. WorldTime
u_resolution vec2 Любые шейдеры Значение задает размер рабочего окна графического объекта в пикселях.
u_mouse vec2 Любые шейдеры Значение задает координаты указателя мыши внутри рабочего окна графического объекта. Координаты могут быть отрицательными или больше размера окна, если курсор находится за его пределами. Вектор оси ординат направлен вверх (точка 0 находится внизу окна).
u_texture sampler2D Только шейдеры функции RenderText Значение задает номер текстуры, использующейся при создании текста в момент выполнения RenderText с указанием на дополнительную шейдерную программу.
u_textpos vec4 Только шейдеры функции RenderText Значение задает координату текущего символа внутри текстуры и его размеры на ней в момент вывода символа функцией RenderText. При этом x и y составляющие вектора u_textpos задают координату символа (изменяются в диапазоне [0..1)), а z и w составляющие вектора u_textpos задают ширину и высоту символа (также изменяются в диапазоне [0..1)). Координаты и размеры заданы в пропорции размеров текстуры.
u_screenpos vec4 Только шейдеры функции RenderText Значение задает координату текущего символа и его размеры на экране в момент вывода символа функцией RenderText. При этом x и y составляющие вектора u_screenpos задают координату символа в пикселях, а z и w составляющие вектора u_screenpos задают ширину и высоту символа в пикселях.
u_textcolor vec3 Только шейдеры функции RenderText Значение задает цвет текста выводимого символа (цвет был задан при вызове RenderText). Составляющие цвета изменяются в диапазоне [0..1].
u_outlinesize float Только шейдеры функции RenderText Значение задает ширину рамки вокруг выводимого символа (ширина была задана при вызове RenderText).
u_outlinecolor vec3 Только шейдеры функции RenderText Значение задает цвет рамки выводимого символа (цвет рамки был задан при вызове RenderText). Составляющие цвета изменяются в диапазоне [0..1].

Последовательность выполнения операций при прорисовке кадра

Прорисовка инициируется с помощью функции InitiateRedraw, а также в моменты обновления окна, если объект находится в режиме обновления. Последовательность операций иногда важна при использовании значений переменных, изменяемых внутри событий. Упрощенно, система использует следующую последовательность:

  • Если объект является видимым объектом в памяти (имеет окно) и находится в режиме выделенного цикла обновления, будут выполнены все накопившиеся в очереди событий на данный момент события самого объекта. Это может быть событие изменения размера окна (OnResize) или нажатия клавиш или движение мыши (OnNewInput). См. статью LinkEvent.
  • Выполняется обновление текущего времени кадра (WorldTime).
  • Обновляется статистика генерации кадра (RenderStats, RenderStats2).
  • Для объектов, не имеющих возможности использовать системное ожидание в режиме ограничения кадров, выполняется локальное ожидание, для приведения количества прорисовываемых кадров к необходимому состоянию.
  • Загружается текущая матрица проекции окна.
  • Выполняется событие OnDraw, если оно задано для объекта (внутри события должен быть вызов DrawScene), иначе сразу вызывается функция DrawScene.
    • Внутри цикла DrawScene рекурсивно прорисовываются визуальные объекты сначала родитель, потом его подчиненные объекты. При прорисовке изменяется локальная матрица проекции для каждого визуального объекта, где она была изменена. Проекция родителя действует на подчиненные объекты, которые могут изменять эту матрицу далее.
  • Выполняется операция SwapBuffers (или Flush, если объект не находится в режиме двойного буфера, см. Init).
    • В этот момент CPU может выполнять цикл ожидания для того, чтобы ограничить количество кадров в секунду.

Добавление методов и полей к графическим объектам, классы и дублирование

Этот раздел подготавливается к публикации.

Простые примеры использования объекта GI

Для простой демонстрации графических возможностей системы был создан внешний объект системы (Внешний загружаемый объект) Tetris. Вы можете скачать файл объекта и открыть его в визуальном клиенте. Для работы необходимы установленные драйверы видеокарты и OpenGL не ниже 2.1 (любая современная видеокарта, в т.ч. встроенные). Внешний объект также содержит исходный текст, его можно редактировать и изменять по желанию, если открыть в Студии. Объект в свободном распространении. Копия, данная на скачивание здесь, возможно, будет в дальнейшем немного изменяться, чтобы улучшить читаемость. Ниже дана ссылка на скачивание:

Скачать демонстрацию графического объекта Tetris.


Пример создания и сохранения картинки без вывода на экран с помощью графического объекта

Графический объект GI можно использовать не только для вывода видимой информации, но также для работы с графической спецификацией без создания окон, к примеру, для создания картинок. Ниже дан простой пример такой работы с созданием маленькой картинки с размерами 100 на 100 точек.

Картика, сгенерированная примером
//Создание невидимого окна с разрешением 100x100
aGI:=GI.Init(,,100,100);
//Включим режим MSAA
aGI.AntiAliasing(1);
//Ограчение окна для рисования и установка пропорции точек
aGI.glViewport(0,0,100,100);
//Белый фон
aGI.glClearColor(1.0,1.0,1.0,1.0);
aGI.glClear(aGI.GL_COLOR_BUFFER_BIT or aGI.GL_DEPTH_BUFFER_BIT);

//Вывод простейшей фигуры-треугольника в невидимое окно
aGI.glBegin(aGI.GL_TRIANGLES);
aGI.glColor3f(1.0,0.0,0.0);
aGI.glVertex2f(0,0.8);
aGI.glColor3f(0.0,1.0,0.0);
aGI.glVertex2f(-0.8,-0.8);
aGI.glColor3f(0.0,0.0,1.0);
aGI.glVertex2f(0.8,-0.8);
aGI.glEnd();

//Для буфера 0 (самого окна), превратим точки в изображение в формате PNG и сохраним его на диск в виде файла output.png.
aGI.BufferSavePicture(0,0,0,100,100,2,"c:\output.png","png");

Пример простого цикла прорисовки

В данном примере создан примитивный 3D мир и описано движение персонажа в этом мире.

//Блок внутри визуального события формы OnOpen
//Окно -- визуальные элемент формы, на котором будет происходить рисование.
Mutex.ExecuteFunctionInSeparateThread("ЦиклПрорисовки",1,Form.ThisForm,Form.Окно);
//Блок внутри программного модуля module.sf

//Событие прорисовки
Function OnDraw(aGI,СпКоорд)
  //Вызов стандартной прорисовки моделей (здесь модели не используются)  
  aGI.DrawScene();

  //Очистить экран и буфер глубины  
  aGI.glClearColor(0.45,0.45,0.75,1.0);
  aGI.glClear(aGI.GL_COLOR_BUFFER_BIT or aGI.GL_DEPTH_BUFFER_BIT);

  //Нарисовать простую поверхность (плоскость)
  aGI.glColor3f(1,0,0);
  aGI.glBegin(aGI.GL_QUADS);
  aGI.glVertex3f(-100,-0.5,-100);
  aGI.glVertex3f(100,-0.5,-100);
  aGI.glVertex3f(100,-0.5,100);
  aGI.glVertex3f(-100,-0.5,100);
  aGI.glEnd();  
  
  //Нарисовать примитивную 3D фигуру, которая будет вращаться в зависимости от времени (aGI.WorldTime)
  Len:=0.8;
  c:=1/2*Len;
  s:=c*tan(_PI/6);
  l:=atan(s/c);

  aGI.glPushMatrix();
  aGI.glRotatef(aGI.WorldTime*100,0.0,0.0,1.0);
  aGI.glBegin(aGI.GL_TRIANGLE_STRIP);
  aGI.glColor3f(1.0,0.0,0.0);aGI.glVertex3f(-c,-s,-s);//A
  aGI.glColor3f(0.0,1.0,0.0);aGI.glVertex3f(0,l,0);//C
  aGI.glColor3f(0.0,0.0,1.0);aGI.glVertex3f(c,-s,-s);//B
  aGI.glColor3f(1.0,1.0,1.0);aGI.glVertex3f(0,0,l);//D
  aGI.glColor3f(1.0,0.0,0.0);aGI.glVertex3f(-c,-s,-s);//A
  aGI.glColor3f(0.0,1.0,0.0);aGI.glVertex3f(0,l,0);//C
  aGI.glEnd();  
  aGI.glPopMatrix();  
  

  //Вывести также статистику в виде текста
  //Перейти к 2D текстовой перспективе
  aGI.TextWorldPerspective(1);
  аДата:=СпКоорд[4];//Прошлое время изменения текста
  If GetPeriodMs(аДата)>100 Then //Меняем текст каждые 100мс
    СпКоорд[4]:=Date();
    аФПС:=0;
    аВремя:=0;
    аВремя2:=0;
    aGI.RenderStats(аФПС,аВремя);
    aGI.RenderStats2(аВремя2);
    СпКоорд[5]:=""+аФПС+"к/с, время CPU: "+FormatNumber(аВремя,0,"",3)+"мс, время GPU: "+FormatNumber(аВремя2,0,"",3)+"мс";
  EndIf;
  //Выводим текущий текст
  aGI.RenderText(СпКоорд[5],"Tahoma,15,IB,"+DecToBase(MixColors(_CLR_BLUE,_CLR_RED,35),16)+",,",0,10,aGI.Height-30,0.5,"0,2,FFFFFF,3");
  //RenderText включает режим GL_BLEND и изменяет Blend-функцию. Выключим режим
  aGI.glDisable(aGI.GL_BLEND);
  //Вернемся к 3D перспективе
  aGI.TextWorldPerspective(0);
EndFunction


//Событие движения мыши и нажатия на клавиши
Function OnNewInput(aGI,СпУскор,ТипСобытия,Арг1,Арг2,Арг3,Арг4)
  If ТипСобытия=0 Then
    //Движение мыши -- обновить переменные поворота
    //Арг2, Арг3 -- смещение мыши по X и Y относительно окна прорисовки
    If aGI.MouseCaptured Then
      СпУскор[4]:=Арг2-aGI.Width div 2;
      СпУскор[5]:=Арг3-aGI.Height div 2;
    EndIf;
  ElseIf ТипСобытия=1 Then
    //Нажатие мыши на экран, захватить мышь
    aGI.CaptureMouse();
  ElseIf ТипСобытия=11 Then //Клавиша нажата
    If (Арг1=0x57)Or(Арг1=0x26) Then//W или стрелка вперед -- движение по Z
      СпУскор[3]:=1;
    ElseIf (Арг1=0x53)Or(Арг1=0x28) Then//S или стрелка назад -- движение по Z
      СпУскор[3]:=-1;
    ElseIf (Арг1=0x51)Or(Арг1=0x25) Then//Q или стрелка влево -- движение по X
      СпУскор[1]:=-1;
    ElseIf (Арг1=0x45)Or(Арг1=0x27) Then//E или стрелка вправо -- движение по X
      СпУскор[1]:=1;
    ElseIf (Арг1=0x20)Or(Арг1=0x41) Then//A или пробел -- прыжок
      СпУскор[2]:=1;
    ElseIf Арг1=0x1B Then//ESC -- отпустить мышь
      aGI.ReleaseMouse();
    EndIf;
  ElseIf ТипСобытия=12 Then //Клавиша отпущена
    If ((Арг1=0x57)Or(Арг1=0x26))And(СпУскор[3]=1) Then//Отменить движение по Z, если оно было инициировано W
      СпУскор[3]:=0;
    ElseIf ((Арг1=0x53)Or(Арг1=0x28))And(СпУскор[3]=-1) Then//Отменить движение по Z, если оно было инициировано S
      СпУскор[3]:=0;
    ElseIf ((Арг1=0x51)Or(Арг1=0x25))And(СпУскор[1]=-1) Then//Отменить движение по X, если оно было инициировано Q
      СпУскор[1]:=0;
    ElseIf ((Арг1=0x45)Or(Арг1=0x27))And(СпУскор[1]=1) Then//Отменить движение по X, если оно было инициировано E
      СпУскор[1]:=0;
    ElseIf _Or(Арг1=0x20,Арг1=0x41) Then//Отменить прыжок
      СпУскор[2]:=0;
    EndIf;
  ElseIf ТипСобытия=21 Then//Потеря фокуса окном, отпустить мышь
    aGI.ReleaseMouse();
  EndIf;
EndFunction


Function ЦиклПрорисовки(aForm,аЭлемент)
  //Ожидание окончания инициализации формы
  While not aForm.IsFullyInitialized Do
    Sleep(100);
  EndDo;
  //Инициализация графического объекта для элемента аЭлемент: режим выделенного цикла, двойная буферизация
  aGI:=GI.Init(аЭлемент,,1,1);

  //Внутренние переменные, для использования в обработчиках событий
  //Внимание: такой подход не требуется, если переменные заданы глобально, чтобы поток ЦиклПрорисовки мог иметь к ним доступ
  СпКоорд:=List.Create(0,0,1,Date(),"");//Основные переменные положения: x,y,z,прошлое время изменения текста статистики, текст вывода статистики
  СпУскор:=List.Create(0,0,0,0,0);      //Переменные ускорения: по x, по y, по z,поворот мыши по x,поворот мыши по y
 
  //Автоматически захватывать мышь
  aGI.MouseMode(1);
  //Указание на функции обработчиков событий
  aGI.LinkEvent("ONDRAW","OnDraw",1,СпКоорд);
  aGI.LinkEvent("ONNEWINPUT","OnNewInput",1,СпУскор);
  //Включить режим фильтрации MSAA
  aGI.AntiAliasing(1);
  //Включить режим ограничения кадров по развертке экрана
  aGI.FrameLimiter(1);
  //Включить 3D перспективу, FOV 90
  aGI.WorldPerspective(0,90,0.1,1000);

  //Переменные скорости
  СкорX:=0;
  СкорY:=0;
  СкорZ:=0;
  УскорY:=0;
  
  //Переменные поворота
  УголX:=0;
  УголY:=0;

  //Цикл прорисовки
  While 1 Do
    //Движение Z, макс. скорость=2
    УскорZ:=СпУскор[3];
    СкорZ:=СкорZ+УскорZ*?(Sign(СкорZ)<>Sign(УскорZ),0.5,0.2);
    If УскорZ=0 Then
      СкорZ:=?(СкорZ>0,Max(СкорZ-СкорZ*0.2,0),Min(СкорZ-СкорZ*0.2,0));
    EndIf;
    If Abs(СкорZ)>2 Then
      СкорZ:=2*Sign(СкорZ);
    ElseIf Round(СкорZ,10)=0 Then
      СкорZ:=0;
    EndIf;
  
    //Движение X, макс. скорость=2
    УскорX:=СпУскор[1];
    СкорX:=СкорX+УскорX*?(Sign(СкорX)<>Sign(УскорX),0.5,0.2);
    If (УскорX=0)And(СкорX<>0) Then
      СкорX:=?(СкорX>0,Max(СкорX-СкорX*0.2,0),Min(СкорX-СкорX*0.2,0));
    EndIf;
    If Abs(СкорX)>2 Then
      СкорX:=2*Sign(СкорX);
    ElseIf Round(СкорX,10)=0 Then
      СкорX:=0;
    EndIf;
    
    //Прыжок Y, макс. скорость=2.5
    If (СпУскор[2]>0)And(СпКоорд[2]=0) Then//Прыжок с "поверхности"
      СкорY:=2.5;
      УскорY:=-0.1;
      СпУскор[2]:=0;
      СпКоорд[2]:=СпКоорд[2]+СкорY*0.01;
    ElseIf СпКоорд[2]>0 Then//Взлет и падение
      СкорY:=СкорY+УскорY;
      СпКоорд[2]:=Max(СпКоорд[2]+СкорY*0.01,0);
      If СпКоорд[2]=0 Then
        СкорY:=0;
      EndIf;
    EndIf;

    //Поворот по x и y мышью
    If _Or(СпУскор[4]<>0,СпУскор[5]<>0) Then
      //Угол поворота: fi:=atan(x/y), где x -- перемещение мыши, y -- расстояние от глаза до экрана (1).
      //Данный подход неверен -- дает отрицательное ускорение (персонаж поворачивается тем быстрее, чем медленнее двигается мышь).
      //Для реального применения потребуется изменение этой простой формулы.

      //Поворот по X
      Пов:=СпУскор[4]*0.5;
      Пов:=atan(Пов/1);
      УголX:=УголX+Пов;
      
      //Поворот по Y
      Пов:=СпУскор[5]*0.1;
      Пов:=atan(Пов/1);
      УголY:=УголY+Пов;

      //Изменение общей матрицы проекции (только поворот)
      aGI.MoveAndRotate(,,,УголY,УголX,);
    EndIf;

    //Очистим принятые перемещения мыши, чтобы не использовать в следующем обороте цикла
    СпУскор[4]:=0;
    СпУскор[5]:=0;

    //Движение камеры (персонажа)    
    Фи:=Radians(УголX);
    Фи2:=Radians(90+УголX);
    СпКоорд[3]:=СпКоорд[3]-(СкорZ*cos(Фи)+СкорX*cos(Фи2))*0.01;
    СпКоорд[1]:=СпКоорд[1]+(СкорX*sin(Фи2)+СкорZ*sin(Фи))*0.01;

    //Изменение общей матрицы проекции (только движение)
    aGI.MoveAndRotate(СпКоорд[1],СпКоорд[2],СпКоорд[3],,,);
    
    //Выполнение событий OnDraw и OnNewInput. Мы не создаем модели в этом примере, автоматически ничего рисоваться не будет
    aGI.InitiateRedraw();    
  EndDo;

Пример создания и использования простой модели

Данный фрагмент взят из демонстрации tetris (см. выше). Фрагмент демонстрирует работу с простой моделью, создание объекта, инициализация модели, заполнение модели. Объекты прорисовываются системой автоматически в цикле прорисовки, поэтому дальнейших действий не требуется. Для дополнительной информации см. SimpleModel.

//Создание новой модели
аМодель:=GIModel.New();
//Указание на тип модели и добавление объекта буфера к ней
аМодель.SimpleModel(Buffer.Create());
//Создание нового объекта
аОбъект:=aGI.AddObject();
//Использование созданной ранее (пока пустой) модели с новым объектом
аОбъект.Model(аМодель);

...

//Далее идет фрагмент заполнения модели объекта, он может вызываться в моменты ее изменения
//Так как изменение модели не происходит при прорисовке каждого кадра
//Переменные x,y,z,dx -- положение и размер рисуемого квадрата
аБуфер:=аОбъект.Model.Buffer;//Получение объекта буфера
аСмещ:=0;//Смещение в буфере, увеличивается автоматически
аБуфер.AddValues(аСмещ,4,201,aGI.GL_TEXTURE_2D,0);//glBindTexture
аБуфер.AddValues(аСмещ,4,300,0);//ShaderProgramUse (отключим программу)
аБуфер.AddValues(аСмещ,4,101);аБуфер.AddValues(аСмещ,104,0,0,0);//glColor
аБуфер.AddValues(аСмещ,4,1,aGI.GL_QUADS);//glBegin
аБуфер.AddValues(аСмещ,4,100);аБуфер.AddValues(аСмещ,104,x,y,z);//glVertex
аБуфер.AddValues(аСмещ,4,100);аБуфер.AddValues(аСмещ,104,x,y+dx,z);//glVertex
аБуфер.AddValues(аСмещ,4,100);аБуфер.AddValues(аСмещ,104,x+dx,y+dx,z);//glVertex
аБуфер.AddValues(аСмещ,4,100);аБуфер.AddValues(аСмещ,104,x+dx,y,z);//glVertex
аБуфер.AddValues(аСмещ,4,2);//glEnd
//Буфер может быть больше, чем добавленные в него команды, поэтому, добавим команду конца.
аБуфер.AddValues(аСмещ,4,0);//EOF

...

//Далее показан фрагмент поворота и движения объекта, заполнять модель заново при этом не нужно
//Переменные x,y здесь какие-то используемые в программе переменные положения
аОбъект.MoveRotateAndScale(-0.5*x,-0.5*y);

Атрибуты и функции

Идентификатор Статус Тип Визуальная Параметры Описание
Init Реализована Функция
Да
GI.Init(<Указатель на окно или объект окна (INT,FORM)>,<Тип спецификации (STRING)>=OGL,<Режим объекта или ширина объекта без окна (INT)>,<Режим буферизации или высота объекта без окна (INT)>):<Новый объект (GI)> Функция позволяет создать и инициализировать новый объект GI для окна, экранного элемента или окна, задаваемого системным указателем (см. Form.Handle). Если первый аргумент пустой или опущен, объект инициализируется без окна, все действия с ним будут происходить без вывода информации на экран. В этом режиме можно, к примеру, нарисовать картинку средствами графической системы и сохранить ее в файл. Также для такого режима необходимо указать размеры скрытого окна объекта, поэтому, третий и четвертый аргументы используются для указания размеров, тогда как в обычном режиме они описывают свойства объекта.
<Функция API спецификации> Реализована Функция
Да
GI.<Функция API спецификации>(<Аргумент 1>,<Аргумент 2>...):<Результат> К функциям API спецификации можно обращаться напрямую после того, как объект был инициализирован. К примеру aGI.glClear(GI.GL_COLOR_BUFFER_BIT or GI.GL_DEPTH_BUFFER_BIT).
<Константа API спецификации> Реализована Атрибут GI.<Константа API спецификации>:<Значение константы (NUMBER)> Значение констант API спецификации можно получать по их имени даже при вызове к интерфейсу (без самого объекта или с оным). К примеру aGI.glClear(GI.GL_COLOR_BUFFER_BIT or GI.GL_DEPTH_BUFFER_BIT).
Tag Реализована Атрибут GI.Tag:<Произвольное дополнительное значение объекта> Атрибут хранит произвольное значение, связанное с текущим объектом.
WorldTime Реализована Атрибут GI.WorldTime:<Время в секундах (REAL)> Атрибут получает или изменяет текущее время сцены в секундах. Данное время изменяется дискретно один раз за кадр после выполнения всех событий объекта. Изменять время удобно, к примеру, после загрузки сохранения или в подобных случаях. Получение или изменение время таким образом должно выполняться в потоке, который содержит цикл прорисовки. Для других потоков необходимо использовать функцию WorldTimeSafe, которая будет сначала ожидать окончания выполнения цикла рисования основного потока.
WorldTimeSafe Реализована Атрибут GI.WorldTimeSafe:<Время в секундах (REAL)> Атрибут получает или изменяет текущее время сцены в секундах. Данное время изменяется дискретно один раз за кадр после выполнения всех событий объекта. Изменять время удобно, к примеру, после загрузки сохранения или в подобных случаях. Получение или изменение время таким образом создано для выполнения в параллельном к циклу прорисовки потоке, так как функция сначала ожидает окончания выполнения цикла рисования основного потока. Однако, если выполнить ее в потоке с циклом прорисовки, замедления выполнения также не будет.
Height Реализована Атрибут GI.Height:<Высота окна объекта GI (INT)> Атрибут отдает текущую высоту окна объекта GI в точках.
Width Реализована Атрибут GI.Width:<Ширина окна объекта GI (INT)> Атрибут отдает текущую ширину окна объекта GI в точках.
DrawScene Реализована Функция
Да
GI.DrawScene() Функция инициирует прорисовку всех визуальных объектов внутри события OnDraw. Функция вызывается автоматически, если событие для объекта не задано, и также будет вызвана автоматически после окончания выполнения события OnDraw, если в последнем не было ее вызова. Функция помогает точно указать момент в цикле, когда нужно выполнить рисование объектов. Если к примеру, до рисования необходимо очистить окно или поменять перспективу, а после рисования объектов, требуется вывести определенный текст, функцию можно разместить между блоками кода, выполняющими эти действия.
InitiateRedraw Реализована Функция
Да
GI.InitiateRedraw() Функция создает запрос на прорисовку нового кадра объекта. Функция может использоваться для объектов GI в режиме обновления экрана системой и запросами на обновление. К примеру, ее можно вызывать в событие таймера окна или когда что-то изменилось и окно требует перерисовки. Перерисовка в таком случае будет выполнена в ближайшее время, но не сразу, функция возвращается до ее выполнения. Для объектов с выделенным циклом обновления вызов этой функции совпадает с вызовом функции DrawScene, функция не возвращается, пока прорисовка не будет окончена.
WorldPerspective Реализована Функция
Да
GI.WorldPerspective(<Тип перспективы окна GI (INT)>=0,<Параметр 1 (INT)>,<Параметр 2 (INT)>,<Параметр 3 (INT)>) Функция изменяет текущую перспективу окна GI, либо инициирует режим, когда система не будет менять перспективу вообще.
TextWorldPerspective Реализована Функция
Да
GI.TextWorldPerspective(<Включить текстовую перспективу (INT)>=1) Функция изменяет текущую перспективу окна GI на простую текстовую 2D перспективу в которой удаление и приближение по оси z не сказывается на размерах объектов, размер точки окна совпадает с единицей измерения координатных осей x и y, и координата (0,0) находится в верхней левой точке окна. Выключение такого режима (aGI.TextWorldPerspective(0)) возвратит предыдущий режим перспективы. Режим удобен для рисования простых 2D спрайтов, фигур или текста (RenderText).
MouseMode Реализована Функция
Да
GI.MouseMode(<Режим захвата мыши (INT)>,<Режим вывода курсора мыши (INT)>,<Режим ограничения движения курсора в 3D перспективе (INT)>) Функция изменяет режим захвата мыши окном GI. Захват мыши обычно необходим для игрового окна, при этом он может быть автоматическим при получении фокуса окном или может вызываться по необходимости с помощью функции CaptureMouse.
FrameLimiter Реализована Функция
Да
GI.FrameLimiter(<Режим ограничения количества кадров (INT)>=0,<Параметры режима (INT)>) Функция изменяет режим ограничения количества кадров окном GI. По умолчанию такой режим не меняется и может зависеть от графического драйвера, поэтому, рекомендуется вызвать эту функцию для окна GI по крайней мере один раз. Некоторые графические драйверы могут не поддерживать режимы синхронизации с вертикальной разверткой экрана, в этом случае, можно использовать режим ограничения кадров по их количеству.
AntiAliasing Реализована Функция
Да
GI.AntiAliasing(<Режим сглаживания рисунка на экране (INT)>=0,<Параметры режима (INT)>) Функция изменяет режим сглаживания рисунка для окна GI. По умолчанию сглаживание не производится. Рекомендуется вызвать эту функцию по крайней мере один раз.
RenderStats Реализована Функция
Да
GI.RenderStats(<Кадров в секунду (INT)>,<Время работы CPU для создания одного кадра в мс. (REAL)>) Функция получает статистику создания кадров с позиции центрального процессора (CPU). Функция не замедляет работу цикла прорисовки. См. также RenderStats2.
RenderStats2 Реализована Функция
Да
GI.RenderStats2(<Время работы GPU для создания одного кадра в мс. (REAL)>) Функция получает время создания кадров с позиции графического процессора (GPU). Функция практически не замедляет работу цикла прорисовки. См. также RenderStats.
LinkEvent Реализована Функция GI.LinkEvent(<Имя события (STRING)>,<Имя локальной функции (STRING)>,<Глубина поиска (INT)>=0,<Аргумент функции>) Функция ассоциирует локальную функцию по ее имени со стандартным событием объекта GI. Также функции может передаваться один произвольный аргумент. На данный момент доступны следующие стандартные события: OnDraw, OnResize, OnNewInput.
MoveAndRotate Реализована Функция
Да
GI.MoveAndRotate(<Смещение камеры по X (REAL)>,<Смещение камеры по Y (REAL)>,<Смещение камеры по Z (REAL)>,<Поворот сцены вокрут оси X (REAL)>,<Поворот сцены вокрут оси Y (REAL)>,<Поворот сцены вокрут оси Z (REAL)>) Функция изменяет внутренние переменные смещения камеры и повороты сцены, которыми система обновляет текущую проекцию окна GI каждый раз до начала рисования кадра.
CaptureMouse Реализована Функция
Да
GI.CaptureMouse() В зависимости от режима захвата мыши MouseMode, функция прячет курсор мыши, переносит ее положение в центр окна GI, либо ничего не делает, если режим захвата выключен, либо захват уже был выполнен.
ReleaseMouse Реализована Функция
Да
GI.ReleaseMouse() В зависимости от режима захвата мыши MouseMode, функция отображает ранее спрятанный курсор мыши, если захват был выполнен ранее.
MouseCaptured Реализована Атрибут
Да
GI.MouseCaptured:<Захвачена ли мышь (INT)> Атрибут отдает 1, если мышь захвачена в данный момент и 0 в другом случае.
RenderText Реализована Функция
Да
GI.RenderText(<Текст для вывода (STRING)>,<Свойства шрифта (STRING)>,<Выбор в графический буфер или на текстуру (LIST) или на экран (0) (LIST,INT)>,<Смещение начальной точки вывода по X (REAL)>,<Смещение начальной точки вывода по Y (REAL)>,<Смещение начальной точки вывода по Z (REAL)>,<Дополнительные параметры (STRING)>="",<Уникальный номер программы шейдеров (INT)>=0) Функция вывод требуемый текст с указанными шрифтом, цветом, размерами и другими параметрами в указанное место окна, графического буфера или текстуры. Важно понимать, что только в текстовой перспективе режиме (TextWorldPerspective) координаты, передаваемые функции будут точно соответствовать экранным координатам внутри окна. При выводе можно использовать программу-шейдер. Функция пользуется стандартными возможностями системы для вывода символов, поэтому, для добавления новых шрифтов, их сначала необходимо добавить в систему. Из-за того, что скорость вывода текста на экран системными функциями слишком низка для создания графических кадров, функция сохраняет каждый выводимый символ на большой текстуре, откуда уже производит копирование в строку-результат. Существует возможность начального заполнения такой текстуры с помощью функции PrerenderText, если шрифт настолько необычный, что необходимо добавлять символы в определенной последовательности, чтобы система смогло корректно определить их размеры. Так как текстуры создаются по мере заполнения и на каждый размер, начертание и свойство (типа наклонности) шрифта создаются отдельные текстуры, иногда может возникнуть необходимость очистить существующие текстуры, чтобы освободить графическую память. Для этого можно воспользоваться функцией FreeTextBuffers.
PrerenderText Реализована Функция
Да
GI.PrerenderText(<Символы для подготовки текстуры-буфера (STRING)>,<Свойства шрифта (STRING)>) Функция позволяет подготовить внутренний буфер-текстуру для указанной строки символов с указанными шрифтом, размерами и другими параметрами заранее. Обычно в таком подходе нет необходимости. См. также описание RenderText.
TextWidthAndHeight Реализована Функция
Да
GI.TextWidthAndHeight(<Текст для нахождения размеров (STRING)>,<Свойства шрифта (STRING)>,<Ширина текста в пикселях (INT)>,<Высота текста в пикселях (INT)>,<Правый отступ в пикселях (INT)>) Функция находит ширину и, если требуется, высоту и правый выступ последнего символа текста, включаемый в общую ширину. Такие отступы обычно используются для кернинга символов. Функция помещает новые символы текста во внутренний буфер-текстуру (см. RenderText), для того, чтобы не пользоваться системными функциями при последовательных вызовах, что увеличивает скорость работы.
FreeTextBuffers Планируется Функция GI.FreeTextBuffers(<Свойства шрифта (STRING)>) Функция удаляет из видеопамяти текстуры, созданные для буферизации вывода текста по наименованию шрифта, его свойствам и размеру. Если размер указан, как 0 удаляются текстуры всех размеров для шрифта с данными свойствами. См. также RenderText.
BufferSavePicture Реализована Функция GI.BufferSavePicture(<Уникальный номер буфера или 0 для экрана (INT)>=0,<Смещение по x внутри буфера (INT)>=0,<Смещение по y внутри буфера (INT)>=0,<Ширина захватываемой картинки (INT)>=0,<Высота захватываемой картинки (INT)>=0,<Тип результата (INT)>=0,<Параметр, зависящий от типа результата>,<Формат результата (STRING)>="BMP",<Тип буфера (если не экран) (INT)>=0):<Результирующая картинка (BUFFER,STRING)> Функция позволяет получить изображение из указанной области буфера или экрана (в том числе для мультиэталонного буфера (multi-sample buffer)), превратить его в картинку в указанном формате и поместить в указанный источник (буфер системы, строку или файл на диске).

Атрибуты и функции текстур

Система хранит именованный массив загруженных в видеопамять текстур. По умолчанию текстуры не имеют имен, но когда приложение достаточно сложное и текстур много, идентификация по именам может помочь в нахождении и удалении текстур. Имена текстур могут быть не уникальны или пустыми (по умолчанию). Адресация текстур происходит через их уникальные номера, присваиваемые графическим драйвером. Разработчик может создавать и загружать текстуры напрямую, минуя функции текстур, в этом случае, они не общий список текстур, известных объекту GI, однако, такой подход не имеет большого смысла, так как уникальные номера все равно необходимо где-то хранить.

Идентификатор Статус Тип Визуальная Параметры Описание
Texture Реализована Функция GI.Texture(<Индекс или имя текстуры (INT,STRING)>):<Уникальный номер текстуры (INT)> Функция получает уникальный номер текстуры по ее индексу или имени.
Textures Планируется Функция GI.Textures(<Начальное имя списка текстур>,<Конечное имя списка текстур>):<Список текстур (LIST)> Функция получает список с уникальными номера текстур, находившихся в указанном диапазоне имен (или только для определенного имени, если задан один аргумент).
TextureCount Реализована Функция GI.TextureCount():<Количество зарегистрированных текстур в объекте GI> Функция получает общее количество текстур текущего объекта GI (только загруженных с помощью функций текстур).
TextureUse Реализована Функция
Да
GI.TextureUse(<Уникальный номер текстуры или 0 (INT)>,<Способ использования (INT)>=0,<Тип текстуры (INT)>=0) Функция активирует или деактивирует использование указанной текстуры при выполнении дальнейшего графического вывода, либо делает ее приемником для этого вывода.
TextureLoadFromMemory Реализована Функция GI.TextureLoadFromMemory(<Тип текстуры (INT)>,<Строка, картинка или буфер (STRING,BUFFER,PICTURE)>,<Свойства текстуры (INT)>=0,<Ширина картинки (INT)>,<Высота картинки (INT)>,<Имя текстуры (STRING)>=""):<Уникальный номер текстуры (INT)> Функция загружает картинку из строки или буфера в текстуру с указанным именем и параметрами и возвращает ее уникальный номер.
TextureLoadFromFile Реализована Функция GI.TextureLoadFromFile(<Тип текстуры (INT)>,<Имя файла картинки (STRING)>,<Свойства текстуры (INT)>=0,<Ширина картинки (INT)>,<Высота картинки (INT)>,<Имя текстуры (STRING)>=""):<Уникальный номер текстуры (INT)> Функция загружает картинку из файла в текстуру с указанным именем и параметрами и возвращает ее уникальный номер.
TextureAddBlank Реализована Функция GI.TextureAddBlank(<Тип текстуры (INT)>,<Свойства текстуры (INT)>=0,<Ширина текстуры (INT)>,<Высота текстуры (INT)>,<Имя текстуры (STRING)>=""):<Уникальный номер текстуры (INT)> Функция создает пустую с указанным именем, размерами и параметрами и возвращает ее уникальный номер.
TextureDelete Планируется Функция GI.TextureDelete(<Начальное имя диапазона текстур (STRING)>,<Конечное имя диапазона текстур (STRING)>) Функция удаляет из видеопамяти диапазон текстур по именам, либо все текстуры, если аргументы не заданы.
TextureSavePicture Реализована Функция GI.TextureSavePicture(<Уникальный номер текстуры (INT)>,<Тип результата (INT)>=0,<Параметр, зависящий от типа результата>,<Формат результата (STRING)>="BMP"):<Результирующая картинка (BUFFER,STRING)> Функция позволяет превратить текстуру, заданную по уникальному номеру, в картинку в указанном формате и поместить в указанный источник (буфер системы, строку или файл на диске).

Атрибуты и функции шейдеров и программ шейдеров

В системе существуют две сущности -- шейдеры и их группы -- программы шейдеров. И те и другие адресуются с помощью уникальных номеров. Эти номера (или идентификаторы) для шейдеров могут совпадать с номерами для программ шейдеров и наоборот. Уникальность номеров соблюдается только отдельно для шейдеров и программ. Ниже в описании функций номера будут называться "уникальный номер шейдера" и "уникальный номер программы шейдеров".

Идентификатор Статус Тип Визуальная Параметры Описание
ShaderCount Реализована Функция GI.ShaderCount():<Количество загруженных шейдеров (INT)> Функция возвращает общее количество шейдеров добавленных в объект с помощью функции ShaderAdd.
Shader Реализована Функция GI.Shader(<Индекс (INT)>):<Уникальный номер (INT)> Функция возвращает уникальный номер шейдера по его индексу в массиве шейдеров объекта.
ShaderDelete Планируется Функция GI.ShaderDelete(<Уникальный номер (INT)>) Функция удаляет шейдер из графической памяти и массива шейдеров объекта по его уникальному номеру. Также можно удалить шейдер, который был создан напрямую, минуя функцию ShaderAdd.
ShaderAdd Реализована Функция GI.ShaderAdd(<Тип шейдера (INT)>,<Исходный текст шейдера (STRING)>):<Уникальный номер (INT)> Функция добавляет новый шейдер с указанным типом в массив шейдеров. При добавлении происходит проверка синтаксиса и компиляция. В результате удачной операции, функция возвращает уникальный номер, по которому шейдер можно затем добавить в программу шейдеров. При ошибке будет вызвано исключение с развернутым описанием причины ошибки. Исходный текст может содержать комментарии с международными символами, использование международных символов в именах переменных и функций в исходных текстах шейдеров обычно не поддерживается.
ShaderAddVariable Реализована Функция GI.ShaderAddVariable(<Уникальный номер шейдера (INT)>,<Имя переменной (STRING)>,<Тип переменной (STRING)>) Функция сопоставляет указанное имя переменной с указанным типом с шейдером по его уникальному номеру. В дальнейшем при добавлении шейдера в программу шейдеров, этой переменной можно будет задать значение по ее имени. В именах переменных обычно запрещено использовать международные символы. Система не проверяет, действительно ли такая переменная присутствует в исходном тексте шейдера. Также при установке значения переменной в программе шейдеров система не будет создавать исключение, если такой переменной в действительности не существует. Это сделано из-за того, что переменные могут быть исключены из-за оптимизации в зависимости от графического драйвера или даже его версии, и это могло бы вызвать ошибку в месте, где она раньше отсутствовала, к примеру, после обновления драйвера.
ShaderDeleteVariable Планируется Функция GI.ShaderDeleteVariable(<Уникальный номер шейдера (INT)>,<Имя переменной (STRING)>) Функция удаляет сопоставление переменной по ее имени с шейдером по его уникальному номеру. Обычно такая операция не требуется.
ShaderProgramCount Реализована Функция GI.ShaderProgramCount():<Количество созданных программ шейдеров (INT)> Функция возвращает общее количество программ шейдеров добавленных в объект с помощью функции ShaderProgramAdd.
ShaderProgram Реализована Функция GI.ShaderProgram(<Индекс программы (INT)>):<Уникальный номер программы (INT)> Функция возвращает уникальный номер программы шейдера по его индексу в массиве программ шейдеров объекта.
ShaderProgramAdd Реализована Функция GI.ShaderProgramAdd(<Уникальный номер шейдера 1 (INT,LIST)>,<Уникальный номер шейдера 2 (INT,LIST)>...):<Уникальный номер программы (INT)> Функция создает новую программу шейдеров из совокупности шейдеров по их уникальным номерам, указанным в аргументах функции, которые могут быть как самими номерами, так и списками номеров. Обычно программы состоят из шейдеров разных видов, но позволяется также использовать шейдеры одинаковых видов (последние будут складываться в один, таким образом, к примеру, можно добавить часто используемые функции в отдельный шейдер). Функция возвращает уникальный номер программы шейдеров, который можно в дальнейшем использовать, к примеру, в функции ShaderProgramUse.
ShaderProgramDelete Планируется Функция GI.ShaderProgramDelete(<Уникальный номер программы (INT)>) Функция удаляет программу шейдеров по ее уникальному номеру из памяти.
ShaderProgramSetVariable Реализована Функция GI.ShaderProgramSetVariable(<Уникальный номер программы (INT)>,<Имя переменной (STRING)>,<Количество значений (INT)>=1,<Значение 1>,<Значение 2>...) Функция устанавливает значение переменной (заданной по ее имени) программы шейдеров (заданной по ее уникальному номеру). Количество значений указывается для переменных, содержащих массивы, и задает количество значений в массиве. Значения могут быть заданы несколькими аргументами как числа (вещественные или целые), либо одним аргументом с типом список (содержащий сами значения), либо буфер или структура данных записи. В последнем случае, размера буфера с данными должно быть достаточно, чтобы уместить весь массив значений. Заданная один раз, переменная для данной программы шейдеров в дальнейшем сохраняет свое значение до того момента, пока программа не будет удалена или значение переменной не будет задано снова.
ShaderProgramUse Реализована Функция
Да
GI.ShaderProgramUse(<Уникальный номер программы (INT)>=0) Функция активизирует программу шейдеров для всех последующих графических операций (нужно также помнить, что функции типа RenderText имеют свои программы шейдеров, поэтому, текущая активная программа будет отключена после их использования). Если аргумент функции отсутствует или равен нулю, активная программа шейдеров будет отключена.
ShaderProgramGetVariableID Реализована Функция GI.ShaderProgramGetVariableID(<Уникальный номер программы (INT)>,<Имя переменной (STRING)>):<Уникальный номер переменной в программе шейдеров (INT)> Функция возвращает уникальный номер переменной в указанной по номеру программе шейдеров. Если такая переменная не найдена (к примеру, возможно, она исключена из-за инициализации), функция возвратит -1. Возвращенный номер можно в дальнейшем использовать в прямых вызовах спецификации (к примеру, в простых моделях, когда необходимо вызвать glUniform для спецификации OpenGL).
ShaderProgramGetVariableValue Планируется Функция GI.ShaderProgramGetVariableValue(<Уникальный номер программы (INT)>,<Имя переменной (STRING)>,<Количество значений (INT)>=1):<Буфер, содержащий значения переменной (BUFFER)> Функция получает значения переменной (заданной по ее имени) программы шейдеров (заданной по ее уникальному номеру). Значения переменной отдаются в виде буфера.

Атрибуты и функции моделей

Объект модели является отдельным объектом системы. Одна модель может быть использована в разных объектах GI, в отличие от, к примеру, шейдера или текстуры.

Идентификатор Статус Тип Визуальная Параметры Описание
New Реализована Функция GIModel.New():<Новый объект модели (GIModel)> Функция создает новый пустой объект модели. После создания, модель можно использовать в объектах с помощью функции Model.
Type Реализована Атрибут GIModel.Type:<Тип модели> Атрибут отдает текущий тип модели. Сразу после создания тип будет нулевым 0 (пустая модель). После загрузки модели атрибут изменяется в соответствии с типом загруженной модели.
Load Планируется Функция GIModel.Load() Функция будет производить загрузку моделей определенных типов. Описание функции будет доступно позднее.
SimpleModel Реализована Функция GIModel.SimpleModel(<Источник микрокода (BUFFER)>,<Режим модели (INT)>=0) Функция сопоставляет буфер с микрокодом с текущей моделью. Микрокод зависит от текущей графической спецификации. См. описание для информации и примеров.

Атрибуты и функции графических объектов

Графический объект объекта GI является отдельным объектом системы. Все такие объекты привязаны к их оригинальному объекту GI и не могут быть использованы в других объектах GI. Объекты имеют свои имена (идентификаторы), имена могут быть не уникальны, либо можно не задавать их вообще. Имена используются для быстрого удаления, добавления и классификации группы объектов.

В дальнейшем к описанию будет добавлены функции добавления своих полей и методов и копирование графических объектов.

Идентификатор Статус Тип Визуальная Параметры Описание
AddObject Реализована Функция
Да
GIObject или GI.AddObject(<Идентификатор объекта (STRING)>="",<Идентификатор класса или объект класса (STRING,GIObject)>,<Состояние объекта (INT)>=0,<Произвольное дополнительное значение объекта>,<Координата по X (REAL)>,<Координата по Y (REAL)>,<Координата по Z (REAL)>,<Ширина по X (REAL)>,<Ширина по Y (REAL)>,<Ширина по Z (REAL)>):<Новый объект (GIObject)> Функция добавляет новый графический объект непосредственно к объекту GI или как подчиненный объект другого графического объекта. Для нового объекта можно указать идентификатор, начальное состояние, его положение и размеры (положение и размеры могут использоваться моделью объекта или по усмотрению разработчика), а также сопоставить с ним произвольное значение и задать объект класса (связанный объект свойства и методы которого также можно будет использовать в данном объекте). Прорисовка объектов происходит автоматически (если их состояние ее не запрещает). При прорисовке сцены, сначала рисуется родитель, затем подчиненные ему объекты, сохраняя все заданные для родителя свойства, типа изменения положения и поворота.
Model Реализована Функция GIObject.Model(<Новая модель объекта (GIModel)>=0):<Предыдущая модель объекта (GIModel)> Функция задает указанную модель графическому объекту, если аргумент опущен или пустой, ассоциация модели с объектом удаляется.
Delete Реализована Функция
Да
GIObject.Delete() Функция удаляет привязку графического объекта к его объекту GI, после этой операции графический объект не будет использоваться при прорисовке кадра и будет удален из памяти, когда на него не останется других ссылок. Такую же операцию претерпевают все графические объекты подчиненные данному.
DeleteObjectRange Реализована Функция
Да
GIObject или GI.DeleteObjectRange(<Рекурсивный поиск (INT)>=0,<Начальный идентификатор диапазона объектов (STRING)>,<Конечный идентификатор диапазона объектов (STRING)>) Функция удаляет диапазон графических объектов по их идентификаторам (либо все объекты, если аргументы идентификаторов не заданы). Функция производит поиск объектов для удаления среди подчиненных объектов данного или всех графических объектов GI, если она вызывается для объекта GI. Если задана опция рекурсивного поиска, он будет происходить не только среди непосредственно подчиненных объектов, но и среди всех объектов подчиненных последним. При удалении объекта, все его подчиненные объекты также удаляются.
DeleteChildren Планируется Функция
Да
GIObject или GI.DeleteChildren() Функция удаляет все графические объекта подчиненные данному или вообще все объекты, если она вызвана для объекта GI.
ObjectCount Реализована Функция GIObject или GI.ObjectCount(<Рекурсивный поиск (INT)>=0,<Начальный идентификатор диапазона объектов (STRING)>,<Конечный идентификатор диапазона объектов (STRING)>):<Количество найденных объектов (INT)> Функция посчитывает количество графических объектов в диапазоне, заданном их идентификаторами (либо все объекты, если аргументы идентификаторов не заданы). Функция производит поиск объектов среди графических объектов объекта GI или подчиненных данному графическому объекту. Если задана опция рекурсивного поиска, он будет происходить не только среди непосредственно подчиненных объектов, но и среди всех объектов подчиненных последним.
Objects Реализована Функция GIObject или GI.Objects(<Рекурсивный поиск (INT)>=0,<Начальный идентификатор диапазона объектов (STRING)>,<Конечный идентификатор диапазона объектов (STRING)>):<Список найденных объектов (LIST)> Функция находит диапазон графических объектов по их идентификаторам (либо все объекты, если аргументы идентификаторов не заданы) и возвращает их в виде списка. Функция производит поиск объектов среди подчиненных объектов данного или всех графических объектов GI, если она вызывается для объекта GI. Если задана опция рекурсивного поиска, он будет происходить не только среди непосредственно подчиненных объектов, но и среди всех объектов подчиненных последним.
ParentObject Реализована Атрибут GIObject.ParentObject:<Родительский объект (GIObject)> Атрибут возвращает родительский графический объект текущего или пустое значение, если родительского объекта не существует.
GI Реализована Атрибут GIObject.GI:<Объект GI (GI)> Атрибут возвращает объект GI, которому принадлежит данный графический объект. Объект возвращается даже в случае, когда текущий графический объект был отсоединен от объекта GI (удален).
State Реализована Атрибут
Да
GIObject.State:<Статус графического объекта (INT)> Атрибут возвращает или изменяет статус текущего графического объекта.
Tag Реализована Атрибут GIObject.Tag:<Произвольное дополнительное значение> Атрибут хранит произвольное значение, связанное с текущим графическим объектом.
Name Реализована Атрибут GIObject.Name:<Идентификатор объекта (STRING)> Атрибут возвращает идентификатор текущего объекта, если он был задан, иначе возвращается пустая строка.
MoveRotateAndScale Реализована Функция
Да
GIObject.MoveRotateAndScale(<Смещение объекта по X (REAL)>,<Смещение объекта по Y (REAL)>,<Смещение объекта по Z (REAL)>,<Поворот объекта вокрут оси X (REAL)>,<Поворот объекта вокрут оси Y (REAL)>,<Поворот объекта вокрут оси Z (REAL)>,<Масштаб объекта по X (REAL)>,<Масштаб объекта по Y (REAL)>,<Масштаб объекта по Z (REAL)>) Функция изменяет внутренние переменные смещения графического объекта, его поворота и его масштаба, которыми система обновляет текущую проекцию объекта каждый раз до начала его рисования.
LinkEvent Реализована Функция GIObject.LinkEvent(<Имя события (STRING)>,<Имя локальной функции (STRING)>,<Глубина поиска (INT)>=0,<Аргумент функции>) Функция ассоциирует локальную функцию по ее имени со стандартным событием графического объекта. Также функции может передаваться один произвольный аргумент при ее вызове. На данный момент доступны следующие стандартные события объектов: OnDraw, OnNewInput, OnChange, OnMove.
DrawObject Реализована Функция
Да
GIObject.DrawObject() Функция инициирует прорисовку текущего визуального объекта. Функция вызывается автоматически для всех объектов при прорисовке кадра, однако, если для объекта задано событие OnDraw, внутри этого событие необходимо вызвать эту функцию для выполнения прорисовки объекта. Также эту функцию можно вызвать для произвольного объекта в произвольный момент прорисовки кадра, автоматическая прорисовка для этого объекта будет пропущена для этого кадра. Также функцию можно вызвать несколько раз для одного и того же графического объекта для одного и того же кадра, если в этом есть необходимость.