Стэн Трухильо - Графика для Windows средствами DirectDraw
- Название:Графика для Windows средствами DirectDraw
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стэн Трухильо - Графика для Windows средствами DirectDraw краткое содержание
Графика для Windows средствами DirectDraw - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
void BmpViewWin::DrawScene() {
if (update_screen && bmpsurf) {
ClearSurface(backsurf, 0);
BltSurface(backsurf, bmpsurf, x, y);
primsurf->Flip(0, DDFLIP_WAIT);
update_screen=FALSE;
}
}
Поскольку текущее положение поверхности рассчитывается в другом месте программы, а функция BltSurface()при необходимости автоматически выполняет отсечение, функция DrawScene()реализуется просто. Если переменная update_screenравна TRUEи существует поверхность для вывода, экран обновляется. Если поверхность не заполняет экран целиком, содержимое вторичного буфера стирается; если заполняет, то в стирании буфера нет необходимости. Затем функция BltSurface()копирует поверхность на вторичный буфер, а функция Flip()отображает изменения на экране. После того как обновление будет завершено, переменной update_screenприсваивается значение FALSE.
Обработка пользовательского ввода
Давайте посмотрим, как в нашей программе организована обработка ввода. Нажатые клавиши обрабатываются функций OnKeyDown(), которая выглядит так:
void BmpViewWin::OnKeyDown(UINT key, UINT nRepCnt, UINT nFlags) {
switch (key) {
case VK_UP:
Up();
break;
case VK_DOWN:
Down();
break;
case VK_LEFT:
Left();
break;
case VK_RIGHT:
Right();
break;
case VK_HOME:
Home();
break;
case VK_END:
End();
break;
case VK_PRIOR:
PageUp();
break;
case VK_NEXT:
PageDown();
break;
case VK_ESCAPE:
case VK_SPACE:
case VK_RETURN:
ShowDialog();
break;
}
DirectDrawWin::OnKeyDown(key, nRepCnt, nFlags);
}
С первого взгляда на листинг OnKeyDown()можно разве что понять, какие клавиши обрабатываются программой, потому что вся содержательная работа поручается другим функциям. Обратите внимание — при нажатии клавиш Escape, пробел и Enterвызывается одна и та же функция ShowDialog(). Это облегчает вызов диалогового окна после вывода изображения.
Остальные восемь функций, вызываемых функцией OnKeyDown(), изменяют положение поверхности во время прокрутки:
• Up()
• Down()
• Left()
• Right()
• Home()
• End()
• PageUp()
• PageDown()
Каждая из этих функций определяет положение поверхности по значениям переменных x, y, xlimit, ylimit, xscrollи yscroll. Код всех восьми функций приведен в листинге 5.9.
Листинг 5.9. Функции смещения поверхности
void BmpViewWin::Up(int inc) {
if (!yscroll) return;
if (y+inc<0) {
y+=inc;
update_screen=TRUE;
} else {
y=0;
update_screen=TRUE;
}
}
void BmpViewWin::Down(int inc) {
if (!yscroll) return;
if (y-inc>=ylimit) {
y-=inc;
update_screen=TRUE;
} else {
y=ylimit;
update_screen=TRUE;
}
}
void BmpViewWin::Left(int inc) {
if (!xscroll) return;
if (x+inc<0) {
x+=inc;
update_screen=TRUE;
} else {
x=0;
update_screen=TRUE;
}
}
void BmpViewWin::Right(int inc) {
if (!xscroll) return;
if (x-inc>=xlimit) {
x-=inc;
update_screen=TRUE;
} else {
x=xlimit;
update_screen=TRUE;
}
}
void BmpViewWin::Home() {
if (xscroll && x!=0) {
x=0;
update_screen=TRUE;
}
if (yscroll && y!=0) {
y=0;
update_screen=TRUE;
}
}
void BmpViewWin::End() {
if (yscroll) {
y=-(bmprect.Height()-displayrect.Height());
update_screen=TRUE;
}
if (xscroll) {
x=-(bmprect.Width()-displayrect.Width());
update_screen=TRUE;
}
}
void BmpViewWin::PageUp() {
if (yscroll) {
if (y-displayrect.Height()>0) {
y-=displayrect.Height();
update_screen=TRUE;
} else {
y=0;
update_screen=TRUE;
}
}
}
void BmpViewWin::PageDown() {
if (yscroll) {
if (y+displayrect.Height()<=ylimit) {
y+=displayrect.Height();
update_screen=TRUE;
} else {
y=ylimit;
update_screen=TRUE;
}
}
}
Обработчикам клавиш со стрелками ( Up(), Down(), Left(), Right()) можно передать необязательный аргумент, который определяет шаг прокрутки. Как видно из определения класса BmpViewWin (см. листинг 5.5), по умолчанию шаг прокрутки равен 4.
В этой главе я упоминал о том, что загрузить растровое изображение на поверхность можно и другим, более простым способом. Вспомните — в интерфейс DirectDrawSurfaceвходит функция GetDC(), которая позволяет работать с поверхностями с помощью обычных функций Win32. Реализующая этот подход функция может выглядеть так:
BOOL CopyBmp(LPDIRECTDRAWSURFACE surface, HBITMAP bmp, int x, int y) {
if (bmp==0) {
TRACE("no bmp specified\n");
return FALSE;
}
if (surface==0) {
TRACE("no surface specified\n");
return FALSE;
}
HDC imageDC = CreateCompatibleDC(0);
SelectObject(imageDC, bmp);
BITMAP bitmap;
GetObject(bmp, sizeof(bitmap), &bitmap);
int w=bitmap.bmWidth;
int h=bitmap.bnHeight;
DDSURFACEDESC desc;
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD+HEIGHT |DDSC_WIDTH;
surface->GetSurfaceDesc(&desc);
HDC dc;
HRESULT result;
if ((result=surface->GetDC(&dc))==DD_OK)) {
Stretchblt(dc, 0, 0, desc.dwWidth, desc.dwHeight, imageDC, x, y, w, h, SRCCOPY);
surface->ReleaseDC(dc);
}
DeleteDC(imageDC);
return result==DD_OK;
}
Эта функция не имеет никакого отношения к программе этой главы, ее даже нет на CD-ROM. Она приведена с единственной целью — показать, что с помощью функции GetDC()интерфейса DirectDrawSurfaceи функции Win32 наподобие StretchBlt()можно легко скопировать растровое изображение Windows на поверхность. Разумеется, в этом случае приходится жертвовать скоростью, поскольку механизм GDI не отличается особым быстродействием, а его функции не поддаются оптимизации.
Не будем отклоняться от основной темы этой главы — прямого доступа к поверхностям. Загрузка растров на поверхности была всего лишь упражнением. Теперь, когда вы все знаете о блокировке поверхностей и форматах пикселей, вы сможете самостоятельно реализовать алгоритмы рисования линий, эффекты растрирования (dithering) и даже спрайты. Кроме того, можно включить в программу поддержку других файловых форматов.
В главе 6 мы узнаем, как наделить приложение поддержкой DirectInput. Обходя традиционные механизмы ввода Windows, DirectInput позволяет с максимальной эффективностью получать данные от таких устройств, как клавиатура или мышь.
Глава 6. DirectInput
Давайте отдохнем от DirectDraw и познакомимся с библиотекой DirectInput. Конечно, эта книга посвящена компьютерной графике, но ввод информации пользователем — необходимая часть любого графического приложения. Применение DirectInput улучшает работу программ, так как ввод обнаруживается и обрабатывается с максимальной скоростью. После краткого знакомства с DirectInput API мы обсудим различные схемы получения пользовательского ввода, поддерживаемые DirectInput. Знакомство закончится созданием двух приложений: Qwerty и Smear. Программа Qwerty использует DirectInput для ввода с клавиатуры, а Smear работает с мышью.
Читать дальшеИнтервал:
Закладка: