Конференция "Игры" » Вывод текста Direct3D
 
  • Rembo (20.03.09 21:14) [0]
    Есть растр с симовлами, планировал во время загрузки программы брать его и резать, после чего каждую букву хранить как текстуру в масиве, а дальше двумя треугольниками выводить по букве собсно текст.
    Вопрос: что в этом алгоритме неправильно и как можно сделать лучше?
  • Rembo (20.03.09 23:39) [1]
    Вощем изменил все, решил загружать символы в текстуру целиком а потом с помощью текстурных координат выводить нужную букву на спрайте.
    Итак текстура имеет размеры 256х128, размер буквы 13х17. Пытаюсь для начала вывести букву А, которая идет первой. Текст. координаты опытным путем удалось установить такие:
    0:1      0,0508:1
    0:0,93  0,0508:0,93
    И если 13/256=0,0508 то 17/128=0,1328
    непонятно откуда 0,93 береться, при том что буква отлично расстянулась на спрайте.
  • Rembo (20.03.09 23:57) [2]
    Нашел формулу для 0,93:
    1-17/256
    и даже понял откуда оно береться.
    Вопрос такой: занимаюсь ли я фигней полной или этот действительно текст можно выводить с помощью текстурных координат? И есть ли способ вместо векторов использовать такие простые и понятные пиксели как в случае с пространственными координатами вершин (RHW)?
  • Rembo (21.03.09 03:44) [3]
    Все, вроде понял.
    Если кому интересно.
    Ширина и высота переводяться в вектор: 13/256=0,0508=j и 1-17/256=0,046875=k
    Дальше чтобы получить букву в y строке x столбце делаем текстурные координаты:
    (x-1)*j:1-(y-1)*k   j*x:1-(y-1)*k
    (x-1)*j:1-y*k        j*x:1-y*k
  • @!!ex © (21.03.09 18:11) [4]
    вроде это простая математика?
    Ни?
    Могу дать прогу(генератор шрифтов) и класс для работы с ней(Правда на C++ и под OpenGL, ну да на дельфи и D3D переделывается без проблем).
    +в поддержке шрифтом с динамическим размером шрифта и в небольшом размере файла шрифта.
  • Rembo (23.03.09 02:19) [5]
    Короче все вышло как и планировалось, но вылезло 2 косяка:
    1. Одни буквы выше других и выглядит все просто ужасно. Легко решаеться в принцепе, чего не скажеш о втором.
    2. Жуткие тормоза! Если без текста фпс зашкаливает за тысячу, то каждый символ отнимает по сотне, до полной остановки программы. Я думаю что знаю почему так: каждый кадр для каждого символа создаеться по квадрату размером 17х13 и на него накладываеться текстура 256х256, тоесть кусок текстуры, но обрабатываеться то вся.
    Имхо этот метод тупиковый и безперспективный.
    В итоге гдето вычитал рисовать текст прямо на текстуре, в результате почти полная независимость фпс от количества текста (задержка только в момент его изменения), а в перспективе набор тегов для форматирования текста!
  • @!!ex © (23.03.09 06:57) [6]
    > 2. Жуткие тормоза! Если без текста фпс зашкаливает за тысячу,
    > то каждый символ отнимает по сотне, до полной остановки
    > программы.

    Это вы чето делаете криво...
    Потому что в штатной ситуации подобный подход прекрасно работает.
  • Sapersky (23.03.09 11:19) [7]
    По поводу п.2 - по одной букве, наверное, рисуешь. Или создаёшь VB для каждой буквы...
    Правильно - использовать как можно меньшее кол-во VB/вызовов DrawPrimitive.
    Вообще, модулей для работы с текстом в D3D понаписано уже предостаточно:
    1) CD3DFont в составе framework к DX8 SDK (см. на clootie.ru).
    2) ID3DXFont (D3DX).
    3) TPowerFont (PowerDraw/Asphyre).
    4) http://sapersky.narod.ru/files/AnyDX2D_v0.6.rar (TTextBuffer, пример Fonts)
    и т.д...
  • имя (08.05.09 10:25) [8]
    Удалено модератором
  • Ни фига не (09.05.09 22:04) [9]

    > Вообще, модулей для работы с текстом в D3D понаписано уже
    > предостаточно:
    > 1) CD3DFont в составе framework к DX8 SDK (см. на clootie.
    > ru).
    > 2) ID3DXFont (D3DX).
    > 3) TPowerFont (PowerDraw/Asphyre).
    > 4) http://sapersky.narod.ru/files/AnyDX2D_v0.6.rar (TTextBuffer,
    >  пример Fonts)
    > и т.д...


    лучше сделать это самому, будет лучше. Профессионалы, как говорится, рекомендуют. Если еще и вывод текста брать левый, то что уж говорить о более сложных задачах.


    > Короче все вышло как и планировалось, но вылезло 2 косяка:
    >
    > 1. Одни буквы выше других и выглядит все просто ужасно.
    > Легко решаеться в принцепе, чего не скажеш о втором.
    > 2. Жуткие тормоза! Если без текста фпс зашкаливает за тысячу,
    >  то каждый символ отнимает по сотне, до полной остановки
    > программы. Я думаю что знаю почему так: каждый кадр для
    > каждого символа создаеться по квадрату размером 17х13 и
    > на него накладываеться текстура 256х256, тоесть кусок текстуры,
    >  но обрабатываеться то вся.
    > Имхо этот метод тупиковый и безперспективный.


    не дури. этот метод используется в 99 случаев из 100. только вместо спрайтов используется один динамический буфер вершин формата D3DFVF_XYZRHW(трансформированные координаты - в пространстве экрана. rhw говорит о том, что трансформировать вершинки не нужно) + D3DFVF_TEX1.
    Также можно вместо буфера рисовать примитивы прямо из оперативки - DrawPrimitiveUP/DrawIndexedPrimitiveUP. Это чуть медленнее, что не существенно в данном случае, зато проще.
    Кадры не причем. Все синхронно. Пишешь функцию типа нарисовать строку DrawText(int x, int y, const char *text); Она будет заполнять буфер данными и сразу выводить его на экран. Должна вызываться внутри BeginScene/EndScene
    Теперь шрифт: квадратная текстура, скажем 256x256 текселей. Всего 256 символов - 16 по ширине на 16 по высоте. Каждый символ поэтому занимает макс 16ч16 точек. Выровнен по левому краю сетки. Еще нужна информация: ширина каждой буквы и высота строки. Эти данные можно посчитать самому из сгенеренной текстуры. Я это делал, было вполне терпимо. Либо достать непосредственно из шрифта, если есть возможность. В Builder/Delphi, кажется, через Canvas./Font можно.
  • Rembo (17.05.09 07:39) [10]

    > вместо спрайтов используется один динамический буфер вершин

    А Б В Г Д
    |\|\|\|\|\|
    Я правильно понял?
    Хм, текст. координаты так выставить не получится. По моему самое то: нарисовать строку drowtext или из файла таблицы а потом положить на спрайт
  • Sapersky (18.05.09 15:40) [11]
    Я правильно понял?
    Хм, текст. координаты так выставить не получится.


    "Один буфер" это не в смысле "одной полоской". Это в том смысле, что не нужно рисовать по одной букве.
    Буферизация при выводе спрайтов вообще полезна, не только для текста. У меня для этого сделан спец. класс TSpriteBuffer (DX_sprite.pas), TTextBuffer и все прочие функции вывода спрайтов рисуют через него.
    Т.е. ИМХО вывод текста удобно делать через универсальные механизмы вывода спрайтов (каждая буква - отдельный спрайт), при условии, что эти механизмы достаточно хорошо отлажены и оптимизированы.
    Что касается вывода уже готовых строк из текстуры - в принципе можно, но существенного выигрыша от этого не получить, видеокарте практически всё равно, рисовать 10 или 100 треугольников (между 1000 и 10000 разница, вероятно, будет).
 
Конференция "Игры" » Вывод текста Direct3D
Есть новые Нет новых   [134430   +2][b:0][p:0]