DirectX 8.1 в MASM32: Урок 1

Дата публикации 1 мар 2003

DirectX 8.1 в MASM32: Урок 1 — Архив WASM.RU

Самое главное, что нам потребуется для работы с DirectX это заголовочные файлы и библиотеки. Можно взять их из Microsoft DirectX SDK 8.1. Все, что нам оттуда нужно, это только папка LIB. У меня не было возможности взять SDK с компакта, а качать более 100 метров ради пары десятков файлов полный идиотизм. Хоть мелгомягкие и запрещают выкладывать какие либо части их SDK, находятся еще добрые люди на свете и набрав в поисковике искомое мы всегда получим парочку адресов. Все ленивые могут посмотреть по адресу упомянутому мною в предыдущем уроке. До последнего момента там было то что нам нужно.

Так как SDK рассчитан на работу с языком C++, то заголовочные файлы необходимо адаптировать. Не переживайте. Для данных уроков я уже адаптировал все необходимые файлы и надеюсь, работа будет продолжена. Адаптированные INC файлы включены в исходник уроков, забирайте и пользуйтесь. Формат библиотек является родным и для С++ и для MASM, поэтому библиотеки подходят без проблем. Ну вот и все приготовления и прежде, чем мы перейдем собственно к нашему уроку, хотелось бы еще упомянуть, что все относящееся к DirectX я буду сопровождать подробной справкой. Справка является моим корявым переводом справочника из SDK, поэтому не ругайте меня за возможные ошибки.

Все что у нас сейчас имеется это приложение, при запуске выводящее на экран окошко размером 320х240, и нам надо заставить работать в этом окне Direct3D. Как это сделать? Нет ничего проще!

Первое что мы добавим это подключение необходимых файлов:

Код (Text):
  1.  
  2.     include         d3d8.inc       
  3.     include         d3d8caps.inc
  4.     include         d3d8types.inc
  5.     includelib      d3d8.lib

Теперь обьявим необходимые переменные и структуры:

Код (Text):
  1.  
  2.     Clearcolor      DWORD           0   ; Переменная для очистки экрана цветом
  3.     Zvalue      REAL4               1.0 ; Значение для Z буфера ( см.ниже )
  4.  
  5.     pd3d        DWORD           ?   ; Указатель на Direct3D         
  6.     pd3dDevice  DWORD           ?   ; Указатель на Direct3DDevice       
  7.     d3ddm       D3DDISPLAYMODE          ; Структура для параметров экрана
  8.     d3dpp       D3DPRESENT_PARAMETERS   ; Структура для параметров нашего Direct3Ddevice

Справка

