Jump to content

Warp speed in Space


trancexx
 Share

Recommended Posts

...I'm sure some of you know what will this be about.

Have patience and read the whole post and run some code. I find this theme to be very interesting and worth of lost time. Who knows, maybe I will even say something that you didn't know before.

It's known that you can't take AutoIt and go with it to the stars. It's not made for that. If you try you will probably die doing it (out of oldness). It's slow. But in the same hand it's strong enough to go there.

So, why not mount it on powerful rocket and take a trip here and there. Space is a fun place they say.

Here goes...

Few days back I found some code in which OpenGL functions were used. Code is written by C.Eugene (brilliant man, I must say). I don't know what language was written in but it looks very interesting. I wasn't able to run the code because I don't know how to.

Anyway, since I have some limited experience with OpenGL functions (look here) I was able, after comprehending some aspects of it, to run the code in my head (yeah, I'm a freak).

That code when converted to AutoIt looks like this:

#NoTrayIcon

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
; #include "OpenGLconstants.au3"; constants are extracred for this example
Opt("GUIOnEventMode", 1)


; Used constants from OpenGLconstants.au3
Global Const $GL_VERSION_1_1 = 1
Global Const $GL_DEPTH_BUFFER_BIT = 0x00000100
Global Const $GL_COLOR_BUFFER_BIT = 0x00004000
Global Const $GL_SRC_COLOR = 0x0300
Global Const $GL_DST_COLOR = 0x0306
Global Const $GL_FOG = 0x0B60
Global Const $GL_FOG_DENSITY = 0x0B62
Global Const $GL_FOG_START = 0x0B63
Global Const $GL_FOG_END = 0x0B64
Global Const $GL_FOG_MODE = 0x0B65
Global Const $GL_FOG_COLOR = 0x0B66
Global Const $GL_BLEND = 0x0BE2
Global Const $GL_FOG_HINT = 0x0C54
Global Const $GL_DONT_CARE = 0x1100
Global Const $GL_MODELVIEW = 0x1700
Global Const $GL_PROJECTION = 0x1701
Global Const $GL_LINEAR = 0x2601


Global Const $PFD_TYPE_RGBA = 0
Global Const $PFD_MAIN_PLANE = 0
Global Const $PFD_DOUBLEBUFFER = 1
Global Const $PFD_DRAW_TO_WINDOW = 4
Global Const $PFD_SUPPORT_OPENGL = 32


Global $iNumStars = 106; number of stars


Global $iWidthGUI = 600
Global $iHeightGUI = 400
Global $hGUI = GUICreate("OpenGL Space", $iWidthGUI, $iHeightGUI, -1, -1, $WS_OVERLAPPEDWINDOW)

GUISetBkColor(0)


Global $hDC, $hRC; device context and rendering context

If Not _EnableOpenGL($hGUI, $hDC, $hRC) Then
    MsgBox(48, "Error", "Error initializing usage of OpenGL functions" & @CRLF & "Error code: " & @error)
    Exit
EndIf

_glClear(BitOR($GL_COLOR_BUFFER_BIT, $GL_DEPTH_BUFFER_BIT)); initially cleaning buffers in case something is left there



Global $aStar[$iNumStars][3]; x, y, z coordinates

Global $aStarColor[$iNumStars][3]; r, g, b color for stars


For $i = 0 To $iNumStars - 1
    $aStar[$i][0] = Random(-25, 25)
    $aStar[$i][1] = Random(-25, 25)
    $aStar[$i][2] = Random(-150, 0)

    $aStarColor[$i][1] = Random(0.8, 1)
    $aStarColor[$i][2] = Random(0.8, 1)
Next



_glClearColor(0, 0, 0, 1); black
_glFogi($GL_FOG_MODE, $GL_LINEAR)

Global $tFogColor = DllStructCreate("float[4]")
DllStructSetData($tFogColor, 1, 1, 4)
$pFogColor = DllStructGetPtr($tFogColor)
_glFogfv($GL_FOG_COLOR, $pFogColor)


_glFogf($GL_FOG_DENSITY, 0.1)
_glHint($GL_FOG_HINT, $GL_DONT_CARE)
_glFogf($GL_FOG_START, 70)
_glFogf($GL_FOG_END, 150)
_glEnable($GL_FOG);
_glBlendFunc($GL_SRC_COLOR, $GL_DST_COLOR)
_glEnable($GL_BLEND)


_glLoadIdentity()
_glViewport(0, 0, $iWidthGUI, $iHeightGUI)
_glMatrixMode($GL_PROJECTION)
_glLoadIdentity()
$s = $iWidthGUI / $iHeightGUI
_glFrustum(-$s * 0.75, $s * 0.75, -0.75, 0.75, 6, 150)
_glMatrixMode($GL_MODELVIEW)


GUIRegisterMsg(133, "_Preserve"); WM_NCPAINT
GUIRegisterMsg(5, "_ResizeGL"); WM_SIZE

GUISetOnEvent(-3, "_Quit"); on exit

GUISetState(@SW_SHOW, $hGUI)


While 1

    _GLDraw()
    Sleep(0)

WEnd


; USED FUNCTIONS


Func _GLDraw()

    _glClear(16640); $GL_COLOR_BUFFER_BIT|$GL_DEPTH_BUFFER_BIT; cleaning buffers

    _glBegin(1); $GL_LINES; gonna draw lines

    For $i = 0 To $iNumStars - 1
        _glColor3f($aStarColor[$i][0], $aStarColor[$i][1], $aStarColor[$i][2]); start color

        _glVertex3f($aStar[$i][0], $aStar[$i][1], $aStar[$i][2]); start point

        _glColor3f(0, 0, .2); end color

        _glVertex3f($aStar[$i][0], $aStar[$i][1], $aStar[$i][2] - 1.5); end point (z is moved)

        $aStar[$i][2] += 0.3
        If $aStar[$i][2] > 5 Then
            $aStar[$i][0] = Random(-25, 25)
            $aStar[$i][1] = Random(-25, 25)
            $aStar[$i][2] = -150

    ;$aStarColor[$i][1] = Random(0.8, 1)
    ;$aStarColor[$i][2] = Random(0.8, 1)
        EndIf

    Next

    _glEnd(); end drawing

    _SwapBuffers($hDC); "refresh"

EndFunc ;==>_GLDraw



Func _EnableOpenGL($hWnd, ByRef $hDeviceContext, ByRef $hOpenGLRenderingContext)

    Local $tPIXELFORMATDESCRIPTOR = DllStructCreate("ushort Size;" & _
            "ushort Version;" & _
            "dword Flags;" & _
            "ubyte PixelType;" & _
            "ubyte ColorBits;" & _
            "ubyte RedBits;" & _
            "ubyte RedShift;" & _
            "ubyte GreenBits;" & _
            "ubyte GreenShift;" & _
            "ubyte BlueBits;" & _
            "ubyte BlueShift;" & _
            "ubyte AlphaBits;" & _
            "ubyte AlphaShift;" & _
            "ubyte AccumBits;" & _
            "ubyte AccumRedBits;" & _
            "ubyte AccumGreenBits;" & _
            "ubyte AccumBlueBits;" & _
            "ubyte AccumAlphaBits;" & _
            "ubyte DepthBits;" & _
            "ubyte StencilBits;" & _
            "ubyte AuxBuffers;" & _
            "ubyte LayerType;" & _
            "ubyte Reserved;" & _
            "dword LayerMask;" & _
            "dword VisibleMask;" & _
            "dword DamageMask")

    DllStructSetData($tPIXELFORMATDESCRIPTOR, "Size", DllStructGetSize($tPIXELFORMATDESCRIPTOR))
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "Version", $GL_VERSION_1_1)
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "Flags", BitOR($PFD_DRAW_TO_WINDOW, $PFD_SUPPORT_OPENGL, $PFD_DOUBLEBUFFER))
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "PixelType", $PFD_TYPE_RGBA)
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "ColorBits", 24)
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "DepthBits", 32)
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "LayerType", $PFD_MAIN_PLANE)

    Local $a_hCall = DllCall("kernel32.dll", "hwnd", "GetModuleHandleW", "wstr", "opengl32.dll")
    If @error Then
        Return SetError(1, 0, 0); what???
    EndIf

    If Not $a_hCall[0] Then
        If DllOpen("opengl32.dll") = -1 Then
            Return SetError(2, 0, 0); could not open opengl32.dll
        EndIf
    EndIf

    $a_hCall = DllCall("user32.dll", "hwnd", "GetDC", "hwnd", $hWnd)

    If @error Or Not $a_hCall[0] Then
        Return SetError(3, 0, 0); could not retrieve a handle to a device context
    EndIf

    $hDeviceContext = $a_hCall[0]

    Local $a_iCall = DllCall("gdi32.dll", "int", "ChoosePixelFormat", "hwnd", $hDeviceContext, "ptr", DllStructGetPtr($tPIXELFORMATDESCRIPTOR))
    If @error Or Not $a_iCall[0] Then
        Return SetError(4, 0, 0); could not match an appropriate pixel format
    EndIf
    Local $iFormat = $a_iCall[0]

    $a_iCall = DllCall("gdi32.dll", "int", "SetPixelFormat", "hwnd", $hDeviceContext, "int", $iFormat, "ptr", DllStructGetPtr($tPIXELFORMATDESCRIPTOR))
    If @error Or Not $a_iCall[0] Then
        Return SetError(5, 0, 0); could not set the pixel format of the specified device context to the specified format
    EndIf

    $a_hCall = DllCall("opengl32.dll", "hwnd", "wglCreateContext", "hwnd", $hDeviceContext)
    If @error Or Not $a_hCall[0] Then
        Return SetError(6, 0, 0); could not create a rendering context
    EndIf

    $hOpenGLRenderingContext = $a_hCall[0]

    $a_iCall = DllCall("opengl32.dll", "int", "wglMakeCurrent", "hwnd", $hDeviceContext, "hwnd", $hOpenGLRenderingContext)
    If @error Or Not $a_iCall[0] Then
        Return SetError(7, 0, 0); failed to make the specified rendering context the calling thread's current rendering context
    EndIf

    Return SetError(0, 0, 1); all OK!

