Форум программистов, компьютерный форум CyberForum.ru

двойная буферизация - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.95
jonson
 Аватар для jonson
231 / 204 / 61
Регистрация: 18.03.2010
Сообщений: 749
05.07.2011, 20:04     двойная буферизация #1
Здравствуйте. Ребят не сочтите за труд, помогите разобраться. Проблема собственно вот в чём:
Пишу тетрис, в окошке находится стакан с фигурами, а на фоне нужно чтобы была некая картинка.
Сначала всё сделал с выводом прямо на экран, но столкнулся с миганием окна.
Теперь пробую через двойную буферизацию, но, после показа первого расположения падающей фигурки экран совсем не меняется.
Вот код прорисовки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
case WM_CREATE:
        space_bmp = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP1));
        break;
 
 
case WM_PAINT:
    {
        RECT rect;
        GetClientRect(main_hWnd,&rect);
        HBITMAP hMemBmp;
            
        hdc =  BeginPaint (main_hWnd,&ps);
        memdc = ::CreateCompatibleDC(hdc); // создаю контекст в памяти
        hMemBmp = CreateCompatibleBitmap(hdc, // совместимый битмап
                GetDeviceCaps(hdc, HORZRES), 
                GetDeviceCaps(hdc, VERTRES));
            
    // дальше нужно чтобы совместимый битмап в памяти содержал моё изображение  space_bmp
    // чтобы потом уже на нём прорисовывать
        hMemBmp = space_bmp;
 
        ::SelectObject(memdc,hMemBmp); // контекст в памяти получает совместимый битмап
        
        
        // .......
        // ....... здесь выполняю перерисовку стакана. Всё рисую в memdc
        // ....... 
 
    // теперь вывожу на экран
    BitBlt(hdc, 0, 0, GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES), memdc, 0,0, SRCCOPY);
        
    DeleteObject(hMemBmp);
    DeleteDC(memdc);
    EndPaint(hWnd, &ps);
    break;  
    }
Если закоментировать строку 20 hMemBmp = space_bmp;, то всё работает отлично, не мигая, но на чёрном фоне! что не есть хорошо.
Не могу понять почему не обновляется экран когда подгружаю фоновую картинку?
Миниатюры
двойная буферизация   двойная буферизация  
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.07.2011, 20:04     двойная буферизация
Посмотрите здесь:

C++ двойная буферизация
двойная сортировка C++
C++ Двойная загрузка файла
Двойная диспетчеризация :) C++
C++ Двойная сумма на C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
05.07.2011, 20:24     двойная буферизация #2
Первым же вызовом DeleteObject ты удаляешь space_bmp, потому что hMemBmp = space_bmp.
jonson
 Аватар для jonson
231 / 204 / 61
Регистрация: 18.03.2010
Сообщений: 749
05.07.2011, 20:40  [ТС]     двойная буферизация #3
Цитата Сообщение от Somebody Посмотреть сообщение
Первым же вызовом DeleteObject ты удаляешь space_bmp, потому что hMemBmp = space_bmp.
Somebody, я удаляю hMemBmp, и то после того как выполню всю прорисовку. При следующей генерации WM_PAINT, опять помещаю копию space_bmp в hMemBmp. По идее новая наложеная картинка должна стирать ранее существующую, но не стирает.
Мне кто нибудь может пояснить почему при пустом битмапе в контексте (т. е. hMemBmp) - всё нормально работает. А если копировать туда картинку (space_bmp), то ни фига!
Может я что-то не так делаю?

Добавлено через 5 минут
Цитата Сообщение от Somebody Посмотреть сообщение
Первым же вызовом DeleteObject ты удаляешь space_bmp, потому что hMemBmp = space_bmp.
Somebody, возможно вы поняли так, что фоновая картинка пропадает и потом всё происходит на чёрном фоне? Нет, просто если копировать в hMemBmp копию space_bmp, окно совсем не обновляется.
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
05.07.2011, 21:33     двойная буферизация #4
Цитата Сообщение от jonson Посмотреть сообщение
Somebody, я удаляю hMemBmp, и то после того как выполню всю прорисовку. При следующей генерации WM_PAINT, опять помещаю копию space_bmp в hMemBmp
Никакой копии больше нет. То, что было создано при WM_CREATE было удалено при первом же вызове WM_PAINT. Нет больше картинки. А вот тот битмап, что создан в строке 14 остался неудалённым. По сути, вот эта операция:
C++
1
hMemBmp = space_bmp;
как раз и некорректна. Она не копирует space_bmp в hMemBmp, как Вы рассчитываете.

Добавлено через 4 минуты
В общем копировать надо битмапу. По-настоящему копировать, а не присваивать.
jonson
 Аватар для jonson
231 / 204 / 61
Регистрация: 18.03.2010
Сообщений: 749
05.07.2011, 21:41  [ТС]     двойная буферизация #5
Цитата Сообщение от grizlik78 Посмотреть сообщение
В общем копировать надо битмапу. По-настоящему копировать, а не присваивать.
grizlik78, если копировать в контекст именно space_bmp, т.е.
C++
1
::SelectObject(memdc,space_bmp);
То тогда получается вот такой вывод на экран. Т.е. новая картинка не затирает старую!
Миниатюры
двойная буферизация  
jonson
 Аватар для jonson
231 / 204 / 61
Регистрация: 18.03.2010
Сообщений: 749
05.07.2011, 21:46  [ТС]     двойная буферизация #6
а при копировании в memdc пустого hMemBmp, как я понимаю, после создания он(совместимый битмап) содержит полностью черный цвет. Так вот, он то, черным цветом заливает прежнюю картинку.
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
05.07.2011, 21:48     двойная буферизация #7
Не, в этот контекст рисовать не надо, я сначала так написал, но понял, что ошибся. Надо именно создать совместимый битмап для рисования, а в него скопировать фоновую картинку. Как это сделать правильно с ходу не скажу. На ум приходит только второй контекст в памяти, с выбранным фоном, из которого копируем в первый, затем рисуем в первом и уже после копируем на устройство. Но это как-то громоздко. Надо поискать.
jonson
 Аватар для jonson
231 / 204 / 61
Регистрация: 18.03.2010
Сообщений: 749
05.07.2011, 22:33  [ТС]     двойная буферизация #8
Цитата Сообщение от grizlik78 Посмотреть сообщение
На ум приходит только второй контекст в памяти, с выбранным фоном, из которого копируем в первый,
grizlik78, спасибо за совет, всё получилось.

Добавлено через 36 минут
grizlik78, ээээм, всё-же есть ещё одна маленькая деталь. Окно где выводится колличество очков, оно вот мигает, почему на него не действует двойная буферизация?
его делаю так:
C++
1
2
wnd.score = CreateWindow("static", "0" ,
        SS_CENTER| WS_CHILD | WS_VISIBLE,348,130,135,30,main_hWnd,0, hInstance,0);
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.07.2011, 22:39     двойная буферизация
Еще ссылки по теме:

C++ Двойная алгебраическая сумма (сигма)
Консольная двойная буферирзация C++
Указатели. Матрица и двойная косвенная адресация C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
05.07.2011, 22:39     двойная буферизация #9
У этого окна небось свой обработчик со своей функцией перерисовки?

Не по теме:

Я-то откуда знаю? У меня линукс вообще

Yandex
Объявления
05.07.2011, 22:39     двойная буферизация
Ответ Создать тему
Опции темы

Текущее время: 00:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru