Скролинг текста
От: Ziaw Россия  
Дата: 20.05.11 10:35
Оценка:
Надо на большом окне скролить текст, нечто похожее мы видим в конце каждого фильма.

Так вот ни в WPF ни в WinForms это не выходит по человечески. Хотя я делал такое лет 10 назад на просто на делфи.

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

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

Надо чтобы не тормозило даже на слабых компах. Тащить померший managed DirectX? Посмотрел пример для Xna, плавности тоже не ощутил.

Переходить в native?
Re: Скролинг текста
От: _FRED_ Черногория
Дата: 20.05.11 12:06
Оценка: 18 (1)
Здравствуйте, Ziaw, Вы писали:

Z>В винформсах тупо не хватает быстродействия похоже. Я так и не нашел, как нормально сдвинуть битмап в памяти, потому приходится копировать его аж два раза (BufferedGraphicsManager), окно большое, все это медленно. Ну и подрагивает, ибо отрисовка только из одного потока.


Через WriteableBitmap двигать не пробовали?
Help will always be given at Hogwarts to those who ask for it.
Re: Скролинг текста
От: samius Япония http://sams-tricks.blogspot.com
Дата: 20.05.11 12:34
Оценка: 18 (1)
Здравствуйте, Ziaw, Вы писали:

Z>В винформсах тупо не хватает быстродействия похоже. Я так и не нашел, как нормально сдвинуть битмап в памяти, потому приходится копировать его аж два раза (BufferedGraphicsManager), окно большое, все это медленно. Ну и подрагивает, ибо отрисовка только из одного потока.

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

Z>Надо чтобы не тормозило даже на слабых компах. Тащить померший managed DirectX? Посмотрел пример для Xna, плавности тоже не ощутил.

Году в 2004-м экспериментировал с выводом на слабой карточке. Наблюдал примерный паритет между Managed DirectDraw, OpenGL (Tao), GDI Plus. Все перечисленное спокойно могло обновлять мегапиксел экрана со скоростью 40 fps без заметных дерганий. GL был откинут просто потому что он с оконной системой не сильно дружил. Т.е. если поверх обновляемой области протащить окно, оставался мусор.

Z>Переходить в native?

смысл? Выброс на экран будет происходить теми же средствами.
Re: Скролинг текста
От: adontz Грузия http://adontz.wordpress.com/
Дата: 22.05.11 10:19
Оценка: 18 (1)
Здравствуйте, Ziaw, Вы писали:

ScrollDC и ScrollWindowEx. Последняя доступна через ScrollableControl.SetDisplayRectLocation(int x, int y)
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: Скролинг текста
От: Ziaw Россия  
Дата: 23.05.11 07:14
Оценка:
Здравствуйте, samius, Вы писали:

Z>>В винформсах тупо не хватает быстродействия похоже. Я так и не нашел, как нормально сдвинуть битмап в памяти, потому приходится копировать его аж два раза (BufferedGraphicsManager), окно большое, все это медленно. Ну и подрагивает, ибо отрисовка только из одного потока.

S>Не надо его двигать, надо его блитить со сдвигом на DC.
S>Если "титры" длинные, то одного растра может не хватить, тогда организовать цепочку, и блитить из двух, которые пересекаются с текущим "окном".

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

С гуглом пополам состряпал вот такой пример, в textBitmap отрисован нужный текст, pos это позиция меняющаяся в таймере.
        private void paintText(PaintEventArgs args) // on paint
        {
            IntPtr pTarget = args.Graphics.GetHdc();
            IntPtr pSource = CreateCompatibleDC(pTarget);
            var bmp = textBitmap.bitmap;

            IntPtr pOrig = SelectObject(pSource, bmp.GetHbitmap());
            BitBlt(pTarget, 0, 0, bmp.Width, bmp.Height, pSource, 0, pos, TernaryRasterOperations.SRCCOPY);
            IntPtr pNew = SelectObject(pSource, pOrig);

            DeleteObject(pNew);
            DeleteDC(pSource);
            args.Graphics.ReleaseHdc(pTarget);
        }



Мерцает, видимо я что-то делаю не так .

P.S. Вот тут полный пример, может кто глянуть у себя, мерцает ли?
Re[3]: Скролинг текста
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.05.11 07:42
Оценка: 9 (1)
Здравствуйте, Ziaw, Вы писали:

Z>Здравствуйте, samius, Вы писали:


Z>>>В винформсах тупо не хватает быстродействия похоже. Я так и не нашел, как нормально сдвинуть битмап в памяти, потому приходится копировать его аж два раза (BufferedGraphicsManager), окно большое, все это медленно. Ну и подрагивает, ибо отрисовка только из одного потока.

S>>Не надо его двигать, надо его блитить со сдвигом на DC.
S>>Если "титры" длинные, то одного растра может не хватить, тогда организовать цепочку, и блитить из двух, которые пересекаются с текущим "окном".

Z>Похоже блит это то, что надо. К сожалению я уже напрочь забыл то немногое, что знал из этой части винапи.


Z>С гуглом пополам состряпал вот такой пример, в textBitmap отрисован нужный текст, pos это позиция меняющаяся в таймере.

Z>
Z>        private void paintText(PaintEventArgs args) // on paint
Z>        {
Z>            IntPtr pTarget = args.Graphics.GetHdc();
Z>            IntPtr pSource = CreateCompatibleDC(pTarget);
Z>            var bmp = textBitmap.bitmap;

Z>            IntPtr pOrig = SelectObject(pSource, bmp.GetHbitmap());
Z>            BitBlt(pTarget, 0, 0, bmp.Width, bmp.Height, pSource, 0, pos, TernaryRasterOperations.SRCCOPY);
Z>            IntPtr pNew = SelectObject(pSource, pOrig);

Z>            DeleteObject(pNew);
Z>            DeleteDC(pSource);
Z>            args.Graphics.ReleaseHdc(pTarget);
Z>        }
Z>

