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):
include d3d8.inc include d3d8caps.inc include d3d8types.inc includelib d3d8.libТеперь обьявим необходимые переменные и структуры:
Код (Text):
Clearcolor DWORD 0 ; Переменная для очистки экрана цветом Zvalue REAL4 1.0 ; Значение для Z буфера ( см.ниже ) pd3d DWORD ? ; Указатель на Direct3D pd3dDevice DWORD ? ; Указатель на Direct3DDevice d3ddm D3DDISPLAYMODE ; Структура для параметров экрана d3dpp D3DPRESENT_PARAMETERS ; Структура для параметров нашего Direct3DdeviceСправка
Код (Text):
D3DDISPLAYMODE STRUC Width1 UINT ? ; Ширина экрана в пикселях Height UINT ? ; Высота экрана в пикселях RefreshRate UINT ? ; Частота обновления. 0 означает частота по умолчанию Format DWORD ? ; Формат использ. поверхности ( см. D3d8Types.inc ) D3DDISPLAYMODE ENDS D3DPRESENT_PARAMETERS STRUC BackBufferWidth UINT ? ; Ширина BackBuffer. 0 если работаем в окне. BackBufferHeight UINT ? ; Высота BackBuffer. 0 если работаем в окне. BackBufferFormat DWORD ? ; Формат использ. поверхности ( см. D3d8Types.inc ) BackBufferCount UINT ? ; 0,1,2 или 3 - число буферов. 0 трактуется как 1. ; Если указанное число буферов не может быть ; создано то помещается число буферов которые ; были реально созданы MultiSampleType DWORD ? ; 2-16 уровни мультисэмплинга картинки. ; 1 не используется, а 0 равносилен отсутствию ; мультисэмплинга ( D3DMULTISAMPLE_NONE ) ; Мультисэмплинг возможен только если установлен ; D3DSWAPEFFECT_DISCARD. В противном случае ; здесь должен быть 0. SwapEffect DWORD ? ; Эффект обмена поверхностей. ; Если мы работаем в окне и используем ; D3DSWAPEFFECT_FLIP, тогда будет создан один ; дополнительный BackBuffer. Пока один буфер ; показывается на экране можно рисовать в другой. ; Потом они меняются местами и т.д ; D3DSWAPEFFECT_COPY и ; D3DSWAPEFFECT_COPY_VSYNC требуют чтобы ; BackBufferCount был установлен в 1. ( содержимое ; буфера копируется на экран без ожидания ; обратного хода луча и с ожиданием соответственно) ; D3DSWAPEFFECT_DISCARD сначала буфер ; заполняется а потом показывается на экран hDeviceWindow HWND ? ; ID нашего окошка Windowed BOOL ? ; Режим работы. 0 - полноэкранный, 1 - в окошке EnableAutoDepthStencil BOOL ? ; Если значение установить в 1, то Direct3D будет управлять ; для приложения буфером глубины. Будет создан Z-Stencil ; буфер. При этом в AutoDepthStencilFormat должен быть ; установлен правильный формат поверхности. ; Если 0 - ничего не будет создано AutoDepthStencilFormat DWORD ? ; Формат использ. поверхности ( см. D3d8Types.inc ) ; Игнорир. если EnableAutoDepthStencil не равен 1 Flags DWORD ? ; 0 или D3DPRESENTFLAG_LOCKABLE_BACKBUFFER=1 ; Нужен если мы будем блокировать BackBuffer FullScreen_RefreshRateInHz UINT ? ; Частота обновления экрана в Hz. ; Должно быть 0 если мы работаем в оконном режиме ; Если указать D3DPRESENT_RATE_DEFAULT, то ; берется текущее значение, если в окошке, и по ; умолчанию ( обычно 60 Hz ), если в полноэкранном FullScreen_PresentationInterval UINT ? ; Интервал показа на экране backbufferа ; Должно быть 0 если мы работаем в оконном режиме ; D3DPRESENT_INTERVAL_IMMEDIATE - рисуем немедленно ; не ждя обратного хода луча ; 1 - рисуем ждя обратный ход луча ( FPS - не будет ; превышать Hz экрана ) ; 2 - FPS равен половине Hz ; 3 - FPS равен трети Hz ; 4 - FPS равен четверти Hz D3DPRESENT_PARAMETERS ENDSДалее создадим три процедуры Init_Direct3D, Destroy_Direct3D и Render_Scene
итак Init_Direct3D
Создаем обьект Direct3D8:
Код (Text):
invoke Direct3DCreate8, D3D_SDK_VERSION mov pd3d, eaxСправка
Код (Text):
Direct3DCreate8 передается в качестве параметра версия SDK. Метод возвращает указатель на обьект если все прошло успешно. Если ошибка, то в EAX возвращается код ошибки, какой именно я не знаю :( ( возможно 0 )Затем мы получаем информацию о текущих параметрах экрана:
Код (Text):
d3d8 GetAdapterDisplayMode, pd3d, D3DADAPTER_DEFAULT, ADDR d3ddmСправка
Код (Text):
1. Номер видеоадаптера. D3DADAPTER_DEFAULT - всегда главный адаптер ( под номером 0 ) можно вставить цифру нужного адаптера если в системе их несколько 2. Указатель на структуру параметров экрана ( см. выше ) Возвращает в случае успеха D3D_OK. Если нет то D3DERR_INVALIDCALL - недействительный вызов.Заполняем только те поля структуры которые нам необходимы:
Код (Text):
mov d3dpp.Windowed, TRUE ; Работаем в окошке mov d3dpp.SwapEffect, D3DSWAPEFFECT_FLIP ; Будем менять буфера mov eax, d3ddm.Format ; Берем формат экрана mov d3dpp.BackBufferFormat, eax ; Сохраняем в структуреА сейчас делаем самое главное ! Создаем устройство Direct3DDevice8.
Создавать Direct3DDevice в сообщении WM_Create нельзя ! ( проверено опытным путем ) То же самое можно найти в документации по Direct3D8.
CreateDevice мы должны передать hwnd полностью созданного окна на экране которое находится в фокусе.
Код (Text):
d3d8 CreateDevice, pd3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd , \ D3DCREATE_HARDWARE_VERTEXPROCESSING, ADDR d3dpp, ADDR pd3dDeviceСправка
Код (Text):
1. Номер видеоадаптера. D3DADAPTER_DEFAULT - всегда главный адаптер ( под номером 0 ) можно вставить цифру нужного адаптера если в системе их несколько. 2. Тип устройства рендеринга. D3DDEVTYPE_HAL - аппаратный рендеринг. D3DDEVTYPE_REF - програмный рендеринг. 3. Hwnd - ID нашего окошка. 4. Комбинация флагов. D3DCREATE_FPU_PRESERVE - нам нужна двойная точность вычисления с плавающей запятой. D3DCREATE_HARDWARE_VERTEXPROCESSING - аппаратная обработка вершин D3DCREATE_SOFTWARE_VERTEXPROCESSING - программная обработка вершин D3DCREATE_MIXED_VERTEXPROCESSING - аппаратная + программная обработка вершин D3DCREATE_MULTITHREADED - многопоточность приложения ( direct3D создает глобальный критический раздел это может привести к падению FPS ) D3DCREATE_PUREDEVICE - не поддерживать Get вызовы. Также не обеспечивать эмуляцию каких- либо сервисов связанных с Vertex processing. Имеется в виду что если устройство не поддерживает vertex processing тогда приложение может использовать только post трансформацию вершин. D3DCREATE_DISABLE_DRIVER_MANAGEMENT - D3D будет управлять ресурсами вместо драйвера. Флаги SOFTWARE_VERTEXPROCESSING, HARDWARE_VERTEXPROCESSING и MIXED_VERTEXPROCESSING недопустимы для совместного использования. 5. Указатель на структуру D3DPRESENT_PARAMETERS. ( см. выше ) 6. Адрес переменной куда будет помещен указатель на D3DDevice Возвращает в случае успеха D3D_OK. Если нет то D3DERR_INVALIDCALL - недействительный вызов, D3DERR_NOTAVAILABLE - устройством требуемое не поддерживается или D3DERR_OUTOFVIDEOMEMORY - не хватает видео памяти для данной операции.Теперь наше устройство создано и настало время написать функцию Render_Scene !
итак Render_Scene
Для простого примера применим очистку backbuffer`а цветом и показа его на экране:
Код (Text):
d3dev8 Clear, pd3dDevice, 0 , NULL , D3DCLEAR_TARGET, clearcolor, Zvalue, 0Справка
Код (Text):
1. Число структур прямоугольников в массиве. ( см. Параметр 2 ) 2. Указатель на массив структур прямоугольников. Каждый прямоугольник указывает какое место в поверхности рендеринга очищать. Если 0 то очищается вся поверхность. При этом в первом параметре тоже должен быть 0. 3. Комбинация флагов. D3DCLEAR_STENCIL - очищать стенсель буфер стенсель значением. ( см.параметр 6 ) D3DCLEAR_TARGET - очищать поверхность рендеринга цветовым значением. ( см.параметр 4 ) D3DCLEAR_ZBUFFER - очищать Z буфер z значением. ( см.параметр 5 ) 4. Цветовое значение. 32bit-ное значение в формате ARGB 5. Z значение. Может быть в диапазоне от 0.0 до 1.0 ( для z основного или w основного буфера глубины ) 0.0 - ближняя гараница. 1.0 - дальняя граница. 6. Stencil значение. Может быть в диапазоне от 0 до 2^n-1 где n это глубина бит стенсель буфера. Возвращает в случае успеха D3D_OK. Если нет то D3DERR_INVALIDCALL, D3DERR_NOTAVAILABLE или D3DERR_OUTOFVIDEOMEMORY. ( расшифровку см. выше )А теперь все покажем этой функцией
Код (Text):
d3dev8 Present, pd3dDevice, NULL, NULL, NULL, NULLСправка
Код (Text):
1. Указатель на структуру источник типа RECT. Должно быть 0 если поверхности не были созданы с флагами D3DSWAPEFFECT_COPY и D3DSWAPEFFECT_COPY_VSYNC. 2. Указатель на структуру назначение типа RECT. Должно быть 0 если поверхности не были созданы с флагами D3DSWAPEFFECT_COPY и D3DSWAPEFFECT_COPY_VSYNC. 3. ID окошка куда показывать результат. Если мы указали его ранее в структуре D3DPRESENT_PARAMETERS, то здесь 0 4. Не используется и должен быть 0.Откомпилировав и запустив это приложение, вы увидите, что оно работает. Но это еще не все. После того как наше приложение будет закрыто, нам необходимо удалить все созданные нами интерфейсы и занятые ими ресурсы. Для этого создадим функцию Destroy_Direct3D.
итак Destroy_Direct3D
Код (Text):
d3dev8 Release, pd3dDevice ; Метод специально для Direct3DDevice8 d3d8 Release, pd3d ; Метод специально для Direct3D8На этом позволю себе откланяться. До следующих встреч !
Исходник прилагается.
PS
В следующем уроке мы рассмотрим запуск приложения в полноэкранном режиме, а также связанную с этим проблему потерянного устройства.
Авторство принадлежит Пономареву Михаилу ака keYMax. Все вопросы и ругательства слать по адресу mybox@aib.ru © keYMax
DirectX 8.1 в MASM32: Урок 1
Дата публикации 1 мар 2003