EndFunc ;==>_EnableOpenGL



Func _DisableOpenGL($hWnd, $hDeviceContext, $hOpenGLRenderingContext)

; No point in doing error checking if this is done on exit. Will just call the cleaning functions.

    DllCall("opengl32.dll", "int", "wglMakeCurrent", "hwnd", 0, "hwnd", 0)
    DllCall("opengl32.dll", "int", "wglDeleteContext", "hwnd", $hOpenGLRenderingContext)
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hWnd, "hwnd", $hDeviceContext)

EndFunc ;==>_DisableOpenGL





Func _ResizeGL($hWnd, $iMsg, $wParam, $lParam)

    Local $aClientSize[2] = [BitAND($lParam, 65535), BitShift($lParam, 16)]
    _glLoadIdentity()
    _glViewport(0, 0, $aClientSize[0], $aClientSize[1])
    _glMatrixMode($GL_PROJECTION)
    _glLoadIdentity()
    Local $nRatio = $aClientSize[0] / $aClientSize[1]
    _glFrustum(-$nRatio * .75, $nRatio * .75, -.75, .75, 6.0, 150.0)
    _glMatrixMode($GL_MODELVIEW)

EndFunc ;==>_ResizeGL



Func _glBegin($iMode)
    DllCall("opengl32.dll", "none", "glBegin", "dword", $iMode)
