GI.RenderText

From SunFlurry wiki
Jump to: navigation, search
  RenderText (Общие функции объекта GI)
Объект:Объект GI
Статус разработки: Реализована
Тип:Функция
Обращение к БД:Нет
Исключения:Неверные аргументы.
Визуальность:Да

Функция вывод требуемый текст с указанными шрифтом, цветом, размерами и другими параметрами в указанное место окна, графического буфера или текстуры. Важно понимать, что только в текстовой перспективе режиме (TextWorldPerspective) координаты, передаваемые функции будут точно соответствовать экранным координатам внутри окна. При выводе можно использовать программу-шейдер. Функция пользуется стандартными возможностями системы для вывода символов, поэтому, для добавления новых шрифтов, их сначала необходимо добавить в систему. Из-за того, что скорость вывода текста на экран системными функциями слишком низка для создания графических кадров, функция сохраняет каждый выводимый символ на большой текстуре, откуда уже производит копирование в строку-результат. Существует возможность начального заполнения такой текстуры с помощью функции PrerenderText, если шрифт настолько необычный, что необходимо добавлять символы в определенной последовательности, чтобы система смогло корректно определить их размеры. Так как текстуры создаются по мере заполнения и на каждый размер, начертание и свойство (типа наклонности) шрифта создаются отдельные текстуры, иногда может возникнуть необходимость очистить существующие текстуры, чтобы освободить графическую память. Для этого можно воспользоваться функцией FreeTextBuffers.

Синтаксис

GI.RenderText(<Текст для вывода (STRING)>,<Свойства шрифта (STRING)>,<Выбор в графический буфер или на текстуру (LIST) или на экран (0) (LIST,INT)>,<Смещение начальной точки вывода по X (REAL)>,<Смещение начальной точки вывода по Y (REAL)>,<Смещение начальной точки вывода по Z (REAL)>,<Дополнительные параметры (STRING)>="",<Уникальный номер программы шейдеров (INT)>=0)