Зачем же? Graphics.DrawImage/Unscaled делает всю грязную работу.


Z>Мерцает, видимо я что-то делаю не так .


Z>P.S. Вот тут полный пример, может кто глянуть у себя, мерцает ли?

У меня не мерцает.
сделал
private double pixelsPerTick = 0.0000001;

и закомментировал
          //if (pos != newPos)


Т.е. перерисовка идет при любом случае, текст двигается медленно. Никаких морганий, кроме эпизодических сдвигов на пиксел нет.
При увеличении скорости скачки на пиксель чаще, вот именно от них и рябит в глазах, как мне кажется.
Скринсейвер 3D Text на малых скоростях вращения текста дает схожее дрожание. Имхо, без антиалиасинга от него не избавиться.
Re[4]: Скролинг текста
От: Ziaw Россия  
Дата: 23.05.11 10:26
Оценка:
Здравствуйте, samius, Вы писали:

S>Т.е. перерисовка идет при любом случае, текст двигается медленно. Никаких морганий, кроме эпизодических сдвигов на пиксел нет.

S>При увеличении скорости скачки на пиксель чаще, вот именно от них и рябит в глазах, как мне кажется.
S>Скринсейвер 3D Text на малых скоростях вращения текста дает схожее дрожание. Имхо, без антиалиасинга от него не избавиться.

Вот тут как раз не очень понятно. При увеличении скорости дрожание есть и заметное. Выглядит неприятно. Но такие титры есть в любом фильме, эффект нормальный. Может и правда надо размазать границы?
Re[5]: Скролинг текста
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.05.11 11:47
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Вот тут как раз не очень понятно. При увеличении скорости дрожание есть и заметное. Выглядит неприятно.

Это дрожание не от скорости обновления, а от того что глаз то ловит сдвиг на пиксель, то не ловит его. Если скорость увеличить, эффект пропадет вместе с возможностью чтения текста.

Z>Но такие титры есть в любом фильме, эффект нормальный.

В фильмах титры субпиксельные, двигаются плавно, ане прыгают на пиксель (линию развертки) вверх.

Z> Может и правда надо размазать границы?

http://en.wikipedia.org/wiki/Gaussian_blur ??? Так и резкость пропадет.
Re[6]: Скролинг текста
От: adontz Грузия http://adontz.wordpress.com/
Дата: 23.05.11 11:59
Оценка:
Здравствуйте, samius, Вы писали:

Z>> Может и правда надо размазать границы?

S>http://en.wikipedia.org/wiki/Gaussian_blur ??? Так и резкость пропадет.

blur + cleartype дадут катастрофические результаты. Надо выключать cleartype.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[7]: Скролинг текста
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.05.11 12:37
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, samius, Вы писали:


Z>>> Может и правда надо размазать границы?

S>>http://en.wikipedia.org/wiki/Gaussian_blur ??? Так и резкость пропадет.

A>blur + cleartype дадут катастрофические результаты. Надо выключать cleartype.

а cleartype-а там нет
                bitmap = new Bitmap(width, (int)size.Height);
                var graphics = Graphics.FromImage(bitmap);

                var textRectangle = new RectangleF(0, 0, bitmap.Width, bitmap.Height);
                graphics.FillRectangle(Brushes.Gray, textRectangle);
                graphics.DrawString(text, font, Brushes.Black, textRectangle, format);
Re[8]: Скролинг текста
От: adontz Грузия http://adontz.wordpress.com/
Дата: 23.05.11 12:38
Оценка:
Здравствуйте, samius, Вы писали:

Я бы TextRenderingHint явно указал.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[5]: Скролинг текста
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.05.11 12:39
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Здравствуйте, samius, Вы писали:


S>>Т.е. перерисовка идет при любом случае, текст двигается медленно. Никаких морганий, кроме эпизодических сдвигов на пиксел нет.

S>>При увеличении скорости скачки на пиксель чаще, вот именно от них и рябит в глазах, как мне кажется.
S>>Скринсейвер 3D Text на малых скоростях вращения текста дает схожее дрожание. Имхо, без антиалиасинга от него не избавиться.

Z>Вот тут как раз не очень понятно. При увеличении скорости дрожание есть и заметное. Выглядит неприятно. Но такие титры есть в любом фильме, эффект нормальный. Может и правда надо размазать границы?


Мне кажется что я решил вашу проблему

1)
            var timer = new Timer { Interval = 40 };

2)
            //if (pos != newPos)
            {
                pos += 1;// newPos;
                Refresh();
            }

не идеально, но выглядит довольно плавно.
Re[9]: Скролинг текста
От: samius Япония http://sams-tricks.blogspot.com
Дата: 23.05.11 12:40
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, samius, Вы писали:


A>Я бы TextRenderingHint явно указал.


При рендеринге в растр он отрабатвает немного не так, как на экране.
Re: Скролинг текста
От: hardcase Пират http://nemerle.org
Дата: 23.05.11 12:53
Оценка: 18 (1)
Здравствуйте, Ziaw, Вы писали:

Z>Надо на большом окне скролить текст, нечто похожее мы видим в конце каждого фильма.


В SharpDevelop в окошке About происходит подобная штука.
/* иЗвиНите зА неРовнЫй поЧерК */
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.