EndFunc ;==>_glBegin


Func _glBlendFunc($iSfactor, $iDfactor)
    DllCall("opengl32.dll", "none", "glBlendFunc", "dword", $iSfactor, "dword", $iDfactor)
EndFunc ;==>_glBlendFunc


Func _glColor3fv($pColorFloat)
    DllCall("opengl32.dll", "none", "glColor3fv", "ptr", $pColorFloat)
EndFunc ;==>_glColor3fv


Func _glClear($iMask)
    DllCall("opengl32.dll", "none", "glClear", "dword", $iMask)
EndFunc ;==>_glClear


Func _glClearColor($nRed, $nGreen, $nBlue, $nAlpha)
    DllCall("opengl32.dll", "none", "glClearColor", "float", $nRed, "float", $nGreen, "float", $nBlue, "float", $nAlpha)
EndFunc ;==>_glClearColor


Func _glColor3f($nRed, $nGreen, $nBlue)
    DllCall("opengl32.dll", "none", "glColor3f", "float", $nRed, "float", $nGreen, "float", $nBlue)
EndFunc ;==>_glColor3f


Func _glEnable($iCap)
    DllCall("opengl32.dll", "none", "glEnable", "dword", $iCap)
EndFunc ;==>_glEnable


Func _glEnd()
    DllCall("opengl32.dll", "none", "glEnd")
EndFunc ;==>_glEnd


Func _glFrustum($nLeft, $nRight, $nBottom, $nTop, $nZNear, $nZFar)
    DllCall("opengl32.dll", "none", "glFrustum", "double", $nLeft, "double", $nRight, "double", $nBottom, "double", $nTop, "double", $nZNear, "double", $nZFar)
EndFunc ;==>_glFrustum


Func _glFogf($iName, $nParam)
    DllCall("opengl32.dll", "none", "glFogf", "dword", $iName, "float", $nParam)
EndFunc ;==>_glFogf


Func _glFogi($iName, $iParam)
    DllCall("opengl32.dll", "none", "glFogi", "dword", $iName, "dword", $iParam)
EndFunc ;==>_glFogi


Func _glFogfv($iName, $pParams)
    DllCall("opengl32.dll", "none", "glFogfv", "dword", $iName, "ptr", $pParams)
EndFunc ;==>_glFogfv


Func _glHint($iTarget, $iMode)
    DllCall("opengl32.dll", "none", "glHint", "dword", $iTarget, "dword", $iMode)
EndFunc ;==>_glHint


Func _glLoadIdentity()
    DllCall("opengl32.dll", "none", "glLoadIdentity")
EndFunc ;==>_glLoadIdentity


Func _glMatrixMode($iMode)
    DllCall("opengl32.dll", "none", "glMatrixMode", "dword", $iMode)
EndFunc ;==>_glMatrixMode


Func _glViewport($iX, $iY, $iWidth, $iHeight)
    DllCall("opengl32.dll", "none", "glViewport", "int", $iX, "int", $iY, "dword", $iWidth, "dword", $iHeight)
EndFunc ;==>_glViewport


Func _glVertex3f($nX, $nY, $nZ)
    DllCall("opengl32.dll", "none", "glVertex3f", "float", $nX, "float", $nY, "float", $nZ)
EndFunc ;==>glVertex3f


Func _glVertex3fv($pPointer)
    DllCall("opengl32.dll", "none", "glVertex3fv", "ptr", $pPointer)
EndFunc ;==>_glVertex3fv


Func _SwapBuffers($hDC)
    DllCall("gdi32.dll", "int", "SwapBuffers", "hwnd", $hDC)
EndFunc ;==>_SwapBuffers



Func _Preserve()
    _SwapBuffers($hDC)
EndFunc ;==>_Preserve


Func _Quit()
    _DisableOpenGL($hGUI, $hDC, $hRC)
    Exit
EndFunc ;==>_Quit

If you would go thru code you would see that I'm saying that the number of stars is 106.