Аргументы

  • <Текст для вывода (STRING)> - Аргумент задает текст для вывода. В тексте можно использовать международные символы.
  • <Свойства шрифта (STRING)> - Аргумент задает наименование, размер и другие свойства шрифта текста в формате: <Имя шрифта>,<Размер>,<Стиль>,<Цвет в 16-ричной форме>,<Угол поворота в градусах>,<Тип сглаживания (0..3)>. Стиль шрифта задается как совокупность начальный букв сл. свойств: Bold, Italic, Uderlined, Strikeout, при пустом значении, используется стиль по умолчанию. Доступны следующие типы сглаживания: 0 -- сглаживание по умолчанию на системном уровне, 1 (по умолчанию) -- стандартное сглаживание, 2 -- сглаживание типа ClearType (не рекомендуется), 3 -- без сглаживания. Смотрите также статью Формат записи шрифтов в системе. Цвет шрифта также передается программе-шейдеру в виде переменной u_textcolor, если она используется.
  • <Выбор в графический буфер или на текстуру (LIST) или на экран (0) (LIST,INT)> - (необязательный аргумент) Аргумент задает тип места вывода. Если аргумент не задан, пустое значение или ноль, вывод будет происходить на экран. Иначе аргумент должен быть списком, содержащим 4 цифровых значения в следующем порядке:
    • <Тип места вывода>: 0 -- вывод будет происходить в графический буфер (второе значение -- это глобальный номер этого буфера), 1 -- вывод будет происходить на текстуру (втрое значение -- глобальный номер этой текстуры).
    • <Глобальный номер места вывода>: зависит от предыдущего значения.
    • <Ширина текстуры или буфера>,<Высота текстуры или буфера>: используется, когда происходит на текстуру или в графический буфер, который привязан к текстуре или экрану для корректировки положения вывода.
  • <Смещение начальной точки вывода по X (REAL)>,<Смещение начальной точки вывода по Y (REAL)>,<Смещение начальной точки вывода по Z (REAL)> - Аргументы содержат начальную точку вывода. В зависимости от текущей перспективы, точка (0,0,0) может быть в центре экрана, при этом координата по оси Y растет вверх (см. WorldPerspective), либо в верхнем левом углу экрана и координата по оси Y растет вниз (см. TextWorldPerspective).
  • <Дополнительные параметры (STRING)> - (необязательный аргумент) Аргумент задает строку, в которой указаны значения через запятую (к примеру "0,2,FFFFFF,3") в следующем порядке:
    • <Режим комбинирования>: число, принимающее следующие значения:
      • 0 (по умолчанию) -- функция сначала выводит все символы последовательно на особую текстуру, а потом выводит содержимое этой текстуры в место назначения. Этот режим чуть медленнее режима 1, но при использовании шейдера (в том числе для подсветки контура) он позволяет работать с текстом как с единой картинкой, а не отдельными символами, это необходимо, когда части символов накладываются друг на друга (к примеру, в наклонных шрифтах).
      • 1 -- функция выводит каждый символ отдельно в место назначения. Этот режим чуть быстрее, накладывание символов друг на друга происходит засчет выключения буфера глубины на время вывода. При использовании шейдера подсветки контура или своего шейдера этот режим не рекомендуется, если используется режим тени, а не подсветки, режим будет работать корректно.
    • <Режим подсветки или тени>: число, принимающее следующие значения:
      • 0 (по умолчанию) -- подсветка или тень не используются.
      • 1 -- используется простая "тень" для каждого из символов. "Тень" -- повторение вывода символа с другим цветом и отступом на несколько точек вправо и вниз. Количество точек отступа при этом задается четвертым значением этого аргумента функции. При отрицательном червертом значении, "тень" будет иметь отступ влево и вверх.
      • 2 -- использовать встроенный шейдер для подсветки контура. Встроенный шейдер будет использоваться только, если не задан собственный шейдер (следующий аргумент функции). Код встроенного шейдера дан ниже по тексту для лучшего понимания того, как работает функция. Сила подсветки задается четвертым значением этого аргумента функции.
    • <Цвет тени или подсветки в шестнадцатеричном виде>: используется, если включен режим тени или подсветки, также передается программе-шейдеру в виде переменной u_outlinecolor.
    • <Размер тени или подсветки>: используется, если включен режим тени или подсветки, также передается программе-шейдеру в виде переменной u_outlinesize.
  • <Уникальный номер программы шейдеров (INT)> - (необязательный аргумент) Задает уникальный номер программы шейдеров для использования при выводе. Если этот аргумент задан, встроенная программа-шейдер использоваться не будет. Указанной здесь программе-шейдеру автоматически передаются следующие переменные: u_texture (sampler2D, номер текстуры, всегда 0), u_textpos (vec4, координата текущего символа внутри текстуры и его размеры на ней в момент вывода символа. При этом x и y составляющие вектора u_textpos задают координату символа (изменяются в диапазоне [0..1)), а z и w составляющие вектора u_textpos задают ширину и высоту символа (также изменяются в диапазоне [0..1)). Координаты и размеры заданы в пропорции размеров текстуры), u_screenpos (vec4, координата текущего символа и его размеры на экране в момент вывода символа. При этом x и y составляющие вектора u_screenpos задают координату символа в пикселях, а z и w составляющие вектора u_screenpos задают ширину и высоту символа в пикселях), u_textcolor (vec3, цвет текста выводимого символа, составляющие цвета изменяются в диапазоне [0..1]), u_outlinesize (float, ширину рамки подсветки вокруг выводимого символа), u_outlinecolor (vec3, цвет рамки подсветки выводимого символа, составляющие цвета изменяются в диапазоне [0..1]). Код встроенного шейдера дан ниже по тексту для лучшего понимания того, как работает функция и удобства написания своего.

Код встроенного шейдера создания подсветки символов (пример для OpenGL)