Код (Text):
  1.  
  2.  D3DDISPLAYMODE STRUC
  3.  
  4.     Width1      UINT                ?     ; Ширина экрана в пикселях
  5.     Height      UINT                ?     ; Высота экрана в пикселях
  6.     RefreshRate         UINT        ?     ; Частота обновления. 0 означает частота по умолчанию
  7.     Format      DWORD       ?     ; Формат использ. поверхности ( см. D3d8Types.inc )
  8.  
  9.  D3DDISPLAYMODE ENDS
  10.  
  11.  D3DPRESENT_PARAMETERS  STRUC
  12.  
  13.     BackBufferWidth     UINT        ?   ; Ширина BackBuffer. 0 если работаем в окне.
  14.     BackBufferHeight        UINT        ?   ; Высота BackBuffer. 0 если работаем в окне.
  15.     BackBufferFormat        DWORD       ?   ; Формат использ. поверхности ( см. D3d8Types.inc )
  16.     BackBufferCount     UINT        ?   ; 0,1,2 или 3 - число буферов. 0 трактуется как 1.
  17.                             ; Если указанное число буферов не может быть
  18.                             ; создано то помещается число буферов которые    
  19.                             ; были реально созданы
  20.     MultiSampleType     DWORD       ?   ; 2-16 уровни мультисэмплинга картинки.
  21.                             ; 1 не используется, а 0 равносилен отсутствию
  22.                             ; мультисэмплинга ( D3DMULTISAMPLE_NONE )
  23.                             ; Мультисэмплинг возможен только если установлен
  24.                             ; D3DSWAPEFFECT_DISCARD. В противном случае
  25.                             ; здесь должен быть 0.
  26.     SwapEffect          DWORD       ?   ; Эффект обмена поверхностей.
  27.                             ; Если мы работаем в окне и используем
  28.                             ; D3DSWAPEFFECT_FLIP, тогда будет создан один
  29.                             ; дополнительный BackBuffer. Пока один буфер
  30.                             ; показывается на экране можно рисовать в другой.
  31.                             ; Потом они меняются местами и т.д  
  32.                             ; D3DSWAPEFFECT_COPY и
  33.                             ; D3DSWAPEFFECT_COPY_VSYNC требуют чтобы
  34.                             ; BackBufferCount был установлен в 1. ( содержимое
  35.                                                                         ; буфера копируется на экран без ожидания
  36.                                                                         ; обратного хода луча и с ожиданием соответственно)
  37.                                                                         ; D3DSWAPEFFECT_DISCARD сначала буфер
  38.                                                                         ; заполняется а потом показывается на экран
  39.     hDeviceWindow       HWND            ?   ; ID нашего окошка
  40.     Windowed            BOOL            ?   ; Режим работы. 0 - полноэкранный, 1 - в окошке
  41.     EnableAutoDepthStencil  BOOL                ?   ; Если значение установить в 1, то Direct3D будет управлять
  42.                             ; для приложения буфером глубины. Будет создан Z-Stencil
  43.                             ; буфер. При этом в AutoDepthStencilFormat должен быть
  44.                             ; установлен правильный формат поверхности.
  45.                                                                         ; Если 0 - ничего не будет создано                                                                
  46.     AutoDepthStencilFormat  DWORD       ?   ; Формат использ. поверхности ( см. D3d8Types.inc )
  47.                             ; Игнорир. если EnableAutoDepthStencil не равен 1
  48.     Flags               DWORD           ?   ; 0 или D3DPRESENTFLAG_LOCKABLE_BACKBUFFER=1
  49.                             ; Нужен если мы будем блокировать BackBuffer
  50.     FullScreen_RefreshRateInHz  UINT        ?   ; Частота обновления экрана в Hz.
  51.                                                                         ; Должно быть 0 если мы работаем в оконном режиме
  52.                             ; Если указать D3DPRESENT_RATE_DEFAULT, то
  53.                                                                         ; берется текущее значение, если в окошке, и по
  54.                                                                         ; умолчанию ( обычно 60 Hz ), если в полноэкранном
  55.     FullScreen_PresentationInterval UINT        ?   ; Интервал показа на экране backbufferа
  56.                                                                         ; Должно быть 0 если мы работаем в оконном режиме
  57.                             ; D3DPRESENT_INTERVAL_IMMEDIATE -  рисуем немедленно
  58.                             ; не ждя обратного хода луча
  59.                                     ; 1 - рисуем ждя обратный ход луча ( FPS - не будет
  60.                                                                         ; превышать Hz экрана )
  61.                                     ; 2 - FPS равен половине Hz
  62.                                     ; 3 - FPS равен трети Hz
  63.                                     ; 4 - FPS равен четверти Hz
  64.  D3DPRESENT_PARAMETERS  ENDS

Далее создадим три процедуры Init_Direct3D, Destroy_Direct3D и Render_Scene

итак Init_Direct3D

Создаем обьект Direct3D8:

Код (Text):
  1.  
  2.     invoke      Direct3DCreate8, D3D_SDK_VERSION                       
  3.     mov pd3d, eax

Справка