Why 106. No particular reason. It's just for one that would run that code to see that something is happening actually. I number of stars is smaller you probably wouldn't spot anything.

What can be seen by running it? Well, it's eating up CPU and it's slow like shi*t. But still, it's working!!!

That's a good sign.

Let's speed it up!

How? Will use flying assembly to do that.

If you were reading previous threads on this theme than you know that the code to convert must be without built-in functions. If you go thru posted script again, you will see that the problematic part is Random() and arrays.

Since OpenGL functions are written to be very wide, there is a possibility to pass a pointer to array (of floats e.g.) to some functions instead of three different float values.

For example there is function glColor3f. You feed this function with three float values:

_glColor3f(0.8, 0.5, 0.1)

Func _glColor3f($nRed, $nGreen, $nBlue)
    DllCall("opengl32.dll", "none", "glColor3f", "float", $nRed, "float", $nGreen, "float", $nBlue)
EndFunc ;==>_glColor3f

But, there is also function that does the same but you pass somethig different:

Global $tStartColor = DllStructCreate("float[3]")
DllStructSetData($tStartColor, 1, 0.8, 1); r
DllStructSetData($tStartColor, 1, 0.5, 2); g
DllStructSetData($tStartColor, 1, 0.1, 3); b
Global $pStartColor = DllStructGetPtr($tStartColor)

_glColor3fv($pStartColor)

Func _glColor3fv($pColorFloat)
    DllCall("opengl32.dll", "none", "glColor3fv", "ptr", $pColorFloat)
EndFunc ;==>_glColor3fv

The effect would be the same.

Another problem is to generate random number in some range. How is that done by not using buil-in function?

ntdll.dll exports function RtlRandomEx. This function will generate random number (integer) in range 0 to 2147483648. The problem is obviously how to set range. That could be done using mathematics, like this:

Global $tRandom = DllStructCreate("dword")
Global $pRandom = DllStructGetPtr($tRandom)

For $i = 1 To 10
    ConsoleWrite($i & ". " & _Random(-23, 121) & @CRLF)
Next

Func _Random($iMin, $iMax)

;Return Random($iMin, $iMax)

    DllCall("ntdll.dll", "dword", "RtlRandomEx", "ptr", $pRandom)

    Return DllStructGetData($tRandom, 1) / (2147483648 - 1) * ($iMax - $iMin) + $iMin

EndFunc ;==>_Random

If you know the range you can do the calculations before and write something like this (to return integer in range of -25 to 25):

Global $tRandom = DllStructCreate("dword")
Global $pRandom = DllStructGetPtr($tRandom)

For $i = 1 To 10
    ConsoleWrite($i & ". " & _Random1() & @CRLF)
Next

Func _Random1()

;Return Random(-25, 25)

    DllCall("ntdll.dll", "dword", "RtlRandomEx", "ptr", $pRandom)

    Return Int(DllStructGetData($tRandom, 1) / 42949672) - 25

; Return DllStructGetData($tRandom, 1) / 2147483647 * 50 - 25

EndFunc ;==>_Random1

Now that we know that the original script can be written like this:

#NoTrayIcon

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
; #include "OpenGLconstants.au3"; constants are extracred for this examle
Opt("GUIOnEventMode", 1)


; Used constants from OpenGLconstants.au3
Global Const $GL_VERSION_1_1 = 1
Global Const $GL_DEPTH_BUFFER_BIT = 0x00000100
Global Const $GL_COLOR_BUFFER_BIT = 0x00004000
Global Const $GL_SRC_COLOR = 0x0300
Global Const $GL_DST_COLOR = 0x0306
Global Const $GL_FOG = 0x0B60
Global Const $GL_FOG_DENSITY = 0x0B62
Global Const $GL_FOG_START = 0x0B63
Global Const $GL_FOG_END = 0x0B64
Global Const $GL_FOG_MODE = 0x0B65
Global Const $GL_FOG_COLOR = 0x0B66
Global Const $GL_BLEND = 0x0BE2
Global Const $GL_FOG_HINT = 0x0C54
Global Const $GL_DONT_CARE = 0x1100
Global Const $GL_MODELVIEW = 0x1700
Global Const $GL_PROJECTION = 0x1701
Global Const $GL_LINEAR = 0x2601


Global Const $PFD_TYPE_RGBA = 0
Global Const $PFD_MAIN_PLANE = 0
Global Const $PFD_DOUBLEBUFFER = 1
Global Const $PFD_DRAW_TO_WINDOW = 4
Global Const $PFD_SUPPORT_OPENGL = 32


Global $iNumStars = 106; number of stars

Global $iWidthGUI = 600
Global $iHeightGUI = 400
Global $hGUI = GUICreate("OpenGL Space", $iWidthGUI, $iHeightGUI, -1, -1, $WS_OVERLAPPEDWINDOW)

GUISetBkColor(0)


Global $tRandom = DllStructCreate("dword")
Global $pRandom = DllStructGetPtr($tRandom)

Global $hDC, $hRC; device context and rendering context

If Not _EnableOpenGL($hGUI, $hDC, $hRC) Then
    MsgBox(48, "Error", "Error initializing usage of OpenGL functions" & @CRLF & "Error code: " & @error)
    Exit
