Jump to content

OpenGL


trancexx
 Share

Recommended Posts

Passing dll names to DllCall() loads and unloads the dll each time. This is a huge performance hit if you're doing thousands of dll calls to the same dll. You should definitely use DllOpen() / DllClose() and pass handles (it's in the documentation too).

Edited by wraithdu
Link to comment
Share on other sites

Passing dll names to DllCall() loads and unloads the dll each time. This is a huge performance hit if you're doing thousands of dll calls to the same dll. You should definitely use DllOpen() / DllClose() and pass handles (it's in the documentation too).

You're only partly right.

Lets take an example:

$handle=DllOpen("test.dll")

While True
DllCall("test.dll","none","blah")
WEnd

DllClose($handle)

Even though I call the function with the dll path the dll is only loaded once, the other times the reference count for the dll will only be incremented (this could be considered a small performance hit as well).

This is also why the optional parameter in _IsPressed() is pretty useless since it wants a handle to user32.dll which is always loaded into autoit processes anyway.

But yes, if the openGL libraries haven't even been opened at least once, it will load/unload the dll each time.

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

I'm aware of the reference count, but if someone writes something like that, well, that just shows an incomplete knowledge of the language.

Ufff!!!

...I will edit

edit:

I must react on this because you are, actually, wrong about what that shows. I mean: 'incomplete knowledge of the language'. Come on.

I know this...

You can for example run this:

DllOpen("kernel32.dll"); AutoIt did this already

For $j = 1 To 5

$nPassed = 0

For $i = 1 To 10000

    $hTimer = TimerInit()

    $aCall = DllCall("kernel32.dll", "int", "Beep", "dword", 0, "dword", 500)

    $nPassed += TimerDiff($hTimer)

Next

ConsoleWrite($nPassed & @CRLF)

Next

And then this:

$KERNEL32 = DllOpen("kernel32.dll")

For $j = 1 To 5

$nPassed = 0

For $i = 1 To 10000

    $hTimer = TimerInit()

    $aCall = DllCall($KERNEL32, "int", "Beep", "dword", 0, "dword", 500)

    $nPassed += TimerDiff($hTimer)

Next

ConsoleWrite($nPassed & @CRLF)

Next

DllClose($KERNEL32)

Compare results and you will see what hit it is.

Other thing is dinamically loaded modules (made up term). Windows through LoadLibraryEx (called by LoadLibrary called by DllOpen) deals with the subject in a very subtle way. Reference count is very important part of that. You are right there. It's faster not to call by string.

But still, this is the worst mix (often seen):

$KERNEL32 = DllOpen("kernel32.dll")
$aCall = DllCall($KERNEL32, "int", "Beep", "dword", 500, "dword", 500)
DllClose($KERNEL32)

I call by string after I evaluate what's gained and what's lost. Usually I call by string.

Edited by trancexx
Link to comment
Share on other sites

I haven't looked at your UDF source, and I was replying specifically to monoceres' hypothetical. Calling DllOpen() then DllCall() with the string anyway shows an incomplete knowledge of the language, period. If you know better and do it anyway, I'm not sure what to say to that.

I agree with what both of you said about the performance hit regarding modules already loaded by AutoIt, miniscule. But this discussion was about a dll that's not loaded already by AutoIt, so the difference is significant.

Edited by wraithdu
Link to comment
Share on other sites

How about this?

;#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Change2CUI=y

ConsoleWrite('---Plain DllCall------------'& @CRLF)

For $j = 1 To 3
$hTimer = TimerInit()
For $i = 1 To 30000
$aCall = DllCall("kernel32.dll", "int", "Beep", "dword", 0, "dword", 500)
Next
ConsoleWrite(round(TimerDiff($hTimer),0) & @CRLF)
Next

ConsoleWrite('----------------------------'& @CRLF)
ConsoleWrite('---DllOpen------------------'& @CRLF)

$k=DllOpen("kernel32.dll")

For $j = 1 To 3
$hTimer = TimerInit()
For $i = 1 To 30000
$aCall = DllCall("kernel32.dll", "int", "Beep", "dword", 0, "dword", 500)
Next
ConsoleWrite(round(TimerDiff($hTimer),0) & @CRLF)
Next

ConsoleWrite('----------------------------'& @CRLF)
ConsoleWrite('---DllCall with reference---'& @CRLF)

For $j = 1 To 3
$hTimer = TimerInit()
For $i = 1 To 30000
$aCall = DllCall($k, "int", "Beep", "dword", 0, "dword", 500)
Next
ConsoleWrite(round(TimerDiff($hTimer),0) & @CRLF)
Next

ConsoleWrite('----------------------------'& @CRLF)

DllClose($k)