Код (Text):
  1.  
  2.  Direct3DCreate8 передается в качестве параметра версия SDK.
  3.  
  4.  Метод возвращает указатель на обьект если все прошло успешно.
  5.  Если ошибка, то в EAX возвращается код ошибки, какой именно я не знаю :( ( возможно 0 )  

Затем мы получаем информацию о текущих параметрах экрана:

Код (Text):
  1.  
  2.     d3d8    GetAdapterDisplayMode, pd3d, D3DADAPTER_DEFAULT, ADDR d3ddm

Справка

Код (Text):
  1.  
  2.  1. Номер видеоадаптера. D3DADAPTER_DEFAULT - всегда главный адаптер ( под номером 0 ) можно вставить цифру
  3.                                        нужного адаптера если в системе их несколько
  4.  
  5.  2. Указатель на структуру параметров экрана  ( см. выше )
  6.  
  7.  Возвращает в случае успеха D3D_OK. Если нет то D3DERR_INVALIDCALL - недействительный вызов.

Заполняем только те поля структуры которые нам необходимы:

Код (Text):
  1.  
  2.     mov d3dpp.Windowed, TRUE                ; Работаем в окошке         
  3.     mov d3dpp.SwapEffect, D3DSWAPEFFECT_FLIP    ; Будем менять буфера
  4.     mov eax, d3ddm.Format               ; Берем формат экрана
  5.     mov d3dpp.BackBufferFormat, eax             ; Сохраняем в структуре

А сейчас делаем самое главное ! Создаем устройство Direct3DDevice8.

Создавать Direct3DDevice в сообщении WM_Create нельзя ! ( проверено опытным путем :smile3: ) То же самое можно найти в документации по Direct3D8.

CreateDevice мы должны передать hwnd полностью созданного окна на экране которое находится в фокусе.

Код (Text):
  1.  
  2.     d3d8  CreateDevice, pd3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd , \
  3.               D3DCREATE_HARDWARE_VERTEXPROCESSING, ADDR d3dpp, ADDR pd3dDevice

Справка

Код (Text):
  1.  
  2.  1. Номер видеоадаптера. D3DADAPTER_DEFAULT - всегда главный адаптер ( под номером 0 ) можно вставить цифру
  3.                                        нужного адаптера если в системе их несколько.
  4.  
  5.  2. Тип устройства рендеринга.  D3DDEVTYPE_HAL - аппаратный рендеринг. D3DDEVTYPE_REF - програмный рендеринг.
  6.  
  7.  3. Hwnd - ID нашего окошка.
  8.  
  9.  4. Комбинация флагов. D3DCREATE_FPU_PRESERVE - нам нужна двойная точность вычисления с плавающей запятой.
  10.                    D3DCREATE_HARDWARE_VERTEXPROCESSING - аппаратная обработка вершин
  11.                    D3DCREATE_SOFTWARE_VERTEXPROCESSING - программная обработка вершин
  12.                    D3DCREATE_MIXED_VERTEXPROCESSING - аппаратная + программная обработка вершин
  13.                    D3DCREATE_MULTITHREADED - многопоточность приложения ( direct3D создает глобальный
  14.                                 критический раздел это может привести к падению FPS )
  15.                    D3DCREATE_PUREDEVICE - не поддерживать Get вызовы. Также не обеспечивать эмуляцию
  16.                                   каких- либо сервисов связанных с Vertex processing. Имеется в виду
  17.                                   что если устройство не поддерживает vertex processing тогда
  18.                                 приложение может использовать только post трансформацию вершин.
  19.                  D3DCREATE_DISABLE_DRIVER_MANAGEMENT - D3D будет управлять ресурсами вместо драйвера.
  20.  
  21.  Флаги SOFTWARE_VERTEXPROCESSING, HARDWARE_VERTEXPROCESSING и MIXED_VERTEXPROCESSING недопустимы
  22.  для совместного использования.
  23.  
  24.  5. Указатель на структуру D3DPRESENT_PARAMETERS. ( см. выше )
  25.  6. Адрес переменной куда будет помещен указатель на D3DDevice
  26.  
  27.  Возвращает в случае успеха D3D_OK.
  28.  Если нет то D3DERR_INVALIDCALL - недействительный вызов, D3DERR_NOTAVAILABLE - устройством требуемое не
  29.  поддерживается или D3DERR_OUTOFVIDEOMEMORY - не хватает видео памяти для данной операции.

Теперь наше устройство создано и настало время написать функцию Render_Scene !

итак Render_Scene

Для простого примера применим очистку backbuffer`а цветом и показа его на экране:

Код (Text):
  1.  
  2.     d3dev8  Clear, pd3dDevice, 0 , NULL , D3DCLEAR_TARGET, clearcolor, Zvalue, 0

Справка

Код (Text):
  1.  
  2.  1. Число структур прямоугольников в массиве. ( см. Параметр 2 )
  3.  2. Указатель на массив структур прямоугольников. Каждый прямоугольник указывает какое место в поверхности
  4.                                  рендеринга очищать. Если 0 то очищается вся поверхность.
  5.                         При этом в первом параметре тоже должен быть 0.
  6.  
  7.  3. Комбинация флагов.   D3DCLEAR_STENCIL - очищать стенсель буфер стенсель значением. ( см.параметр 6 )
  8.             D3DCLEAR_TARGET - очищать поверхность рендеринга цветовым значением. ( см.параметр 4 )
  9.             D3DCLEAR_ZBUFFER - очищать Z буфер z значением. ( см.параметр 5 )
  10.  
  11.  4. Цветовое значение. 32bit-ное значение в формате ARGB
  12.  
  13.  5. Z значение. Может быть в диапазоне от 0.0 до 1.0 ( для z основного или w основного буфера глубины )
  14.                0.0 - ближняя гараница. 1.0 - дальняя граница.
  15.  
  16.  6. Stencil значение. Может быть в диапазоне от 0 до 2^n-1 где n это глубина бит стенсель буфера.
  17.  
  18.  Возвращает в случае успеха D3D_OK. Если нет то D3DERR_INVALIDCALL,  
  19.  D3DERR_NOTAVAILABLE или D3DERR_OUTOFVIDEOMEMORY. ( расшифровку см. выше )

А теперь все покажем этой функцией

Код (Text):
  1.  
  2.     d3dev8     Present, pd3dDevice, NULL, NULL, NULL, NULL

Справка

Код (Text):
  1.  
  2.  1. Указатель на структуру источник типа RECT. Должно быть 0 если поверхности не были созданы с флагами
  3.      D3DSWAPEFFECT_COPY и D3DSWAPEFFECT_COPY_VSYNC.
  4.  
  5.  2. Указатель на структуру назначение типа RECT. Должно быть 0 если поверхности не были созданы с флагами
  6.      D3DSWAPEFFECT_COPY и D3DSWAPEFFECT_COPY_VSYNC.
  7.  
  8.  3. ID окошка куда показывать результат. Если мы указали его ранее в структуре D3DPRESENT_PARAMETERS, то здесь 0
  9.  4. Не используется и должен быть 0.

Откомпилировав и запустив это приложение, вы увидите, что оно работает. Но это еще не все. После того как наше приложение будет закрыто, нам необходимо удалить все созданные нами интерфейсы и занятые ими ресурсы. Для этого создадим функцию Destroy_Direct3D.

итак Destroy_Direct3D

Код (Text):
  1.  
  2.     d3dev8  Release, pd3dDevice ; Метод специально для Direct3DDevice8  
  3.     d3d8    Release, pd3d       ; Метод специально для Direct3D8  

На этом позволю себе откланяться. До следующих встреч !

Исходник прилагается.

PS

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

Авторство принадлежит Пономареву Михаилу ака keYMax. Все вопросы и ругательства слать по адресу mybox@aib.ru © keYMax


0 1.066
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532