EndIf

_glClear(BitOR($GL_COLOR_BUFFER_BIT, $GL_DEPTH_BUFFER_BIT)); initially cleaning buffers in case something is left there


Global $tStars = DllStructCreate("float[" & 3 * $iNumStars & "]")
Global $tColors = DllStructCreate("float[" & 3 * $iNumStars & "]")

Global $pStars = DllStructGetPtr($tStars)
Global $pColors = DllStructGetPtr($tColors)


Global $tInt = DllStructCreate("dword")
DllStructSetData($tInt, 1, $pStars)
Global $pInt = DllStructGetPtr($tInt)

Global $tInt1 = DllStructCreate("int")
Global $pInt1 = DllStructGetPtr($tInt1)


Global $tStartColor = DllStructCreate("float[3]")
DllStructSetData($tStartColor, 1, 0.5, 1)
DllStructSetData($tStartColor, 1, 0.9, 2)
DllStructSetData($tStartColor, 1, 0.9, 3)
Global $pStartColor = DllStructGetPtr($tStartColor)


Global $tEndColor = DllStructCreate("float[3]")
DllStructSetData($tEndColor, 1, 0.2, 3)
Global $pEndColor = DllStructGetPtr($tEndColor)


$k = TimerInit()

For $i = 1 To $iNumStars

    DllStructSetData($tStars, 1, _Random1(), ($i * 3) - 2)
    DllStructSetData($tStars, 1, _Random1(), ($i * 3) - 1)
    DllStructSetData($tStars, 1, _Random3(), $i * 3)

    DllStructSetData($tColors, 1, _Random2(), ($i * 3) - 1)
    DllStructSetData($tColors, 1, _Random2(), $i * 3)

Next

ConsoleWrite(TimerDiff($k) & @CRLF)




;INIT
_glClearColor(0, 0, 0, 1)
_glFogi($GL_FOG_MODE, $GL_LINEAR);

$tFogColor = DllStructCreate("float[4]")
DllStructSetData($tFogColor, 1, 1, 4)
$pFogColor = DllStructGetPtr($tFogColor)
_glFogfv($GL_FOG_COLOR, $pFogColor)

_glFogf($GL_FOG_DENSITY, 0.1);
_glHint($GL_FOG_HINT, $GL_DONT_CARE);
_glFogf($GL_FOG_START, 70);
_glFogf($GL_FOG_END, 150);
_glEnable($GL_FOG);
_glBlendFunc($GL_SRC_COLOR, $GL_DST_COLOR);
_glEnable($GL_BLEND)
; End INIT

; ResizeGL
_glLoadIdentity();
_glViewport(0, 0, $iWidthGUI, $iHeightGUI);
_glMatrixMode($GL_PROJECTION);
_glLoadIdentity();
$s = $iWidthGUI / $iHeightGUI
_glFrustum(-$s * .75, $s * .75, -.75, .75, 6.0, 150.0)
_glMatrixMode($GL_MODELVIEW)
; End ResizeGL



GUIRegisterMsg(133, "_Preserve"); WM_NCPAINT
GUIRegisterMsg(5, "_ResizeGL"); WM_SIZE

GUISetOnEvent(-3, "_Quit"); on exit

GUISetState(@SW_SHOW, $hGUI)



Global $a = DllStructCreate("float[3]")
Global $pa = DllStructGetPtr($a)
Global $z

While 1

    _GLDraw()

    Sleep(0)

WEnd



; FUNCTIONS

Func _GLDraw()

    _glClear(16640); $GL_COLOR_BUFFER_BIT|$GL_DEPTH_BUFFER_BIT; cleaning buffers

    _glBegin(1); $GL_LINES; gonna draw lines

    For $i = 1 To $iNumStars

        $z = DllStructGetData($tStars, 1, $i * 3)

        DllStructSetData($a, 1, DllStructGetData($tStars, 1, ($i * 3) - 2), 1)
        DllStructSetData($a, 1, DllStructGetData($tStars, 1, ($i * 3) - 1), 2)
        DllStructSetData($a, 1, $z, 3)

;_glColor3fv($pColors + ($i - 1) * 12); start color (12 = size of float[3])
        _glColor3fv($pStartColor); this is a constant value

;_glVertex3fv($pa); start point
        _glVertex3fv($pStars + ($i - 1) * 12); start point

        _glColor3fv($pEndColor); this is a constant value

        $z -= 1.5; dislocating z coordinate

        DllStructSetData($a, 1, $z, 3)
        _glVertex3fv($pa); end point

        $z += 1.5; returning z coordinate

        $z += 0.3

        DllStructSetData($tStars, 1, $z, $i * 3)

        If $z > 5 Then

            DllStructSetData($tStars, 1, _Random1(), ($i * 3) - 2)
            DllStructSetData($tStars, 1, _Random1(), ($i * 3) - 1)
            DllStructSetData($tStars, 1, -150, $i * 3)

    ;DllStructSetData($tColors, 1, _Random2(), ($i * 3) - 1)
    ;DllStructSetData($tColors, 1, _Random2(), ($i * 3))

        EndIf

    Next

    _glEnd(); end drawing

    _SwapBuffers($hDC); "refresh"


