Конференция "Игры" » Мелкие объекты в Direct3D [Delphi, Windows]
 
  • novarm (22.12.07 20:50) [0]
    Занимаемся разработкой CAD приложения и для новой версии внедряем DirectX для ускорения отрисовки (изначально было GDI). Проблема в том что при уменьшении масштаба исчезают линии и другие мелкие объекты (отрисованные треугольниками). Можно ли как-то этого избежать. Может есть какие-то настройки рендеринга чтобы все отображалось, даже если оно меньше одного пиксела.
    Вопрос в принципе решается сглаживанием, но оно сильно ухудшает читабельность изображения, поэтому решили вообще его не применять. А полный пересчет картинки (с изменением размеров соответственно масштабу) при масштабировании колесом мыши сводит преимущество в скорости перед GDI на нет. Пока обошли методом пересчета через какое-то время после масштабирования, но это решение далеко от идеала, поскольку картинка исчезает при уменьшении масштаба и только через секунду появляется. При быстром увеличении тоже получаются линии и круги огромного размера и через секунду нормализуются.

    Спасибо!
  • @!!ex © (22.12.07 22:03) [1]
    Можно скриншот того что есть, и что должно быть?
    Вообще проблема очень странная, я бы даже сказал что она нереальная...
  • homm © (23.12.07 12:15) [2]
    > [1] @!!ex ©   (22.12.07 22:03)

    Как я понял, он рисует текст и линии полигонами. Когда уменьшает масштаб, у него эти линии пропадают, потому как толкщиной становтся меньше пикселя.
  • novarm (23.12.07 15:53) [3]
    Все объекты преобразуются в треугольники (если полигонами, прийдется часто менять режим, что очень сильно затормаживает рендеринг).
    При уменьшении масштаба изображение частично исчезает поскольку размер меньше пиксела. Можно сделать равным пикселу и пересчитывать картинку под каждый масштаб, что сейчас и делается через секунду после масштабирования колесом. Но было бы намного лучше если бы рисовалось все независимо от размера. Возможно есть какие-то настройки рендеринга.

    Скриншоты:
    Исходная картинка: http://www.novarm.com/pict1.gif
    После масштабирования: http://www.novarm.com/pict2.gif
    После пересчета с изменением ширины линий согласно масштабу (т.е. то что должно быть после масштабирования в идеале):
    http://www.novarm.com/pict3.gif
  • homm © (23.12.07 15:58) [4]
    Чето я не понял, зачем тебе Direct3D, если там НЕТ 3D?
  • @!!ex © (23.12.07 16:21) [5]
    > [3] novarm   (23.12.07 15:53)

    Задачка - бред
    Средствами ГДИ рисуетс я без проблем, даже если плотность объектов будет в 10 раз больше.
    ПРи масштабировании конечно будет тормознее, если объектов ОЧЕНЬ много.
    Отрисовка на ГДИ оптимизируется очень легко, но это homm или anton лучше расскажут, они в этом деле мастера.

    По сабжу.
    Какими средставми вы масштабируете, что такой косяк получается???
    Линия рисуется ВСЕГДА, если у нее две координаты в разных пикселях.
    тоже самое с треугольником.


    > если полигонами, прийдется часто менять режим, что очень
    > сильно затормаживает рендеринг

    Та ну, ерунда.
    Сейчас тыщ пиисят поликов можно поодиночке отрисоывать в реалтайме. на средненькой машинке.
  • @!!ex © (23.12.07 16:34) [6]
    вот результат уменьешния в 1, 100, 200 раз.
    Как видите, даже в сверхамаленьком треугольнике, он никуда не пропадает.
    Полик рисуется ВСЕГДА, если его проекция занимает большое одного пикселя. А линия из одного пикселя в другой, ВСЕГДА больше одного пикселя.
    http://img145.imageshack.us/my.php?image=trianglesoz5.png

    P.S.
    Картинки лучше присылать в формате png. При размерах сравнимых с gif, качество в разы выше.
  • homm © (23.12.07 16:46) [7]
    > [6] @!!ex ©   (23.12.07 16:34)
    > Как видите, даже в сверхамаленьком треугольнике, он никуда
    > не пропадает.

    А можешь сделать такую-же картинку из решетки из 10 полосок, таких, чтобы ширина на исходном рисунке у них была пикселей 5. Я чето тоже всегда считал, что полигоны будут пропадать…
  • novarm (23.12.07 16:57) [8]
    В GDI было раньше и такой режим выбирается, но в нем тормозит при больших файлах (иногда нужно рисовать по нескольку десятков тысяч линий и больше, как оптимизировать помимо применение битмапов вместо объектов, но это сильно ограничивает функциональность - не знаю).
    Задача D3D ускорить отрисовку, с чем оно успешно справляется. Некоторые проекты занимают по нескольку миллионов треугольников, поэтому при переключении режимов сильные тормоза (в начале именно так и пробовалось делать, потом пришли к тому что все надо делать одним или на крайняк несколькими массивами одного типа, но не поодиночке).

    Я так понял в D3D координаты в float значениях (модуль D3D писал не я, а другой программер) из-за чего попадает в тот-же самый пиксел. Сглаживание с задачей отображения справляется, но нам оно не подходит.

    Может мы действительно чего-то не догоняем, поскольку с D3D собственно столкнулись впервые здесь. Возможно стоило писать на OpenGL, в CAD обычно его применяют, а не D3D

    Еще по каким-то непонятным причинам отказывается работать на некоторых машинах (вылетает исключение). Причем все за бугром у пользователей, тут везде где пробовали - работает. Версии DirectX и конфигурации в порядке.
  • novarm (23.12.07 17:05) [9]
    Работает так: Сначала вся картинка состоящая из линий, дуг, окружностей, полилиний, полигонов и т.д. перегоняется в массив треугольников (собственно пересчет), потом этот массив с заданным масштабом и смещением экрана уже попадает в память видухи на рендеринг. При масштабировании берется тот-же массив и загоняется в память с другими координатами (в зависимости от установок масштаба/смещения, но пересчет объектов не делается).
  • @!!ex © (23.12.07 17:13) [10]
    > [7] homm ©   (23.12.07 16:46)

    Мне кажется, что мы говорим о разных вещах.
    Если ты внимательно посмотришь на http://www.novarm.com/pict2.gif, то увидишь, что там пропадают линии, которые даже в уменьшенном масштабе занимают


    > В GDI было раньше и такой режим выбирается, но в нем тормозит
    > при больших файлах (иногда нужно рисовать по нескольку десятков
    > тысяч линий и больше, как оптимизировать помимо применение
    > битмапов вместо объектов, но это сильно ограничивает функциональность
    > - не знаю).

    значительно больше одного пикселя по длине.

    Неужели надо было на экране выводить сразу столько объектов?
    Вообще ИМХО это очень хорошо оптимизица, так как об отрисовке в реалтайме речи нет.
    Например, можно отрисовать мзображение на BackBuffer'e, и при отрисовке просто отрисоывваеть его.
    При изменении/добавлении объекта перерисовывать только часть BackBuffer'a. Все летать будет. Рисунок то сам по себе статичен. Нафига при каждой перерисовке отрисовывать все 100000 объектов?


    > Задача D3D ускорить отрисовку, с чем оно успешно справляется.
    > Некоторые проекты занимают по нескольку миллионов треугольников,
    > поэтому при переключении режимов сильные тормоза (в начале
    > именно так и пробовалось делать, потом пришли к тому что
    > все надо делать одним или на крайняк несколькими массивами
    > одного типа, но не поодиночке).

    VBO - forever. ПРавда не знаю, как его реализовать на D3D.


    > Я так понял в D3D координаты в float значениях (модуль D3D
    > писал не я, а другой программер) из-за чего попадает в тот-
    > же самый пиксел. Сглаживание с задачей отображения справляется,
    > но нам оно не подходит.

    Чет я не вижу на примере, чтобы попадало в один и тот же пиксель. Красным нарисована исчезнувшая линия.
    http://img57.imageshack.us/my.php?image=pict2zd8.png
    Кстати, рисунок в png, без потери качества занимает на 14 кб меньше, чем gif с офигенной потерей качества.


    > Может мы действительно чего-то не догоняем, поскольку с
    > D3D собственно столкнулись впервые здесь. Возможно стоило
    > писать на OpenGL, в CAD обычно его применяют, а не D3D

    Без разницы... Тот же *** только сбоку.


    > Еще по каким-то непонятным причинам отказывается работать
    > на некоторых машинах (вылетает исключение). Причем все за
    > бугром у пользователей, тут везде где пробовали - работает.
    > Версии DirectX и конфигурации в порядке.

    Ну так ловите в чем проблема.
    ЛОГ вам в помощь.
    RAdmin опять же, никто не отменял.

    > [9] novarm   (23.12.07 17:05)

    ИМХО нужно делать три массива.
    1) Текст
    2) объекты с заливкой, переведенные в треугольники.
    3) объекты без заливки, переведенные в линии

    P.S.
    Если объекты стандартные, их надо хранить в нескольких вариантах, для разных масштабов.
  • homm © (23.12.07 17:22) [11]
    > [10] @!!ex ©   (23.12.07 17:13)
    > значительно больше одного пикселя по длине.

    Но значительно меньше по ширине. Как видеокарта должна отрисовывать линию, если ее ширина от 235,4 до 235,8 пикселя? А другия линия с тем же размером попадает на экранные пиксели от 236,8 до 237,2. Попробуй сделать так, как я сказал, всеже охото помотреть.
  • @!!ex © (23.12.07 17:30) [12]
    > [11] homm ©   (23.12.07 17:22)

    Ну чего ты ерунду говоришь.
    ТОлщина линии задается отдельным параметром, на нее не распространяется матрица преобразования, через которую масштабирование делается, т.к. преобразуются только координаты.
  • novarm (23.12.07 17:32) [13]
    Что подразумевается под BackBuffer?
    Если просто битмап, о чем я писал, то он не решает задачи масштабирования, только скроллинг и редактирование (отрисовка на битмапе без объекта в начале действия, а потом битмап и редактируемый объект), когда как Direct3D - решает (там тоже по сути что-то вроде BackBuffer, только вместо битмапа массив треугольников).

    В плане трех массивов или просто отдельных массивов под разные типы объектов не подходит, поскольку важна последовательность прорисовки при многослойных объектах и работает в 2D режиме.
    В принципе, все это мы решили и даже GDI частично оптимизировали (хотя и хуже работает чем D3D).

    Вопросы остались только с прорисовкой мелких объектов при изменении масштаба. Линии рисуются также треугольниками и видимо если две точки треугольника попадают при округлении в один пиксел, то D3D его уже не рисует (или делает штрих-пунктир если линий под наклоном), а надо сделать чтобы рисовал.

    Логи сделали, сейчас ловим. До этого пробовал просто метки проставлять (вылетает в самых разных местах, но только в D3D режиме). RAdmin на крайняк уже будет.
  • homm © (23.12.07 17:36) [14]
    > [12] @!!ex ©   (23.12.07 17:30)
    > ТОлщина линии задается отдельным параметром

    Вот :) А автор же полигонами рисует :) И я тебе о полигонах говорю. А ты научи его (и меня заодно) линиями рисовать :)
  • @!!ex © (23.12.07 17:41) [15]
    Ниче, никуда не вырождается:
    http://img136.imageshack.us/my.php?image=linesyo6.png
  • @!!ex © (23.12.07 17:42) [16]
    Мне не понятно, как из треугольника сделать линию, честно говоря....
  • @!!ex © (23.12.07 17:45) [17]
    > Линии рисуются также треугольниками и видимо если две точки
    > треугольника попадают при округлении в один пиксел, то D3D
    > его уже не рисует (или делает штрих-пунктир если линий под
    > наклоном), а надо сделать чтобы рисовал.

    Откуда берется щтрихпунктир?
    Если две точки треугольника попадают в один пиксель, треугольник вообще вырождается.
    Оно и понятно, толщины то у него нет... Собственно поэтому мне и непонятно, как вы треугольниками линии рисуете...

    P.S.
    ЗАчем вообще здесь треугольники?
    Все чертежи, которые я виденл состояли из линий...
    Вы заливку где то применяете?
    Можно пример чертежа с заливкой?
  • homm © (23.12.07 17:46) [18]
    > [16] @!!ex ©   (23.12.07 17:42)

    Ну как это, линия — это такой вытянутый прямоугольник :)

    А как можно рисовать линии, кроме как задания Wareframe(как-то так) в D3D, правда не знаю, в OGL кажется есть GlBegine(LINE), как-то так.
  • novarm (23.12.07 17:47) [19]
    Подразумевается линия определенной ширины и с закругленными концами как в GDI. Вот она и формируется из залитых треугольников (два в середине и два веера на концах с кол-вом от 0 до 12 в зависимости от масштаба/ширины).
 
Конференция "Игры" » Мелкие объекты в Direct3D [Delphi, Windows]
Есть новые Нет новых   [134431   +10][b:0][p:0]