Ich habe gerade angefangen mit der D3D (DirectX) Bibliothek von Autoit zu arbeiten. Dabei habe ich das Problem, dass das Programm bei der Funktion _jump, welche ich hinzufügte, jedesmal das Fenster weggeht und kurze Zeit später das Programm abschmiert...
Ich vermute, dass das an einem Dateitypfehler liegt. 0 (int) und 0.0 (float/double) macht allerdings keinen Unterschied... es schmiert bei beidem ab.
In der Konsole erscheint keine Fehlermeldung.
Link zur D3D-Bibliothek:
Spoiler anzeigen
Spoiler anzeigen
#include "Camera.au3"
#include "Terrain.au3"
#include <GUIConstantsEx.au3>
#include <Misc.au3>
#include <WindowsConstants.au3>
Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
global $nHeightSave=0,$oFont,$pFont,$pDevice,$tFontDesc,$jump=-1.0,$jumpUp=true
[/autoit] [autoit][/autoit] [autoit];Local Const $sHMapfile = "test2.raw"
;Local Const $sTerrainTex = "test2_texture.png"
Local Const $sHMapfile = ".\..\..\Media\map128.raw"
Local Const $sTerrainTex = ".\..\..\Media\background.jpg"
; Weight modifier used by the weighted averaging of the mouse movement history array
; As the modifier value increases, the camera gets rotated smoothly but takes longer to rotate to the target.
Local Const $nWeightModifier = 0.3
Local Const $iWidth = @DesktopWidth, $iHeight = @DesktopHeight
;Local Const $iWidth = 640, $iHeight = 480
Local Const $iCenterX = $iWidth/2, $iCenterY = $iHeight/2
; Camera mouse movement sensitivity. Decrease for faster scroll, increase for slower, yet more accurate scroll..
Local Const $nSensitivity = 100
Local $hGUI = GUICreate("Direct3D9 - Terrain", $iWidth, $iHeight)
Local $pDevice, $oDevice
; Offset to the window's center from the screen left-top
Local $iWndCenterX, $iWndCenterY
; History array used to hold last X mouse movement deltas,
; so we can use smooth mouse filtering. Smooth mouse filtering reduces
; the jerky motion of the camera caused by the native jerky mouse movement
Local $aHistory[10][2]
; Camera and terrain objects
Local $tCamera, $tTerrain
; Direction to light holds the opposite vector of the light dir
; so if we're lighting our terrain with a source of light [0, -1, 0] or downward,
; the direction to light should be [0, 1, 0] or upward.
Local $tDirToLight
; Terrain texturing switch
Local $fSwitch
_D3D_Startup()
; Check if failed to load necessary dlls
If @error Then
If @error = 1 Then
Exit MsgBox(0x10, "Error", 'Could not load "d3d9.dll"')
Else
Exit MsgBox(0x10, "Error", 'Could not load "d3dx9_36.dll"')
EndIf
EndIf
$pDevice = _D3D_Init($hGUI, $iWidth, $iHeight)
$oDevice = _AutoItObject_WrapperCreate($pDevice, $tagIDirect3DDevice9)
_Setup()
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
; Change terrain texturing using spacebar
GUIRegisterMsg($WM_KEYDOWN, "_WM_KEYDOWN")
OnAutoItExitRegister("_Cleanup")
GUISetState()
While 1
_Render()
_HighPrecisionSleep(8000)
WEnd
Func _Render()
; Allow user to update the camera view
Local $iRunFactor, $aDeltas, $tCameraPos, $nHeight, $tView, $tWorld,$walk=-1,$Strafe=-1
; Left shift to run
If _IsPressed("A0") Then $iRunFactor = 0.5
If _IsPressed("57") Then ; W - move forward
_CameraWalk($tCamera, 0.7 + $iRunFactor)
$walk=0.7 + $iRunFactor
ElseIf _IsPressed("53") Then ; S - move backward
_CameraWalk($tCamera, -0.7 - $iRunFactor)
$walk=-0.7 - $iRunFactor
EndIf
If _IsPressed("41") Then ; A - move leftward
_CameraStrafe($tCamera, -0.7 - $iRunFactor)
$Strafe=-0.7 - $iRunFactor
ElseIf _IsPressed("44") Then ; S - move rightward
_CameraStrafe($tCamera, 0.7 + $iRunFactor)
$Strafe=0.7 + $iRunFactor
EndIf
if _IsPressed(31) then
AdlibRegister("_jump",100)
endif
$aDeltas = _MouseSmoothFilter($aHistory)
[/autoit] [autoit][/autoit] [autoit]_CameraYaw ($tCamera, $aDeltas[0] / $nSensitivity)
_CameraPitch($tCamera, $aDeltas[1] / $nSensitivity)
If IsDllStruct($tTerrain) Then
_CameraGetPos($tCamera, $tCameraPos)
$nHeight = _TerrainGetHeight($tTerrain, DllStructGetData($tCameraPos, "x"), DllStructGetData($tCameraPos, "z"))
if Abs($nHeight-$nHeightSave)<1 or ($nHeightSave=0 and DllStructGetData($tCameraPos, "x")=0.0 and DllStructGetData($tCameraPos, "z")=0.0) then
$nHeightSave=$nHeight
DllStructSetData($tCameraPos, "y", $nHeight + 5)
_CameraSetPos($tCamera, $tCameraPos)
else
if $walk<>-1 then
_CameraWalk($tCamera,-$walk)
endif
if $Strafe<>-1 then
_CameraStrafe($tCamera,-$Strafe)
endif
endif
EndIf
; Get the camera view matrix
$oDevice.SetTransform("long", "int", $D3DTS_VIEW, "ptr", _CameraGetView($tCamera, $tView))
; Draw the scene, clear the depth and back buffers
$oDevice.Clear("long", "uint", 0, "ptr", 0, "uint", BitOR($D3DCLEAR_TARGET, $D3DCLEAR_ZBUFFER), "uint", 0xFF5D6FA2, "float", 1, "uint", 0)
$oDevice.BeginScene("long")
; Draw the text
; The first pointer argument should be a sprite object if we call the DrawTextW function more than once in a row
; The fifth argument specifies the format (DT_LEFT, DT_CALCRECT, etc..) and is the same as the GDI DrawText function format argument
;$oFont.DrawTextW("int", "ptr", 0, "wstr", int($nHeight), "int", -1, "ptr", $pRect, "uint", 0, "uint", 0xFF000000) ; black
If IsDllStruct($tTerrain) Then
_D3DX_MatrixIdentity($tWorld)
_TerrainDraw($tTerrain, $tWorld)
EndIf
$oDevice.EndScene("long")
$oDevice.Present("long", "ptr", 0, "ptr", 0, "hwnd", 0, "ptr", 0)
EndFunc
Func _jump()
if $jump=-1.0 then
$jump=0.1
local $tCameraPos
_CameraGetPos($tCamera, $tCameraPos)
$y=DllStructGetData($tCamera,"y")
_CameraFly($tCamera, $y+$jump)
elseif $jump=0.0 then
$jump=-1.0
$jumpUp=true
AdlibUnRegister("_jump")
elseif $jump<0.9 and $jumpUp then
$jump+=0.1
local $tCameraPos
_CameraGetPos($tCamera, $tCameraPos)
$y=DllStructGetData($tCamera, "y")
_CameraFly($tCamera, $y+$jump)
elseif $jump>0.9 then
$jumpUp=false
$jump=0.8
elseif $jump<0.9 and not $jumpUp then
$jump-=0.1
local $tCameraPos
_CameraGetPos($tCamera, $tCameraPos)
$y=DllStructGetData($tCamera, "y")
_CameraFly($tCamera, $y+$jump)
endif
EndFunc
Func _MouseSmoothFilter(ByRef $aMovement)
Local $aPos, $iDX, $iDY
; Get cursor position
$aPos = _GetCursorPos()
; Reset mouse position back to the center of the window
_SetCursorPos($iWndCenterX, $iWndCenterY)
$iDX = $aPos[0] - $iWndCenterX
$iDY = $aPos[1] - $iWndCenterY
_MousePerformFiltering($aMovement, $iDX, $iDY)
Return _MousePerformSmoothing($aMovement)
EndFunc
Func _MousePerformFiltering(ByRef $aMovement, $nDX, $nDY)
Local $aDeltas[2], $nAvgX, $nAvgY, $nAvgSum, $nCurrWeight = 1
; Update the arraw by pushing all elements of the array, thus the array contains the last X deltas
; where X is the size of the array
For $i = UBound($aMovement)-1 To 1 Step -1
$aMovement[$i][0] = $aMovement[$i - 1][0]
$aMovement[$i][1] = $aMovement[$i - 1][1]
Next
$aMovement[0][0] = $nDX
$aMovement[0][1] = $nDY
; Weighted average of deltas
For $i = 0 To UBound($aMovement)-1
$nAvgX += $aMovement[$i][0] * $nCurrWeight
$nAvgY += $aMovement[$i][1] * $nCurrWeight
$nAvgSum += $nCurrWeight
$nCurrWeight *= $nWeightModifier
Next
$aDeltas[0] = $nAvgX / $nAvgSum
$aDeltas[1] = $nAvgY / $nAvgSum
; Update the current mouse movement delta with the weighted delta
$aMovement[0][0] = $aDeltas[0]
$aMovement[0][1] = $aDeltas[1]
Return $aDeltas
EndFunc
Func _MousePerformSmoothing(ByRef $aMovement)
Local $aDeltas[2]
$aDeltas[0] = ($aMovement[0][0] + $aMovement[1][0]) * 0.5
$aDeltas[1] = ($aMovement[0][1] + $aMovement[1][1]) * 0.5
Return $aDeltas
EndFunc
Func _Setup()
Local $tProj, $aPos, $aRet, $iSize
$tFontDesc = _D3D_CreateFontDesc(25, 12, 500, "Times New Roman")
$pFont = _D3DX_CreateFontIndirect($pDevice, DllStructGetPtr($tFontDesc))
$oFont = _AutoItObject_WrapperCreate($pFont, $tagID3DXFont)
; Use the square root of the file size for dimensions of the terrain
$iSize = Int(Sqrt(FileGetSize($sHMapfile)))
; Create the first person camera object. Land object camera type.
$tCamera = _CameraCreate($CAMERATYPE_LANDOBJECT)
; Create the direction to light vector for colors shading. Light rays travel at -45 degrees down relative to the x-axis
; so the direction to light is upword at 135 degrees relative to the x-axis
; Note that the direction to light vector is a unit vector.
_D3D_CreateVector3($tDirToLight, -0.707, 0.707, 0)
; Higher cell spaced terrains are said to be lower resolution terrains.
$tTerrain = _TerrainCreate($pDevice, $sHMapfile, $iSize, $iSize, 8, 0.7)
If Not @error Then
_TerrainLoadTexture($sTerrainTex)
_TerrainGenerateTexture($tTerrain, $tDirToLight)
EndIf
; Set texture filters
$oDevice.SetSamplerState("long", "uint", 0, "int", $D3DSAMP_MAGFILTER, "uint", $D3DTEXF_LINEAR)
$oDevice.SetSamplerState("long", "uint", 0, "int", $D3DSAMP_MINFILTER, "uint", $D3DTEXF_LINEAR)
$oDevice.SetSamplerState("long", "uint", 0, "int", $D3DSAMP_MIPFILTER, "uint", $D3DTEXF_LINEAR)
; Set projection matrix (45 degrees)
$oDevice.SetTransform("long", "int", $D3DTS_PROJECTION, "ptr", _D3DX_MatrixPerspectiveFovLH($tProj, ASin(1)/2, $iWidth/$iHeight, 1, 1000))
; Calculate the screen position of our window's center
$aPos = WinGetPos($hGUI)
$iWndCenterX = $aPos[0] + $iCenterX
$iWndCenterY = $aPos[1] + $iCenterY
; Reset mouse to the center of the window and hide the mouse cursor
_SetCursorPos($iWndCenterX, $iWndCenterY)
GUISetCursor(16)
EndFunc
Func _WM_KEYDOWN($hWnd, $iMsg, $iwParam, $ilParam)
If $iwParam = 0x20 Then
If IsDllStruct($tTerrain) Then
_TerrainSwitchTexture($fSwitch)
$fSwitch = Not $fSwitch
EndIf
EndIf
Return $GUI_RUNDEFMSG
EndFunc
Func _Quit()
Exit
EndFunc
Func _Cleanup()
$oDevice = 0
GUIDelete()
_D3D_Shutdown()
EndFunc
; #FUNCTION#;===============================================================================
;
; Name...........: _HighPrecisionSleep()
; Description ...: Sleeps down to 0.1 microseconds
; Syntax.........: _HighPrecisionSleep( $iMicroSeconds, $hDll=False)
; Parameters ....: $iMicroSeconds - Amount of microseconds to sleep
; $hDll - Can be supplied so the UDF doesn't have to re-open the dll all the time.
; Return values .: None
; Author ........: Andreas Karlsson (monoceres)
; Modified.......:
; Remarks .......: Even though this has high precision you need to take into consideration that it will take some time for autoit to call the function.
; Related .......:
; Link ..........;
; Example .......; No
;
;;==========================================================================================
Func _HighPrecisionSleep($iMicroSeconds,$hDll=False)
Local $hStruct, $bLoaded
If Not $hDll Then
$hDll=DllOpen("ntdll.dll")
$bLoaded=True
EndIf
$hStruct=DllStructCreate("int64 time;")
DllStructSetData($hStruct,"time",-1*($iMicroSeconds*10))
DllCall($hDll,"dword","ZwDelayExecution","int",0,"ptr",DllStructGetPtr($hStruct))
If $bLoaded Then DllClose($hDll)
EndFunc
Func _GetCursorPos()
Local $aRet[2], $tPoint = DllStructCreate("int;int")
DllCall("user32.dll", "bool", "GetCursorPos", "ptr", DllStructGetPtr($tPoint))
$aRet[0] = DllStructGetData($tPoint, 1) ; X
$aRet[1] = DllStructGetData($tPoint, 2) ; Y
Return $aRet
EndFunc
Func _SetCursorPos($iX, $iY)
DllCall("user32.dll", "bool", "SetCursorPos", "int", $iX, "int", $iY)
EndFunc