
Демонстрационная программа
Демонстрационная программа используя DirectXвыводитвертекс буфер моделичайника, как анимированное изображение.
Листинг
.586
.MMX
.XMM
.MODEL FLAT, STDCALL
OPTION CASEMAP:none
INCLUDE \Masm32\Include\windows.inc ; Структуры, константы ...
INCLUDE \Masm32\Include\kernel32.inc ;Системные функции приложения ...
INCLUDE \Masm32\Include\user32.inc ; Интерфейс ...
INCLUDE \Masm32\Include\gdi32.inc ; Графический вывод ...
INCLUDE \masm32\include\winmm.inc ; Функция timeGetTime
INCLUDELIB \Masm32\Lib\kernel32.lib
INCLUDELIB \Masm32\Lib\user32.lib
INCLUDELIB \Masm32\Lib\gdi32.lib
INCLUDELIB \masm32\lib\winmm.lib
INCLUDE \masm32\Dxsdk90\Include\2005_jun\d3d9_all.inc
INCLUDELIB \masm32\Dxsdk90\lib\2005_jun\d3d9.lib
INCLUDELIB \masm32\Dxsdk90\lib\2005_jun\d3dx9.lib ; Подключение D3DX функций (динамическая библиотека)
;ПРОТОТИПЫ ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Init_Direct3D PROTO ; Текст этих функций можно найти ниже
Destroy_Direct3D PROTO
Set_Render_Parameters PROTO
Init_Scene PROTO
Render_Scene PROTO
;==============================================================================
; Основная часть
;==============================================================================
.DATA ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
szClassName db "MyClass", 0
szAppName db "8-78-3 Baranov I.V.", 0
;WNDCLASSEX --------------------------------------------
cbSize dd 12*4
style dd CS_HREDRAW+CS_VREDRAW+20h
lpfnWndProc dd OFFSET WndProc
cbClsExtra dd 0
cbWndExtra dd 0
hInstance dd 400000h
hIcon dd 0
hCursor dd 0
hbrBackground dd BLACK_PEN
lpszMenuName dd 0
lpszClassName dd OFFSET szClassName
hIconSm dd 0
;Сообщения об ошибках ----------------------------------
szDirect3D9 db "Не удалось создать обьект Direct3D9",9,9,0
szD3DDevice9 db "Не удалось создать устройство Direct3D9",9,0
.DATA? ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
msg MSG <>
hwnd HWND ?
clientwindow RECT <>
.CONST ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
WIN_X EQU 640 ; Размер окна по горизонтали
WIN_Y EQU 480 ; Размер окна по вертикали
.CODE ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke LoadCursor, NULL, IDC_ARROW
mov hCursor, eax
invoke RegisterClassEx, ADDR cbSize
invoke GetSystemMetrics, SM_CXSCREEN
push eax
invoke GetSystemMetrics, SM_CYSCREEN
sub eax, WIN_Y
shr eax, 1
pop ebx
sub ebx, WIN_X
shr ebx, 1
invoke CreateWindowEx, NULL, ADDR szClassName, ADDR szAppName,\
WS_SYSMENU or WS_VISIBLE, \
ebx, eax, WIN_X, WIN_Y, NULL, NULL, hInstance, NULL
mov hwnd, eax
invoke GetClientRect, eax, ADDR clientwindow
invoke Init_Direct3D ; Создаем устройство
msg_loop:
invoke PeekMessageA, ADDR msg, 0 , 0 , 0 , PM_REMOVE ;
test eax, eax ;
jne message ; Если у окна нет сообщений...
;
invoke Render_Scene ; ... то отрисовывается сцена
jmp msg_loop ;
;
message: ;
mov eax, DWORD PTR msg.message ;
cmp eax, WM_QUIT ;
je end_loop ;
;
invoke TranslateMessage, ADDR msg ;
invoke DispatchMessage, ADDR msg ;
jmp msg_loop
end_loop:
mov eax, msg.wParam ; Если цикл обработки сообщений прерван,
; то код выхода из программы передается в поле wParam
Exit: ; сообщения MSG.
invoke ExitProcess, eax
ret
;==============================================================================
WndProc proc hWnd:HWND , uMsg:UINT, wParam:WPARAM, lParam:LPARAM
;==============================================================================
cmp uMsg, WM_CREATE ; Это сообщение посылается окну, когда оно создается
je wmCreate
cmp uMsg, WM_DESTROY ; Это сообщение посылается окну, когда оно должно быть уничтожено.
je wmDestroy
cmp uMsg, WM_KEYDOWN ; Это сообщение посылается окну, когда нажали клавишу на клавиатуре.
je wmKeydown
invoke DefWindowProc, hWnd, uMsg, wParam, lParam ; Если Мы НЕ ХОТИМ обрабатывать полученное сообщение, то
ret ; нам надо вызвать DefWindowProc с параметрами, которые Мы получили.
; Эта функция API обрабатывает не интересующие Нас события.
wmDestroy: ;------------------------------------------
invoke Destroy_Direct3D
invoke PostQuitMessage, NULL
xor eax,eax
ret
wmCreate: ;------------------------------------------
xor eax, eax
ret
wmKeydown: ;------------------------------------------
mov eax, wParam
cmp eax, VK_ESCAPE
jne noExit
invoke SendMessage, hwnd , WM_CLOSE , NULL, NULL
noExit:
xor eax, eax
ret
WndProc endp
;==============================================================================
; Начинается работа с Direct3D
;==============================================================================
Init_Direct3D proc ; Создавать Direct3DDevice в сообщении WM_Create нельзя !
.DATA
;D3DPRESENT_PARAMETERS ------------------------------------------
BackBufferWidth dd 640 ; Ширина BackBuffer
BackBufferHeight dd 480 ; Высота BackBuffer
BackBufferFormat dd D3DFMT_X8R8G8B8 ; Формат используемой поверхности
BackBufferCount dd 3 ; число Back буферов.
MultiSampleType dd 0 ; уровни мультисэмплинга картинки. (обычно от 2-ух и выше)
MultiSampleQuality dd 0 ;
SwapEffect dd D3DSWAPEFFECT_FLIP ; Эффект обмена поверхностей (BackBuffer)
hDeviceWindow dd 0 ; ID нашего окошка
Windowed dd 1 ; 0 - полноэкранный, 1 - в окошке
EnableAutoDepthStencil dd TRUE ; 1 - Direct3D создает Z + Stencil буфер. Если 0 - ничего не будет создано
AutoDepthStencilFormat dd D3DFMT_D24S8 ; Формат используемой поверхности
Flags dd 1 ; 0 или D3DPRESENTFLAG_LOCKABLE_BACKBUFFER=1
FullScreen_RefreshRateInHz dd 0 ; Частота обновления экрана в Hz
FullScreen_PresentationInterval dd 1 ; Интервал показа на экране backbufferа. 1 = Ждать обратного хода луча
.DATA?
pd3d dd ? ; или LPDIRECT3D9 (указатель на Direct3D9)
pd3dDevice dd ? ; или LPDIRECT3DDEVICE9 (указатель на Direct3DDevice)
.CODE
invoke Direct3DCreate9,D3D_SDK_VERSION
mov pd3d, eax
test eax, eax
jnz @F
push OFFSET szDirect3D9
jmp Error_Message
@@:
push clientwindow.right
pop BackBufferWidth
push clientwindow.bottom
pop BackBufferHeight
d3d9 CreateDevice, pd3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd ,\
D3DCREATE_SOFTWARE_VERTEXPROCESSING, \
ADDR BackBufferWidth, ADDR pd3dDevice
test eax, eax ; Если возникла ошибка при создании устройства
jz @F
push OFFSET szD3DDevice9
jmp Error_Message
@@:
invoke Init_Scene
invoke Set_Render_Parameters
ret
Init_Direct3D endp
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Destroy_Direct3D proc
mov eax,a_PS
test eax, eax
;jz @F
d3dev9 Release, eax
mov eax,c_PS
test eax, eax
;jz @F
d3dev9 Release, eax
mov eax,a_VS
test eax, eax
;jz @F
d3dev9 Release, eax
mov eax,c_VS
test eax, eax
;jz @F
d3dev9 Release, eax
mov eax,TeapotP
test eax, eax
;jz @F
mov eax,BackBufferP
test eax, eax
;jz @F
mov eax,pd3dDevice
test eax, eax
;jz @F
d3dev9 Release, eax
mov eax,pd3d
test eax, eax
;jz @F
d3dev9 Release, eax
ret
Destroy_Direct3D endp
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Init_Scene proc
.DATA
EyeVector D3DVECTOR <0.0f, -300.0f, 100.0f> ; Координаты камеры в пространстве
LookAtVector D3DVECTOR <0.0f,0.0f, 0.0f> ; Указывает куда смотрит камера
UpVector D3DVECTOR <0.0f, 1.0f, 0.0f> ; Верх камеры. Обычно берется 0.0,1.0,0.0
FieldOfView dd 0.7853981635f
AspectRatio dd NULL ; AspectRatio
NearViewPlanZ dd 1.0f ; Передняя отсекающая плоскость
FarViewPlanZ dd 10000.0f ; Задняя отсекающая плоскость
Teapot db "model\Teapot.x", 0
f_VS db "shaders\VS_01.txt", 0
f_PS db "shaders\PS_01.txt", 0
.DATA?
m_VS1 D3DXMATRIX <?>
WorldMatrix D3DMATRIX <?> ; Мировая матрица
ViewMatrix D3DMATRIX <?> ; Матрица вида
ProjectionMatrix D3DMATRIX <?> ; Матрица проекции
BackBufferP LPDIRECT3DSURFACE9 ?
TeapotP dd ?
TeapotPT dd ?
TeapotPB dd ?
TeapotP_VB dd ?
TeapotP_IB dd ?
TeapotP_NV dd ?
TeapotP_NF dd ?
a_VS LPD3DXBUFFER ?
b_VS dd ?
c_VS LPDIRECT3DVERTEXSHADER9 ?
a_PS LPD3DXBUFFER ?
b_PS dd ?
c_PS LPDIRECT3DVERTEXSHADER9 ?
.CODE
fild BackBufferWidth ; Вычисление Aspect (можно просто сразу поместить 1.33(3)f)
fild BackBufferHeight
fdiv
fstp AspectRatio
invoke D3DXMatrixRotationY, ADDR WorldMatrix, NULL ;World Matrix (мировая матрица)
invoke D3DXMatrixLookAtLH, ADDR ViewMatrix, ADDR EyeVector, \ ;View Matrix (матрица вида)
ADDR LookAtVector, ADDR UpVector
invoke D3DXMatrixPerspectiveFovLH, ADDR ProjectionMatrix, FieldOfView,\ ;Matrix Projection (матрица проекции)
AspectRatio, NearViewPlanZ, FarViewPlanZ
; начальная загрузка
invoke D3DXLoadMeshFromXA, addr Teapot, D3DXMESH_DYNAMIC,pd3dDevice, 0, 0, NULL, 0,addr TeapotP
d3dxmesh GetFVF,TeapotP
mov TeapotPT,eax
d3dxmesh GetNumBytesPerVertex,TeapotP
mov TeapotPB,eax
d3dxmesh GetVertexBuffer,TeapotP, addr TeapotP_VB
d3dxmesh GetIndexBuffer,TeapotP, addr TeapotP_IB
d3dxmesh GetNumVertices,TeapotP
mov TeapotP_NV,eax
d3dxmesh GetNumFaces,TeapotP
mov TeapotP_NF,eax
invoke D3DXAssembleShaderFromFileA, addr f_VS, 0, 0, D3DXSHADER_DEBUG, addr a_VS,0
d3dxbuf GetBufferPointer,a_VS
mov b_VS,eax
d3dev9 CreateVertexShader, pd3dDevice,b_VS ,addr c_VS
invoke D3DXAssembleShaderFromFileA, addr f_PS, 0, 0, D3DXSHADER_DEBUG, addr a_PS,0
d3dxbuf GetBufferPointer,a_PS
mov b_PS,eax
d3dev9 CreatePixelShader, pd3dDevice,b_PS ,addr c_PS
ret
Init_Scene endp
Set_Render_Parameters proc
.CODE
d3dev9 SetRenderState, pd3dDevice, D3DRS_CULLMODE, D3DCULL_NONE
d3dev9 SetRenderState, pd3dDevice, D3DRS_ZENABLE,D3DZB_TRUE
d3dev9 SetSamplerState, pd3dDevice, 0, D3DSAMP_MIPFILTER,D3DTEXF_ANISOTROPIC
d3dev9 SetSamplerState, pd3dDevice, 0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC
d3dev9 SetSamplerState, pd3dDevice, 0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC
d3dev9 SetSamplerState, pd3dDevice, 1, D3DSAMP_MIPFILTER,D3DTEXF_ANISOTROPIC
d3dev9 SetSamplerState, pd3dDevice, 1, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC
d3dev9 SetSamplerState, pd3dDevice, 1, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC
d3dev9 SetSamplerState, pd3dDevice, 2, D3DSAMP_MIPFILTER,D3DTEXF_ANISOTROPIC
d3dev9 SetSamplerState, pd3dDevice, 2, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC
d3dev9 SetSamplerState, pd3dDevice, 2, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC
ret
Set_Render_Parameters endp
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Render_Scene proc
.DATA
Zvalue dd 1.0f ; Значение для очистки Z буфера
Clearcolor dd 0 ; Цвет для очистки BackBuffer'а
.DATA?
.CODE
d3dev9 TestCooperativeLevel, pd3dDevice ; Проверка кооперации
cmp eax, D3DERR_DEVICELOST ; Если устройство потеряно то выход
jne noreset ;
ret ;
noreset: ;
cmp eax, D3DERR_DEVICENOTRESET ; Если устройство не потеряно и не сброшено то сбрасываем
jne noreset2 ;
d3dev9 Reset, pd3dDevice, ADDR BackBufferWidth ;
invoke Set_Render_Parameters
noreset2:
d3dev9 BeginScene, pd3dDevice
d3dev9 SetRenderTarget,pd3dDevice,0, BackBufferP
d3dev9 Clear, pd3dDevice, 0, NULL, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER,Clearcolor, Zvalue, 0 ; Очистка BackBuffer'а и Z-буфера
invoke D3DXMatrixMultiply, ADDR m_VS1 , ADDR WorldMatrix, ADDR ViewMatrix
invoke D3DXMatrixMultiply, ADDR m_VS1, ADDR m_VS1, ADDR ProjectionMatrix
invoke D3DXMatrixTranspose , ADDR m_VS1, ADDR m_VS1
d3dev9 SetVertexShader,pd3dDevice,c_VS
d3dev9 SetPixelShader,pd3dDevice,c_PS
d3dev9 SetVertexShaderConstantF,pd3dDevice,0, addr m_VS1 , 4 ;c0
d3dev9 SetFVF, pd3dDevice, TeapotPT
d3dev9 SetStreamSource, pd3dDevice, 0 , TeapotP_VB, 0, TeapotPB
d3dev9 SetIndices, pd3dDevice, TeapotP_IB
d3dev9 DrawIndexedPrimitive, pd3dDevice, D3DPT_TRIANGLELIST,0,0,TeapotP_NV,0,TeapotP_NF
d3dev9 EndScene, pd3dDevice
; Анимируем сцену
.DATA
RotZ dd 0.0f
Prib dd 0.01f
.CODE
fld RotZ
fadd Prib
fstp RotZ
invoke D3DXMatrixRotationZ, ADDR WorldMatrix, RotZ
d3dev9 Present, pd3dDevice, NULL, NULL, NULL, NULL ; Вывод BackBuffer'а на экран
ret
Render_Scene endp
Error_Message: ; Вывод сообщения об ошибке и завершение работы приложения
mov eax, DWORD PTR [esp]
invoke MessageBox, hwnd, eax, ADDR szAppName, MB_ICONERROR
pop eax
invoke Destroy_Direct3D
jmp Exit
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
end Start