EndFunc ;==>_GLDraw



Func _Random($iMin, $iMax)

;Return Random($iMin, $iMax)

    DllCall("ntdll.dll", "dword", "RtlRandomEx", "ptr", $pRandom)

    Return DllStructGetData($tRandom, 1) / 2147483647 * ($iMax - $iMin) + $iMin

EndFunc ;==>_Random



Func _Random1()

;Return Random(-25, 25)

    DllCall("ntdll.dll", "dword", "RtlRandomEx", "ptr", $pRandom)

    Return Int(DllStructGetData($tRandom, 1) / 42949672) - 25

    Return DllStructGetData($tRandom, 1) / 2147483647 * 50 - 25

EndFunc ;==>_Random1


Func _Random2()

;Return Random(0.8, 1)

    DllCall("ntdll.dll", "dword", "RtlRandomEx", "ptr", $pRandom)

    Return Int((DllStructGetData($tRandom, 1) / 2147483647)) / 5 + 0.8

EndFunc ;==>_Random2



Func _Random3()

;Return Random(-150, 0)

    DllCall("ntdll.dll", "dword", "RtlRandomEx", "ptr", $pRandom)

    Return -DllStructGetData($tRandom, 1) / 14316558

EndFunc ;==>_Random3



Func SwapEndian($iValue)
    Return Hex(BinaryMid($iValue, 1, 4))
EndFunc ;==>SwapEndian


Func _EnableOpenGL($hWnd, ByRef $hDeviceContext, ByRef $hOpenGLRenderingContext)

    Local $tPIXELFORMATDESCRIPTOR = DllStructCreate("ushort Size;" & _
            "ushort Version;" & _
            "dword Flags;" & _
            "ubyte PixelType;" & _
            "ubyte ColorBits;" & _
            "ubyte RedBits;" & _
            "ubyte RedShift;" & _
            "ubyte GreenBits;" & _
            "ubyte GreenShift;" & _
            "ubyte BlueBits;" & _
            "ubyte BlueShift;" & _
            "ubyte AlphaBits;" & _
            "ubyte AlphaShift;" & _
            "ubyte AccumBits;" & _
            "ubyte AccumRedBits;" & _
            "ubyte AccumGreenBits;" & _
            "ubyte AccumBlueBits;" & _
            "ubyte AccumAlphaBits;" & _
            "ubyte DepthBits;" & _
            "ubyte StencilBits;" & _
            "ubyte AuxBuffers;" & _
            "ubyte LayerType;" & _
            "ubyte Reserved;" & _
            "dword LayerMask;" & _
            "dword VisibleMask;" & _
            "dword DamageMask")

    DllStructSetData($tPIXELFORMATDESCRIPTOR, "Size", DllStructGetSize($tPIXELFORMATDESCRIPTOR))
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "Version", $GL_VERSION_1_1)
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "Flags", BitOR($PFD_DRAW_TO_WINDOW, $PFD_SUPPORT_OPENGL, $PFD_DOUBLEBUFFER))
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "PixelType", $PFD_TYPE_RGBA)
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "ColorBits", 24)
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "DepthBits", 32)
    DllStructSetData($tPIXELFORMATDESCRIPTOR, "LayerType", $PFD_MAIN_PLANE)

    Local $a_hCall = DllCall("kernel32.dll", "hwnd", "GetModuleHandleW", "wstr", "opengl32.dll")
    If @error Then
        Return SetError(1, 0, 0); what???
    EndIf

    If Not $a_hCall[0] Then
        If DllOpen("opengl32.dll") = -1 Then
            Return SetError(2, 0, 0); could not open opengl32.dll
        EndIf
    EndIf

    $a_hCall = DllCall("user32.dll", "hwnd", "GetDC", "hwnd", $hWnd)

    If @error Or Not $a_hCall[0] Then
        Return SetError(3, 0, 0); could not retrieve a handle to a device context
    EndIf

    $hDeviceContext = $a_hCall[0]

    Local $a_iCall = DllCall("gdi32.dll", "int", "ChoosePixelFormat", "hwnd", $hDeviceContext, "ptr", DllStructGetPtr($tPIXELFORMATDESCRIPTOR))
    If @error Or Not $a_iCall[0] Then
        Return SetError(4, 0, 0); could not match an appropriate pixel format
    EndIf
    Local $iFormat = $a_iCall[0]

    $a_iCall = DllCall("gdi32.dll", "int", "SetPixelFormat", "hwnd", $hDeviceContext, "int", $iFormat, "ptr", DllStructGetPtr($tPIXELFORMATDESCRIPTOR))
    If @error Or Not $a_iCall[0] Then
        Return SetError(5, 0, 0); could not set the pixel format of the specified device context to the specified format
    EndIf

    $a_hCall = DllCall("opengl32.dll", "hwnd", "wglCreateContext", "hwnd", $hDeviceContext)
    If @error Or Not $a_hCall[0] Then
        Return SetError(6, 0, 0); could not create a rendering context
    EndIf

    $hOpenGLRenderingContext = $a_hCall[0]

    $a_iCall = DllCall("opengl32.dll", "int", "wglMakeCurrent", "hwnd", $hDeviceContext, "hwnd", $hOpenGLRenderingContext)
    If @error Or Not $a_iCall[0] Then
        Return SetError(7, 0, 0); failed to make the specified rendering context the calling thread's current rendering context
    EndIf

    Return SetError(0, 0, 1); all OK!

