asm 调用 d3d例子(二)

整理资源时发现的,大约3年多前,正好有段时间比较空,于是用asm调用d3d,实现了directx9.x的sdk附带的几个例子,使用masm32编译。

第二个例子,光照(对应d3d的sdk例子light)。

下面是源代码:

.586
.model flat,stdcall
option casemap:none

  include windows.inc
  include d3d9.inc
   include d3dx9.inc
   include winuser.INC

   includelib user32.lib
   includelib kernel32.lib
   includelib gdi32.lib
   includelib d3d9.lib
   includelib d3dx9d.lib
   includelib libc.lib
   includelib winmm.lib

 fpc4 MACRO val:REQ
 	;LOCAL x :DWORD
 	;fld val
 	;fstp x
 	exitm 
 endm  

WinMain proto :HINSTANCE,:HINSTANCE,:LPSTR,:DWORD
Init proto :HWND
Destroy proto
GameProc proto :HWND
Render proto
MemCopy proto Source:PTR BYTE,Dest:PTR BYTE,ln:DWORD
SetupMatrices proto
SetupLights proto
D3DXMatrixIdentity proto pOut: ptr D3DXMATRIX
Error proto

CUSTOMVERTEX struct
	position D3DXVECTOR3 <>
	normal D3DXVECTOR3 <>
CUSTOMVERTEX ends

D3DFVF_CUSTOMVERTEX EQU D3DFVF_XYZ or D3DFVF_NORMAL

.data
   ClassName db "MainWinClass",0
   AppName  db "Main Window",0
 ERRORTXT db "error", 0
   errorflag db 0

   PI2 DD   6.2831854e-3
   F1000 dd 1000.0
   PIDIV4 FLOAT 0.785398163
   F1_0 REAL4 1.0
   F0_0 REAL4 0.0
   F100_0 REAL4 100.0
   F350_0 REAL4 350.0
   F1000_0 REAL4 1000.0
   FPI2  REAL4  6.2831855
   F1P_49 REAL4  2.0408163e-2
   F_1_0 REAL4 -1.0
   F500_0 REAL4 500.0
.data?
   hInstance HINSTANCE ?
   pDevice LPDIRECT3DDEVICE9 ?
   d3dpp D3DPRESENT_PARAMETERS <>
   g_pD3D LPDIRECT3D9 ?
   g_pVB LPDIRECT3DVERTEXBUFFER9 ?
.code

start:
	invoke GetModuleHandle, NULL
	mov    hInstance,eax
	invoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULT
	invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
	LOCAL wc:WNDCLASSEX
	LOCAL msg:MSG
	LOCAL hwnd:HWND
	mov   wc.cbSize,SIZEOF WNDCLASSEX
	mov   wc.style, CS_HREDRAW or CS_VREDRAW
	mov   wc.lpfnWndProc, OFFSET WndProc
	mov   wc.cbClsExtra,NULL
	mov   wc.cbWndExtra,NULL
	push  hInstance
	pop   wc.hInstance
	mov   wc.hbrBackground,COLOR_BTNFACE+1
	mov   wc.lpszMenuName,NULL
	mov   wc.lpszClassName,OFFSET ClassName

	invoke LoadIcon,NULL,IDI_APPLICATION
	mov   wc.hIcon,eax
	mov   wc.hIconSm,eax

	invoke LoadCursor,NULL,IDC_ARROW
	mov   wc.hCursor,eax

	invoke RegisterClassEx, addr wc
	INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
           hInst,NULL
	mov   hwnd,eax
	invoke Init, hwnd
	invoke ShowWindow, hwnd,SW_SHOWNORMAL
	invoke UpdateWindow, hwnd

	.WHILE TRUE
		invoke PeekMessage, ADDR msg,NULL,0,0,PM_REMOVE
		.BREAK .IF (msg.message == WM_QUIT )
		.if( eax )
		invoke TranslateMessage, ADDR msg
		invoke DispatchMessage, ADDR msg
		.else
		invoke Render
		.endif
	.ENDW
	invoke Destroy
	mov     eax,msg.wParam
	ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

	.IF uMsg==WM_DESTROY
		invoke PostQuitMessage,NULL
	.ELSE
		invoke DefWindowProc,hWnd,uMsg,wParam,lParam
		ret
	.ENDIF

	xor eax,eax
	ret
WndProc endp
Error proc
mov errorflag, 1
	invoke MessageBox,NULL,addr ERRORTXT,addr ERRORTXT,MB_OK
		invoke Destroy

	ret

Error endp

LPCUSTOMVERTEX typedef ptr CUSTOMVERTEX
Init proc hwnd:HWND
LOCAL pVertices :LPCUSTOMVERTEX
LOCAL theta :REAL4
LOCAL i :DWORD
LOCAL temp :DWORD
LOCAL Vertices :CUSTOMVERTEX
	invoke  Direct3DCreate9, D3D_SDK_VERSION
	.IF eax == 0
		jmp error
	.endif
	mov g_pD3D, eax
	invoke ZeroMemory, addr d3dpp, sizeof d3dpp
	mov d3dpp.BackBufferFormat, D3DFMT_UNKNOWN
	mov eax, hwnd
	mov d3dpp.hDeviceWindow, eax
	mov d3dpp.Windowed, TRUE
	mov d3dpp.SwapEffect, D3DSWAPEFFECT_DISCARD
	mov d3dpp.EnableAutoDepthStencil, TRUE
	mov d3dpp.AutoDepthStencilFormat, D3DFMT_D16
	invoke vf(g_pD3D, IDirect3D9, CreateDevice), D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, \
				D3DCREATE_SOFTWARE_VERTEXPROCESSING, offset d3dpp, offset pDevice
	.if FAILED(eax)
		jmp error
	.endif
	invoke vf( pDevice, IDirect3DDevice9, SetRenderState ), D3DRS_CULLMODE, D3DCULL_NONE
	invoke vf( pDevice, IDirect3DDevice9, SetRenderState ), D3DRS_ZENABLE, TRUE
	invoke vf( pDevice, IDirect3DDevice9, CreateVertexBuffer), 50*2*sizeof CUSTOMVERTEX ,\
                                                  0, D3DFVF_CUSTOMVERTEX,\
                                                  D3DPOOL_DEFAULT, addr g_pVB, NULL
        .if( FAILED(eax ) )
        	jmp error
        .endif
        mov pVertices, 0
        invoke vf( g_pVB,IDirect3DVertexBuffer9, Lock_ ), 0, 0, addr pVertices, 0
        .if( FAILED( eax ) )
        	jmp error
        .endif
        ; 添加定点数据
        mov i, 0
        mov temp, 0
        mov eax, pVertices
        assume eax : ptr CUSTOMVERTEX
        .repeat
        	fld FPI2
        	fimul temp
        	fmul F1P_49
        	mov edx, i
        	fstp theta
        	fld theta
        	fcos
        	fld st(0)
        	fld st(0)
        	fld st(0)
        	fstp [eax + edx].position.z
        	fstp [eax + edx].normal.z
        	fstp [eax + edx+ sizeof CUSTOMVERTEX].position.z
        	fstp [eax + edx + sizeof CUSTOMVERTEX].normal.z
        	fld theta
        	fsin
        	fld st(0)
        	fld st(0)
        	fld st(0)
        	fstp [eax + edx].position.x
        	fstp [eax + edx].normal.x
        	fstp [eax + edx+sizeof CUSTOMVERTEX].position.x
        	fstp [eax + edx+sizeof CUSTOMVERTEX].normal.x
        	fld F_1_0
        	fstp [eax + edx].position.y
        	fld1
        	fstp [eax + edx + sizeof CUSTOMVERTEX].position.y
        	fldz
        	fstp [eax + edx].normal.y
        	fldz
        	fstp [eax + edx+sizeof CUSTOMVERTEX].normal.y
        	add i, sizeof CUSTOMVERTEX*2
        	add temp, 1
  	.until	i == 50*2*sizeof CUSTOMVERTEX

        invoke vf( g_pVB, IDirect3DVertexBuffer9, Unlock )
	ret
	error:
	;mov errorflag, 1
	;invoke MessageBox,hwnd,addr ERRORTXT,addr ERRORTXT,MB_OK
		invoke Error
		ret
Init endp

Destroy proc
	.if( g_pVB )
		invoke vf( g_pVB, IDirect3DVertexBuffer9, Release )
	.endif
	.if( pDevice )
		invoke vf( pDevice, IUnknown, Release)
	.endif
	.if( g_pD3D )
		invoke vf( g_pD3D, IUnknown, Release)
	.endif
	ret
Destroy endp
GameProc proc hwnd:HWND
	ret
GameProc endp
Render proc
	.if errorflag != 0
		ret
	.endif
	invoke vf( pDevice, IDirect3DDevice9, Clear), 0, NULL, D3DCLEAR_TARGET+2, D3DCOLOR_XRGB(0,0,251), F1_0, 0
	invoke vf( pDevice, IDirect3DDevice9, BeginScene )
	.if FAILED( eax )
		invoke Error
		ret
	.endif
	invoke SetupLights
	invoke SetupMatrices
	invoke vf( pDevice, IDirect3DDevice9, SetStreamSource), 0, g_pVB, 0, sizeof CUSTOMVERTEX
        invoke vf( pDevice, IDirect3DDevice9, SetFVF), D3DFVF_CUSTOMVERTEX
        invoke vf( pDevice, IDirect3DDevice9, DrawPrimitive), D3DPT_TRIANGLELIST+1, 0, 2*50-2
	invoke vf( pDevice, IDirect3DDevice9, EndScene )
	invoke vf( pDevice, IDirect3DDevice9, Present ), NULL, NULL, NULL, NULL
	ret

