Модераторы: gambit, Partizan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Двойная буферизация в C# 
:(
    Опции темы
tdebugger
Дата 26.8.2007, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 20.1.2007

Репутация: 2
Всего: 4



Ну не обессудьте, я делюсь из жизненного опыта, а что не так, так то нюансы. 
--------------------
ТЕХНОЛОГИЯ "JAVA"  НЕ ПРЕДНАЗНАЧЕНА ДЛЯ УПРАВЛЕНИЯ ЯДЕРНЫМИ УСТАНОВКАМИWindows98 License.txt
PM MAIL MSN   Вверх
CyraxZ
Дата 27.8.2007, 08:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 10.12.2006

Репутация: нет
Всего: нет



Цитата

у своего контрола, то мерцания исчезли и без этих ухищрений.

А что за мерцания у тебя были ?  Когда происходили ?


Кстати, двойная буферизация как работает ?
Там есть какой-то промежуток времени, через который буфера свопятся или другой алгоритм ?
PM MAIL   Вверх
Alek86
Дата 27.8.2007, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: нет
Всего: 25



при прорисовке поля игры при щелчке мышкой на нем (на поле добавлялась точка) я вызывал invalidate и update (позже перешел на refresh, ибо первый способ не всегда работал). вот тогда все и мерцало. Ну, и при ресайзе тоже.

наверное, все рисуется в памяти, а потом сразу свопится.


--------------------
user posted image    user posted image
PM MAIL   Вверх
CyraxZ
Дата 27.8.2007, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 10.12.2006

Репутация: нет
Всего: нет



Цитата

при прорисовке поля игры при щелчке мышкой на нем (на поле добавлялась точка) я вызывал invalidate и update (позже перешел на refresh

А вызывал ты Invalidate без параметров ?
И где ты рисовал - на Graphics или на bitmap'е ?

Код

private void button1_Click(object sender, EventArgs e)
        {
            btBac = new Bitmap(panel1.Width, panel1.Height);
            Graphics gr = Graphics.FromImage(btBac);
            gr.FillEllipse(Brushes.DarkGreen, 0, 0, panel1.Width, panel1.Height);
            panel1.Invalidate();
        }

Ничего не понял. Здесь у тебя создаётся bitmap и его Graphics. Далее рисуем эллипс на Graphics, то бишь на bitmap'е, и перерисовываем... Вопрос: что здесь перерисовывается ?  Graphics и bitmap никак не связаны с контролом panel1.

И вообще я не совсем понял, что должен перерисовывать Invalidate. Рисую-то я сам - на Graphics'е, полученном из контрола, либо на bitmap'е, который я потом сам должен скидывать на контрол через его graphics.

Т.е. сейчас я в обработчике OnPaint скидываю bitmap на панель - это в UI-потоке.
В то же время в потоке таймера периодически требуется обновить какую-либо область панели. Вот здесь не совсем понятно, что делать. До настоящего момента я вручную перерисовывал эту область через Graphics панели (перерисовка происходила через Invoke в UI-потоке).
Теперь, если использовать bitmap, нужно на нём перерисовать изменённую область и скинуть этот битмэп на контрол. Но это делать нужно в UI-потоке во избежание одновременного доступа к контролу, т.е. опять использовать Invoke...

PM MAIL   Вверх
Alek86
Дата 28.8.2007, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: нет
Всего: 25



рисовать на битмапе нужно в методе OnPaint
и вообще, рисуй на панели в OnPaint, но поставь у нее (панели) DoubleBuffered = true

smile




--------------------
user posted image    user posted image
PM MAIL   Вверх
Experimenter
Дата 28.8.2007, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 430
Регистрация: 8.5.2007
Где: Уфа

Репутация: 1
Всего: 17



А вот интересный момент: раньше советовали для устранения мерцаний в конструкторе объявлять:
Код

SetStyle(ControlStyles.OptimizedDoubleBuffer, true); // раньше вроде бы было просто DoubleBuffer

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


--------------------
public Zlo FromTwoEvilsChooseSmaller(Zlo zlo1, Zlo zlo2){
    if(zlo1 < zlo2) return zlo1;
    else if(zlo1 > zlo2) return zlo2;
    else throw new Exception("Kill yourself by the wall"); }
PM WWW ICQ   Вверх
CyraxZ
Дата 28.8.2007, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 10.12.2006

Репутация: нет
Всего: нет



Цитата

рисовать на битмапе нужно в методе OnPaint

И тут же скидывать bitmap на панель ?
Тогда толку от bitmap'а ?

У меня следующая ситуация. На панели происходит перерисовка в следующих двух случаях:
1. Когда изменяется состояние (для дискретных сигналов) или значение (для аналоговых сигналов) элемента, я его (и только его, не всю схему) тут же перерисовываю на панели. Перерисовка происходит посредством Invoke(), посему выполняется в UI-потоке. Здесь у меня никаких проблем с тормозами нет.
2. Когда окно перемещается за пределы экрана, а затем выдвигается из-за него, то много раз вызывается обработчик Paint панели. В этом обработчике у меня происходит перерисовка всейсхемы. Перерисовываю я сам - поэлементно (естественно, DoubleBuffered здесь не поможет). Посему наблюдаются сильные тормоза...

Как мне избавиться от тормозов во втором случае ?

Судя по всему, нужно хранить уже отрисованный bitmap (например, в классе панели), а в обработчике Paint панели всего лишь скидывать этот bitmap на панель. Так ?

Что касается первого случая, то там нужно при изменении элемента перерисовать на bitmap'е этот элемент, затем посредством Invoke вызвать метод Invalidate(с параметрами, где указывается область перерисоки). Но тогда проще будет через Invoke вызвать свой метод, который рисует непосредственно на Graphics панели (т.е. фактически аналог вызова Invalidate())...

Как всё это лучше организовать ?
PM MAIL   Вверх
Alek86
Дата 28.8.2007, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: нет
Всего: 25



Цитата(CyraxZ @  28.8.2007,  21:11 Найти цитируемый пост)

И тут же скидывать bitmap на панель ?
Тогда толку от bitmap'а ?


толк, как я понимаю, в том, что все "прорисовывается" в памяти, а не во время рисования формы, то есть очень быстро.

а все-же, попробуй поставь DoubleBuffered, ибо, если я тебя правильно понял, он-то тут как раз и нужен


--------------------
user posted image    user posted image
PM MAIL   Вверх
CyraxZ
Дата 29.8.2007, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 10.12.2006

Репутация: нет
Всего: нет



Цитата

а все-же, попробуй поставь DoubleBuffered, ибо, если я тебя правильно понял, он-то тут как раз и нужен

DoubleBuffered у меня стоит. Но это свойство у формы. Я же рисую на панели. Впрочем, свойство, возможно, распространяется на прорисоку и всех его контролов.
DoubleBuffered не поможет, когда я сам все элементы по очереди отрисовываю на панели. У меня как раз такой случай. Я должен сам делать двойную буферизацию - собственно, через промежуточный image и есть такая буферизация (рисую на image и скидываю махом на панель).

Насколько я понял, метод Invalidate элементарно вызывает обработчик Paint...
PM MAIL   Вверх
tdebugger
Дата 30.8.2007, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 20.1.2007

Репутация: 2
Всего: 4



Цитата

Насколько я понял, метод Invalidate элементарно вызывает обработчик Paint...
Посылает сообщение для вызова пеперисовки - это более корректно, чем вызывать Paint напрямую...не под DOS программируем...

Цитата

DoubleBuffered у меня стоит. Но это свойство у формы. Я же рисую на панели. Впрочем, свойство, возможно, распространяется на прорисоку и всех его контролов.
На вряд ли. 
Цитата

 Я же рисую на панели. 
Здесь не мешало бы собственный контрол заделать. 

Цитата

толк, как я понимаю, в том, что все "прорисовывается" в памяти, а не во время рисования формы, то есть очень быстро.
Ну по крайней мере на порядок быстрее. Метод особенно хорошо помогает , когда требуется действительно сложная логика рисования - прорисовка внутри алгоритма, попиксельное сравнение...
Цитата

рисовать на битмапе нужно в методе OnPaint
Да где угодно можно, еще один плюс обратного буфера...

SetStyle(ControlStyles.OptimizedDoubleBuffer, true); -  то же самое, что DoubleBuffer=true; Кроме этого могут быть полезны  следующие установки:
Код

SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);

--------------------
ТЕХНОЛОГИЯ "JAVA"  НЕ ПРЕДНАЗНАЧЕНА ДЛЯ УПРАВЛЕНИЯ ЯДЕРНЫМИ УСТАНОВКАМИWindows98 License.txt
PM MAIL MSN   Вверх
CyraxZ
Дата 30.8.2007, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 10.12.2006

Репутация: нет
Всего: нет



Цитата

SetStyle(ControlStyles.UserPaint, true);

Изображение, которое я рисую на форме (на панели) будет перерисовываться вместе с самой формой при выдвигании формы из-за экрана или из-за другой формы ?
Если да, то никакие битмапы мне не понадобятся, поскольку только из-за этого я и ввёл битмапы...

PM MAIL   Вверх
tdebugger
Дата 31.8.2007, 01:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 20.1.2007

Репутация: 2
Всего: 4



Каждый контрол сам по себе перерисовывается...
--------------------
ТЕХНОЛОГИЯ "JAVA"  НЕ ПРЕДНАЗНАЧЕНА ДЛЯ УПРАВЛЕНИЯ ЯДЕРНЫМИ УСТАНОВКАМИWindows98 License.txt
PM MAIL MSN   Вверх
CyraxZ
Дата 31.8.2007, 06:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 10.12.2006

Репутация: нет
Всего: нет



Цитата

Каждый контрол сам по себе перерисовывается

У меня форма/панель при выдвигании из-за экрана или из-за другой формы не перерисовывается - остаётся белое пространство...
PM MAIL   Вверх
tdebugger
Дата 31.8.2007, 08:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 20.1.2007

Репутация: 2
Всего: 4



Тяжелый случай. После чего это произошло? 
Да и на счет контрола повторюсь, даже если кода минимум, все равно удобно... 
--------------------
ТЕХНОЛОГИЯ "JAVA"  НЕ ПРЕДНАЗНАЧЕНА ДЛЯ УПРАВЛЕНИЯ ЯДЕРНЫМИ УСТАНОВКАМИWindows98 License.txt
PM MAIL MSN   Вверх
CyraxZ
Дата 31.8.2007, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 10.12.2006

Репутация: нет
Всего: нет



Цитата

Тяжелый случай. После чего это произошло? 

А всегда так было - от самого начала и до самого конца.
При выдвигании сама форма-то перерисовывается, а то, что я сам до задвигания формы за экран рисовал, - не перерисовывается. Приходится самому... в OnPaint'е...

Ну так SetStyle(ControlStyles.UserPaint, true); не решит эту проблему ?

Цитата

Здесь не мешало бы собственный контрол заделать. 

Именно. Но сейчас уже поздно. Вот если бы сразу такую мысль...

Это сообщение отредактировал(а) CyraxZ - 31.8.2007, 17:49
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.1250 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.