EndFunc ;==>_EnableOpenGL



Func _DisableOpenGL($hWnd, $hDeviceContext, $hOpenGLRenderingContext)

; No point in doing error checking if this is done on exit. Will just call the cleaning functions.

    DllCall("opengl32.dll", "int", "wglMakeCurrent", "hwnd", 0, "hwnd", 0)
    DllCall("opengl32.dll", "int", "wglDeleteContext", "hwnd", $hOpenGLRenderingContext)
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hWnd, "hwnd", $hDeviceContext)

EndFunc ;==>_DisableOpenGL





Func _ResizeGL($hWnd, $iMsg, $wParam, $lParam)

    Local $aClientSize[2] = [BitAND($lParam, 65535), BitShift($lParam, 16)]
    _glLoadIdentity()
    _glViewport(0, 0, $aClientSize[0], $aClientSize[1])
    _glMatrixMode($GL_PROJECTION)
    _glLoadIdentity()
    Local $nRatio = $aClientSize[0] / $aClientSize[1]
    _glFrustum(-$nRatio * .75, $nRatio * .75, -.75, .75, 6.0, 150.0)
    _glMatrixMode($GL_MODELVIEW)

EndFunc ;==>_ResizeGL



Func _glBegin($iMode)
    DllCall("opengl32.dll", "none", "glBegin", "dword", $iMode)
EndFunc ;==>_glBegin


Func _glBlendFunc($iSfactor, $iDfactor)
    DllCall("opengl32.dll", "none", "glBlendFunc", "dword", $iSfactor, "dword", $iDfactor)
EndFunc ;==>_glBlendFunc


Func _glColor3fv($pColorFloat)
    DllCall("opengl32.dll", "none", "glColor3fv", "ptr", $pColorFloat)
EndFunc ;==>_glColor3fv


Func _glClear($iMask)
    DllCall("opengl32.dll", "none", "glClear", "dword", $iMask)
EndFunc ;==>_glClear


Func _glClearColor($nRed, $nGreen, $nBlue, $nAlpha)
    DllCall("opengl32.dll", "none", "glClearColor", "float", $nRed, "float", $nGreen, "float", $nBlue, "float", $nAlpha)
EndFunc ;==>_glClearColor


Func _glColor3f($nRed, $nGreen, $nBlue)
    DllCall("opengl32.dll", "none", "glColor3f", "float", $nRed, "float", $nGreen, "float", $nBlue)
EndFunc ;==>_glColor3f


Func _glEnable($iCap)
    DllCall("opengl32.dll", "none", "glEnable", "dword", $iCap)
EndFunc ;==>_glEnable


Func _glEnd()
    DllCall("opengl32.dll", "none", "glEnd")
EndFunc ;==>_glEnd


Func _glFrustum($nLeft, $nRight, $nBottom, $nTop, $nZNear, $nZFar)
    DllCall("opengl32.dll", "none", "glFrustum", "double", $nLeft, "double", $nRight, "double", $nBottom, "double", $nTop, "double", $nZNear, "double", $nZFar)
EndFunc ;==>_glFrustum


Func _glFogf($iName, $nParam)
    DllCall("opengl32.dll", "none", "glFogf", "dword", $iName, "float", $nParam)
EndFunc ;==>_glFogf


Func _glFogi($iName, $iParam)
    DllCall("opengl32.dll", "none", "glFogi", "dword", $iName, "dword", $iParam)
EndFunc ;==>_glFogi


Func _glFogfv($iName, $pParams)
    DllCall("opengl32.dll", "none", "glFogfv", "dword", $iName, "ptr", $pParams)
EndFunc ;==>_glFogfv


Func _glHint($iTarget, $iMode)
    DllCall("opengl32.dll", "none", "glHint", "dword", $iTarget, "dword", $iMode)
EndFunc ;==>_glHint


Func _glLoadIdentity()
    DllCall("opengl32.dll", "none", "glLoadIdentity")
EndFunc ;==>_glLoadIdentity


Func _glMatrixMode($iMode)
    DllCall("opengl32.dll", "none", "glMatrixMode", "dword", $iMode)
EndFunc ;==>_glMatrixMode


Func _glViewport($iX, $iY, $iWidth, $iHeight)
    DllCall("opengl32.dll", "none", "glViewport", "int", $iX, "int", $iY, "dword", $iWidth, "dword", $iHeight)
EndFunc ;==>_glViewport


Func _glVertex3f($nX, $nY, $nZ)
    DllCall("opengl32.dll", "none", "glVertex3f", "float", $nX, "float", $nY, "float", $nZ)
EndFunc ;==>glVertex3f


Func _glVertex3fv($pPointer)
    DllCall("opengl32.dll", "none", "glVertex3fv", "ptr", $pPointer)
EndFunc ;==>_glVertex3fv


Func _SwapBuffers($hDC)
    DllCall("gdi32.dll", "int", "SwapBuffers", "hwnd", $hDC)
EndFunc ;==>_SwapBuffers