#version 130
//Автоматически передаваемые переменные
//Номер текстуры (всегда 0)
uniform sampler2D u_texture;
//Позиция и размер символа (или всех символов) внутри текстуры
uniform vec4 u_textpos;
//Позиция и размер символа (или всех символов) на экране
uniform vec4 u_screenpos;
//Цвет текста
uniform vec3 u_textcolor;
//Цвет подсветки
uniform vec3 u_outlinecolor;
//Размер подсветки
uniform float u_outlinesize;
void main(void) {
  //Нахождение текущей координаты внутри текстуры в зависимости от текущей координаты экрана gl_FragCoord
  vec2 txcoord=(gl_FragCoord.xy-u_screenpos.xy)/u_screenpos.zw;
  txcoord=u_textpos.xy+txcoord.xy*u_textpos.zw;
  //Получение цвета точки текстуры символа (данные символов в текстуре хранятся только как составляющая альфа (w), остальные каналы цвета содержат нули)
  vec4 txcolor=texture(u_texture,txcoord);
  //Шаг размера точки на текстуре, чтобы найти соседние точки текстуры
  vec2 pixelsize=1.0/vec2(textureSize(u_texture,0));
  //Интенсивность подсветки в текущей точке экрана будет находиться в этой переменной
  float outlinecolor=0;
  //Искать подсветку будем только для точек вне символов или частично прозрачных точек
  if (txcolor.w<0.9999) {
    //Соберем интенсивности точек, окружающие текущую точку на расстоянии u_outlinesize. Чем больше u_outlinesize, тем медленнее работает этот шейдер.
    int num=1;
    for (float i=-u_outlinesize;i<u_outlinesize+1;i+=1.0) {
      for (float j=-u_outlinesize;j<u_outlinesize+1;j+=1.0) {
        //Смещение от текущей точки в координатах текстуры.
        vec2 offset=vec2(i,j)*pixelsize+txcoord;
        //Количество собранных интенсивностей точек
        num+=1;
        //Если точка текстуры не выходит за пределы текстуры...
        if (clamp(offset.xy,u_textpos.xy,u_textpos.xy+u_textpos.zw)==offset.xy) {
          //Получим интенсивность этой точки (альфа-канал)
          vec4 txcolor2=texture(u_texture,offset);
          //и добавим к собираемой интенсивности
          outlinecolor+=txcolor2.w;
        }
      }
    }
    //Найдем результирующую интенсивность подсветки в текущей точке экрана.
    outlinecolor=outlinecolor/num*(u_outlinesize*2+1);
  }
  //Убедимся, что добавление найденной интенсивности не будет мешать интенсивности текущего символа с текстуры и не приведет к переполнению (1.0).
  outlinecolor=min(1.0,txcolor.w+outlinecolor)-txcolor.w;
  //Вычислим текущий цвет точки экрана с учетом интенсивности подсветки u_outlinecolor, интенсивности цвета символа txcolor, цвета символа u_textcolor и цвета подсветки outlinecolor.
  gl_FragColor=vec4(mix(u_outlinecolor.xyz,u_textcolor.xyz,txcolor.w),txcolor.w+outlinecolor);
}

Пример вывода текста на текстуру без видимого окна GI

//Создать невидимое окно 200x200
aGI:=GI.Init(,,200,200);
//Создать пустую текстуру 200x200
аТекст:=aGI.TextureAddBlank(0,0,200,200);
//Белый фон
aGI.TextureUse(аТекст);
aGI.glClearColor(1.0,1.0,1.0,1.0);
aGI.glClear(aGI.GL_COLOR_BUFFER_BIT or aGI.GL_DEPTH_BUFFER_BIT);
//Текстовая перспектива
aGI.TextWorldPerspective(1);
//Выводим текст "Проверка" на текстуру, начиная с точки 10,10 в верхнем левом углу текстуры с зеленой "тенью"
aGI.RenderText("Проверка","Arial,15,B,0000FF,,1",List.Create(1,аТекст,200,200),10,10,0.5,"1,1,00FF00,2");
//Сохраним тектуру в виде файла
aGI.TextureSavePicture(аТекст,2,"c:\testtexture.png","PNG");

Пример вывода статистики в окно GI

...
аДата:=Date();
СтрСтат:="";

...

  //Выведем статистку в левый нижний угол экрана
  aGI.TextWorldPerspective(1);
  If GetPeriodMs(аДата)>100 Then
    аДата:=Date();
    аФПС:=0;
    аВремя:=0;
    аВремя2:=0;
    aGI.RenderStats(аФПС,аВремя);
    aGI.RenderStats2(аВремя2);
    СтрСтат:=""+аФПС+"FPS, CPU time: "+FormatNumber(аВремя,0,"",3)+"ms, GPU time: "+FormatNumber(аВремя2,0,"",3)+"ms";
  EndIf;
  aGI.RenderText(СтрСтат,"Tahoma,15,IB,"+DecToBase(_CLR_BLUE,16),0,10,aGI.Height-30,0.5,"0,2,FFFFFF,3");
  aGI.TextWorldPerspective(0);

...