Библиотека Интернет Индустрии I2R.ru |
|||
|
BitBlt Tutorial[введение] BitBlt - важная часть GDI32 API. Если Вы хотите делать игру, вам просто необходимо научиться переносу битов графического образа (Blit) из-за его быстроты. Знакомство с BitBlt будет хорошей стартовой точкой для изучения DirectDraw. Существует два способа, через которые может быть реализован BitBlt. Есть "Плохой" способ - использовать Picture Box, как область памяти для хранения графического образа, это очень медленный способ. "Хороший" способ - это использовать напрямую зарезервированную область памяти для хранения в ней графики. Это позволяет создавать быструю анимацию без заметных мерцаний. Зарезервированная область памяти называется Memory DC (DC - Device Context - контекст устройства), или просто DC. Blitting состоит из нескольких шагов:
Этот процесс также называется буфферинг. Если вы будете собирать изображение из нескольких спрайтов прямо на экране, будет заметно мерцание. С помощью буфферинга, вы переводите изображение на экран за одну операцию. [форма] Picture1: ScaleMode=Pixel [программа] Для начала, определим несколько функций. Я рекомендую поместить эти объявления в модуль, так чтобы Вы могли поключить его к проекту, где понадобится BitBlt. Сначала, объявления: Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long Здесь объявляются функции API, которые мы будем использовать. CreateCompatibleDC создает экземпляр DC, CreateCompatibleBitmap - растрового изображения, DeleteObject и DeleteDC... а вот не скажу! BitBlt получается как сердце, соединяющее все это. Синтаксис BitBlt похож на синтаксис PaintPicture. Теперь, несколько массивов, костант и объявление типа. Dim MemHdc() As Long С помощью типа мы сможеи подступиться к нужной области памяти. Константы определяют, каким образом будет скопировано растровое изображение. SRCAND используется для наложения маски. Маска обрезает ненужные пиксели и меняет цвет других так, чтобы вокруг спрайта на фоне не было черного обрамления. SRCINVERT используется для спрайта, а SRCCOPY для загрузки фона и окончания переноса битов. После этого, нам надо создать DС. Я использовал для этого функцию. Function CreateMemHdc (ScreenHdc As Long, Width As Integer, Height As Integer) As Long Эта функция вызывается позже в программе. Вот место, где рождаются DC! Конечно, создание одних лишь DC без загрузки в них графики - бесполезная трата времени. Вот подпрограмма, которая занимается этим: Sub LoadBmpToHdc(MHdc As Long, FileN As String) Сердце этой подпрограммы - вызов функции SelectObject, которая загружает изображение из файла в созданный DC. Отлично, этот модуль почти сделан, но нам еще понадобится подпрограмма, которая уничтожит все созданные DC, чтобы освободить ОЗУ при выходе из программы. Sub DestroyHdcs() Итак, это уже целый модуль. То есть, если вы скопируете его себе, все должно работать (если только нет опечаток, но я вроде проверял). Наконец, настало время писать подпрограммы, которые соберут вместе все вышеупомянутые процедуры и заставят их работать. Снова все по порядку. Сначала секция General: Dim x As Integer Здесь определяются все объекты, использующиеся для адресации наших DC. PicOrgBack - это оригинальный фон, PicSprite и PicMask для спрайта и для маски, PicWork это для DC, где все собирается. Теперь, процедура Form_Load: Private Sub Form_Load() Здесь вызывается начальная процедура, которая создаст DC: Sub init() Здесь вызывается CreateMemHdc для создания DC, затем растровые изображения загружаются в свежесозданные DC, за исключением PicWork, так как там мы будем собирать сцену. Для PicSprite и PicMask числа - это реальный размер изображения. Теперь код для элемента Timer, с помощью которого будет создана анимация. Private Sub Timer1_Timer() Таймер вызывает процедуру screen_refresh, которая с помощью переноса битов собирает все вместе и очищает предыдущий экран. Она копирует все в PicWork, а затем перебрасывает его содержимое в PictureBox. Sub screen_refresh() Сначала фон копируется на рабочую часть. Затем, накладывается маска за ней - спрайт. Наконец, последняя инструкция копирует сцену из памяти на экран. Попробуйте изменять свойство Inteval у таймера. Такой способ не повлияет на скорость PaintPicture, так как он и так медленный, но при использовании BitBlt вы сразу заметите разницу. Вы можете, а скорее даже нужно заменить объект Таймер циклом. Таймер - очень плохой элемент для анимации из за своих глюков. Ну вот, это был учебник BitBlt. Если вы запустили программу и удивились - какая разница?! - попробуйте запустить программу, использующую PaintPicture в одном окне, а рядом нашу программу с BitBlt. BitBlt как минимум в три раза быстрее! Я надеюсь, что четко все для вас изложил. Я провел чертовски тяжелое время, добывая хорошую информацию. Примерно 3/4 учебников я написал используя "плохую" технику blitting'а. Я бы никогда не научился blitting'у без Timbo's VB Game Tutorial и программы Tutor2 с Zorro's VB Fun Page. |
|
2000-2008 г. Все авторские права соблюдены. |
|