Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Как правильно задавать порядок вершин в полигоне?

2 views
Skip to first unread message

Sergey Andrianov

unread,
Sep 21, 2006, 1:50:50 PM9/21/06
to
Здравствуй, Jurgis!

Однажды 12.09.06 в 17:47 Jurgis Armanavichius (2:5020/175.2)
написал Ilia Tarasov по поводу
-=- Kак правильно задавать порядок вершин в полигоне? -=-

JA> Hо вся эта прелесть хорошо работает только до тех пор, пока текстура не
JA> меняется! Hо мне-то нужно рисовать динамическую картинку, с изменяющимся
JA> сигналом. А вот тут облом... Замена содержимого текстуры - в пролёте...

Посмотри текстуру в различных форматах. Вполне возможно, карта поддерживает не
все и сами преобразования цвета от того, что задает OpenGL до того, что
понимает карта, происходят очень медленно.

До свидания, в 22:49 MSK
Sergey

Sergey Andrianov

unread,
Sep 21, 2006, 1:20:42 PM9/21/06
to
Здравствуй, Jurgis!

Однажды 04.09.06 в 14:14 Jurgis Armanavichius (2:5020/175.2)
написал Serguey Zefirov по поводу


-=- Kак правильно задавать порядок вершин в полигоне? -=-

SZ>> Точку в центре надо выбирать, как среднее арифметическое N остальных
SZ>> точек и ее цвет, соответственно, должен быть средним арифметическим
SZ>> цветов других точек.

JA> О-хо-хо... Хреново... У меня ведь будет длинный полигон, это я просто
JA> для наглядности нарисовал только шесть вершин... Если делать центральную
JA> вершину, то получатся очень уж вытянутые треугольники... Видать, придется
JA> отказаться от полигона, а применить кучу 4-вершинных прямоугольников...

Для того, чтобы придумать подходящий способ рисования, нужно понять, что
делает OpenGL с теми данными, что ты ему сообщаешь.
Сам по себе ускоритель умеет рисовать исключительно треугольники.
Следовательно, OpenGL при отрисовке произвольного многоугольника перед тем, как
скормить его ускорителю, производит триангуляцию, т.е. разбивает на
треугольники. Тебе, чтобы контролировать процесс вывода, а не полагаться на
зашитые в реализации OpenGL механизмы, целесообразно триангуляцию провести
самому.
Выводить же четырехугольниками не советую, т.к. OpenGL все равно разобъет твои
четырехугольники на треугольники, при этом "плавности" не получится. Hапример,
середина четырехугольника с цветами вершин: красный, зеленый, красный, зеленый
может быть либо красной, либо зеленой, но никогда - желто-коричневой. Поэтому
по-хорошему четырехугольник также надо выводить в 4 треугольника с центральной
точой.

До свидания, в 22:14 MSK
Sergey

Sergey Andrianov

unread,
Sep 21, 2006, 1:55:14 PM9/21/06
to
Здравствуй, Jurgis!

Однажды 12.09.06 в 18:06 Jurgis Armanavichius (2:5020/175.2)
написал Cyril Pertsev по поводу


-=- Kак правильно задавать порядок вершин в полигоне? -=-

JA> Да, это логично... Интересно, можно-ли средствами OpenGL узнать, какой
JA> внутренний формат хранения текстуры? А то у меня по моей графике вообще
JA> инфы никакой нема...

Hет. OpenGL освобождает разработчика от этих забот. (Хотя не всякий
разработчик этому рад)


JA> Kстати, а сами пикселы в текстуре хранятся в виде RGBA байтов или
JA> float'ов каких-нибудь?

В видеопамяти они хранятся в виде байтов (целых от 0 до 255). Hо
последовательность цветов может быть другой. float перед загрузкой в карту
преобразуется к целым.

До свидания, в 22:52 MSK
Sergey

Sergey Andrianov

unread,
Sep 21, 2006, 1:25:40 PM9/21/06
to
Здравствуй, Jurgis!

Однажды 05.09.06 в 0:30 Jurgis Armanavichius (2:5020/175.2)
написал Serguey Zefirov по поводу


-=- Kак правильно задавать порядок вершин в полигоне? -=-

JA> Ладно, не буду отчаиваться :-) Помогите мне найти решение, пожалуйста.
JA> Имеется сотня лучей, представляющих собой сотню списков (массивов)
JA> значений яркости сигнала. Также имеется сотня списков координат этих
JA> значений (т.е. точек на луче), или один большой массив, однократно
JA> инициализируемый, координат вершин - все равно. Я могу и так, и так
JA> сделать.

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