sleep(30000)

---Plain DllCall------------

5212

5214

5219

----------------------------

---DllOpen------------------

5185

5173

5123

----------------------------

---DllCall with reference---

5034

4981

5014

----------------------------

Link to comment
Share on other sites

Above results where form running it in the SciTE

Default build exe (UPX compressed):

---Plain DllCall------------

4852

4833

4840

----------------------------

---DllOpen------------------

4830

4835

4840

----------------------------

---DllCall with reference---

4703

4710

4719

----------------------------

No UPX:

---Plain DllCall------------

4859

4856

4846

----------------------------

---DllOpen------------------

4848

4823

4837

----------------------------

---DllCall with reference---

4734

4727

4725

----------------------------

Note: At work computer got different results for UPX vs no UPX.

Link to comment
Share on other sites

@trancexx

I only mentioned because on Win7, it doesn't error out, it would actually run for the 6 hours. Setting freq to 500 and duration to 0 yields the correct results.

But no, I wasn't surprised by the results, as I said I agree with you that the performance hit in doing that is minimal. It's the same situation with base dll's like kernel32 as with monoceres' example where he calls DllOpen() first, then DllCall() with strings. It doesn't make it right though, and I don't see a reason not to do it the right way. After looking at your UDF I see you actually did it that way, so I see why you took the above comments personally. Not my intent.

Hell, if you're ever in Chicago I'll buy ya a drink anyway :)

Link to comment
Share on other sites

May be so, but then explain the results that are different for three test consistently... I tried different computers and ways to test it.

(in some cases even UPX matters for the first 2 tests)

Edited by dexto
Link to comment
Share on other sites

May be so, but then explain the results that are different for three test consistently... I tried different computers and ways to test it.

(in some cases even UPX matters for the first 2 tests)

You think I can't? :)

Speed tests with AutoIt are very hard to make objective. Engine needs heating for one thing.

What do you think why there are differences between the same tests? I mean perfectly same.

Edited by trancexx
Link to comment
Share on other sites

I dono if you can but I can't if I accept that there is no difference :)

As far as Autoit it even matters how long variables are... :S

Lets take a Autoit heating out of the way and run the separately:

DllOpen("kernel32.dll")
For $j = 1 To 3
$hTimer = TimerInit()
For $i = 1 To 30000
$aCall = DllCall("kernel32.dll", "int", "Beep", "dword", 0, "dword", 500)
Next
ConsoleWrite(round(TimerDiff($hTimer),0) & @CRLF)
Next
DllClose("kernel32.dll")

5135

5157

5165

$k=DllOpen("kernel32.dll")
For $j = 1 To 3
$hTimer = TimerInit()
For $i = 1 To 30000
$aCall = DllCall($k, "int", "Beep", "dword", 0, "dword", 500)
Next
ConsoleWrite(round(TimerDiff($hTimer),0) & @CRLF)
Next
DllClose($k)

5053

5031

5004

Link to comment
Share on other sites

In practice difference is anything but small.

Again, I'm not trying to prove you or anyone wrong if fact I don't care just an observation on my part.

I learned that actually when looking at your "OpenGL Sparkler".

Original (CPU using 0.76-12%):

#NoTrayIcon
Opt("GUIOnEventMode", 1)

Global Const $GL_VERSION_1_1 = 1
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 Const $GL_PROJECTION = 0x1701
Global Const $GL_COLOR_BUFFER_BIT = 0x00004000
Global Const $GL_LINES = 0x0001
Global Const $GL_SRC_COLOR = 0x0300
Global Const $GL_DST_COLOR = 0x0306
Global Const $GL_BLEND = 0x0BE2
Global Const $GL_MODELVIEW = 0x1700
Global Const $GL_DEPTH_BUFFER_BIT = 0x00000100

Global $hGUI = GUICreate("OpenGL Sparkler", 445, 445)

GUISetBkColor(0x000000)

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
_glEnable($GL_BLEND)
_glBlendFunc($GL_SRC_COLOR, $GL_DST_COLOR)
_glViewport(0, 0, 445, 445)

GUIRegisterMsg(133, "_Preserve") ; WM_NCPAINT
GUISetOnEvent(-3, "_Quit") ; on exit

GUISetState(@SW_SHOW, $hGUI)

Global $m

While 1

    _GLDraw()
    $m += .0003
    Sleep(10)

WEnd