Render endp
comment *
MemCopy proc Source:PTR BYTE,Dest:PTR BYTE,ln:DWORD

    ; ---------------------------------------------------------
    ; Copy ln bytes of memory from Source buffer to Dest buffer
    ;      ~~                      ~~~~~~           ~~~~
    ; USAGE:
    ; invoke MemCopy,ADDR Source,ADDR Dest,4096
    ;
    ; NOTE: Dest buffer must be at least as large as the source
    ;       buffer otherwise a page fault will be generated.
    ; ---------------------------------------------------------
    cld
    mov esi, [Source]
    mov edi, [Dest]
    mov ecx, [ln]
    shr ecx, 2
    rep movsd
    mov ecx, [ln]
    and ecx, 3
    rep movsb
    ret

MemCopy endp
*
;comment end

SetupMatrices proc
	LOCAL matWorld: D3DXMATRIX
	LOCAL iTime:DWORD
	LOCAL fAngle:REAL4
	LOCAL matProj: D3DXMATRIX
	LOCAL matView: D3DXMATRIX
	LOCAL tvEyePt:D3DXVECTOR3
	LOCAL tvLookatPt:D3DXVECTOR3
	LOCAL tvUpVec:D3DXVECTOR3
	invoke D3DXMatrixIdentity, addr matWorld
	invoke timeGetTime
	mov fAngle, eax
	fild fAngle
	fdiv F500_0
	fstp fAngle
	;tvEyePt.x = 1.0
	fld vEyePt.x
	fstp tvEyePt.x
	fld vEyePt.y
	fstp tvEyePt.y
	fld vEyePt.z
	fstp tvEyePt.z
	fld vLookatPt.x
	fstp tvLookatPt.x
	fld vLookatPt.y
	fstp tvLookatPt.y
	fld vLookatPt.z
	fstp tvLookatPt.z
	fld vUpVec.x
	fstp tvUpVec.x
	fld vUpVec.y
	fstp tvUpVec.y
	fld vUpVec.z
	fstp tvUpVec.z
	invoke D3DXMatrixRotationX, addr matWorld, fAngle
	invoke vf( pDevice, IDirect3DDevice9, SetTransform ),D3DTS_WORLD-4, addr matWorld
	invoke D3DXMatrixLookAtLH, addr matView, addr tvEyePt, addr tvLookatPt, addr tvUpVec
	invoke vf( pDevice, IDirect3DDevice9, SetTransform ), D3DTS_VIEW, addr matView
	invoke D3DXMatrixPerspectiveFovLH, addr matProj, PIDIV4, F1_0,F1_0,F100_0
	invoke vf( pDevice, IDirect3DDevice9, SetTransform ), D3DTS_PROJECTION, addr matProj
	ret
SetupMatrices endp
SetupLights proc
	LOCAL mtrl :D3DMATERIAL9
	LOCAL vecDir :D3DVECTOR
	LOCAL light :D3DLIGHT9
	invoke ZeroMemory, addr mtrl, sizeof D3DMATERIAL9
	fld1
	fld1
	fld1
	fld1
	fld1
	fld1
	fstp mtrl.Ambient.r
	fstp mtrl.Diffuse.r
	fstp mtrl.Diffuse.g
	fstp mtrl.Ambient.g
	fstp mtrl.Ambient.a
	fstp mtrl.Ambient.a
	invoke vf( pDevice, IDirect3DDevice9, SetMaterial ), addr mtrl
	invoke ZeroMemory, addr light, sizeof D3DLIGHT9
	mov light.Type_, D3DLIGHT_DIRECTIONAL
	fld1
	fld1
	fld1
	fstp  light.Diffuse.r
	fstp  light.Diffuse.g
	fstp  light.Diffuse.b
	invoke timeGetTime
	mov vecDir.x, eax
	fld vecDir.x
	fdiv F350_0
	fcos
	fstp vecDir.x
	fld1
	fstp vecDir.y
	invoke timeGetTime
	mov vecDir.z, eax
	fld vecDir.z
	fdiv F350_0
	fsin
	fstp vecDir.z
	invoke D3DXVec3Normalize, addr light.Direction, addr vecDir
	fld F1000_0
	fstp light.Range
	invoke vf( pDevice, IDirect3DDevice9, SetLight ), 0, addr light
	invoke vf( pDevice, IDirect3DDevice9, LightEnable ), 0, TRUE
	invoke vf( pDevice, IDirect3DDevice9, SetRenderState ), D3DRS_LIGHTING, TRUE
	invoke vf( pDevice, IDirect3DDevice9, SetRenderState ), D3DRS_AMBIENT, 202020h
	ret
vEyePt  D3DVECTOR <0.0, 3.0,-5.0>
vLookatPt  D3DVECTOR <0.0, 0.0, 0.0>
vUpVec  D3DVECTOR <0.0, 1.0, 0.0>
SetupLights endp

D3DXMatrixIdentity proc pOut: ptr D3DXMATRIX
	invoke ZeroMemory, pOut, sizeof D3DXMATRIX
	fld1
	fld1
	fld1
	fld1
	fstp [pOut][0][0]
	fstp [pOut][1][1]
	fstp [pOut][2][2]
	fstp [pOut][3][3]
	ret
D3DXMatrixIdentity endp	

end start
发布日期:
分类:程序

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据