DirectX7: Введение в DirectDraw
Сегодня мы будем изучать самую главную часть DirectX - DirectDraw, которая отвечает за 2D-графику. Как всегда нам потребуются библиотеки DirectX версии 7(не SDK) или выше. Стащить можно прямо с сайта Microsoft.
После данной нехитрой операции можно приступать к программированию. Загрузим Visual Basic, создадим новый проект (Standard EXE). Подключим библиотеки DirectX к проекту: "Project - References - DirectX 7 for Visual Basic Type library". Теперь можно приступить к написанию программного кода:
Объявим в General Declarations формы:
Dim dx as New DirectX7 'объявляем об использовании DirectX7 Dim dd As DirectDraw7 'объявляем об использовании DirectDraw7.
DirectX7 является последней версией на момент написания статьи. Возможно, что мой читатель располагает более поздней версией DirectX и тогда он будет объявляеть Dim dd as DirectDraw8 и т.п. !!!
Создадим несколько, так называемых "поверхностей" (surfaces). Поверхности Primary и Back будут служебными, их мы будем использовать для создания back buffer'а (обратного буфера). Intro будет использоваться для создания фона, а Sprites для объекта. Также мы будем использовать ddsd1 и ddsd2 - шаблоны-дескрипторы, которые устанавливают свойства выводимых данных.
Dim Primary As DirectDrawSurface7 Dim Back As DirectDrawSurface7 Dim Intro As DirectDrawSurface7 Dim Sprites As DirectDrawSurface7 Dim ddsd1 As DDSURFACEDESC2 Dim ddsd2 As DDSURFACEDESC2
!!! Аналогичная история с версиями DirectX !!!
Перед инициализацией неплохо бы написать модуль, который показывал/скрывал курсор мышки. Далее приведён именно он:
'API функция для показа/скрытия курсора Declare Function ShowCursor Lib "User32" (ByVal bShow As Long) As Long Public lShowCursor As Long 'служебные Public lRet As Long 'переменные Public Sub HideMouse() 'Sub, который прячет курсор Do lShowCursor = lShowCursor - 1 lRet = ShowCursor(False) Loop Until lRet < 0 End Sub Public Sub ShowMouse() 'Sub, который показывет курсор Do lShowCursor = lShowCursor - 1 lRet = ShowCursor(True) Loop Until lRet >= 0 End Sub
Теперь можно приступить к процессу инициализации DirectDraw. Напишем специальный Sub для этого:
Sub Init() 'если происходит ошибка в ходе выполнения всего этого безобразия идём к 'процессу очистки памяти On Local Error GoTo errOut Call HideMouse 'скрываем курсор, чтобы не мешал
Наполняем переменную dd смыслом её жизни:
Set dd = dx.DirectDrawCreate("")
Только потом показываем форму, а не наоборот!
Form1.Show
Теперь укажем режим работы. В следующем примере используется разрешение 640x480, 16 разрядов цветов, полноэкранный, расширенный режим. Можно, конечно же, работать и в оконном (DDSCL_NORMAL), но производительность тогда заметно падает. Работа в VGA режиме (DDSDM_STANDARDVGAMODE) нынче тоже совсем не нужна...
!!! Если вы хотите использовать 256 цветов, тогда пишите Call dd.SetDisplayMode(640 , 480, 8, 0, DDSDM_DEFAULT) !!!
Call dd.SetCooperativeLevel(Me.hWnd, DDSCL_FULLSCREEN Or DDSCL_EXCLUSIVE) Call dd.SetDisplayMode(640, 480, 16, 0, DDSDM_DEFAULT)
Установим флажки к дескриптору поверхности Primary.
ddsd1.lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT ddsd1.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX ddsd1.lBackBufferCount = 1
Устанавливаем параметры поверхности Primary из уже готового шаблона-дескриптора ddsd1.
Set Primary = dd.CreateSurface(ddsd1)
Наполняем back buffer из уже подготовленной поверхности Primary:
Dim caps As DDSCAPS2 caps.lCaps = DDSCAPS_BACKBUFFER Set Back = Primary.GetAttachedSurface(caps)
Загружем картинку в поверхность Intro, используя дескриптор ddsd2, для использования её, как фона. Предварительно неплохо бы иметь файл background.bmp в директории проекта.
ddsd2.lFlags = DDSD_CAPS ddsd2.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN Set Intro = dd.CreateSurfaceFromFile("background.bmp", ddsd2)
Заполним поверхность Sprites из файла sprites.bmp. Дескриптор тот же, т.е. ddsd2. Обратите внимания на то, что я добавил ещё параметры IHeight и IWidth. Его следует использовать, если размер заготовленной картинки меньше размеров, объявленных в dd.SetDisplayMode. В данном случае высота у моей картинки равна 32 пикселям (IHeight), и ширина равна 32 пикселям (IWidht). Если размеры картинки равны объявленным в dd.SetDisplayMode, то IHeight и IWidth можно не указывать. Если бы у меня длина картинки была бы равна указанной в dd.SetDisplayMode, то я бы IWidth и не писал бы.
ddsd2.lHeight = 32 ddsd2.lWidth = 32 Set Sprites = dd.CreateSurfaceFromFile("sprites.bmp ", ddsd2)
Объявим переменную key, как DDCOLORKEY и укажем ей границу DirectDraw-цвета от 0 до 0. Это означает, что цветом для прозрачности будет абсолютно чёрный. Можно указывать несколько цветов, например от 0 до 10 и т.д.
Dim key As DDCOLORKEY key.low = 0 key.high = 0 Sprites.SetColorKey DDCKEY_SRCBLT, key
Рисуем спрайты при помощи следующих команд. Их содержимое рассматривается далее.
UpdateBack UpdateObject errOut: CleanUp '!! Процедуру CleanUp надо добавить и в form_unload !! End Sub
Создадим процедуру UpdateObject, которая будет обновлять объект.
Sub UpdateObject() Dim ddrval As Long 'буфер для прорисовки спрайта. Dim rcRect As RECT 'тип данных, задающий позицию спрайта
Позиции объекта в графическом файле (sprites.bmp) (Left - слева, Top - сверху, Right - справа, Buttom - снизу)
rcRect.Left = 0 rcRect.Top = 0 rcRect.Right = 32 rcRect.Bottom = 32 x=0 y=0
Для анимации спрайтов лучше всего использовать метод BltFast. Мы рисуем его на поверхности Back. Переменные x и y - место расположение спрайта на форме.
ddrval = Back.BltFast(x, y, Sprites, rcRect, DDBLTFAST_SRCCOLORKEY Or DDBLTFAST_WAIT) End Sub
Следующий Sub используется для отрисовки фона:
Sub UpdateBack() Dim rcRect As RECT 'уже знакомые нам переменные Dim ddrval As Long Размер фона 640x480: rcRect.Left = 0 rcRect.Top = 0 rcRect.Right = 640 rcRect.Bottom = 480
Теперь рисуем используя картинку, загруженную в поверхность Intro:
ddrval = Back.BltFast(0, 0, Intro, rcRect, DDBLTFAST_NOCOLORKEY Or DDBLTFAST_WAIT) End Sub
И последний Sub: расчистка, который показывает мышь и восстанавливает видео-режим.
Sub CleanUp() Call ShowMouse Call dd.RestoreDisplayMode Call dd.SetCooperativeLevel(Me.hWnd, DDSCL_NORMAL) End End Sub
www.vbstreets.ru
Оставить комментарий
Комментарии
Primary.Flip Nothing, 0