Func _GLDraw()

    _glClear(BitOR($GL_COLOR_BUFFER_BIT, $GL_DEPTH_BUFFER_BIT)) ; cleaning buffers

    _glBegin($GL_LINES) ; gonna draw lines

    For $i = 1 To 10

        $i += 2 * ($m > .08) + 3 * ($m > .1) ; blowing out
        $m *= ($m < .14) ; looping

        If $m < .12 Then
            $s = Random(-9, 9, 1) / 32
            $t = Random(-9, 9, 1) / 35

            _glColor3f(1, 0, 0) ; begin with this color
            _glVertex2d(-$m, -2 * $m) ; start line here

            _glColor3f(0, 1, 1) ; end with this color
            _glVertex2d($s - $m, $t - 2 * $m) ; end line here

            If Not Mod(1000 * $m, 35) Then ; few flashes to make it more real
                _glColor3f(1, 0, 0) ; begin with this color
                _glVertex2d(-$m, -2 * $m) ; start line here

                _glColor3f(0, 1, 1) ; end with this color
                _glVertex2d(2 * $s - $m, 2 * $t - 2 * $m) ; end line here
            EndIf
        EndIf

    Next

    _glColor3f(1, .3, 0) ; stick color on the one side
    _glVertex2d(0, 0) ; stick starts here
    _glColor3f(0, 0, 1) ; stick color on the other side
    _glVertex2d(-.25, -.5) ; stick ends here

    _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", $hDeviceContext, "hwnd", 0)
    DllCall("opengl32.dll", "int", "wglDeleteContext", "hwnd", $hOpenGLRenderingContext)
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hWnd, "hwnd", $hDeviceContext)
    DllCall("gdi32.dll", "int", "DeleteDC", "hwnd", $hDeviceContext)

EndFunc   ;==>_DisableOpenGL



Func _glVertex2d($x, $y)
    DllCall("opengl32.dll", "none", "glVertex2d", "double", $x, "double", $y)
EndFunc   ;==>_glVertex2d


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


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


Func _glColor3f($red, $green, $blue)
    DllCall("opengl32.dll", "none", "glColor3f", "float", $red, "float", $green, "float", $blue)
EndFunc   ;==>_glColor3f


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


Func _glViewport($x, $y, $width, $height)
    DllCall("opengl32.dll", "none", "glViewport", "int", $x, "int", $y, "int", $width, "int", $height)
EndFunc   ;==>_glViewport


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


Func _glBlendFunc($sfactor, $dfactor)
    DllCall("opengl32.dll", "none", "glBlendFunc", "uint", $sfactor, "dword", $dfactor)
EndFunc   ;==>_glBlendFunc


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

DllCall with reference(using CPU 0.76-3.04%):

#NoTrayIcon
Opt("GUIOnEventMode", 1)

Global $g = DllOpen("gdi32.dll")
Global $o = DllOpen("opengl32.dll")
Global $u = DllOpen("user32.dll")
Global $k = DllOpen("kernel32.dll")

Global Const $GL_VERSION_1_1 = 1
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 Const $GL_PROJECTION = 0x1701
Global Const $GL_COLOR_BUFFER_BIT = 0x00004000
Global Const $GL_LINES = 0x0001
Global Const $GL_SRC_COLOR = 0x0300
Global Const $GL_DST_COLOR = 0x0306
Global Const $GL_BLEND = 0x0BE2
Global Const $GL_MODELVIEW = 0x1700
Global Const $GL_DEPTH_BUFFER_BIT = 0x00000100

Global $hGUI = GUICreate("OpenGL Sparkler", 445, 445)

GUISetBkColor(0x000000)

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
_glEnable($GL_BLEND)
_glBlendFunc($GL_SRC_COLOR, $GL_DST_COLOR)
_glViewport(0, 0, 445, 445)

GUIRegisterMsg(133, "_Preserve") ; WM_NCPAINT
GUISetOnEvent(-3, "_Quit") ; on exit

GUISetState(@SW_SHOW, $hGUI)

Global $m

While 1
    _GLDraw()
    $m += .0003
    ;Sleep(10)
WEnd