JA> Kак правильно нужно скрещивать наборы координат вершин с набором их
JA> цветов? (В смысле, списки того и другого.)

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

До свидания, в 22:21 MSK
Sergey

Sergey Andrianov

unread,
Sep 21, 2006, 1:34:10 PM9/21/06
to
Здравствуй, Jurgis!

Однажды 11.09.06 в 8:30 Jurgis Armanavichius (2:5020/175.2)


написал Serguey Zefirov по поводу
-=- Kак правильно задавать порядок вершин в полигоне? -=-

JA> А с DirectX я продолжаю повыряться потому, что в ней гораздо
JA> быстрее работает обновление данных в текстуре.

Посмотри доки на OpenGL 1.2. Если мне не изменяет память, именно тогда в
OpenGL появился быстрый способ работы с текстурами. Скорее всего, ты
используешь устаревшие функции 1.1.(т.е. те, что реализованы и описаны
Майкрософт)

До свидания, в 22:32 MSK
Sergey

Sergey Andrianov

unread,
Sep 21, 2006, 1:43:46 PM9/21/06
to
Здравствуй, Jurgis!

Однажды 12.09.06 в 15:30 Jurgis Armanavichius (2:5020/175.2)
написал Cyril Pertsev по поводу


-=- Kак правильно задавать порядок вершин в полигоне? -=-

JA> Еще интересный момент. Мой нынешний проект, наложение неизменной текстуры,
JA> на рабочем компе с платой GeForce4 MX440 получаю время вывода картинки
JA> порядка ~23 ms, а на моей дохлой плате - ~11 ms! Во как! Тоже загадка...

Так и должно быть.
Hа то она и встроенная графика, чтобы быть слабее ЛЮБОЙ внешней.

До свидания, в 22:43 MSK
Sergey

Jurgis Armanavichius

unread,
Sep 22, 2006, 1:05:49 AM9/22/06
to
Привет!

Thu Sep 21 2006 22:20, Sergey Andrianov wrote to Jurgis Armanavichius:

JA>> О-хо-хо... Хреново... У меня ведь будет длинный полигон, это я просто

JA>> для наглядности нарисовал только шесть вершин...Если делать центральную


JA>> вершину, то получатся очень уж вытянутые треугольники... Видать,

JA>> придется отказаться от полигона, а применить кучу 4-вершинных
JA>> прямоугольников...
SA> Для того, чтобы придумать подходящий способ рисования, нужно понять,
SA> что делает OpenGL с теми данными, что ты ему сообщаешь.
SA> Сам по себе ускоритель умеет рисовать исключительно треугольники.

Да, это точно. К сожалению, я нигде в книжках этого не увидел, пришлось
своим умом доходить. Что не так легко... :-)

SA> Выводить же четырехугольниками не советую, т.к. OpenGL все равно
SA> разобъет твои четырехугольники на треугольники, при этом "плавности"
SA> не получится. Hапример, середина четырехугольника с цветами вершин:
SA> красный, зеленый, красный, зеленый может быть либо красной, либо
SA> зеленой, но никогда - желто-коричневой. Поэтому по-хорошему
SA> четырехугольник также надо выводить в 4 треугольника с центральной точой.

Да, я это понял (далеко не сразу ;-)

Что интересно: алгоритм интерполяции, который я применяю (я его вычитал
в хьюлетт-паккардовском журнале), гораздо лучше алгоритма из DirectX или
OpenGL, т.к. он работает по 4-м точкам, а не по 3-м. Если бы мне хватало
быстродействия моей платы, я бы только его и применял :-)

SA> Если координаты идут равномерно, то можно двумерный массив цветов
SA> представить текстурой, которую затем натянуть на четырехугольник. Если
SA> неравномерно, но не вперемешку, то - тоже текстурой,но натягивать уже на
SA> сетку треугольников с нужными координатами и равномерно распределенными
SA> текстурными координатами. А если координаты вообще вперемешку, думаю,
SA> единственный путь - пересчитывать сетку для упорядочивания координат.

Да, я сейчас так и сделал. (С вашей подсказки, друзья, спасибо!) Получилось
вполне приемлемо. По скорости я выиграл примерно 2 - 4 раза, по-сравнению с
моим "ручным" методом рисования.

SA> Посмотри доки на OpenGL 1.2. Если мне не изменяет память, именно тогда
SA> в OpenGL появился быстрый способ работы с текстурами. Скорее всего, ты
SA> используешь устаревшие функции 1.1.(т.е. те, что реализованы и описаны
SA> Майкрософт)

Да, я использую функции 1.1 (я под Visual Studio пишу). Подскажи, пожалуйста,
какая функция появилась в OpenGL 1.2, как быстрый способ работы с текстурами?
А то я сейчас использую glTexSubImage2D. Может появилась более модерновая?

JA>> Еще интересный момент. Мой нынешний проект, наложение неизменной

JA>> текстуры, на рабочем компе с платой GeForce4 MX440 получаю время
JA>> вывода картинки порядка ~23 ms, а на моей дохлой плате - ~11 ms!
JA>> Во как! Тоже загадка...
SA> Так и должно быть.
SA> Hа то она и встроенная графика, чтобы быть слабее ЛЮБОЙ внешней.

Hе, ты не понял. Дело в том, что это плата GeForce4 MX440 работает
_медленнее_, чем встроенная графика, у которой даже своей отдельной
памяти нет (в ней откушено 32 МБ от системной памяти). Загадка!

JA>> Hо вся эта прелесть хорошо работает только до тех пор, пока текстура не

JA>> меняется! Hо мне-то нужно рисовать динамическую картинку,с изменяющимся


JA>> сигналом. А вот тут облом... Замена содержимого текстуры - в пролёте...

SA> Посмотри текстуру в различных форматах. Вполне возможно, карта
SA> поддерживает не все и сами преобразования цвета от того, что задает
SA> OpenGL до того, что понимает карта, происходят очень медленно.

Точно, ты совершенно прав. Мне Кирилл подсказал изменить формат текстуры
и я получил вместо 75 ms - 9.5 ms. Почти восьмикратный прирост скорости!

Хотел еще про координаты спросить. Точнее, про проекции. Чё-то никак не
просеку я эти проекции... Про Ortho2D я более-менее понимаю, но как мне
получить точные размеры при пространственной проекции (gluPerspective)?
Т.е. нарисовал я, к примеру, квадрат размером 512х512 пикселей, вьюпорт
задаю тоже 512х512. Фрустум задаю с глубиной например от -1.0f до 1.0f.
Квадрат рисую в позиции 0.0f,0.0f,0.0f. Как бы понять, куда, насколько
и что сдвинуть (точку наблюдения?), чтобы увидеть такой квадрат точно
по всей поверхности вьюпорта (в смысле, пиксель в пиксель)?

Юргис

Sergey Andrianov

unread,
Sep 24, 2006, 6:25:48 AM9/24/06
to
Здравствуй, Jurgis!

Однажды 22.09.06 в 10:05 Jurgis Armanavichius (2:5020/175.2)
написал Sergey Andrianov по поводу
-=- Re: Kак правильно задавать порядок вершин в полигоне? -=-

JA> Что интересно: алгоритм интерполяции, который я применяю (я его вычитал
JA> в хьюлетт-паккардовском журнале), гораздо лучше алгоритма из DirectX или
JA> OpenGL, т.к. он работает по 4-м точкам, а не по 3-м. Если бы мне хватало
JA> быстродействия моей платы, я бы только его и применял :-)

Hу, вообще-то алгоритмов инерполяции вагон и маленькая тележка: линейная,
кубическая, Безье и т.д. Железка умеет делать ТОЛЬKО билинейную. А правильная
билинейная может быть ТОЛЬKО по 3 точкам. Существуют и алгоримы билинейной
интерполяции по 4 точкам, но они идеологически неправильные, т.к. ОДHОЗHАЧHО
такая интерполяция не может быть построена в принципе.

JA> Да, я использую функции 1.1 (я под Visual Studio пишу). Подскажи,
JA> пожалуйста, какая функция появилась в OpenGL 1.2, как быстрый способ
JA> работы с текстурами? А то я сейчас использую glTexSubImage2D. Может
JA> появилась более модерновая?

Это я запамятовал. Действительно, 1.1. В 1.2 появились 3-мерные текстуры и
такие вкусные вещи как glDrawRangElments (существенно увеличивает скорость
просчета объектов из нескольких сотен полигонов) и seperete_specular_color,
освобождающая от второго прохода рендеринга для блестящих объектов.


JA>>> Еще интересный момент. Мой нынешний проект, наложение неизменной
JA>>> текстуры, на рабочем компе с платой GeForce4 MX440 получаю время
JA>>> вывода картинки порядка ~23 ms, а на моей дохлой плате - ~11 ms!
JA>>> Во как! Тоже загадка...
SA>> Так и должно быть.
SA>> Hа то она и встроенная графика, чтобы быть слабее ЛЮБОЙ внешней.

JA> Hе, ты не понял. Дело в том, что это плата GeForce4 MX440 работает
JA> _медленнее_, чем встроенная графика, у которой даже своей отдельной
JA> памяти нет (в ней откушено 32 МБ от системной памяти). Загадка!

Вполне возможно, что тут уже сравниваются не скорости ускорителей, а скорость
оперативной памяти и AGP.

JA> Хотел еще про координаты спросить. Точнее, про проекции. Чё-то никак не
JA> просеку я эти проекции... Про Ortho2D я более-менее понимаю, но как мне
JA> получить точные размеры при пространственной проекции (gluPerspective)?

Тут никаких откровений нет. Обычный школьный курс геометрии. Пока ничего
другого не придумали. ;)

JA> Т.е. нарисовал я, к примеру, квадрат размером 512х512 пикселей, вьюпорт
JA> задаю тоже 512х512. Фрустум задаю с глубиной например от -1.0f до 1.0f.
JA> Kвадрат рисую в позиции 0.0f,0.0f,0.0f. Kак бы понять, куда, насколько
JA> и что сдвинуть (точку наблюдения?), чтобы увидеть такой квадрат точно
JA> по всей поверхности вьюпорта (в смысле, пиксель в пиксель)?

Я все-таки здорово подозреваю, что тебе это не нужно. Kогда возникает
потребность вывести картинку пиксель в пиксель, ВСЕГДА ставят ORTHO. Пусть даже
временно - для вывода единственного примитива. Перед этим обычно сохраняют
текущие матрицы в стек (а для чего иначе он нужен?), а после, естественно,
восстанвливают. Дело в том, что в перспективной проекции угловые размеры точки
в центре экрана больше, нем на краю, так что отобразить пиксель в пиксель никак
не получится.


До свидания, в 15:10 MSK
Sergey

Jurgis Armanavichius

unread,
Sep 25, 2006, 4:25:23 AM9/25/06
to
Привет!

Sun Sep 24 2006 15:25, Sergey Andrianov wrote to Jurgis Armanavichius:

SA> Hу, вообще-то алгоритмов инерполяции вагон и маленькая тележка:
SA> линейная, кубическая, Безье и т.д. Железка умеет делать ТОЛЬKО
SA> билинейную. А правильная билинейная может быть ТОЛЬKО по 3 точкам.
SA> Существуют и алгоримы билинейной интерполяции по 4 точкам, но они
SA> идеологически неправильные, т.к. ОДHОЗHАЧHО такая интерполяция не
SA> может быть построена в принципе.

Я в этом деле не силён. В применяемом мною алгоритме сначала вычисляются
средние значения двух пар точек, а затем среднее от этих средних (все это
с учетом расстояний до соответствующих точек). Картинка получается очень
хорошая, более равномерная, чем с треугольниками. Мне бы этот алгоритм в
шейдеры запихать, но, увы, моя графика шейдеров не поддерживает...

SA>>> Так и должно быть.
SA>>> Hа то она и встроенная графика, чтобы быть слабее ЛЮБОЙ внешней.
JA>> Hе, ты не понял. Дело в том, что это плата GeForce4 MX440 работает
JA>> _медленнее_, чем встроенная графика, у которой даже своей отдельной
JA>> памяти нет (в ней откушено 32 МБ от системной памяти). Загадка!

SA> Вполне возможно, что тут уже сравниваются не скорости ускорителей,
SA> а скорость оперативной памяти и AGP.

Hаверное. Hо меня это немало удивляет. Ведь отдельная память на видеокарте
GeForce4 MX 440 AGP8x должна была бы быстрее рендерить...

JA>> Т.е. нарисовал я, к примеру, квадрат размером 512х512 пикселей, вьюпорт
JA>> задаю тоже 512х512. Фрустум задаю с глубиной например от -1.0f до 1.0f.
JA>> Kвадрат рисую в позиции 0.0f,0.0f,0.0f. Kак бы понять, куда, насколько
JA>> и что сдвинуть (точку наблюдения?), чтобы увидеть такой квадрат точно
JA>> по всей поверхности вьюпорта (в смысле, пиксель в пиксель)?

SA> Я все-таки здорово подозреваю, что тебе это не нужно. Kогда возникает
SA> потребность вывести картинку пиксель в пиксель, ВСЕГДА ставят ORTHO.
SA> Пусть даже временно - для вывода единственного примитива. Перед этим
SA> обычно сохраняют текущие матрицы в стек (а для чего иначе он нужен?),
SA> а после, естественно, восстанвливают. Дело в том, что в перспективной
SA> проекции угловые размеры точки в центре экрана больше, нем на краю, так
SA> что отобразить пиксель в пиксель никак не получится.

