D3D stürzt ab (vermutlich Datentyp-Fehler)

  • 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
    [autoit]

    #include "Camera.au3"
    #include "Terrain.au3"
    #include <GUIConstantsEx.au3>
    #include <Misc.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars", 1)
    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    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"

    [/autoit] [autoit][/autoit] [autoit]

    ; 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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    Local $hGUI = GUICreate("Direct3D9 - Terrain", $iWidth, $iHeight)
    Local $pDevice, $oDevice

    [/autoit] [autoit][/autoit] [autoit]

    ; 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]

    [/autoit] [autoit][/autoit] [autoit]

    ; 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

    [/autoit] [autoit][/autoit] [autoit]

    _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

    [/autoit] [autoit][/autoit] [autoit]

    $pDevice = _D3D_Init($hGUI, $iWidth, $iHeight)
    $oDevice = _AutoItObject_WrapperCreate($pDevice, $tagIDirect3DDevice9)

    [/autoit] [autoit][/autoit] [autoit]

    _Setup()
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
    ; Change terrain texturing using spacebar
    GUIRegisterMsg($WM_KEYDOWN, "_WM_KEYDOWN")
    OnAutoItExitRegister("_Cleanup")
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    _Render()
    _HighPrecisionSleep(8000)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Render()
    ; Allow user to update the camera view
    Local $iRunFactor, $aDeltas, $tCameraPos, $nHeight, $tView, $tWorld,$walk=-1,$Strafe=-1

    [/autoit] [autoit][/autoit] [autoit]

    ; Left shift to run
    If _IsPressed("A0") Then $iRunFactor = 0.5

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    if _IsPressed(31) then
    AdlibRegister("_jump",100)
    endif

    [/autoit] [autoit][/autoit] [autoit]

    $aDeltas = _MouseSmoothFilter($aHistory)

    [/autoit] [autoit][/autoit] [autoit]

    _CameraYaw ($tCamera, $aDeltas[0] / $nSensitivity)
    _CameraPitch($tCamera, $aDeltas[1] / $nSensitivity)

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    ; Get the camera view matrix
    $oDevice.SetTransform("long", "int", $D3DTS_VIEW, "ptr", _CameraGetView($tCamera, $tView))

    [/autoit] [autoit][/autoit] [autoit]

    ; 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

    [/autoit] [autoit][/autoit] [autoit]

    $oDevice.EndScene("long")
    $oDevice.Present("long", "ptr", 0, "ptr", 0, "hwnd", 0, "ptr", 0)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    Func _MouseSmoothFilter(ByRef $aMovement)
    Local $aPos, $iDX, $iDY

    [/autoit] [autoit][/autoit] [autoit]

    ; 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

    [/autoit] [autoit][/autoit] [autoit]

    _MousePerformFiltering($aMovement, $iDX, $iDY)
    Return _MousePerformSmoothing($aMovement)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _MousePerformFiltering(ByRef $aMovement, $nDX, $nDY)
    Local $aDeltas[2], $nAvgX, $nAvgY, $nAvgSum, $nCurrWeight = 1

    [/autoit] [autoit][/autoit] [autoit]

    ; 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

    [/autoit] [autoit][/autoit] [autoit]

    $aMovement[0][0] = $nDX
    $aMovement[0][1] = $nDY

    [/autoit] [autoit][/autoit] [autoit]

    ; 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

    [/autoit] [autoit][/autoit] [autoit]

    $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]

    [/autoit] [autoit][/autoit] [autoit]

    Return $aDeltas
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _MousePerformSmoothing(ByRef $aMovement)
    Local $aDeltas[2]

    [/autoit] [autoit][/autoit] [autoit]

    $aDeltas[0] = ($aMovement[0][0] + $aMovement[1][0]) * 0.5
    $aDeltas[1] = ($aMovement[0][1] + $aMovement[1][1]) * 0.5

    [/autoit] [autoit][/autoit] [autoit]

    Return $aDeltas
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Setup()
    Local $tProj, $aPos, $aRet, $iSize

    [/autoit] [autoit][/autoit] [autoit]

    $tFontDesc = _D3D_CreateFontDesc(25, 12, 500, "Times New Roman")
    $pFont = _D3DX_CreateFontIndirect($pDevice, DllStructGetPtr($tFontDesc))
    $oFont = _AutoItObject_WrapperCreate($pFont, $tagID3DXFont)

    [/autoit] [autoit][/autoit] [autoit]

    ; Use the square root of the file size for dimensions of the terrain
    $iSize = Int(Sqrt(FileGetSize($sHMapfile)))

    [/autoit] [autoit][/autoit] [autoit]

    ; 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

    [/autoit] [autoit][/autoit] [autoit]

    ; 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)

    [/autoit] [autoit][/autoit] [autoit]

    ; Set projection matrix (45 degrees)
    $oDevice.SetTransform("long", "int", $D3DTS_PROJECTION, "ptr", _D3DX_MatrixPerspectiveFovLH($tProj, ASin(1)/2, $iWidth/$iHeight, 1, 1000))

    [/autoit] [autoit][/autoit] [autoit]

    ; Calculate the screen position of our window's center
    $aPos = WinGetPos($hGUI)
    $iWndCenterX = $aPos[0] + $iCenterX
    $iWndCenterY = $aPos[1] + $iCenterY

    [/autoit] [autoit][/autoit] [autoit]

    ; Reset mouse to the center of the window and hide the mouse cursor
    _SetCursorPos($iWndCenterX, $iWndCenterY)
    GUISetCursor(16)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _WM_KEYDOWN($hWnd, $iMsg, $iwParam, $ilParam)
    If $iwParam = 0x20 Then
    If IsDllStruct($tTerrain) Then
    _TerrainSwitchTexture($fSwitch)
    $fSwitch = Not $fSwitch
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Quit()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Cleanup()
    $oDevice = 0
    GUIDelete()
    _D3D_Shutdown()
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; #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

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetCursorPos()
    Local $aRet[2], $tPoint = DllStructCreate("int;int")
    DllCall("user32.dll", "bool", "GetCursorPos", "ptr", DllStructGetPtr($tPoint))

    [/autoit] [autoit][/autoit] [autoit]

    $aRet[0] = DllStructGetData($tPoint, 1) ; X
    $aRet[1] = DllStructGetData($tPoint, 2) ; Y

    [/autoit] [autoit][/autoit] [autoit]

    Return $aRet
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _SetCursorPos($iX, $iY)
    DllCall("user32.dll", "bool", "SetCursorPos", "int", $iX, "int", $iY)
    EndFunc

    [/autoit]