Func _Preserve()
    _SwapBuffers($hDC)
EndFunc ;==>_Preserve


Func _Quit()
    _DisableOpenGL($hGUI, $hDC, $hRC)
    Exit
EndFunc ;==>_Quit

Ok, that's almost half of the job. All that needs to be done now is to convert the slow part to assembly.

There are some things that should be said before though.

New (assembly) code will be executed using function CallWindowProc. Some other functions could be used too but there is always a thread issue. You can't be sure if there would be a new thread created. Why is this important?

Because if you look at documentation of wglMakeCurrent function, you will see that it works for threads (not processes!). If you make a new thread and want to draw to some rendering context you need to call wglMakeCurrent from that thread to make the association.

Interesting thing is that in XP you could even skip that, but on Vista skipping association leads to crash.

That's why you will see calls to wglMakeCurrent in script that follows in places you didn't in the previous scripts.

Since the script is somewhere larger and this post is large enough I have to attach it.

Space.au3

Change the speed using mouse wheel or up an down arrows on your keyboard.

Every line of code is commented (hell, even the comments are commented).

That script is dealing with 7777 stars (again no particular reason why) and is very, very low on CPU.

If you are interested you can learn about floats and dealing with them on processor level by examining that script (that's new) and many, many other stuff.

I think I could write a short book on that code :D

It's almost a perfect screensaver.

If anyone have any question, ask.

You know how they say: "Space: the final frontier..."

Edited by trancexx
New version

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Sweet! Nice job.

Link to comment
Share on other sites

Wh- Ho- Wha-*head explodes*

I am speachless. However, i have noticed many stars aling directly on a center line going u and down and left to right.

please format as screensaver

*EDIT*

Ok, so I started looking at the sorce. This is soo well documented that it should be easy to make into a screensaver. If anyone had an empty screensaver template or "shell" I would appreciate it.

Verry verry verry verry verry verry verry verry verry verry verry verry verry nice. Still have no idea how you got it to go that fast.....

Edited by corgano

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Link to comment
Share on other sites

Well done trancexx :D

The assembly parts rock :D and very well documented!

Respect!

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Thanks guys.

@corgano, that would be about axes that I mentioned in the first post.

I'm generating random numbers in range of -25 to 25 but as integers (converted to floats later). It would be better to generate for example 12.2345 instead of 12. That would make things more natural because that star would go in it's own direction.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Thanks guys.

@corgano, that would be about axes that I mentioned in the first post.

I'm generating random numbers in range of -25 to 25 but as integers (converted to floats later). It would be better to generate for example 12.2345 instead of 12. That would make things more natural because that star would go in it's own direction.

The script will make a noticable and interesting patteren if you set the stars to 99999. I have been playing around a bit, but some of your notes (and even your notes' notes) are above me. i have been playing around, this does not give the same effect of stars, but still looks cool.

Space_mod_.au3

post-43194-1245781099_thumb.gif

Edited by corgano

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Link to comment
Share on other sites

Very cool. I am confused by the code a bit but I have some suggestions to take it to the next level.

-Directional movement based on mouse position

-Speed modifier

-Size jitter

-Nebula background image

-Eliminate stars along X and Y axis, they seem to reduce the "effect"

-TIE Fighters

-Rocks that when split when fired at, and then those fragments split when fired at, etc...

Edited by weaponx
Link to comment
Share on other sites

Sure you could.

But I'm sure you will grant me a right not to answer that. Mostly because of irrelevance of that.

ok, no problem...

anyway can you explain why its not possible to handle arrays with this inline assembly ?

Link to comment
Share on other sites

Yet another amazing example, trancexx. :D

It really reminds me of something out of Star Trek.

Now if we only had a view-screen...

Oh wait... ! (added like 3 lines)

(Note: Space isn't centered right in this one)

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Link to comment
Share on other sites

Yet another amazing example, trancexx. :D

It really reminds me of something out of Star Trek.

Now if we only had a view-screen...

Oh wait... ! (added like 3 lines)

(Note: Space isn't centered right in this one)

Did you notice that your avatar looks like there is some green fish on the left doing a blow job. :D

@oMBRa, how would you access array from there. You need pointers and we don't have pointers to created arrays, just available data.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Compile it to an .exe file, and then rename it to [name].scr

you need more than that. just running a .scr opens up the settings box. it has something to do with command line, one opens settings, the other opens preview(the screen saver)

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Link to comment
Share on other sites

you need more than that. just running a .scr opens up the settings box. it has something to do with command line, one opens settings, the other opens preview(the screen saver)

How about the Screensaver UDF?
Link to comment
Share on other sites

What if I wanted to have it make the starfield on the Program Manager window (on the desktop)

So it would be like a animated desktop walpaper.

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Link to comment
Share on other sites

@oMBRa, how would you access array from there. You need pointers and we don't have pointers to created arrays, just available data.

And if we allocate some memory with MemAlloc, and then we get the pointer to the first byte with MemLock? or I misunderstood what you said?
Link to comment
Share on other sites

maybe you can do something like that to add it as desktop background:

http://www.autoitscript.com/forum/index.php?showtopic=95842

Edited by JRSmile
$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")
For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)
Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI"
Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;
MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...