Func _GLDraw()

    _glClear(BitOR($GL_COLOR_BUFFER_BIT, $GL_DEPTH_BUFFER_BIT)) ; cleaning buffers

    _glBegin($GL_LINES) ; gonna draw lines

    For $i = 1 To 10

        $i += 2 * ($m > .08) + 3 * ($m > .1) ; blowing out
        $m *= ($m < .14) ; looping

        If $m < .12 Then
            $s = Random(-9, 9, 1) / 32
            $t = Random(-9, 9, 1) / 35

            _glColor3f(1, 0, 0) ; begin with this color
            _glVertex2d(-$m, -2 * $m) ; start line here

            _glColor3f(0, 1, 1) ; end with this color
            _glVertex2d($s - $m, $t - 2 * $m) ; end line here

            If Not Mod(1000 * $m, 35) Then ; few flashes to make it more real
                _glColor3f(1, 0, 0) ; begin with this color
                _glVertex2d(-$m, -2 * $m) ; start line here

                _glColor3f(0, 1, 1) ; end with this color
                _glVertex2d(2 * $s - $m, 2 * $t - 2 * $m) ; end line here
            EndIf
        EndIf

    Next

    _glColor3f(1, .3, 0) ; stick color on the one side
    _glVertex2d(0, 0) ; stick starts here
    _glColor3f(0, 0, 1) ; stick color on the other side
    _glVertex2d(-.25, -.5) ; stick ends here

    _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($k, "hwnd", "GetModuleHandleW", "wstr", $o)
    If @error Then
        Return SetError(1, 0, 0) ; what???
    EndIf

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

    $a_hCall = DllCall($u, "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($g, "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($g, "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($o, "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($o, "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($o, "int", "wglMakeCurrent", "hwnd", $hDeviceContext, "hwnd", 0)
    DllCall($o, "int", "wglDeleteContext", "hwnd", $hOpenGLRenderingContext)
    DllCall($u, "int", "ReleaseDC", "hwnd", $hWnd, "hwnd", $hDeviceContext)
    DllCall($g, "int", "DeleteDC", "hwnd", $hDeviceContext)

EndFunc   ;==>_DisableOpenGL



Func _glVertex2d($x, $y)
    DllCall($o, "none", "glVertex2d", "double", $x, "double", $y)
EndFunc   ;==>_glVertex2d


Func _glBegin($mode)
    DllCall($o, "none", "glBegin", "dword", $mode)
EndFunc   ;==>_glBegin


Func _glClear($mask)
    DllCall($o, "none", "glClear", "dword", $mask)
EndFunc   ;==>_glClear


Func _glColor3f($red, $green, $blue)
    DllCall($o, "none", "glColor3f", "float", $red, "float", $green, "float", $blue)
EndFunc   ;==>_glColor3f


Func _glEnd()
    DllCall($o, "none", "glEnd")
EndFunc   ;==>_glEnd


Func _glViewport($x, $y, $width, $height)
    DllCall($o, "none", "glViewport", "int", $x, "int", $y, "int", $width, "int", $height)
EndFunc   ;==>_glViewport


Func _glEnable($cap)
    DllCall($o, "none", "glEnable", "dword", $cap)
EndFunc   ;==>_glEnable


Func _glBlendFunc($sfactor, $dfactor)
    DllCall($o, "none", "glBlendFunc", "uint", $sfactor, "dword", $dfactor)
EndFunc   ;==>_glBlendFunc


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


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


Func _Quit()
    _DisableOpenGL($hGUI, $hDC, $hRC)
    DllClose($g)
    DllClose($o)
    DllClose($u)
    DllClose($k)
    Exit
EndFunc   ;==>_Quit
Link to comment
Share on other sites

Second example is more correct and better and it should always look like that.

Run this to see what I dislike with 'globalizing' from within UDF:

#include <WindowsConstants.au3>
$error = 0

But, the final product should definitely look as you posted.

... now show me the improvements on Space script.

edit: missing letters

Edited by trancexx
Link to comment
Share on other sites

I know what you mean about Global vars. When i program i am always aware of what variable names i am using and i have unwritten rules for myself to prevent the conflicts or unwanted interactions.

It is rewarding enough to optimize the code with Globals. I learn from experience more then I do from anything else and from what I seen so far no matter C++ or Autoit Globals are faster.

Link to comment
Share on other sites

  • 2 weeks later...

Here's another OpenGL example in AutoIt.

It's 3D rotation.

Will draw square pyramid and do rotation (not the way it's expected - to make it more interesting).

#NoTrayIcon

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


; Used Dlls
Global Const $hUSER32 = DllOpen("user32.dll")
Global Const $hGDI32 = DllOpen("gdi32.dll")
Global Const $hOPENGL32 = DllOpen("opengl32.dll")

; General constants
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

; Used GL constants. See OpenGLConstants.au3
Global Const $GL_VERSION_1_1 = 1
Global Const $GL_COLOR_BUFFER_BIT = 0x00004000
Global Const $GL_TRIANGLES = 0x0004
Global Const $GL_BLEND = 0x0BE2
Global Const $GL_ONE = 1
Global Const $GL_DEPTH_BUFFER_BIT = 0x00000100

; Create GUI
Global $iWidth = 450
Global $iHeight = 450
Global $hGUI = GUICreate("OpenGL 3D Rotation", $iWidth, $iHeight)

GUISetBkColor(0) ; black


; Enable OpenGL
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

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

; About blending (not needed but to show it)
_glEnable($GL_BLEND) ; enable GL_BLEND
_glBlendFunc($GL_ONE, $GL_ONE) ; blending fashion

_glViewport(0, 0, $iWidth, $iHeight) ; position the view


; To keep it 'full' all the time
GUIRegisterMsg(133, "_Preserve") ; WM_NCPAINT

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


; Show GUI
GUISetState(@SW_SHOW, $hGUI)


Global $nM ; this to use for rotation


; Loop and draw till exit
While 1

    _GLDraw()
    Sleep(20)

WEnd



; Main drawing function
Func _GLDraw()

    _glClear(BitOR($GL_COLOR_BUFFER_BIT, $GL_DEPTH_BUFFER_BIT)) ; cleaning buffers

    $nM -= 0.5 ; decreasing. To rotate otherwise do increasing

    _glPopMatrix()
    _glPushMatrix()

    _glRotatef($nM, 1, 1, 1) ; this is actual rotation

    _glBegin($GL_TRIANGLES) ; draw triangle

    ; Will make square pyramid
    _glColor3f(0.5, 0, 0) ; red nuance
    _glVertex3f(0, 0.5, 0) ; front top
    _glColor3f(0, 0.5, 0) ; green nuance
    _glVertex3f(-0.5, -0.5, 0.5) ; front left
    _glColor3f(0, 0, 0.5) ; blue nuance
    _glVertex3f(0.5, -0.5, 0.5) ; front right

    _glColor3f(0.5, 0, 0) ; red nuance
    _glVertex3f(0, 0.5, 0) ; top right
    _glColor3f(0, 0, 0.5) ; blue nuance
    _glVertex3f(0.5, -0.5, 0.5) ; left right
    _glColor3f(0, 0.5, 0); green nuance
    _glVertex3f(0.5, -0.5, -0.5) ; right right

    _glColor3f(0.5, 0, 0) ; red nuance
    _glVertex3f(0, 0.5, 0) ; top back
    _glColor3f(0, 0.5, 0) ; green nuance
    _glVertex3f(0.5, -0.5, -0.5) ; left back
    _glColor3f(0, 0, 0.5) ; blue nuance
    _glVertex3f(-0.5, -0.5, -0.5) ; right back

    _glColor3f(0.5, 0, 0) ; red nuance
    _glVertex3f(0, 0.5, 0) ; top left
    _glColor3f(0, 0, 0.5) ; blue nuance
    _glVertex3f(-0.5, -0.5, -0.5) ; left left
    _glColor3f(0, 0.5, 0) ; green nuance
    _glVertex3f(-0.5, -0.5, 0.5) ; right left
    ; That's it

    _glEnd() ; end drawing

    _SwapBuffers($hDC) ; "refresh"

EndFunc   ;==>_GLDraw



; USED FUNCTIONS

; This is needed for initialization
Func _EnableOpenGL($hWnd, ByRef $hDeviceContext, ByRef $hOPENGL32RenderingContext)

    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($hUSER32, "hwnd", "GetDC", "hwnd", $hWnd)

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

    $hDeviceContext = $a_hCall[0]

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

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

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

    $hOPENGL32RenderingContext = $a_hCall[0]

    $a_iCall = DllCall($hOPENGL32, "int", "wglMakeCurrent", "hwnd", $hDeviceContext, "hwnd", $hOPENGL32RenderingContext)
    If @error Or Not $a_iCall[0] Then
        Return SetError(5, 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



; This is cleaning function
Func _DisableOpenGL($hWnd, $hDeviceContext, $hOPENGL32RenderingContext)

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

    DllCall($hOPENGL32, "int", "wglMakeCurrent", "hwnd", 0, "hwnd", 0)
    DllCall($hOPENGL32, "int", "wglDeleteContext", "hwnd", $hOPENGL32RenderingContext)
    DllCall($hUSER32, "int", "ReleaseDC", "hwnd", $hWnd, "hwnd", $hDeviceContext)

EndFunc   ;==>_DisableOpenGL



; Used GL functions
Func _glBegin($iMode)
    DllCall($hOPENGL32, "none", "glBegin", "dword", $iMode)
EndFunc   ;==>_glBegin

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

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

Func _glColor3f($red, $green, $blue)
    DllCall($hOPENGL32, "none", "glColor3f", "float", $red, "float", $green, "float", $blue)
EndFunc   ;==>_glColor3f

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

Func _glEnd()
    DllCall($hOPENGL32, "none", "glEnd")
EndFunc   ;==>_glEnd

Func _glLoadIdentity()
    DllCall($hOPENGL32, "none", "glLoadIdentity")
EndFunc   ;==>_glLoadIdentity

Func _glPopMatrix()
    DllCall($hOPENGL32, "none", "glPopMatrix")
EndFunc   ;==>_glPopMatrix

Func _glPushMatrix()
    DllCall($hOPENGL32, "none", "glPushMatrix")
EndFunc   ;==>_glPushMatrix

Func _glRotatef($nAngle, $nX, $nY, $nZ)
    DllCall($hOPENGL32, "none", "glRotatef", "float", $nAngle, "float", $nX, "float", $nY, "float", $nZ)
EndFunc   ;==>_glRotatef

Func _glVertex3f($x, $y, $z)
    DllCall($hOPENGL32, "none", "glVertex3f", "float", $x, "float", $y, "float", $z)
EndFunc   ;==>_glVertex3f

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

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


; Other functions
Func _SwapBuffers($hDC)
    DllCall($hGDI32, "int", "SwapBuffers", "hwnd", $hDC)
EndFunc   ;==>_SwapBuffers


; Two more used functions (wrappers)

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

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

In form of attachment: 3D Rotation Example.au3

Link to comment
Share on other sites

Here's one more. This time two parallel planes are manipulated. What's really new is drawing text.

#NoTrayIcon

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


; Used Dlls
Global Const $hUSER32 = DllOpen("user32.dll")
Global Const $hGDI32 = DllOpen("gdi32.dll")
Global Const $hOPENGL32 = DllOpen("opengl32.dll")

; General constants
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

; Used GL constants. See OpenGLConstants.au3
Global Const $GL_VERSION_1_1 = 1
Global Const $GL_COLOR_BUFFER_BIT = 0x00004000
Global Const $GL_QUADS = 0x0007
Global Const $GL_BLEND = 0x0BE2
Global Const $GL_ONE = 1
Global Const $GL_DEPTH_BUFFER_BIT = 0x00000100
Global Const $GL_ALL_ATTRIB_BITS = 0x000FFFFF
Global Const $GL_TRANSFORM_BIT = 0x00001000
Global Const $GL_VIEWPORT_BIT = 0x00000800
Global Const $GL_LIST_BIT = 0x00020000
Global Const $GL_UNSIGNED_BYTE = 0x1401

; Create GUI
Global $iWidth = 450
Global $iHeight = 450
Global $hGUI = GUICreate("OpenGL 3D rotation and font demo", $iWidth, $iHeight)

GUISetBkColor(0) ; black


; Enable OpenGL
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

; Font
Global $hFontList = _CreateOpenGLFont(20, 400, 256, "Segoe UI")

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

; About blending (not needed but to show it)
_glEnable($GL_BLEND) ; enable GL_BLEND
_glBlendFunc($GL_ONE, $GL_ONE) ; blending fashion

_glViewport(0, 0, $iWidth, $iHeight) ; position the view


; To keep it 'full' all the time
GUIRegisterMsg(133, "_Preserve") ; WM_NCPAINT

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


; Show GUI
GUISetState(@SW_SHOW, $hGUI)


Global $nM ; this to be used for rotation


; Loop and draw till exit
While 1

    _GLDraw()
    Sleep(25)

WEnd



; Main drawing function
Func _GLDraw()

    _glClear(BitOR($GL_COLOR_BUFFER_BIT, $GL_DEPTH_BUFFER_BIT)) ; cleaning buffers

    $nM -= 0.5 ; decreasing. To rotate otherwise do increasing

    _glPopMatrix()
    _glPushMatrix()

    ;Draw text
    _glColor3f(0.2, 0.3, 0.9) ; color of text
    _glDrawText(-0.8, -0.3, "3D rotation/translation of two", $hFontList)
    _glColor3f(0.8, 0.8, 0.2) ; new color
    _glDrawText(-0.45, -0.5, "parallel planes", $hFontList)

    ; Rotate
    _glRotatef($nM, 1, 1, 1)

    ; Start drawing
    _glBegin($GL_QUADS)

    ; Will make plane
    _glColor3f(0.7, 0, 0) ; red nuance
    _glVertex3f(0.5, 0.5, 0) ; front top

    _glColor3f(0.7, 0.7, 0) ; yellow nuance
    _glVertex3f(0.5, -0.5, 0) ; front right

    _glColor3f(0, 0.7, 0) ; green nuance
    _glVertex3f(-0.5, -0.5, 0) ; front left

    _glColor3f(0, 0, 0.7) ; blue nuance
    _glVertex3f(-0.5, 0.5, 0) ; front top
    ; That's it

    ; End drawing
    _glEnd()

    ; Dislocate it
    _glTranslatef(0.1, 0.1, 0.3)

    ; Start drawing again
    _glBegin($GL_QUADS)

    ; Will make new plane
    _glColor3f(0.7, 0, 0) ; red nuance
    _glVertex3f(0.5, 0.5, 0) ; front top

    _glColor3f(0.7, 0.7, 0) ; yellow nuance
    _glVertex3f(0.5, -0.5, 0) ; front right

    _glColor3f(0, 0.7, 0) ; green nuance
    _glVertex3f(-0.5, -0.5, 0) ; front left

    _glColor3f(0, 0, 0.7) ; blue nuance
    _glVertex3f(-0.5, 0.5, 0) ; front top
    ; That's it

    ; End drawing
    _glEnd()

    ; Replace old with the new one
    _SwapBuffers($hDC)

EndFunc   ;==>_GLDraw



; USED FUNCTIONS

; This is needed for initialization
Func _EnableOpenGL($hWnd, ByRef $hDeviceContext, ByRef $hOPENGL32RenderingContext)

    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($hUSER32, "hwnd", "GetDC", "hwnd", $hWnd)

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

    $hDeviceContext = $a_hCall[0]

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

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

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

    $hOPENGL32RenderingContext = $a_hCall[0]

    $a_iCall = DllCall($hOPENGL32, "int", "wglMakeCurrent", "hwnd", $hDeviceContext, "hwnd", $hOPENGL32RenderingContext)
    If @error Or Not $a_iCall[0] Then
        Return SetError(5, 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



; This is cleaning function
Func _DisableOpenGL($hWnd, $hDeviceContext, $hOPENGL32RenderingContext)

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

    DllCall($hOPENGL32, "int", "wglMakeCurrent", "hwnd", 0, "hwnd", 0)
    DllCall($hOPENGL32, "int", "wglDeleteContext", "hwnd", $hOPENGL32RenderingContext)
    DllCall($hUSER32, "int", "ReleaseDC", "hwnd", $hWnd, "hwnd", $hDeviceContext)

EndFunc   ;==>_DisableOpenGL



; Used GL functions (and few not used too)
Func _glBegin($iMode)
    DllCall($hOPENGL32, "none", "glBegin", "dword", $iMode)
EndFunc   ;==>_glBegin

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

Func _glCallListsChar($iSize, $iType, $pList)
    DllCall($hOPENGL32, "none", "glCallLists", "dword", $iSize, "dword", $iType, "str", $pList)
EndFunc   ;==>_glCallListsChar

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

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

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

Func _glColor4f($nRed, $nGreen, $nBlue, $nAlpha)
    DllCall($hOPENGL32, "none", "glColor4f", "float", $nRed, "float", $nGreen, "float", $nBlue, "float", $nAlpha)
EndFunc   ;==>_glColor4f

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

Func _glEnd()
    DllCall($hOPENGL32, "none", "glEnd")
EndFunc   ;==>_glEnd

Func _glListBase($iBase)
    DllCall($hOPENGL32, "none", "glListBase", "dword", $iBase)
EndFunc   ;==>_glListBase

Func _glLoadIdentity()
    DllCall($hOPENGL32, "none", "glLoadIdentity")
EndFunc   ;==>_glLoadIdentity

Func _glPopAttrib()
    DllCall($hOPENGL32, "none", "glPopAttrib")
EndFunc   ;==>_glPopAttrib

Func _glPopMatrix()
    DllCall($hOPENGL32, "none", "glPopMatrix")
EndFunc   ;==>_glPopMatrix

Func _glPushAttrib($iMask)
    DllCall($hOPENGL32, "none", "glPushAttrib", "dword", $iMask)
EndFunc   ;==>_glPushAttrib

Func _glPushMatrix()
    DllCall($hOPENGL32, "none", "glPushMatrix")
EndFunc   ;==>_glPushMatrix

Func _glRotatef($nAngle, $nX, $nY, $nZ)
    DllCall($hOPENGL32, "none", "glRotatef", "float", $nAngle, "float", $nX, "float", $nY, "float", $nZ)
EndFunc   ;==>_glRotatef

Func _glRasterPos2f($nX, $nY)
    DllCall($hOPENGL32, "none", "glRasterPos2f", "float", $nX, "float", $nY)
EndFunc   ;==>_glRasterPos2f

Func _glTranslatef($nX, $nY, $nZ)
    DllCall($hOPENGL32, "none", "glTranslatef", "float", $nX, "float", $nY, "float", $nZ)
EndFunc   ;==>_glTranslatef

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

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




; Other functions
Func _SwapBuffers($hDC)
    DllCall($hGDI32, "int", "SwapBuffers", "hwnd", $hDC)
EndFunc   ;==>_SwapBuffers


; Few more used functions (wrappers)

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


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


Func _glDrawText($iXcoordinate, $iYcoordinate, $sString, $hFontList)

    _glPushMatrix()
    _glRasterPos2f($iXcoordinate, $iYcoordinate)
    _glPushAttrib($GL_ALL_ATTRIB_BITS)
    _glListBase($hFontList)
    _glCallListsChar(StringLen($sString), $GL_UNSIGNED_BYTE, $sString) ; this function is in such form that it receives strings only (deliberately)
    _glPopAttrib()
    _glPopMatrix()

EndFunc   ;==>_glDrawText

; Font function
Func _CreateOpenGLFont($iSize = 8.5, $iWeight = 400, $iAttribute = 256, $sFontName = "", $hFontList = 0, $iNumberOf = 1)

    ; Get current DC (DC is global variable so this in not strictly necessary. But still... to have more freedom)
    Local $aCall = DllCall($hOPENGL32, "hwnd", "wglGetCurrentDC")

    If @error Or Not $aCall[0] Then
        Return SetError(1, 0, 0)
    EndIf

    Local $hDC = $aCall[0]

    ; This is needed to propery determine the size of the new font
    $aCall = DllCall($hGDI32, "int", "GetDeviceCaps", _
            "hwnd", $hDC, _
            "int", 90) ; LOGPIXELSY

    If @error Or Not $aCall[0] Then
        Return SetError(2, 0, 0)
    EndIf

    Local $iDCaps = $aCall[0]

    ; $iAttribute is complex. Contains more than one passed data.
    Local $iItalic = BitAND($iAttribute, 2)
    Local $iUnderline = BitAND($iAttribute, 4)
    Local $iStrikeout = BitAND($iAttribute, 8)

    Local $iQuality
    If BitAND($iAttribute, 16) Then
        $iQuality = 1 ; DRAFT_QUALITY
    ElseIf BitAND($iAttribute, 32) Then
        $iQuality = 2 ; PROOF_QUALITY
    ElseIf BitAND($iAttribute, 64) Then
        $iQuality = 3 ; NONANTIALIASED_QUALITY
    ElseIf BitAND($iAttribute, 128) Then
        $iQuality = 4 ; ANTIALIASED_QUALITY
    ElseIf BitAND($iAttribute, 256) Then
        $iQuality = 5 ; CLEARTYPE_QUALITY
    ElseIf BitAND($iAttribute, 512) Then
        $iQuality = 6 ; CLEARTYPE_COMPAT_QUALITY
    EndIf

    ; Create new font
    $aCall = DllCall($hGDI32, "ptr", "CreateFontW", _
            "int", -$iSize * $iDCaps / 72, _
            "int", 0, _
            "int", 0, _
            "int", 0, _
            "int", $iWeight, _
            "dword", $iItalic, _
            "dword", $iUnderline, _
            "dword", $iStrikeout, _
            "dword", 0, _
            "dword", 0, _
            "dword", 0, _
            "dword", $iQuality, _
            "dword", 0, _
            "wstr", $sFontName)

    If @error Or Not $aCall[0] Then
        Return SetError(3, 0, 0)
    EndIf

    Local $hFont = $aCall[0]

    ; New font to DC
    $aCall = DllCall($hGDI32, "hwnd", "SelectObject", "hwnd", $hDC, "hwnd", $hFont)

    If @error Or Not $aCall[0] Then
        DllCall($hGDI32, "int", "DeleteObject", "hwnd", $hFont)
        Return SetError(4, 0, 0)
    EndIf

    ; This was before
    Local $hOldFont = $aCall[0]

    ; If old FontList is passed delete it to free memory.
    If $hFontList Then DllCall($hOPENGL32, "dword", "glDeleteLists", "dword", $hFontList, "dword", $iNumberOf)

    ; Generate empty display list
    $aCall = DllCall($hOPENGL32, "dword", "glGenLists", "dword", 1)

    If @error Or Not $aCall[0] Then
        DllCall($hGDI32, "int", "DeleteObject", "hwnd", $hFont)
        Return SetError(5, 0, 0)
    EndIf

    $hFontList = $aCall[0]

    ; Make glyph bitmaps
    $aCall = DllCall($hOPENGL32, "int", "wglUseFontBitmapsW", _
            "ptr", $hDC, _
            "dword", 0, _
            "dword", 256, _
            "ptr", $hFontList)

    If @error Or Not $aCall[0] Then
        DllCall($hGDI32, "int", "DeleteObject", "hwnd", $hFont)
        Return SetError(6, 0, 0)
    EndIf

    ; There can be only one. Delete old font.
    DllCall($hGDI32, "int", "DeleteObject", "hwnd", $hOldFont)

    ; All OK. Return FontList
    Return SetError(0, 0, $hFontList)

EndFunc   ;==>_CreateOpenGLFont

3D Rotation Example1.au3

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...