InfoCity
InfoCity - виртуальный город компьютерной документации
Реклама на сайте







Размещение сквозной ссылки

 

Часть пятая: DirectDraw в окне


Итак, скорее всего это будет заключительная часть моего учебника. Но это не значит, что изучение DirectDraw заканчивается! Я еще не расказал о тайлах, скроллинге, изометрии и тому подобных вещах, но это ведь уже будут не "Основы". Все, что каксается "продвинутого" программирования DirectDraw я буду выпускать отдельными статьями, так что заходите на сайт почаще!

Немножко теории


Чаще всего DD используется в полноэкранном режиме, так как только в нем мы можем использовать большинство функций работы с видеокартой. Однако, вам может понадобиться использование DirectDraw в окне. Все-таки как ни крути, DirectDraw даже в окне работает быстрее, чем BitBlt и другие "рисовательные" API функции, не говоря уже о методах PaintPicture и им подобных.

  • Оконный режим требует немножко больше памяти и работает медленнее, чем полноэкранный
  • Вы не можете использовать другой формат цвета, чем тот, что установлен в "панели управления"
  • Вы не можете менять разрешение экрана
  • Вам понадобится объект под названием "Клиппер" (Clipper). Когда программа работает в окне, оно может быть перекрыто другим окном, в этом случае, закрытая часть "обрезается" клиппером и не прорисовываетя.
  • Вам не нужен задний буфер! Все что вам потребуется - это главная поверхность и оффскринные буфера для того, чтобы хранить картинки

Чуть-чуть больше об объекте клиппер. Когда вы рисуете какой-то спрайт и он частично уходит за пределы видимой области, DirectDraw, вместо того, чтобы выдавать ошибку, просто прекращает рисовать весь спрайт и на экране вы видите, что он пропадает. К счастью для оконного режима, в нем DirectDraw позволяет использовать объект DirectDrawClipper, который действует по принципу детской формочки - он накладывается на определенный участок, например на PictureBox, а затем, все изображения, которые помещаются в этот PictureBox обрезаются об края клиппера и остаюется только то, что внутри него. Ну вот - полная песочница!

Объявляется и создается клиппер следующим образом:

'Для начала, нужно его объявить
Dim ddClipper As DirectDrawClipper

'Затем, выполняется такая последовательность:
Set ddClipper = dd.CreateClipper(0) 'Создать клиппер из объекта DirectDraw
ddClipper.SetHwnd Object.Hwnd 'Наложить клиппер на некий объект
ddsPrimary.SetClipper DDClipper 'Установить клиппер

Ну вот, примерно так вы будете создавать клиппер в ваших приложениях.

Но учтите, что в полноэкранном режиме, объект клиппер не работает! Вам придется обрезать спрайты, выходящие за границы экрана, вручную.

Немножко попишем


Ладно, с теорией, я надеюсь, разобрались. Переходим к созданию приложений.

Мы обновим наш модуль mdlDirectDraw7 и добавим в него новую функцию для создания DirectDraw в окне.

Сначала, поместите в модуль новое объявление:

Public ddClipper As DirectDrawClipper 'Объект Clipper

Теперь, примемся за саму функцию:

Public Sub CreateDDWindowed(srcHwnd As Long, clipHwnd As Long)
'Создаем объекты и устанавливаем обычный режим
Set dd = dx.DirectDrawCreate("")
Call dd.SetCooperativeLevel(srcHwnd, DDSCL_NORMAL)

'Создаем главный буфер
ddsd.lFlags = DDSD_CAPS
ddsd.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE
Set ddsPrimary = dd.CreateSurface(ddsd)

'Создаем клиппер и "присандаливаем" его к заданному объекту: форме или
'PictureBox
Set ddClipper = dd.CreateClipper(0)
ddClipper.SetHWnd clipHwnd
ddsPrimary.SetClipper ddClipper

End Sub

Отлично! С модулем покончено (ну в смысле закончено... ну вы меня поняли...) Теперь напишем программу, которая будет выводить в окне спрайт, и с изменением размеров формы, размер спрайта также будет меняться.

Создайте проект, если вы его еще не создали и нарисуйте форму frmMain. Далее, внесите в модуль кода формы следующий код:

Dim ddsPic As DirectDrawSurface7 'Поверхность для рисунка
Dim rc1 As RECT 'Дополнительная структура RECT

Private Sub Form_Load()
mdlDirectDraw7.CreateDDWindowed Me.hWnd, Me.hWnd 'Инициализация
'Загружаем картинку
Set ddsPic = mdlDirectDraw7.CreateDDSFromFile(App.Path & "\demo.bmp")
End Sub

При загрузке формы будет происходить инициализация, но не будет начинаться рисование. Процедура рисования будет вызываться при событиях формы Paint (чтобы перерисовывать спрайт, когда форма перекрывается другим окном, уходит за пределы экрана и т.п.), а также Resize (ну это понятно - чтобы менять размеры спрайта вместе с формой).

Private Sub Form_Paint()
'При перерисовке формы, например если ее перекрыло окном, обновляем картинку
Run
End Sub

Private Sub Form_Resize()
'При изменении размеров формы, перерисовываем картинку
Run
End Sub

Я думаю, вы уже догадались, что Run - это процедура рисования. А вот и она сама:

'Процедура рисования
Private Sub Run()
DoEvents
Call dx.GetWindowRect(Me.hWnd, rc1) 'Получить координаты формы в структуру RC1

'В RC заносим координаты исходного рисунка в буфере DD
rc.Left = 0
rc.Top = 0
rc.Right = 350
rc.Bottom = 279

'Рисуем картинку прямо на переднем буфере
Call ddsPrimary.Blt(rc1, ddsPic, rc, DDBLT_WAIT)
End Sub

Готово! Запускайте программу (конечно вам еще понадобится картинка с соответствующими размерами (у меня 350x279)) и попробуйте поменять размеры формы, перекрывать ее другими окнами, частично вытаскивать за пределы экрана. Картинка на форме должна постоянно обновляться.

В этом примере нет анимации. Я приготовил для вас еще один пример - с анимацией, но различия там скорее только технические и к DirectDraw относятся мало, поэтому я предлагаю вам его просто скачать. Посмотрите в "приложении" к этой главе.

[Назад]


Реклама на InfoCity

Яндекс цитирования



Финансы: форекс для тебя








1999-2009 © InfoCity.kiev.ua