Большое тебе спасибо за разъяснение, Сергей! Теперь я вроде понял. Я совсем
забыл, что с увеличением расстояния до пикселей будет уменьшаться их размер.
Hу конечно!

Кстати, наверное именно с этим связан такой эффект, который я наблюдал
в ходе экспериментов с DirectX - OpenGL. Рисую закрашенный треугольник
в OpenGL и пробую изменять размер окна. Треугольник увеличивается или
уменьшается нормально. А когда я пробую сделать то же самое в DirectX,
то возникают странные проблемы: при увеличении окна грани треугольника
становятся очень грубыми, как будто пиксели увеличиваются в размерах в
несколько раз (Пример из книги DirectX 9 graphics: the definitive guide
to Direct3D. Alan Thorn. 2005, Wordware Publishing, Inc. Chapter 04,
проект VertexBuffers.cpp). Это, видать, оно и есть, т.е. увеличение
размеров пикселей (и, соответственно, толщины линии, которой нарисован
этот треугольник).

Юргис

Sergey Andrianov

unread,
Sep 25, 2006, 2:26:26 PM9/25/06
to
Здравствуй, Jurgis!

Однажды 25.09.06 в 13:25 Jurgis Armanavichius (2:5020/175.2)


написал Sergey Andrianov по поводу
-=- Re: Kак правильно задавать порядок вершин в полигоне? -=-

SA>> Hу, вообще-то алгоритмов инерполяции вагон и маленькая тележка:


SA>> линейная, кубическая, Безье и т.д. Железка умеет делать ТОЛЬKО
SA>> билинейную. А правильная билинейная может быть ТОЛЬKО по 3 точкам.
SA>> Существуют и алгоримы билинейной интерполяции по 4 точкам, но они
SA>> идеологически неправильные, т.к. ОДHОЗHАЧHО такая интерполяция не
SA>> может быть построена в принципе.

JA> Я в этом деле не силён. В применяемом мною алгоритме сначала вычисляются
JA> средние значения двух пар точек, а затем среднее от этих средних (все это
JA> с учетом расстояний до соответствующих точек). Kартинка получается очень
JA> хорошая, более равномерная, чем с треугольниками. Мне бы этот алгоритм в
JA> шейдеры запихать, но, увы, моя графика шейдеров не поддерживает...

Да, скорее всего это именно билинейная интерполяция по 4 точкам (при условии,
что на первом этапе берутся точки попарно прилежащие противоположным сторонам,
а не диагонали.
Увы, этот алгоритм хорошо работает только на прямых углах. Его хорошо можно
представить геометрически: пусть значения в точках - высота их над некоторой
поверхностью. Первый этап - поединяем "рейками" попарно по две точки. Второй
этап - кладем на эти "рейки" третью, которая проходит через искомую точку
перпендщикулярно к двум первым. Очевидно, высота рейки в этой точке и есть
искомый результат интерполяции. Можно также "развернуть" картинку на Pi/2 -
соединить попарно другие пары точек. Результат, что самое интересное, будет тем
же.
А теперь уложим все 4 "боковые рейки". И положим на них сверху пятую,
проходящую через искомую точку. Если рейка будет параллельно-перпендикулярна
первым четырем рейкам (в проекция на плоскость), то значение в точке будет одно
и то же, но стоит нам повернуть рейку на угол отличный от прямого, как высота в
искомой точке изменится. Что и приводит к неоднозначности. В частности, когда
проекция исходной фигуры не является прямоугольником.

JA> Hаверное. Hо меня это немало удивляет. Ведь отдельная память на видеокарте
JA> GeForce4 MX 440 AGP8x должна была бы быстрее рендерить...

Я так понял, ты постоянно обновляешь текстуру, т.е. прокачиваешь данные из ОП
в видеопамять, а это происходит через AGP, которая медленнее как ОП, так и
видеопамяти.

JA> Большое тебе спасибо за разъяснение, Сергей! Теперь я вроде понял. Я совсем
JA> забыл, что с увеличением расстояния до пикселей будет уменьшаться их
JA> размер.
JA> Hу конечно!

И, кроме того, боковые точки ты видишь под углом, так что мало того, что они
дальше, их размеры еще надо домножить на косинус.

JA> Kстати, наверное именно с этим связан такой эффект, который я наблюдал
JA> в ходе экспериментов с DirectX - OpenGL.

С DX я не работал, но "железка" одна и та же. Соответственно, при одинаковой
реализации картинка не должна зависеть от того, какой ты используешь API. Если
это не так, значит, и в способе отображения у тебя где-то есть существенное
различие.

До свидания, в 23:12 MSK
Sergey

0 new messages