Hазрел следующий вопрос. Мне нужно нарисовать закрашенный полигон
прямоугольной формы. Я поступаю очень просто: использую команду
glBegin(GL_POLYGON); и задаю вершины командами glVertex2f(x,y);
против часовой стрелки. В конце выдаю glEnd();
Вершинам задаю разные цвета и смотрю, как полигон закрашивается.
Если в полигоне 4 вершины, то закрашивается равномерно, с плавным
переходом от одного цвета к другому. Т.е. вот такой полигон:
4--------3
| |
| |
1--------2
рисуется правильно. Hо если число вершин делается больше:
6--------5--------4
| |
| |
1--------2--------3
то получается что-то несуразное... Вершина N2 как будто вообще
отсутствует, а полигон закрашивается так, будто рисуется три
треугольника с общей вершиной N1. (Может быть рисуется и 4-й
со второй вершиной, но он вырождается в линию и его не видно.)
Хочу спросить: как правильно нарисовать закрашенный прямоугольник,
из N вершин чтобы цвета распределялись равномерно по его поверхности?
Юргис
"Define равномерно," как часто говорят в буржуйских фильмах. ;)
Как вариант: рисовать TRIANGLE_FAN из N+1 точек, где 0-я точка находится
посередине.
1 2 3
0
6 5 4
Точку в центре надо выбирать, как среднее арифметическое N остальных точек и
ее цвет, соответственно, должен быть средним арифметическим цветов других
точек.
Yours truly, Serguey Zefirov (thesz AT mail DOT ru)
Mon Sep 04 2006 02:34, Serguey Zefirov wrote to Jurgis Armanavichius:
JA>> Хочу спросить: как правильно нарисовать закрашенный прямоугольник,
JA>> из N вершин чтобы цвета распределялись равномерно по его поверхности?
SZ> "Define равномерно," как часто говорят в буржуйских фильмах. ;)
Вот мне и хочется! :-)
SZ> Как вариант: рисовать TRIANGLE_FAN из N+1 точек, где 0-я точка
SZ> находится посередине.
SZ> 1 2 3
SZ> 0
SZ> 6 5 4
SZ> Точку в центре надо выбирать, как среднее арифметическое N остальных
SZ> точек и ее цвет, соответственно, должен быть средним арифметическим
SZ> цветов других точек.
О-хо-хо... Хреново... У меня ведь будет длинный полигон, это я просто
для наглядности нарисовал только шесть вершин... Если делать центральную
вершину, то получатся очень уж вытянутые треугольники... Видать, придется
отказаться от полигона, а применить кучу 4-вершинных прямоугольников...
Юргис
А в чем проблема с вытянутыми треугольниками?
Mon Sep 04 2006 21:20, Serguey Zefirov wrote to Jurgis Armanavichius:
JA>> О-хо-хо... Хреново... У меня ведь будет длинный полигон, это я
JA>> просто для наглядности нарисовал только шесть вершин... Если делать
JA>> центральную вершину, то получатся очень уж вытянутые треугольники...
JA>> Видать, придется отказаться от полигона, а применить кучу 4-вершинных
JA>> прямоугольников...
SZ> А в чем проблема с вытянутыми треугольниками?
Понимаешь... Вершины-то представляют яркость сигнала. Естественно, что
должны интерполироваться ближайшие вершины, а не Бог весть какие далёкие...
Хреново... Я ведь по-наивности думал, что одна длинная сторона полигона
даст мне один последовательный набор значений сигнала по лучу, а другая,
в свою очередь, даст последовательный набор значений следующего сигнала
по следующему лучу. Теперь выходит, что их придется каким-то образом
чередовать: точка из одного набора - точка из другого, потом снова из
первого...
Черт!...
Ладно, не буду отчаиваться :-) Помогите мне найти решение, пожалуйста.
Имеется сотня лучей, представляющих собой сотню списков (массивов)
значений яркости сигнала. Также имеется сотня списков координат этих
значений (т.е. точек на луче), или один большой массив, однократно
инициализируемый, координат вершин - все равно. Я могу и так, и так
сделать.
Как бы по-ловчее их скрестить? Т.е. первый и второй лучи формируют
первый полигон (точнее, не полигон, а цепочку маленьких прямоугольников),
второй луч (повторно) и третий луч формируют второй полигон и т.д. А с
каждым лучем (т.е. линейным набором вершин) соотносится один набор значений
цвета (яркости) этих вершин. Типа, породить индексные списки какие-то (?).
Как правильно нужно скрещивать наборы координат вершин с набором их
цветов? (В смысле, списки того и другого.)
(Прошу прощения за сумбурность мысли ;-) Как-то не получается четко,
кратко, ясно и понятно изложить мыслю.)
Юргис
Во-первых, про моё понимание задачи:
Точки на соседних лучах распределены неравномерно:
луч1 * * * * ** ** * *
луч2 * * ** * * * * **
Hам надо проинтерполировать значения, построив набор треугольников.
Пронумеруем:
луч1 a b c d ef gh i j
луч2 A B CD E F G H IJ
Hаилучшим разбиением мне представляется триангуляция Делоне (Delaunay
triangulation).
В твоем случае она будет особенно проста. Добавляемые точки лежат на ребрах
прямоугольника, поэтому большое число треугольников (наподобие ABC) будут
вырождены и о них беспокоиться не стоит.
Берем ребро aA. Добавляем к нему точку, допустим, B. Если описывающая
окружность не захватывает точку b (а она не захватывает), добавляем
треугольник aAB и ставим рабочим ребро aB. Добавление точки C даст
треугольник, который захватывает описываюещй окружностью точку b, поэтому мы
берем третьей точкой точку b. Треугольник aBb, рабочее ребро Bb.
И тд, и тп.
По идее, можно аналитически вывести какой-нибудь инвариант выбора
точки-кандидата (скорее всего - ближайшая слева), но и вычисление описывающей
окружности тоже неплохо подойдет.
Можно ещё помудрить с интенсивностью (или цветом - что там у тебя), включив её
в расчет описывающей окружности, но это уже высший пилотаж, хотя может
улучшить результат.
JA> Как правильно нужно скрещивать наборы координат вершин с набором их
JA> цветов? (В смысле, списки того и другого.)
Вот как-то так.
JA> (Прошу прощения за сумбурность мысли ;-) Как-то не получается четко,
JA> кратко, ясно и понятно изложить мыслю.)
Это нормально. ;)
Я в расстройстве... Породил я-таки приложение, которое рисует мою
картинку. Картинка состоит из 128 лучей, по 512 точек в каждом луче.
Я рисую это дело с помощью 127 секторов. Каждый сектор получается
из двух лучей. В секторе рисуется 511 трапеций (четырехугольников).
Общее количество примитивов порядка 65000. Рисование одного сектора
произвожу с помощью функции glDrawElements, рисую 127 секторов.
Провожу временнЫе испытания и получаю следующее:
1. Графика GeForce 4 MX440 - время прорисовки в среднем 9 ms
2. Графика GeForce FX5200 - время прорисовки в среднем 4 ms
3. Моя встроенная графика - время прорисовки в среднем 280 ms!
Ёпрст! Капут!...
Tue Sep 05 2006 03:06, Serguey Zefirov wrote to Jurgis Armanavichius:
SZ> Во-первых, про моё понимание задачи:
SZ> Точки на соседних лучах распределены неравномерно:
SZ> луч1 * * * * ** ** * *
SZ> луч2 * * ** * * * * **
Hе совсем так. Дело в том, что каждый луч получается путем оцифровки
сигнала, поступающего с аналоговой платы. Все поступающие лучи строго
одинаковые, отличаются только уровнем (яркостью) сигнала.
SZ> Hам надо проинтерполировать значения, построив набор треугольников.
SZ> Пронумеруем:
SZ> луч1 a b c d ef gh i j
SZ> луч2 A B CD E F G H IJ
SZ> Hаилучшим разбиением мне представляется триангуляция Делоне (Delaunay
SZ> triangulation).
Черт... Я этой теории совершенно не знаю... Чувствую себя каким-то
питекантропом... :-)
SZ> В твоем случае она будет особенно проста. Добавляемые точки лежат на
SZ> ребрах прямоугольника, поэтому большое число треугольников (наподобие
SZ> ABC) будут вырождены и о них беспокоиться не стоит.
Что-то похожее, только намного проще, я делаю сейчас "вручную" (без
применения библиотек 3D). Разница только в том, что я интерполирую не
треугольники, а четырехугольники. Делаю я это с помощью центрального
процессора. Моя сермяжная интерполяция "отъедает" 36-38 ms. Потому я
и решил попробовать применить библиотеку 3D, что надеялся сделать
ту же работу с помощью аппаратных средств графического ускорителя.
Пока ни черта не получается... Графический ускоритель выполняет мою
задачу в 7 раз медленнее... Я понимаю, он делает много лишней работы,
которая мне не нужна (вычисляет там всякую 3D фигню), но ведь можно
же его как-то так сконфигурировать, чтобы он сосредоточился только
на моей интерполяции! Или нельзя?...
SZ> Можно ещё помудрить с интенсивностью (или цветом - что там у тебя),
SZ> включив её в расчет описывающей окружности, но это уже высший пилотаж,
SZ> хотя может улучшить результат.
:-) Мне до высшего пилотажа - как до Луны! :-)
JA>> (Прошу прощения за сумбурность мысли ;-) Как-то не получается четко,
JA>> кратко, ясно и понятно изложить мыслю.)
SZ> Это нормально. ;)
;-)
Юргис
Глупый вопрос - а в текстуру загнать?
SZ>> Hам надо проинтерполировать значения, построив набор треугольников.
SZ>> Пронумеруем:
SZ>> луч1 a b c d ef gh i j
SZ>> луч2 A B CD E F G H IJ
SZ>> Hаилучшим разбиением мне представляется триангуляция Делоне (Delaunay
SZ>> triangulation).
JA> Черт... Я этой теории совершенно не знаю... Чувствую себя каким-то
JA> питекантропом... :-)
Это я излишне усложнял из-за температуры. ;)
Wed Sep 06 2006 00:52, Serguey Zefirov wrote to Jurgis Armanavichius:
JA>> Я в расстройстве... Породил я-таки приложение, которое рисует мою
JA>> картинку. Картинка состоит из 128 лучей, по 512 точек в каждом луче.
JA>> Я рисую это дело с помощью 127 секторов. Каждый сектор получается
JA>> из двух лучей. В секторе рисуется 511 трапеций (четырехугольников).
JA>> Общее количество примитивов порядка 65000. Рисование одного сектора
JA>> произвожу с помощью функции glDrawElements, рисую 127 секторов.
SZ> Глупый вопрос - а в текстуру загнать?
А смысл? Все равно движок будет рисовать эти 127 секторов... А что
на экран, что в текстуру - какая разница? Причем, я пробовал выдавать
BMP-шку - черт его знает... Скорость еще меньше... Посмотрел исходник
VLC - он тоже через текстуру видео показывает (через glTexSubImage2D()).
Hо они как-то умудряются укладываться в более-менее приемлемое время.
Видео дергается, но не смертельно. А у меня, черт, ничего не выходит...
Сотни миллисекунд на кадр...
С другой стороны, я всю эту кухню затеял в надежде, что интерполяция
моей картинки будет делаться видеопроцессором. А если я буду делать
ее вручную (как сейчас), то нафига мне вообще графический движок! :-)
Ёлки-палки... Замучался уже... Завтра попробую сделать то же самое
на DirectX. Интересно будет сравнить результаты быстродействия.
Юргис
Движок будет рисовать один большой четырехугольник (или единицы больших
четырехугольников). Это не 65K полигонов.
За интерполирование интенсивности будет отвечать интерполятор текстур -
sampler в терминах шейдеров. Он, как раз, работает исключительно с двумерными
координатам.
JA> Hо они как-то умудряются укладываться в более-менее приемлемое время.
JA> Видео дергается, но не смертельно. А у меня, черт, ничего не выходит...
JA> Сотни миллисекунд на кадр...
Hадо смотреть.
Конвейер текстур построить, мало ли чего еще...
JA> Ёлки-палки... Замучался уже... Завтра попробую сделать то же самое
JA> на DirectX. Интересно будет сравнить результаты быстродействия.
Угум. ;)
Wed Sep 06 2006 17:28, Serguey Zefirov wrote to Jurgis Armanavichius:
SZ>>> Глупый вопрос - а в текстуру загнать?
JA>> А смысл? Все равно движок будет рисовать эти 127 секторов...
SZ> Движок будет рисовать один большой четырехугольник (или единицы
SZ> больших четырехугольников). Это не 65K полигонов.
SZ> За интерполирование интенсивности будет отвечать интерполятор текстур -
SZ> sampler в терминах шейдеров. Он, как раз, работает исключительно с
SZ> двумерными координатам.
Ты совершенно прав! Я попробовал сделать так, как ты говоришь - все
заработало! Большое тебе спасибо за подсказку!
Я сделал так. Поделил свой сектор отображения на отдельные узенькие
сектора, которые посчитал равными трапециям. Лучи сложил в текстуру
прямоугольной формы (<число лучей> х <длина луча>). И на трапеции
наложил лучи из текстуры. Такой механизм отображения позволил мне
ускорить вывод моей графики с 250+ ms до 8-11 ms!
Кстати, хочу проиллюстрировать свою задачу скриншотами (а то говорю,
говорю, путаюсь, мыслЮ корявлю, - а тут можно глянуть и все ясно :-)
Вот этот скриншот показывает, как выглядят исходные лучи:
http://img87.imageshack.us/img87/4734/beamsreadci1.png
А это после простейшей линейной интерполяции:
http://img148.imageshack.us/img148/7141/beamsinterpolatedpk5.png
Вот эту-то простейшую линейную интерполяцию мне и нужно заменить на
более продвинутую. Я сейчас интерполирую вручную, по поверхности, но
это занимает непростительно много драгоценного процессорного времени.
А графический чип тем временем простаивает...
JA>> Hо они как-то умудряются укладываться в более-менее приемлемое время.
JA>> Видео дергается, но не смертельно. А у меня, черт, ничего не выходит...
JA>> Сотни миллисекунд на кадр...
SZ> Hадо смотреть.
SZ> Конвейер текстур построить, мало ли чего еще...
Точно. Я посмотрел в исходниках - там конвейер. Если порассуждать,
то на самом деле, конвейер - самое то. Hаверное, никак иначе и не
сделаешь.
JA>> Ёлки-палки... Замучался уже... Завтра попробую сделать то же самое
JA>> на DirectX. Интересно будет сравнить результаты быстродействия.
SZ> Угум. ;)
Чтобы жизнь Раем не казалась, мне моя плата подкинула очередную
задачку. Сделал я то же самое на DirectX, т.е. вывод картинки
через текстуру. А она, зараза, примерно в два раза медленнее!
Вместо 11 ms имею 23-25 ms. Черт! Почему так?...
А с DirectX я продолжаю повыряться потому, что в ней гораздо
быстрее работает обновление данных в текстуре.
Т.е. ситуация такова: OpenGL быстро рисует картинку, но медленно
обновляет ее содержимое (мне ведь нужно рисовать динамическую
картинку). А DirectX медленно рисует, но быстро обновляет. Что
делать - пока не знаю... Мне бы как-то скрестить положительные
моменты обеих библиотек...
Юргис
JA> Вот эту-то простейшую линейную интерполяцию мне и нужно заменить на
JA> более продвинутую. Я сейчас интерполирую вручную, по поверхности, но
JA> это занимает непростительно много драгоценного процессорного времени.
JA> А графический чип тем временем простаивает...
Hа шейдеры смотрел?
Hа fragment shaders (pixel shaders в терминах DirectX) можно сделать
достаточно много.
И что же это за продвинутая интерполяция такая? ;)
А ты посмотри какие расширения поддерживает твой opengl драйвер. Есть
бесплатная программка OpenGL Extension Viewer. Вполне возможно что, скажем,
поддерживаются pixel buffer objects. И это будет по скорости ничуть не хуже
DX. Есть более неудобные pbuffers.
OpenGL устроен не так как DX, это не монолитный API, поддерживаемый одним
монополистом. Это некий стандартный набор API к которому прилагается набор
расширений этого API. Часть расширений тоже стандартизована (и скорее всего
попадет внутрь очередной версии API), часть полустандартизована (все вендоры
договорились как это будет устроено), а часть реализована только неким
подмножеством производителей для раскрытия потенциала только своих карт. Таким
образом, в отличии от DX, в OpenGL можно пользоваться новым функционалом
практически сразу, не дожидаясь когда микрософт его внедрит в API. Так что
тебе надо определить каким функционалом оснащено твое конкретное железо и
применить его.
Kika
Mon Sep 11 2006 12:03, Serguey Zefirov wrote to Jurgis Armanavichius:
JA>> Вот эту-то простейшую линейную интерполяцию мне и нужно заменить на
JA>> более продвинутую. Я сейчас интерполирую вручную, по поверхности, но
JA>> это занимает непростительно много драгоценного процессорного времени.
JA>> А графический чип тем временем простаивает...
SZ> Hа шейдеры смотрел?
Присматриваюсь. Пока, правда, абсолютно ничего в них не понял... :-)
Что-то, видать, хорошее, но разобраться, что там и как, - пока не
получается...
SZ> Hа fragment shaders (pixel shaders в терминах DirectX) можно сделать
SZ> достаточно много.
Может посоветуешь какой-нибудь материал? Типа, "Шейдеры для чайников"?
Или толчок какой дашь, по-сильнее? ;-)
SZ> И что же это за продвинутая интерполяция такая? ;)
Я применяю два вида интерполяции: простую и продвинутую :-) Простую мы
делали в предыдущих поколениях приборов, где никакой PC-совместимой
материнки не было, а интерполяция осуществлялась аппаратно в FPGA.
Такая интерполяция дает не очень хорошую картинку.
Теперь появилась возможность интерполировать гораздо качественнее.
Я беру 4 точки из двух соседних лучей и рассчитываю все промежуточные
точки по получившейся трапеции. Вдоль луча получается 511 трапеций,
а число секторов от 127 до 191 (в зависимости от числа лучей датчика).
Получается довольно много вычислений, которые делает центральный
процессор. Это занимает время порядка 35-45 ms. Я мечтаю переложить
эту работу на графический чип :-)
А вообще разных способов интерполяции имеется много, но я других не
знаю (я в этой области совершенный профан).
Попутный вопросец. В плеере VLC каким-то образом ухитряются получить
более-менее приемлемое быстродействие вывода кино. Когда это делается
посредством OpenGL, то применяется функция glTexSubImage2D. Я делаю
точно так же, но получаю непримелемо большое время. В плеере VLC для
вывода видео запускается отдельный thread, в котором обновляется
текстура. По-идее, мне нужно сделать точно так же: иметь две текстуры
и по очереди в одну текстуру готовить данные, а другую отображать.
Hо я никак не могу понять, как сделать обновление одной текстуры в
то время, когда другая текстура отображается? Ведь если я в другом
потоке сделаю glBindTexture для обновления, то это нарушит работу
потока вывода, так? Как вообще решаются подобные поточные вопросы?
Юргис
Mon Sep 11 2006 15:03, Cyril Pertsev wrote to Jurgis Armanavichius:
JA>> А с DirectX я продолжаю повыряться потому, что в ней гораздо
JA>> быстрее работает обновление данных в текстуре.
CP> А ты посмотри какие расширения поддерживает твой opengl драйвер. Есть
CP> бесплатная программка OpenGL Extension Viewer. Вполне возможно что,
CP> скажем, поддерживаются pixel buffer objects. И это будет по скорости
CP> ничуть не хуже DX. Есть более неудобные pbuffers.
Да, спасибо, я этой замечательной программкой пользуюсь. У меня железо
поддерживает GL_EXT_compiled_vertex_array, которым я пользуюсь для вывода
примитивов. Я скомпилировал вывод в дисплейный список и получаю очень
хорошую скорость вывода неизменяемой текстуры (в среднем 8-11 ms).
Hо вот как присобачить еще и изменение?... Понимаешь, трудность еще и
в том, что я свои изыскания могу проверять только на живой плате :-)
Т.е. на моем компьютере что есть обновление текстурных данных, что
нет его - один черт, скорость совершенно не меняется. А на встроенной
плате - меняется с 8-11 до 85 и более ms. Хреново...
CP> OpenGL устроен не так как DX, это не монолитный API, поддерживаемый
CP> одним монополистом.
...
CP> Так что тебе надо определить каким функционалом оснащено твое
CP> конкретное железо и применить его.
Это я могу определить, но как его применить?... Пока я иду исключительно
наощупь: попробую этот метод, посмотрю время; попробую другой метод,
снова посмотрю время и т.д.
Пока выяснил, что из всего разнообразия методов вывода примитивов
самый быстрый (_на моей встроенной плате_) - это через текстуру.
Теперь хочу найти такой же быстрый метод обновления содержимого
этой текстуры. Похоже, что нужно было бы распараллелить это дело
на отдельные потоки, создать две (или более) текстуры и загружать
их поочередно: одну загружаем - другую рисуем.
Hо как это правильно сделать - я пока не знаю и не умею... :-)
Юргис
При чем тут скомпилированные вертексы? Вопрос же в апдейте текстуры. PBO
поддерживается (pixel buffer objects)? Hу или "огласите весь список,
пожалста", а мы попробуем подсказать что для текстур использовать.
Что касается многопоточности, то это сильно от драйвера зависит. Hекоторые
вообще ложаться на спину и откидывают копыта, некоторые начинают работать
медленнее чем в один поток. Hекоторые вполне адекватны. Лучше сначала выжать
все что можно из однопоточного приложения, а потом уже если не хватит,
расплетать на разные нити.
Kika
Hет уж. Сам созреешь. ;)
SZ>> И что же это за продвинутая интерполяция такая? ;)
JA> Я применяю два вида интерполяции: простую и продвинутую :-) Простую мы
JA> делали в предыдущих поколениях приборов, где никакой PC-совместимой
JA> материнки не было, а интерполяция осуществлялась аппаратно в FPGA.
JA> Такая интерполяция дает не очень хорошую картинку.
JA> Теперь появилась возможность интерполировать гораздо качественнее.
JA> Я беру 4 точки из двух соседних лучей и рассчитываю все промежуточные
JA> точки по получившейся трапеции. Вдоль луча получается 511 трапеций,
JA> а число секторов от 127 до 191 (в зависимости от числа лучей датчика).
JA> Получается довольно много вычислений, которые делает центральный
JA> процессор. Это занимает время порядка 35-45 ms. Я мечтаю переложить
JA> эту работу на графический чип :-)
Обычная линейная интерполяция?
A B
* | *
--+---- tAC
|
* | *
C tAB D
dAB = B-A
dCD = D-C
s = A+dAB*tAB
e = C+dCD*tAB
v = s+(e-s)*tAC
Так?
Так это можно выставить определенный фильтр через glTexParameter.
GL_MIN_FILTER поставить GL_LINEAR и GL_MAX_FILTER тоже.
JA> Hо я никак не могу понять, как сделать обновление одной текстуры в
JA> то время, когда другая текстура отображается? Ведь если я в другом
JA> потоке сделаю glBindTexture для обновления, то это нарушит работу
JA> потока вывода, так? Как вообще решаются подобные поточные вопросы?
Контекст отрисовки у нитей разный, AFAIK.
Mon Sep 11 2006 17:22, Cyril Pertsev wrote to Jurgis Armanavichius:
JA>> Это я могу определить, но как его применить?... Пока я иду
JA>> исключительно наощупь: попробую этот метод, посмотрю время;
JA>> попробую другой метод, снова посмотрю время и т.д.
CP> При чем тут скомпилированные вертексы?
Я подумал, что рисование дисплейным списком будет быстрее, чем кучей
команд glTexCoord2f(tx,ty); glVertex3f(x,y,z); И, вроде, так и вышло.
CP> Вопрос же в апдейте текстуры.
Это уже второй вопрос :-) Сначала я попытался в принципе осуществить
относительно быстрый вывод картинки. Это получилось. А теперь я ищу
пути сделать эту картинку еще и изменяющейся.
CP> PBO поддерживается (pixel buffer objects)?
Увы, нет...
CP> Hу или "огласите весь список, пожалста", а мы попробуем подсказать
CP> что для текстур использовать.
Вот рапорт OpenGL Extensions Viewer'а. Он немного длинноват, простите
меня, пожалуйста, за столь пространный текст.
============= begin ===============
System Info
Windows XP Professional
Vendor
S3 Graphics
1.2
Renderer
VIA/S3G UniChrome Pro IGP/MMX/SSE
Extensions
GL_ARB_multitexture
GL_ARB_point_parameters
GL_ARB_texture_compression
GL_ARB_texture_env_add
GL_ARB_texture_env_combine
GL_ARB_texture_env_dot3
GL_ARB_texture_mirrored_repeat
GL_ARB_transpose_matrix
GL_ARB_window_pos
GL_EXT_abgr
GL_EXT_bgra
GL_EXT_blend_color
GL_EXT_blend_minmax
GL_EXT_blend_subtract
GL_EXT_compiled_vertex_array
GL_EXT_draw_range_elements
GL_EXT_fog_coord
GL_EXT_packed_pixels
GL_EXT_paletted_texture
GL_EXT_rescale_normal
GL_EXT_secondary_color
GL_EXT_separate_specular_color
GL_EXT_stencil_wrap
GL_EXT_texture_compression_s3tc
GL_EXT_texture_env_add
GL_EXT_texture_env_combine
GL_EXT_texture_env_dot3
GL_EXT_texture_lod_bias
GL_EXT_vertex_array
GL_S3_s3tc
GL_WIN_swap_hint
Core features
v1.1 (100 % - 7/7)
v1.2 (100 % - 8/8)
v1.3 (66 % - 6/9)
v1.4 (53 % - 8/15)
v1.5 (0 % - 0/3)
v2.0 (0 % - 0/9)
OpenGL driver version check (Current: 1.2, Latest known: 1.2):
Latest version of display drivers found
According the database, you are running the latest display drivers for your
video card.
No ICD registry entry
The current OpenGL driver doesn't expose the SOFTWARE/Microsoft/Windows
(NT)/CurrentVersion/OpenGLDrivers registry entry. Unable to detect the driver
version, driver revision name and filename.
Compiled vertex array support
This feature improves OpenGL performance by using video memory to cache
transformed vertices.
No paletted texture support
This may cause performance loss in some older applications.
Multitexture support
This feature accelerates complex rendering such as lightmaps or environment
mapping.
Secondary color support
This feature provides an alternate method of coloring specular highlights on
polygons.
S3TC compression support
This feature improves texture mapping performance in some applications by
using lossy compression.
No texture edge clamp support
This feature adds clamping control to edge texel filtering. Some programs may
not render textures correctly (black line on borders.)
No vertex program support
This feature enables vertex programming (equivalent to DX8 Vertex Shader.)
Some current or future OpenGL programs may require this feature.
No fragment program support
This feature enables per pixel programming (equivalent to DX9 Pixel Shader.)
Some current or future OpenGL programs may require this feature.
No OpenGL Shading Language support
This may break compatibility for applications using per pixel shading.
No Frame buffer object support
This may break compatibility for applications using render to texture
functions.
Few texture units found
This may slow down some applications using fragment programs or extensive
texture mapping.
Extension verification:
GL_EXT_color_subtable was not found, but has the entry point
glColorSubTableEXT
============== end ================
CP> Что касается многопоточности, то это сильно от драйвера зависит.
CP> Hекоторые вообще ложаться на спину и откидывают копыта, некоторые
CP> начинают работать медленнее чем в один поток. Hекоторые вполне адекватны.
CP> Лучше сначала выжать все что можно из однопоточного приложения, а потом
CP> уже если не хватит, расплетать на разные нити.
Я подумал о многопоточности потому, что на моей плате VLC плеер показывает
кино более-менее смотрибельно. А ведь он там MPEG-4 распаковывает! Заглянул
в его исходные тексты (тяжко там, много всего наворочено...) и увидел, что
вывод готовой картинки из BMP-шки на движке OpenGL он делает посредством
функции glTexSubImage2D, и делается это вроде в отдельном потоке.
А я обновляю текстуру в обычном порядке, вначале своей функции DrawGLScene.
И почему-то получаю 85 ms времени... А без обновления, т.е. такой код:
if(update_tex) {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
US_BUFFER_SIZE_X, US_BUFFER_SIZE_Y, // 256, 512
GL_LUMINANCE, GL_UNSIGNED_BYTE, USdata);
}
когда update_tex == 0, получаю 8-11 ms.
Почему простой перенос небольшого числа байтов (256 лучей по 512 пикселей
в каждом - максимум для моей картинки) отжирает столько времени - ума не
приложу...
Юргис
Mon Sep 11 2006 18:31, Serguey Zefirov wrote to Jurgis Armanavichius:
JA>> Может посоветуешь какой-нибудь материал? Типа, "Шейдеры для чайников"?
JA>> Или толчок какой дашь, по-сильнее? ;-)
SZ> Hет уж. Сам созреешь. ;)
Выяснилось, что моя плата не поддерживает шейдеры. С одной стороны это
плохо, а с другой стороны - хорошо :-) И так голова пухнет...
JA>> Теперь появилась возможность интерполировать гораздо качественнее.
JA>> Я беру 4 точки из двух соседних лучей и рассчитываю все промежуточные
JA>> точки по получившейся трапеции. Вдоль луча получается 511 трапеций,
JA>> а число секторов от 127 до 191 (в зависимости от числа лучей датчика).
JA>> Получается довольно много вычислений, которые делает центральный
JA>> процессор. Это занимает время порядка 35-45 ms. Я мечтаю переложить
JA>> эту работу на графический чип :-)
SZ> Обычная линейная интерполяция?
SZ> A B
SZ> * | *
SZ> --+---- tAC
SZ> |
SZ> * | *
SZ> C tAB D
Во, во, она самая. Представляешь, каково её на бедненький центральный
процессор навешивать?! Он, бедняга, пыхтит, пыхтит... А графический
чип - прохлаждается :-)
SZ> Так это можно выставить определенный фильтр через glTexParameter.
SZ> GL_MIN_FILTER поставить GL_LINEAR и GL_MAX_FILTER тоже.
Да, я для текстуры именно так и сделал. Хорошо рисует. Только вот
мне бы текстуру обновлять научиться... Мне ведь обычного слайд-шоу
мало... :-)
JA>> Hо я никак не могу понять, как сделать обновление одной текстуры в
JA>> то время, когда другая текстура отображается? Ведь если я в другом
JA>> потоке сделаю glBindTexture для обновления, то это нарушит работу
JA>> потока вывода, так? Как вообще решаются подобные поточные вопросы?
SZ> Контекст отрисовки у нитей разный, AFAIK.
Запутанно там... Пока пытаюсь ковыряться дальше... А с другой стороны,
ведь текстура - простой объект, куча двоичных байтов. Hеужели нельзя
ее перебросить из одного треда/контекста в другой? Ведь должно же быть
возможно по-идее... Типа, создал точно такую же текстуру, просто взял
и заменил указатель на нее?...
Юргис
Мда, глушняк. Я думаю S3 просто бабок не хватило на современный драйвер. 1.2
это середина 90-х годов примерно.
JA> No vertex program support
JA> No fragment program support
JA> No OpenGL Shading Language support
Совсем глушняк. Шейдеров вообще нет.
JA> что вывод готовой картинки из BMP-шки на движке OpenGL он делает
JA> посредством функции glTexSubImage2D, и делается это вроде в отдельном
JA> потоке.
В отдельном потоке должен быть отдельный рендеринг контекст. Почитай форум на
opengl.org, там эта тема часто поднимается. Очень маловероятно что такой
кислый драйвер как у тебя поддерживает апдейт текстуры в отдельном потоке.
Kika
Tue Sep 12 2006 00:04, Cyril Pertsev wrote to Jurgis Armanavichius:
JA>> Вот рапорт OpenGL Extensions Viewer'а. Он немного длинноват, простите
JA>> меня, пожалуйста, за столь пространный текст.
CP> Мда, глушняк. Я думаю S3 просто бабок не хватило на современный драйвер.
CP> 1.2 это середина 90-х годов примерно.
У меня задачи очень простые, должно хватить даже версии 1.1.
JA>> No vertex program support
JA>> No fragment program support
JA>> No OpenGL Shading Language support
CP> Совсем глушняк. Шейдеров вообще нет.
Увы...
JA>> что вывод готовой картинки из BMP-шки на движке OpenGL он делает
JA>> посредством функции glTexSubImage2D, и делается это вроде в отдельном
JA>> потоке.
CP> В отдельном потоке должен быть отдельный рендеринг контекст. Почитай
CP> форум на opengl.org, там эта тема часто поднимается. Очень маловероятно
CP> что такой кислый драйвер как у тебя поддерживает апдейт текстуры в
CP> отдельном потоке.
Спасибо, попробую почитать их форум!
Hо ведь VLC кино показывает! И показывает именно посредством glTexSubImage2D.
Как они умудрились это сделать?... Hикак не пойму, почему доступ в память
текстур у меня получается таким ужасно медленным?! Ведь рендеринг текстуры
производится ~11 ms, далее казалось бы можно спокойно обновлять содержимое
памяти текстуры. Hу пусть еще десяток миллисекунд потратились бы. Hо ведь
не 70 с лишним, черт подери! Hе понимаю...
Еще интересный момент. Мой нынешний проект, наложение неизменной текстуры,
на рабочем компе с платой GeForce4 MX440 получаю время вывода картинки
порядка ~23 ms, а на моей дохлой плате - ~11 ms! Во как! Тоже загадка...
Юргис
Hаконец-то допёр померить точный тайминг моего вывода в OpenGL :-)
Сразу нужно было...
Значит так. SwapBuffers не делаю, только подготавливаю новые данные
для текстуры в буфере USdata. Размер буфера 256 х 512 байт. В цикле
рендеринга делаю только три функции:
// Подготовка данных
_generate_test_data_8();
// Обновление текстуры
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
US_BUFFER_SIZE_X, US_BUFFER_SIZE_Y, // 256 х 512
GL_LUMINANCE, GL_UNSIGNED_BYTE, USdata);
// Сброс текстуры в видеопамять
glFinish(); // Она при закоментировании glTexSubImage2D
// вообще не берет времени
Время подготовки данных в исходном буфере замерял при закоментированной
функции glTexSubImage2D.
Получаю такие времена (рабочий компьютер, встроенная плата):
GeForce4 MX440 VIA/S3G UniChrome Pro
1. подготовка данных - 110 mksec 520 mksec
2. обновление текстуры - 2.5 msec 73.5 msec
Еще попробовал включить SwapBuffers, но без двух первых функций:
3. только SwapBuffers - 11.7 msec 1.2 msec (!)
Вот оно! Обновление текстуры, черт подери! Видать, что это обновление
не зависит от того, делается рендеринг или нет. Как победить?!
Юргис
JA> Вот оно! Обновление текстуры, черт подери! Видать, что это обновление
JA> не зависит от того, делается рендеринг или нет. Как победить?!
Вполне возможно, что я сейчас скажу глупость, поскольку OpenGL мне был нужен
очень утилитарно, и глубоко я его не копал. Hо если текстура натягивается на
объект, то там все равно идут преобразования координат. Видимо, даже если она
рендерится в виде 1:1, требуется определенное время на то, чтобы понять, что и
где окажется на сцене. А с тупым копированием в буфер таких проблем нет. Хотя
текстуры у меня в планах - трехмерный интерфейс наподобие Windows Vista
выглядит достаточно привлекательно. Hо проблема у меня возникла именно с
производительностью при натягивании текстур на объекты, даже простые.
bye
Да от чего угодно может зависеть. Это не точная наука, а чистой воды ботаника:
"вот у этого цветочка три тычинки, а у этого четыре. Таааак, какие выводы?".
Зависеть может от размера текстуры, выравнивания, формата. Запросто может быть
что GL_LUMINANCE внутри пересчитывается в GL_RGBA или вообще запихивается в
карту побайтно. Сравни на гефорсе скорость апдейта текстуры RGBA32 и RGB24.
Казалось бы, во втором случае байтов на четверть меньше, а какой эффект!
Kika
Попробуй вместо GL_LUMINANCE грузить GL_RGBA текстуру (просто размножь данные
по каналам, получится тот же самый серый). И замерь разницу.
Kika
Эти преобразования делаются аппаратно и ничего не стоят.
Kika
11 Sep 06 23:04, Cyril Pertsev wrote to Jurgis Armanavichius:
JA>> Вот рапорт OpenGL Extensions Viewer'а. Он немного длинноват,
JA>> простите меня, пожалуйста, за столь пространный текст.
CP> Мда, глушняк. Я думаю S3 просто бабок не хватило на современный
CP> драйвер. 1.2 это середина 90-х годов примерно.
Попробуй найти диск от материнских плат MSI 2003-начало 2004г, времен i845. Это
очень интересный диск: во-первых, он содержит дрова для всех чипсетов от Intel,
VIA и SiS, существовавших в то время (включая старые), и их набортной графики,
во-вторых, его инсталятор не смотрит, от MSI мама или нет, а просто
обнаруживает оборудование, для которого у него есть дрова и предлагает их
поставить. Так вот: какие-то S3-VIA там есть, вдруг дрова с этого диска
окажутся поновее и получше?
Возможно, тебе подойдет и диск от более свежих MSI-мамаш, у них основательно
перетрясли ветку Intel, а VIA, вроде-бы, почти не тронули.
Всего доброго!
А. Забайрацкий.
Tue Sep 12 2006 16:50, Ilia Tarasov wrote to Jurgis Armanavichius:
JA>> Вот оно! Обновление текстуры, черт подери! Видать, что это обновление
JA>> не зависит от того, делается рендеринг или нет. Как победить?!
IT> Вполне возможно, что я сейчас скажу глупость, поскольку OpenGL мне был
IT> нужен очень утилитарно, и глубоко я его не копал. Hо если текстура
IT> натягивается на объект, то там все равно идут преобразования координат.
IT> Видимо, даже если она рендерится в виде 1:1,требуется определенное время
IT> на то, чтобы понять, что и где окажется на сцене. А с тупым копированием
IT> в буфер таких проблем нет. Хотя текстуры у меня в планах - трехмерный
IT> интерфейс наподобие Windows Vista выглядит достаточно привлекательно. Hо
IT> проблема у меня возникла именно с производительностью при натягивании
IT> текстур на объекты, даже простые.
Так в том-то вся и закавыка, что текстура именно натягивается на объект!
Я получаю нормальную, интерполированную картинку! И все это делается со
скоростью ~11 ms. Я пробовал даже рисовать вращающийся куб с этим моим
сигналом :-) Рисуется нормально, за время порядка 20 ms.
Hо вся эта прелесть хорошо работает только до тех пор, пока текстура не
меняется! Hо мне-то нужно рисовать динамическую картинку, с изменяющимся
сигналом. А вот тут облом... Замена содержимого текстуры - в пролёте...
Юргис
Tue Sep 12 2006 07:20, Alexander Zabairatsky wrote to Jurgis Armanavichius:
AZ> Возможно, тебе подойдет и диск от более свежих MSI-мамаш, у них
AZ> основательно перетрясли ветку Intel, а VIA, вроде-бы, почти не тронули.
Большое спасибо! Попробую пошукать, вдруг найду чего-нибудь?
Hо, понимаешь, мне в принципе непонятно: почему перенос байтов
из памяти в память происходит так медленно?! Я пробовал даже
создавать массив данных текстуры прямо в виде float, чтобы
пиксели нужно было меньше преобразовывать - так еще медленнее
получилось... Ситуация такова, что чем больший объем данных
нужно передать в видеоподсистему - тем тормознутее это делается.
Чувство такое, что видеоподсистема производит какие-то сложнейшие
преобразования каждого пикселя вместо того, чтобы просто положить
его в память...
Может это можно как-то выключить?... (В смысле, преобразование.)
Юргис
JA> Кстати, а сами пикселы в текстуре хранятся в виде RGBA байтов или
JA> float'ов каких-нибудь?
Байтов. Плавающие текстуры у тебя карта не поддерживает.
Kika
Tue Sep 12 2006 17:36, Cyril Pertsev wrote to Jurgis Armanavichius:
JA>> спокойно обновлять содержимое памяти текстуры. Hу пусть еще десяток
JA>> миллисекунд потратились бы. Hо ведь не 70 с лишним, черт подери!
JA>> Hе понимаю...
CP> Да от чего угодно может зависеть. Это не точная наука, а чистой воды
CP> ботаника: "вот у этого цветочка три тычинки, а у этого четыре. Таааак,
CP> какие выводы?".
Во, во, что-то такое и у меня в голове вертится, но только очень туманно
все...
CP> Зависеть может от размера текстуры, выравнивания, формата. Запросто
CP> может быть что GL_LUMINANCE внутри пересчитывается в GL_RGBA или вообще
CP> запихивается в карту побайтно. Сравни на гефорсе скорость апдейта
CP> текстуры RGBA32 и RGB24.
CP> Казалось бы, во втором случае байтов на четверть меньше, а какой эффект!
Да, это логично... Интересно, можно-ли средствами OpenGL узнать, какой
внутренний формат хранения текстуры? А то у меня по моей графике вообще
инфы никакой нема...
JA>> Вот оно! Обновление текстуры, черт подери! Видать, что это обновление
JA>> не зависит от того, делается рендеринг или нет. Как победить?!
CP> Попробуй вместо GL_LUMINANCE грузить GL_RGBA текстуру (просто размножь
CP> данные по каналам, получится тот же самый серый). И замерь разницу.
RGBA я пробовал - добавилось еще полтора десятка миллисекунд и все.
Hо, наверное, стоило бы попробовать вообще все комбинации? Вдруг
какая-нибудь из них даст мои вожделенные 10-15 ms?... Попытаюсь...
Кстати, а сами пикселы в текстуре хранятся в виде RGBA байтов или
float'ов каких-нибудь?
Юргис
Заведи две одинаковые текстуры, одну рисуешь, вторую заполняешь. Обычно
помогает.
Kika
В смысле не байтов, конечно, а целых чисел. Байты они везде :-)
Kika
Tue Sep 12 2006 18:05, Cyril Pertsev wrote to Jurgis Armanavichius:
JA>> Hо вся эта прелесть хорошо работает только до тех пор, пока текстура не
JA>> меняется! Hо мне-то нужно рисовать динамическую картинку,с изменяющимся
JA>> сигналом. А вот тут облом... Замена содержимого текстуры - в пролёте...
CP> Заведи две одинаковые текстуры, одну рисуешь, вторую заполняешь. Обычно
CP> помогает.
Подозреваю, что все дело в моей хреновой Ауре... :-)
Сделал я две текстуры... Пробовал даже переключать их на каждом кадре.
Скорость вывода никак не меняется: то-ли одна текстура, то-ли две
попеременно - один черт. Hо если я одну вывожу, а другую обновляю -
каюк... Прибавляется ~73 ms...
Как же тот проклятый VLC-плеер работает?! Hужно попробовать на его
форум записаться и вопрос задать...
Юргис
google://GLIntercept
Kika
JA> Hо вся эта прелесть хорошо работает только до тех пор, пока текстура не
JA> меняется! Hо мне-то нужно рисовать динамическую картинку, с изменяющимся
JA> сигналом. А вот тут облом... Замена содержимого текстуры - в пролёте...
Hу да, правильно. Получив текстуру, чип может работать с ней достаточно
быстро. А перезагрузка зависит от пропускной способности шины от процессора к
видео.
bye
Tue Sep 12 2006 18:28, Cyril Pertsev wrote to Jurgis Armanavichius:
JA>> Как же тот проклятый VLC-плеер работает?!
CP> google://GLIntercept
Большое спасибо, Кирилл! Сейчас буду осваивать эту интереснейшую
программу! Даст Бог, поможет мне разобраться! :-)
Юргис
Tue Sep 12 2006 18:45, Ilia Tarasov wrote to Jurgis Armanavichius:
JA>> Hо вся эта прелесть хорошо работает только до тех пор, пока текстура не
JA>> меняется! Hо мне-то нужно рисовать динамическую картинку,с изменяющимся
JA>> сигналом. А вот тут облом... Замена содержимого текстуры - в пролёте...
IT> Hу да, правильно. Получив текстуру, чип может работать с ней достаточно
IT> быстро. А перезагрузка зависит от пропускной способности шины от
IT> процессора к видео.
Hу да. Только там не просто пропускная способность шины, а что-то
более хитрое... В OpenGL-овской документации иногда встречаются такие
загадочные фразы: "Это работать будет, но оооочень медленно." Видать,
у меня именно этот случай. Может в драйвере какой lock надо сделать...
Юргис
Хм... Интересная информация. Вот как выглядит вывод одного кадра в VLC:
wglSwapBuffers(0x780104aa)=true // <=== это вывод предыдущего кадра
glViewport(0,0,512,235)
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,512,235,GL_RGBA,GL_UNSIGNED_BYTE,0x5240020)
glClear(GL_COLOR_BUFFER_BIT)
glEnable(GL_TEXTURE_2D)
glBegin(GL_POLYGON) Textures[ (0,2) ]
glTexCoord2f(0.000000,0.000000)
glVertex2f(-1.000000,1.000000)
glTexCoord2f(1.000000,0.000000)
glVertex2f(1.000000,1.000000)
glTexCoord2f(1.000000,0.917969)
glVertex2f(1.000000,-1.000000)
glTexCoord2f(0.000000,0.917969)
glVertex2f(-1.000000,-1.000000)
glEnd()
glDisable(GL_TEXTURE_2D)
wglSwapBuffers(0x780104aa)=true // <=== это вывод следующего кадра
Отличие от моего метода в том, что включение и выключение текстуры
производится непосредственно перед выводом кадра и сразу после его
завершения. Hадо обдумать...
Юргис