Sign in to follow this  
Followers 0
Starg

Simple 3D Graphics with GDI+

50 posts in this topic




Nice work. If you set smoothing for the gfx handle it looks much better ;)
 

Func _S3d_SelectGraphic($hGraphic, $iWidth, $iHeight)
    $__S3d_hGraphic = $hGraphic
    $__S3d_iWidth = $iWidth
    $__S3d_iHeight = $iHeight
    _GDIPlus_GraphicsSetSmoothingMode($__S3d_hGraphic, 2)
EndFunc ;==>_S3d_SelectGraphic

Using matrices to rotate the object is cool.  :thumbsup: 
 
Br,
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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

UEZ,

Thanks for the advice.

Using matrices to rotate the object is cool. :thumbsup:

I'm going to write some examples to show the power of Local Matrices.

Share this post


Link to post
Share on other sites

This looks like something I can use.

I have a small program for editing meshes but it lacks a preview feature and have to use another program to see my results.

It is able to draw UV stamps for the models using GDI, so it shouldn't be too different to adapt to this.

This looks approachable. Thanks for sharing.  I'll be back with results after trying it out.

Share this post


Link to post
Share on other sites

UPDATE

New version (v1.1.0) released!

Please see the first post.

  • Added: _S3d_RegPolygon, _S3d_Star
  • Added: _S3d_LocalTranslate, _S3d_LocalScale, _S3d_LocalRotateX, _S3d_LocalRotateY, _S3d_LocalRotateZ
  • Added: _S3d_SelectGraphic sets smoothing mode for Graphics object
  • Changed: default value of $fFill in _S3d_Square changed to True

 

Enjoy!

Share this post


Link to post
Share on other sites

UPDATE

New version (v1.1.1) released! Please see the first post.

  • Added an example of _S3d_Star function.

Any comments are welcome.

Share this post


Link to post
Share on other sites

Using floating point calls gives the movement more smoothness:

S3d.au3

;=================================================
; S3d - Simple 3D Graphic Library
; v1.1.1 (26/JUL/2013)
;
; Author: Starg
;
; - Tested on: Windows XP SP3
; AutoIt v3.3.8.1, v3.3.9.12
; - Requires GDIPlus.au3
;
; * Use at your own risk!
;
; - Special Thanks: S.Programs
;=================================================

#include-once
#include <GDIPlus.au3>

;=================================================
; Constants
;=================================================

Global Const $__S3d_PI = 3.14159265358979

;=================================================
; Global Variables
;=================================================

Global $__S3d_hGraphic, $__S3d_iWidth, $__S3d_iHeight
Global $__S3d_nFAngleTan, $__S3d_nFScale

Global $__S3d_hPen, $__S3d_hBrush, $__S3d_hFont, $__S3d_hFormat

Global $__S3d_aConvertMatrix = __S3d_CreateMatrix()
Global $__S3d_aLocalMatrix = __S3d_CreateMatrix()
Global $__S3d_aCameraMatrix = __S3d_CreateMatrix()

Global $__S3d_aCameraPos[3]

; $__S3d_nPosBuf0X and $__S3d_nPosBuf0Y are used as "Current Position"
Global $__S3d_nPosBuf0X, $__S3d_nPosBuf0Y, $__S3d_nPosBuf1X, $__S3d_nPosBuf1Y


;=================================================
; Functions
;=================================================
; _S3d_SelectGraphic -- select a graphic object to write to
Func _S3d_SelectGraphic($hGraphic, $iWidth, $iHeight)
$__S3d_hGraphic = $hGraphic
$__S3d_iWidth = $iWidth
$__S3d_iHeight = $iHeight

_GDIPlus_GraphicsSetSmoothingMode($__S3d_hGraphic, 2) ; Thanks to UEZ
EndFunc ;==>_S3d_SelectGraphic

; _S3d_SelectPen -- select a pen object
Func _S3d_SelectPen($hPen)
$__S3d_hPen = $hPen
EndFunc ;==>_S3d_SelectPen

; _S3d_SelectBrush -- select a brush object
Func _S3d_SelectBrush($hBrush)
$__S3d_hBrush = $hBrush
EndFunc ;==>_S3d_SelectBrush

; _S3d_SelectFont -- select a Font object
Func _S3d_SelectFont($hFont)
$__S3d_hFont = $hFont
EndFunc ;==>_S3d_SelectFont

; _S3d_SelectFormat -- select a String Format object
Func _S3d_SelectFormat($hFormat)
$__S3d_hFormat = $hFormat
EndFunc ;==>_S3d_SelectFormat

;=================================================

; _S3d_Dist -- returns the distance betwenn two points
Func _S3d_Dist($nPos1X = 0, $nPos1Y = 0, $nPos1Z = 0, $nPos2X = 0, $nPos2Y = 0, $nPos2Z = 0)
Return Sqrt(($nPos2X - $nPos1X) ^ 2 + ($nPos2Y - $nPos1Y) ^ 2 + ($nPos2Z - $nPos1Z) ^ 2)
EndFunc ;==>_S3d_Dist

Func _S3d_DistFromCamera($nPosX = 0, $nPosY = 0, $nPosZ = 0)
Return Sqrt(($nPosX - $__S3d_aCameraPos[0]) ^ 2 + ($nPosY - $__S3d_aCameraPos[1]) ^ 2 + ($nPosZ - $__S3d_aCameraPos[2]) ^ 2)
EndFunc ;==>_S3d_DistFromCamera


; _S3d_SetCamera -- sets camera and target coordinates
Func _S3d_SetCamera($nCameraX, $nCameraY, $nCameraZ, $nTargetX, $nTargetY, $nTargetZ, $nVAngle = 0, $nFAngle = 0.8, $nFScale = 1000)

Local $nDist = _S3d_Dist($nTargetX, $nTargetY, $nTargetZ, $nCameraX, $nCameraY, $nCameraZ)
Local $nXYLen = _S3d_Dist($nTargetX, $nTargetY, 0, $nCameraX, $nCameraY, 0)

; cos(-a) = cos(a)
; sin(-a) = - sin(a)
Local $nXYCos = ($nTargetX - $nCameraX) / $nXYLen
Local $nXYSin = -($nTargetY - $nCameraY) / $nXYLen

Local $nXZCos = $nXYLen / $nDist
Local $nXZSin = -($nTargetZ - $nCameraZ) / $nDist

Local $aMxXY = __S3d_CreateMatrix(), $aMxXZ = __S3d_CreateMatrix(), $aMxV = __S3d_CreateMatrix()
Local $aTransMatrix = __S3d_CreateMatrix()
Local $aTempMatrix = __S3d_CreateMatrix()

__S3d_SetMatrix($aTransMatrix, _
1, 0, 0, -$nCameraX, _
0, 1, 0, -$nCameraY, _
0, 0, 1, -$nCameraZ, _
0, 0, 0, 1)

__S3d_SetMatrix($aMxXY, _
$nXYCos, -$nXYSin, 0, 0, _
$nXYSin, $nXYCos, 0, 0, _
0, 0, 1, 0, _
0, 0, 0, 1)

__S3d_SetMatrix($aMxXZ, _
$nXZCos, 0, -$nXZSin, 0, _
0, 1, 0, 0, _
$nXZSin, 0, $nXZCos, 0, _
0, 0, 0, 1)

__S3d_SetMatrix($aMxV, _
1, 0, 0, 0, _
0, Cos(-$nVAngle), -Sin(-$nVAngle), 0, _
0, Sin(-$nVAngle), Cos(-$nVAngle), 0, _
0, 0, 0, 1)

__S3d_MultiplyMatrix($__S3d_aCameraMatrix, $aMxXY, $aTransMatrix)
__S3d_MultiplyMatrix($aTempMatrix, $aMxXZ, $__S3d_aCameraMatrix)
__S3d_MultiplyMatrix($__S3d_aCameraMatrix, $aMxV, $aTempMatrix)

_S3d_SetLocalMatrix()

$__S3d_nFAngleTan = Tan($nFAngle)
$__S3d_nFScale = $nFScale

$__S3d_aCameraPos[0] = $nCameraX
$__S3d_aCameraPos[1] = $nCameraY
$__S3d_aCameraPos[2] = $nCameraZ
EndFunc ;==>_S3d_SetCamera

; _S3d_SetLocalMatrix - local coordinates -> world coordinates
Func _S3d_SetLocalMatrix( _
$n00 = 1, $n01 = 0, $n02 = 0, $n03 = 0, _
$n10 = 0, $n11 = 1, $n12 = 0, $n13 = 0, _
$n20 = 0, $n21 = 0, $n22 = 1, $n23 = 0, _
$n30 = 0, $n31 = 0, $n32 = 0, $n33 = 1)

__S3d_SetMatrix($__S3d_aLocalMatrix, _
$n00, $n01, $n02, $n03, _
$n10, $n11, $n12, $n13, _
$n20, $n21, $n22, $n23, _
$n30, $n31, $n32, $n33)

__S3d_MultiplyMatrix($__S3d_aConvertMatrix, $__S3d_aCameraMatrix, $__S3d_aLocalMatrix)

EndFunc ;==>_S3d_SetLocalMatrix

; _S3d_MultiplyLocalMatrix
Func _S3d_MultiplyLocalMatrix( _
$n00 = 1, $n01 = 0, $n02 = 0, $n03 = 0, _
$n10 = 0, $n11 = 1, $n12 = 0, $n13 = 0, _
$n20 = 0, $n21 = 0, $n22 = 1, $n23 = 0, _
$n30 = 0, $n31 = 0, $n32 = 0, $n33 = 1)

Local $aMatrix = __S3d_CreateMatrix(), $aBufLocalMatrix = $__S3d_aLocalMatrix

__S3d_SetMatrix($aMatrix, _
$n00, $n01, $n02, $n03, _
$n10, $n11, $n12, $n13, _
$n20, $n21, $n22, $n23, _
$n30, $n31, $n32, $n33)

__S3d_MultiplyMatrix($__S3d_aLocalMatrix, $aMatrix, $aBufLocalMatrix)
__S3d_MultiplyMatrix($__S3d_aConvertMatrix, $__S3d_aCameraMatrix, $__S3d_aLocalMatrix)

EndFunc ;==>_S3d_MultiplyLocalMatrix


Func _S3d_LocalTranslate($nX, $nY, $nZ)
_S3d_MultiplyLocalMatrix( _
1, 0, 0, $nX, _
0, 1, 0, $nY, _
0, 0, 1, $nZ, _
0, 0, 0, 1)

EndFunc ;==>_S3d_LocalTranslate

Func _S3d_LocalScale($nX, $nY, $nZ)
_S3d_MultiplyLocalMatrix( _
$nX, 0, 0, 0, _
0, $nY, 0, 0, _
0, 0, $nZ, 0, _
0, 0, 0, 1)

EndFunc ;==>_S3d_LocalScale

; $nAngle is radians if $fDeg is false, degrees if true.
Func _S3d_LocalRotateX($nAngle, $fDeg = False)
If $fDeg Then $nAngle = __S3d_Deg2Rad($nAngle)
_S3d_MultiplyLocalMatrix( _
1, 0, 0, 0, _
0, Cos($nAngle), -Sin($nAngle), 0, _
0, Sin($nAngle), Cos($nAngle), 0, _
0, 0, 0, 1)

EndFunc ;==>_S3d_LocalRotateX

Func _S3d_LocalRotateY($nAngle, $fDeg = False)
If $fDeg Then $nAngle = __S3d_Deg2Rad($nAngle)
_S3d_MultiplyLocalMatrix( _
Cos($nAngle), 0, -Sin($nAngle), 0, _
0, 1, 0, 0, _
Sin($nAngle), 0, Cos($nAngle), 0, _
0, 0, 0, 1)
EndFunc ;==>_S3d_LocalRotateY

Func _S3d_LocalRotateZ($nAngle, $fDeg = False)
If $fDeg Then $nAngle = __S3d_Deg2Rad($nAngle)
_S3d_MultiplyLocalMatrix( _
Cos($nAngle), -Sin($nAngle), 0, 0, _
Sin($nAngle), Cos($nAngle), 0, 0, _
0, 0, 1, 0, _
0, 0, 0, 1)
EndFunc ;==>_S3d_LocalRotateZ


Func _S3d_GetLocalMatrix()
Return $__S3d_aLocalMatrix
EndFunc ;==>_S3d_GetLocalMatrix

;=================================================

; _S3d_GetPos - converts 3D -> 2D
Func _S3d_GetPos($nX, $nY, $nZ)
Local $aPos[2]
__S3d_ConvertPos($aPos[0], $aPos[1], $nX, $nY, $nZ)
If @error Then Return SetError(1, 0, 0)
Return $aPos
EndFunc ;==>_S3d_GetPos

Func _S3d_MoveTo($nX, $nY, $nZ = Default)
If IsKeyword($nZ) Then
$__S3d_nPosBuf0X = $nX
$__S3d_nPosBuf0Y = $nY
Else
__S3d_ConvertPos($__S3d_nPosBuf0X, $__S3d_nPosBuf0Y, $nX, $nY, $nZ)
If @error Then Return SetError(1, 0, 0)
EndIf
Return 1
EndFunc ;==>_S3d_MoveTo

Func _S3d_Clear($nColor = 0xFF000000)
Return _GDIPlus_GraphicsClear($__S3d_hGraphic, $nColor)
EndFunc ;==>_S3d_Clear

Func _S3d_Line($nX1, $nY1, $nZ1, $nX2, $nY2, $nZ2)
Local $nOutX1, $nOutY1, $nOutX2, $nOutY2, $iError1, $iError2

__S3d_ConvertPos($nOutX1, $nOutY1, $nX1, $nY1, $nZ1)
$iError1 = @error
__S3d_ConvertPos($nOutX2, $nOutY2, $nX2, $nY2, $nZ2)
$iError2 = @error

If (Not $iError1) And (Not $iError2) Then
;~ _GDIPlus_GraphicsDrawLine($__S3d_hGraphic, $nOutX1, $nOutY1, $nOutX2, $nOutY2, $__S3d_hPen)
DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $__S3d_hGraphic, "handle", $__S3d_hPen, "float", $nOutX1, "float", $nOutY1, "float", $nOutX2, "float", $nOutY2)
Return 1
ElseIf (Not $iError1) Or (Not $iError2) Then
; clipping

Local $nAX, $nAY, $nAZ, $nBX, $nBY, $nBZ
Local $nCX, $nCY, $nCZ, $nPos3X, $nPos3Y

If Not $iError1 Then
$__S3d_nPosBuf0X = $nOutX1
$__S3d_nPosBuf0Y = $nOutY1

$nAX = $nX1
$nAY = $nY1
$nAZ = $nZ1

$nBX = $nX2
$nBY = $nY2
$nBZ = $nZ2
Else
$__S3d_nPosBuf0X = $nOutX2
$__S3d_nPosBuf0Y = $nOutY2

$nAX = $nX2
$nAY = $nY2
$nAZ = $nZ2

$nBX = $nX1
$nBY = $nY1
$nBZ = $nZ1
EndIf

Local $i
For $i = 1 To 10 ; 2 ^ 10 = 1024

$nCX = ($nAX + $nBX) / 2
$nCY = ($nAY + $nBY) / 2
$nCZ = ($nAZ + $nBZ) / 2

__S3d_ConvertPos($nPos3X, $nPos3Y, $nCX, $nCY, $nCZ)

If Not @error Then
$nAX = $nCX
$nAY = $nCY
$nAZ = $nCZ

;~ _GDIPlus_GraphicsDrawLine($__S3d_hGraphic, $__S3d_nPosBuf0X, $__S3d_nPosBuf0Y, $nPos3X, $nPos3Y, $__S3d_hPen)
DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $__S3d_hGraphic, "handle", $__S3d_hPen, "float", $__S3d_nPosBuf0X, "float", $__S3d_nPosBuf0Y, "float", $nPos3X, "float", $nPos3Y)

$__S3d_nPosBuf0X = $nPos3X
$__S3d_nPosBuf0Y = $nPos3Y
Else
$nBX = $nCX
$nBY = $nCY
$nBZ = $nCZ
EndIf

Next

Return 2
Else
Return 0
EndIf
EndFunc ;==>_S3d_Line

Func _S3d_LineTo($nX, $nY, $nZ)
Local $nOutX, $nOutY
__S3d_ConvertPos($nOutX, $nOutY, $nX, $nY, $nZ)

;~ _GDIPlus_GraphicsDrawLine($__S3d_hGraphic, $__S3d_nPosBuf0X, $__S3d_nPosBuf0Y, $nOutX, $nOutY, $__S3d_hPen)
DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $__S3d_hGraphic, "handle", $__S3d_hPen, "float", $__S3d_nPosBuf0X, "float", $__S3d_nPosBuf0Y, "float", $nOutX, "float", $nOutY)

$__S3d_nPosBuf0X = $nOutX
$__S3d_nPosBuf0Y = $nOutY
EndFunc ;==>_S3d_LineTo

Func _S3d_Box($nX1, $nY1, $nZ1, $nX2, $nY2, $nZ2)

_S3d_Line($nX1, $nY1, $nZ1, $nX2, $nY1, $nZ1)
_S3d_Line($nX2, $nY1, $nZ1, $nX2, $nY2, $nZ1)
_S3d_Line($nX2, $nY2, $nZ1, $nX1, $nY2, $nZ1)
_S3d_Line($nX1, $nY2, $nZ1, $nX1, $nY1, $nZ1)

_S3d_Line($nX1, $nY1, $nZ2, $nX2, $nY1, $nZ2)
_S3d_Line($nX2, $nY1, $nZ2, $nX2, $nY2, $nZ2)
_S3d_Line($nX2, $nY2, $nZ2, $nX1, $nY2, $nZ2)
_S3d_Line($nX1, $nY2, $nZ2, $nX1, $nY1, $nZ2)

_S3d_Line($nX1, $nY1, $nZ1, $nX1, $nY1, $nZ2)
_S3d_Line($nX1, $nY2, $nZ1, $nX1, $nY2, $nZ2)
_S3d_Line($nX2, $nY1, $nZ1, $nX2, $nY1, $nZ2)
_S3d_Line($nX2, $nY2, $nZ1, $nX2, $nY2, $nZ2)

EndFunc ;==>_S3d_Box

Func _S3d_Arrow($nX1, $nY1, $nZ1, $nX2, $nY2, $nZ2, $nLen = 30, $nAngle = 0.6)

If $nLen < 0 Then Return SetError(1, 0, 0)

Local $nPos1X, $nPos1Y, $nPos2X, $nPos2Y
__S3d_ConvertPos($nPos1X, $nPos1Y, $nX1, $nY1, $nZ1)
If @error Then Return SetError(2, 0, 0)
__S3d_ConvertPos($nPos2X, $nPos2Y, $nX2, $nY2, $nZ2)
If @error Then Return SetError(3, 0, 0)

;~ _GDIPlus_GraphicsDrawLine($__S3d_hGraphic, $nPos1X, $nPos1Y, $nPos2X, $nPos2Y, $__S3d_hPen)
DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $__S3d_hGraphic, "handle", $__S3d_hPen, "float", $nPos1X, "float", $nPos1Y, "float", $nPos2X, "float", $nPos2Y)

Local $nDist = _S3d_Dist($nPos1X, $nPos1Y, 0, $nPos2X, $nPos2Y, 0)

Local $nCenX = ($nPos1X - $nPos2X) / $nDist * $nLen
Local $nCenY = ($nPos1Y - $nPos2Y) / $nDist * $nLen

Local $nCos = Cos($nAngle), $nSin = Sin($nAngle)

Local $aPosA1X = $nCenX * $nCos - $nCenY * $nSin + $nPos2X
Local $aPosA1Y = $nCenX * $nSin + $nCenY * $nCos + $nPos2Y
; sin (-a) = - sin a
; cos (-a) = cos a
Local $aPosA2X = $nCenX * $nCos + $nCenY * $nSin + $nPos2X
Local $aPosA2Y = -$nCenX * $nSin + $nCenY * $nCos + $nPos2Y

;~ _GDIPlus_GraphicsDrawLine($__S3d_hGraphic, $nPos2X, $nPos2Y, $aPosA1X, $aPosA1Y, $__S3d_hPen)
DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $__S3d_hGraphic, "handle", $__S3d_hPen, "float", $nPos2X, "float", $nPos2Y, "float", $aPosA1X, "float", $aPosA1Y)
;~ _GDIPlus_GraphicsDrawLine($__S3d_hGraphic, $nPos2X, $nPos2Y, $aPosA2X, $aPosA2Y, $__S3d_hPen)
DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $__S3d_hGraphic, "handle", $__S3d_hPen, "float", $nPos2X, "float", $nPos2Y, "float", $aPosA2X, "float", $aPosA2Y)

Return 1
EndFunc ;==>_S3d_Arrow

Func _S3d_Circle($nX, $nY, $nZ, $nRad, $fFill = False)

If $nRad <= 0 Then Return SetError(1, 0, 0)
Local $nPosX, $nPosY
; (_S3d_DistFromCamera($nX, $nY, $nZ) * $__S3d_nFAngleTan) : $nRad = $__S3d_nFScale : $nVRad
Local $nVRad = $nRad * $__S3d_nFScale / _S3d_DistFromCamera($nX, $nY, $nZ) / $__S3d_nFAngleTan
__S3d_ConvertPos($nPosX, $nPosY, $nX, $nY, $nZ)
If @error Then Return SetError(2, 0, 0)

If $fFill Then
;~ Return _GDIPlus_GraphicsFillEllipse($__S3d_hGraphic, $nPosX - $nVRad, $nPosY - $nVRad, $nVRad * 2, $nVRad * 2, $__S3d_hBrush)
Return DllCall($ghGDIPDll, "int", "GdipFillEllipse", "handle", $__S3d_hGraphic, "handle", $__S3d_hBrush, "float", $nPosX - $nVRad, "float", $nPosY - $nVRad, "float", $nVRad * 2, "float", $nVRad * 2)
Else
;~ Return _GDIPlus_GraphicsDrawEllipse($__S3d_hGraphic, $nPosX - $nVRad, $nPosY - $nVRad, $nVRad * 2, $nVRad * 2, $__S3d_hPen)
Return DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $__S3d_hGraphic, "handle", $__S3d_hPen, "float", $nPosX - $nVRad, "float", $nPosY - $nVRad, "float", $nVRad * 2, "float", $nVRad * 2)
EndIf
EndFunc ;==>_S3d_Circle

; $aPoints[0][0] : The number of points
; $aPoints[n][0] : nth X
; $aPoints[n][1] : nth Y
; $aPoints[n][2] : nth Z
Func _S3d_Polygon($aPoints, $fFill = False)
If Not IsArray($aPoints) Then Return SetError(1, 0, 0)
Local $a2dPoints[$aPoints[0][0] + 1][2], $i
$a2dPoints[0][0] = $aPoints[0][0]

For $i = 1 To $aPoints[0][0]
__S3d_ConvertPos($a2dPoints[$i][0], $a2dPoints[$i][1], $aPoints[$i][0], $aPoints[$i][1], $aPoints[$i][2])
If @error Then Return SetError(2, $i, 0)
Next

If $fFill Then
;~ SetError(_GDIPlus_GraphicsFillPolygon($__S3d_hGraphic, $a2dPoints, $__S3d_hBrush))
SetError(_GDIPlus_GraphicsFillPolygonF($__S3d_hGraphic, $a2dPoints, $__S3d_hBrush))
Else
;~ _GDIPlus_GraphicsDrawPolygon($__S3d_hGraphic, $a2dPoints, $__S3d_hPen)
_GDIPlus_GraphicsDrawPolygonF($__S3d_hGraphic, $a2dPoints, $__S3d_hPen)
EndIf
Return 1
EndFunc ;==>_S3d_Polygon

; Always draw on XY plane
Func _S3d_RegPolygon($nX, $nY, $nZ, $nRad, $iNum, $fFill = True)
If $nRad <= 0 Then Return SetError(1, 0, 0)
If (Not IsInt($iNum)) Or $iNum <= 0 Then Return SetError(2, 0, 0)

Local $aPoints[$iNum + 1][3], $i, $nCurDir = 0
$aPoints[0][0] = $iNum

For $i = 1 To $iNum
$aPoints[$i][0] = $nX + $nRad * Cos($nCurDir)
$aPoints[$i][1] = $nY + $nRad * Sin($nCurDir)
$aPoints[$i][2] = $nZ
$nCurDir += $__S3d_PI * 2 / $iNum
Next

Return _S3d_Polygon($aPoints, $fFill)
EndFunc ;==>_S3d_RegPolygon

; Always draw on XY plane
Func _S3d_Star($nX, $nY, $nZ, $nRad1, $nRad2, $iNum, $fFill = True)
If $nRad1 <= 0 Then Return SetError(1, 0, 0)
If $nRad2 <= 0 Then Return SetError(2, 0, 0)
If (Not IsInt($iNum)) Or $iNum <= 0 Then Return SetError(3, 0, 0)

Local $aPoints[$iNum * 2 + 1][3], $i, $nCurDir = 0
$aPoints[0][0] = $iNum * 2

For $i = 1 To $iNum * 2 Step 2
$aPoints[$i][0] = $nX + $nRad1 * Cos($nCurDir)
$aPoints[$i][1] = $nY + $nRad1 * Sin($nCurDir)
$aPoints[$i][2] = $nZ
$nCurDir += $__S3d_PI / $iNum

$aPoints[$i + 1][0] = $nX + $nRad2 * Cos($nCurDir)
$aPoints[$i + 1][1] = $nY + $nRad2 * Sin($nCurDir)
$aPoints[$i + 1][2] = $nZ
$nCurDir += $__S3d_PI / $iNum
Next

Return _S3d_Polygon($aPoints, $fFill)
EndFunc ;==>_S3d_Star

Func _S3d_Square($nX1, $nY1, $nZ1, $nX2, $nY2, $nZ2, $nX3, $nY3, $nZ3, $nX4, $nY4, $nZ4, $fFill = True)
Local $aPoints[5][3] = [[4, 0, 0], [$nX1, $nY1, $nZ1], [$nX2, $nY2, $nZ2], [$nX3, $nY3, $nZ3], [$nX4, $nY4, $nZ4]]
Return _S3d_Polygon($aPoints, $fFill)
EndFunc ;==>_S3d_Square

Func _S3d_MoveTo2($nXL, $nYL, $nZL, $nXR, $nYR, $nZR)
__S3d_ConvertPos($__S3d_nPosBuf0X, $__S3d_nPosBuf0Y, $nXL, $nYL, $nZL)
If @error Then Return SetError(1, 0, 0)
__S3d_ConvertPos($__S3d_nPosBuf1X, $__S3d_nPosBuf1Y, $nXR, $nYR, $nZR)
If @error Then Return SetError(2, 0, 0)
Return 1
EndFunc ;==>_S3d_MoveTo2

Func _S3d_RibbonTo($nXL, $nYL, $nZL, $nXR, $nYR, $nZR)
Local $aPos[5][2]
$aPos[0][0] = 4

$aPos[1][0] = $__S3d_nPosBuf0X
$aPos[1][1] = $__S3d_nPosBuf0Y
$aPos[2][0] = $__S3d_nPosBuf1X
$aPos[2][1] = $__S3d_nPosBuf1Y

__S3d_ConvertPos($aPos[4][0], $aPos[4][1], $nXL, $nYL, $nZL)
If @error Then Return SetError(1, 0, 0)
__S3d_ConvertPos($aPos[3][0], $aPos[3][1], $nXR, $nYR, $nZR)
If @error Then Return SetError(2, 0, 0)

;~ _GDIPlus_GraphicsFillPolygon($__S3d_hGraphic, $aPos, $__S3d_hBrush)
_GDIPlus_GraphicsFillPolygonF($__S3d_hGraphic, $aPos, $__S3d_hBrush)

$__S3d_nPosBuf0X = $aPos[4][0]
$__S3d_nPosBuf0Y = $aPos[4][1]
$__S3d_nPosBuf1X = $aPos[3][0]
$__S3d_nPosBuf1Y = $aPos[3][1]

EndFunc ;==>_S3d_RibbonTo

Func _S3d_String($sString, $nX, $nY, $nZ)
Local $nPosX, $nPosY
__S3d_ConvertPos($nPosX, $nPosY, $nX, $nY, $nZ)
If @error Then Return SetError(1, 0, 0)

Local $tLayout = _GDIPlus_RectFCreate($nPosX, $nPosY, 0, 0)
Local $aInfo = _GDIPlus_GraphicsMeasureString($__S3d_hGraphic, $sString, $__S3d_hFont, $tLayout, $__S3d_hFormat)
Return _GDIPlus_GraphicsDrawStringEx($__S3d_hGraphic, $sString, $__S3d_hFont, $aInfo[0], $__S3d_hFormat, $__S3d_hBrush)
EndFunc ;==>_S3d_String

;=================================================
; Functions (Internal use only)
;=================================================

; __S3d_Rotate -- ($nInX, $nInY) -> ($nOutX, $nOutY)
Func __S3d_Rotate(ByRef $nOutX, ByRef $nOutY, $nInX, $nInY, $nCenterX, $nCenterY, $nAngle)
$nOutX = ($nInX - $nCenterX) * Cos($nAngle) - ($nInY - $nCenterY) * Sin($nAngle) + $nInX
$nOutY = ($nInX - $nCenterX) * Sin($nAngle) + ($nInY - $nCenterY) * Cos($nAngle) + $nInY
EndFunc ;==>__S3d_Rotate

Func __S3d_CreateMatrix()
Local $aMatrix[4][4], $i, $j

For $i = 0 To 3
For $j = 0 To 3
$aMatrix[$i][$j] = 0
Next
Next

Return $aMatrix
EndFunc ;==>__S3d_CreateMatrix

Func __S3d_SetMatrix(ByRef $aMatrix, _
$n00 = 1, $n01 = 0, $n02 = 0, $n03 = 0, _
$n10 = 0, $n11 = 1, $n12 = 0, $n13 = 0, _
$n20 = 0, $n21 = 0, $n22 = 1, $n23 = 0, _
$n30 = 0, $n31 = 0, $n32 = 0, $n33 = 1)

$aMatrix[0][0] = $n00
$aMatrix[0][1] = $n01
$aMatrix[0][2] = $n02
$aMatrix[0][3] = $n03

$aMatrix[1][0] = $n10
$aMatrix[1][1] = $n11
$aMatrix[1][2] = $n12
$aMatrix[1][3] = $n13

$aMatrix[2][0] = $n20
$aMatrix[2][1] = $n21
$aMatrix[2][2] = $n22
$aMatrix[2][3] = $n23

$aMatrix[3][0] = $n30
$aMatrix[3][1] = $n31
$aMatrix[3][2] = $n32
$aMatrix[3][3] = $n33

EndFunc ;==>__S3d_SetMatrix


; $aOutMatrix = $nInMatrix1 * $nInMatrix2
Func __S3d_MultiplyMatrix(ByRef $aOutMatrix, ByRef $aInMatrix1, ByRef $aInMatrix2)

Local $i, $j, $k
For $i = 0 To 3
For $j = 0 To 3
$aOutMatrix[$i][$j] = 0
For $k = 0 To 3
$aOutMatrix[$i][$j] += $aInMatrix1[$i][$k] * $aInMatrix2[$k][$j]
Next
Next
Next

EndFunc ;==>__S3d_MultiplyMatrix

; __S3d_ConvertPos - converts 3D -> 2D
Func __S3d_ConvertPos(ByRef $nOutX, ByRef $nOutY, $nInX, $nInY, $nInZ)

Local $aInPos[4] = [$nInX, $nInY, $nInZ ,1], $aOutPos[4] = [0, 0, 0, 0], $i, $j
For $i = 0 To 3
For $j = 0 To 3
$aOutPos[$i] += $__S3d_aConvertMatrix[$i][$j] * $aInPos[$j]
Next
Next

If $aOutPos[0] <= 0 Then Return SetError(1, 0, 0) ; behind the camera

$nOutX = (- $aOutPos[1] / $aOutPos[0] / $__S3d_nFAngleTan) * ($__S3d_nFScale / 2) + ($__S3d_iWidth / 2)
$nOutY = (- $aOutPos[2] / $aOutPos[0] / $__S3d_nFAngleTan) * ($__S3d_nFScale / 2) + ($__S3d_iHeight / 2)

Return 1
EndFunc ;==>__S3d_ConvertPos

Func __S3d_Deg2Rad($nDeg)
Return $nDeg / 180 * $__S3d_PI
EndFunc ;==>__S3d_Deg2Rad

Func _GDIPlus_GraphicsFillPolygonF($hGraphics, $aPoints, $hBrush = 0)
Local $iCount = $aPoints[0][0]
Local $tPoints = DllStructCreate("float[" & $iCount * 2 & "]")
For $iI = 1 To $iCount
DllStructSetData($tPoints, 1, $aPoints[$iI][0], (($iI - 1) * 2) + 1)
DllStructSetData($tPoints, 1, $aPoints[$iI][1], (($iI - 1) * 2) + 2)
Next

__GDIPlus_BrushDefCreate($hBrush)
Local $aResult = DllCall($ghGDIPDll, "int", "GdipFillPolygon", "handle", $hGraphics, "handle", $hBrush, _
"struct*", $tPoints, "int", $iCount, "int", "FillModeAlternate")
Local $tmpError = @error, $tmpExtended = @extended
__GDIPlus_BrushDefDispose()
If $tmpError Then Return SetError($tmpError, $tmpExtended, False)
Return $aResult[0] = 0
EndFunc ;==>_GDIPlus_GraphicsFillPolygon

Func _GDIPlus_GraphicsDrawPolygonF($hGraphics, $aPoints, $hPen = 0)
Local $iCount = $aPoints[0][0]
Local $tPoints = DllStructCreate("float[" & $iCount * 2 & "]")
For $iI = 1 To $iCount
DllStructSetData($tPoints, 1, $aPoints[$iI][0], (($iI - 1) * 2) + 1)
DllStructSetData($tPoints, 1, $aPoints[$iI][1], (($iI - 1) * 2) + 2)
Next

__GDIPlus_PenDefCreate($hPen)
Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawPolygon", "handle", $hGraphics, "handle", $hPen, "struct*", $tPoints, "int", $iCount)
Local $tmpError = @error, $tmpExtended = @extended
__GDIPlus_PenDefDispose()
If $tmpError Then Return SetError($tmpError, $tmpExtended, False)
Return $aResult[0] = 0
EndFunc ;==>_GDIPlus_GraphicsDrawPolygon

Br,

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Enjoying this.

 

I have a question about _S3d_SetCamera()

 

I am drawing a wireframe of a mesh using a vertex list and a triangle list. ( _S3d_Line() works perfect for this. )

 

But I am having trouble positioning the camera.

_S3d_SetCamera() accepts $position_x, $position_y, $position_z and $target_x, $target_y, $target_z

Target is behaving exactly how I expect it to.

But when changing the position values, it seems to be rotating the view instead of translating.

  

Local $position_x = $Model_Width / 2
Local $position_y = $Model_Height / 2
Local $position_z = $Model_depth * 2 ; guessing
Local $target_x = 0
Local $target_y = 0
Local $target_z = 0

_S3d_SetCamera( $position_x, $position_y, $position_z, $target_x, $target_y, $target_z )
I expected this to put the camera at roughly the center of mass in the x/y plane and some amount out along the z plane, looking at the mesh's feet (which are at 0,0,0.)

Instead it is below and somewhere behind the origin.

I am assuming x is left-right, y is up-down, and z is fore-aft.

Is this correct?

And do the position values translate or rotate? Or am I missing something completely.

(attached a pic to show that it is indeed drawing.. which I find to be very cool.)

post-66299-0-22428900-1374910449_thumb.p

Share this post


Link to post
Share on other sites

I am assuming x is left-right, y is up-down, and z is fore-aft.

Is this correct?

By default, z is up-down.

 

And do the position values translate or rotate? Or am I missing something completely.

To translate the view, you need to change both Position and Target.

Example:

_S3d_SetCamera(500 + $i, 200, 300, $i, 0, 0)

Share this post


Link to post
Share on other sites

I'm glad it was just a difference of axis alignments. I can accommodate that by just switching how I load the data from the vertex list.

I started playing with the target values (instead of leaving them at 0) and the camera view began behaving as expected. Thanks for clearing that up.

I intend to use this as a wireframe preview for a little mesh editing tool. It's just enough to help identify pieces and features within the model (that's all that is needed.) Once I have a cleaner implementation of it, I'll post an example of the code that uses your functions here.

Thanks again for putting this together. I have ideas for working with 3d models, but am terrible at the math behind it.

Share this post


Link to post
Share on other sites

Thanks for using my UDF!

Example usage of _S3d_SetLocalMatrix

#include <GUIConstantsEx.au3>
#include <S3d.au3>

Main()

Func Main()
    ; Create a window and initialize GDI+
    Local $hGUI = GUICreate("S3d Example", 650, 550)
    GUISetState()
    _GDIPlus_Startup()
    
    Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics(650, 550, $hGraphics)
    Local $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    
    Local $hFormat = _GDIPlus_StringFormatCreate()
    Local $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    Local $hFont = _GDIPlus_FontCreate($hFamily, 30, 2)
    
    Local $hBrush = _GDIPlus_BrushCreateSolid(0xCC448844)
    
    ; Select a Graphic object
    ; width = 650, height = 550
    _S3d_SelectGraphic($hGraphic, 650, 550)
    
    ; Select brush, font, and format object
    _S3d_SelectBrush($hBrush)
    _S3d_SelectFont($hFont)
    _S3d_SelectFormat($hFormat)
    
    Local $hPenB = _GDIPlus_PenCreate(0xAA0044FF, 2)
    Local $hPenR = _GDIPlus_PenCreate(0xAAFF6633, 3)
    
    Local $i = 0
    ; Loop until user exits
    Do
        ; Clear the Graphics object
        _S3d_Clear(0xFFFFFFFF)
        
        ; Set camera
        _S3d_SetCamera(500 * Cos($i), 500 * Sin($i), 300 * Cos($i * 1.5), 0, 0, 0)
        _GDIPlus_GraphicsDrawString($hGraphic, "Camera (" & Round(500 * Cos($i)) & ", " & Round(500 * Sin($i)) & ", " & Round(300 * Cos($i * 1.5)) & ")", 20, 20)
        
        ;**************************************************
        ; _S3d_SetLocalMatrix examples
        Switch 1   ; <- change this!
            Case 0
                ; do nothing
            Case 1
                ; Y <-> Z
                _S3d_SetLocalMatrix( _
                    1, 0, 0, 0, _
                    0, 0, 1, 0, _
                    0, 1, 0, 0, _
                    0, 0, 0, 1)
            Case 2
                ; Z -> -Z
                _S3d_SetLocalMatrix( _
                    1, 0,  0, 0, _
                    0, 1,  0, 0, _
                    0, 0, -1, 0, _
                    0, 0,  0, 1)
            Case 3
                ; X -> Y, Y -> Z, Z -> X
                _S3d_SetLocalMatrix( _
                    0, 1, 0, 0, _
                    0, 0, 1, 0, _
                    1, 0, 0, 0, _
                    0, 0, 0, 1)
            Case 4
                ; rotation in XZ plane by 2 radians   This is equivalent to _S3d_LocalRotateY(2)
                _S3d_SetLocalMatrix( _
                    Cos(2),      0, -Sin(2),      0, _
                         0,      1,       0,      0, _
                    Sin(2),      0,  Cos(2),      0, _
                         0,      0,       0,      1)
            Case 5
                ; X -> X + 300    This is equivalent to _S3d_LocalTranslate(300, 0, 0)
                _S3d_SetLocalMatrix( _
                    1, 0, 0, 300, _
                    0, 1, 0,   0, _
                    0, 0, 1,   0, _
                    0, 0, 0,   1)
            Case 6
                ; Z -> -Z
                _S3d_SetLocalMatrix( _
                    1, 0,  0, 0, _
                    0, 1,  0, 0, _
                    0, 0, -1, 0, _
                    0, 0,  0, 1)
                ; and then X -> X + 300
                _S3d_MultiplyLocalMatrix( _
                    1, 0, 0, 300, _
                    0, 1, 0,   0, _
                    0, 0, 1,   0, _
                    0, 0, 0,   1)
        EndSwitch
        ;**************************************************
        
        ; Select a pen obiect
        _S3d_SelectPen($hPenB)
        ; Draw cube
        _S3d_Box(-100, -100, -100, 100, 100, 100)
        
        ; Select a pen obiect
        _S3d_SelectPen($hPenR)
        
        ; Draw an arrow from (0, 0, 0) to (200, 0, 0)
        _S3d_Arrow(0, 0, 0, 200, 0, 0)
        ; Draw a string
        _S3d_String("X", 250, 0, 0)
        
        _S3d_Arrow(0, 0, 0, 0, 200, 0)
        _S3d_String("Y", 0, 250, 0)
        
        _S3d_Arrow(0, 0, 0, 0, 0, 200)
        _S3d_String("Z", 0, 0, 250)
        
        ; Copy to the window
        _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0)
        
        $i += 0.04
        Sleep(30)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    
    ; Clean up resources
    
    _GDIPlus_PenDispose($hPenB)
    _GDIPlus_PenDispose($hPenR)
    _GDIPlus_BrushDispose($hBrush)
    
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    
    GUIDelete($hGUI)
EndFunc ;==>Main

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

I made this FPS controller a while back, all you need to do is add a 3-D world and edit the _PlayerTransform() funtion.

; Simple FPS style control, change the _PlayerTransform() function to use it in a game.
#include <Misc.au3>

; #PUBLIC VARIABLES# ==============================================================================
; Position and rotation of the player, change it to alter the starting position.
Global $anPlayerPosition[3] = [0, 0, 0]
Global $anPlayerRotation[2] = [180, 0]

Global $aiRotationLimit[2] = [180, 180] ; Limit for rotation, can be used to constrain rotation
Global $nWalkSpeed = 0.1 ; Speed when walking (W, A, S, D)
Global $nSprintSpeed = 0.25 ; Speed when sprinting (SHIFT+W)
Global $nJumpHeight = 10 ; Height when jumping (SPACE)
Global $nJumpSpeed = 1.5
Global $nFallSpeed = 1.0
Global $nClimbSpeed = 1.0
Global $nFloorHeight = 0 ; Height of the floor, change it and the player falls/climbs
; =================================================================================================

Global $fCrouched = False, $fJumping = False, $fGoingUp = False, $fLeftMouse = False
Global $hDLL = DllOpen("user32.dll")

; _FPS_Control() should get called every frame
AdlibRegister("_FPS_Control", 1000 / 30)
HotKeySet("{ESC}", "_Exit")
HotKeySet("{F2}", "_ChangeFloorHeight")

; The main loop (GUI, GDI+, etc) goes here
While 1
    Sleep(1000)
WEnd

; This function should move the player to the mew position
Func _PlayerTransform(ByRef $anPlayerPosition, ByRef $anPlayerRotation, $fCrouched, $fJumping, $fLeftMouse, $fMiddleMouse, $fRightMouse)
    ToolTip("XYZ = " & $anPlayerPosition[0] & ", " & $anPlayerPosition[1] & ", " & $anPlayerPosition[2] & @CRLF _
             & "Rot = " & $anPlayerRotation[0] & ", " & $anPlayerRotation[1] & @CRLF _
             & "$fCrouched = " & $fCrouched & @CRLF _
             & "$fJumping = " & $fJumping & @CRLF & @CRLF _
             & "$fLeftMouse = " & $fLeftMouse & @CRLF _
             & "$fMiddleMouse = " & $fMiddleMouse & @CRLF _
             & "$fRightMouse= " & $fRightMouse, 0, 0)
EndFunc   ;==>_PlayerTransform

Func _ChangeFloorHeight()
    $sInput = InputBox("", "Input the new value for $nFloorHeight" & @CRLF & "$nFloorHeight = " & $nFloorHeight)
    If @error = 0 Then
        $nFloorHeight = Number($sInput)
    EndIf
EndFunc   ;==>_ChangeFloorHeight

Func _Exit()
    DllClose($hDLL)
    Exit
EndFunc   ;==>_Exit

Func _FPS_Control()
    If MouseGetPos(0) <= 0 Then
        MouseMove(@DesktopWidth - 2, MouseGetPos(1), 0)
    ElseIf MouseGetPos(0) >= @DesktopWidth - 1 Then
        MouseMove(0, MouseGetPos(1), 0)
    EndIf

    $anPlayerRotation[0] = (MouseGetPos(0) - (@DesktopWidth / 2)) / (@DesktopWidth / 2) * $aiRotationLimit[0] + $aiRotationLimit[0]
    $anPlayerRotation[0] = Round($anPlayerRotation[0])

    $anPlayerRotation[1] = (MouseGetPos(1) - (@DesktopHeight / 2)) / (@DesktopHeight / 2) * $aiRotationLimit[1]
    $anPlayerRotation[1] = Round($anPlayerRotation[1])

    $fLeftMouse = _IsPressed("01", $hDLL)
    $fMiddleMouse = _IsPressed("04", $hDLL)
    $fRightMouse = _IsPressed("02", $hDLL)

    If _IsPressed("57", $hDLL) Then
        If _IsPressed("10", $hDLL) Then
            $anPlayerPosition[1] += $nSprintSpeed
        Else
            $anPlayerPosition[1] += $nWalkSpeed
        EndIf
    ElseIf _IsPressed("53", $hDLL) Then
        If _IsPressed("10", $hDLL) Then
            $anPlayerPosition[1] -= $nSprintSpeed
        Else
            $anPlayerPosition[1] -= $nWalkSpeed
        EndIf
    EndIf

    If _IsPressed("41", $hDLL) Then
        If _IsPressed("10", $hDLL) Then
            $anPlayerPosition[0] -= $nSprintSpeed
        Else
            $anPlayerPosition[0] -= $nWalkSpeed
        EndIf
    EndIf
    If _IsPressed("44", $hDLL) Then
        If _IsPressed("10", $hDLL) Then
            $anPlayerPosition[0] += $nSprintSpeed
        Else
            $anPlayerPosition[0] += $nWalkSpeed
        EndIf
    EndIf

    If _GetButtonUp("11", $hDLL) Then
        If $fCrouched Then
            $anPlayerPosition[2] = $nFloorHeight
        Else
            $anPlayerPosition[2] = $nFloorHeight - 5
        EndIf
        $fCrouched = Not $fCrouched
        $fJumping = False
    ElseIf $fJumping = False And _GetButtonUp("20", $hDLL) Then
        $fJumping = True
        $fGoingUp = True
    EndIf
    If $fJumping Then
        If $fGoingUp Then
            $anPlayerPosition[2] += $nJumpSpeed
        Else
            $anPlayerPosition[2] -= $nFallSpeed
        EndIf
        If $anPlayerPosition[2] >= $nFloorHeight + $nJumpHeight Then
            $fGoingUp = False
        EndIf
        If $fGoingUp = False Then
            If ($fCrouched And $anPlayerPosition[2] <= $nFloorHeight - 5) Or (Not $fCrouched And $anPlayerPosition[2] <= $nFloorHeight) Then
                $fJumping = False
            EndIf
        EndIf
    Else
        If ($fCrouched And $anPlayerPosition[2] < $nFloorHeight - 5) Or (Not $fCrouched And $anPlayerPosition[2] < $nFloorHeight) Then
            $anPlayerPosition[2] += $nClimbSpeed
        ElseIf ($fCrouched And $anPlayerPosition[2] > $nFloorHeight - 5) Or (Not $fCrouched And $anPlayerPosition[2] > $nFloorHeight) Then
            $anPlayerPosition[2] -= $nFallSpeed
        EndIf
        If $anPlayerPosition[2] <> $nFloorHeight And _IsBetween($anPlayerPosition[2], $nFloorHeight - $nFallSpeed, $nFloorHeight + $nClimbSpeed) Then
            If $fCrouched Then
                $anPlayerPosition[2] = $nFloorHeight - 5
            Else
                $anPlayerPosition[2] = $nFloorHeight
            EndIf
        EndIf
    EndIf

    ; Round the XYZ pos
    For $x = 0 To 2
        $anPlayerPosition[$x] = Round($anPlayerPosition[$x], 5)
    Next

    ; Call the tramsforming function
    _PlayerTransform($anPlayerPosition, $anPlayerRotation, $fCrouched, $fJumping, $fLeftMouse, $fMiddleMouse, $fRightMouse)
EndFunc   ;==>_FPS_Control

Func _IsBetween($iNumber, $iLowNum, $iHighNum)
    Return $iNumber >= $iLowNum And $iNumber <= $iHighNum
EndFunc   ;==>_IsBetween

Func _GetButtonUp($sHexKey, $vDLL)
    If _IsPressed($sHexKey, $vDLL) Then
        While _IsPressed($sHexKey, $vDLL)
            Sleep(10)
        WEnd
        Return True
    Else
        Return False
    EndIf
EndFunc   ;==>_GetButtonUp
Edited by DatMCEyeBall

"Just be fred, all we gotta do, just be fred."  -Vocaliod

"That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha

@tabhooked

Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

UPDATE

New version (v1.1.2) released! Please see the first post.

  • _S3d_Arrow and _S3d_Square now work even if some of the points (one for _S3d_Arrow, up to three for _S3d_Square) are behind the camera.

If you have written some example scripts that use S3d.au3, feel free to post them here.

Edited by Starg

Share this post


Link to post
Share on other sites

Very nice work. thank you.

regards

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

UPDATE

New version (v1.1.2) released! Please see the first post.

  • _S3d_Arrow and _S3d_Square now work even if some of the points is behind the camera.

If you have written some example scripts that use S3d.au3, feel free to post them here.

 

Could you add an array that stores all the drawn objects so when I call _S3d_SetCamera() it redraws all the objects

Edited by DatMCEyeBall

"Just be fred, all we gotta do, just be fred."  -Vocaliod

"That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha

@tabhooked

Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation

Share this post


Link to post
Share on other sites

Could you add an array that stores all the drawn objects so when I call _S3d_SetCamera() it redraws all the objects

Thanks for the suggestion. I think making a wrapper for it is better than changing S3d itself.

Share this post


Link to post
Share on other sites

You can make the help file >by means of it

Thanks. I'll try it.

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

This might help:

'?do=embed' frameborder='0' data-embedContent>>

Edited by DatMCEyeBall

"Just be fred, all we gotta do, just be fred."  -Vocaliod

"That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha

@tabhooked

Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation

Share this post


Link to post
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
Sign in to follow this  
Followers 0

  • Similar Content

    • c.haslam
      By c.haslam
      In my code, the mouse wheel causes the line to move up and down. It does move down to where the picture is, but is not seen there. This can be observed by scrolling down to the picture, and then up again: the line reappears as expected.
      How can I get the line to show on the picture? This seems to be a matter of transparency, but I have not found a way of getting the background of $graphLine to be transparent.
      The code is now:
      #include <ButtonConstants.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Opt('MustDeclareVars',1) Global Const $MK_SHIFT = 0x4 Global Const $MK_CONTROL = 0x8 GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL") Global $gY0,$gY1,$gForm1,$glblLine,$glblPic main() Func main() $gForm1 = GUICreate("Form1", 623, 601, 192, 114) $glblLine = GUICtrlCreateLabel("", 8, 8, 604, 137) $glblPic = GUICtrlCreateLabel("", 8, 8, 589, 500) Local $btn = GUICtrlCreateButton("Rotate", 472, 560, 65, 25) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### Local $oldY0,$oldY1 _GDIPlus_Startup() Local $h = GUICtrlGetHandle($glblLine) ; limit graphics to area of $label Local $GraphicLine = _GDIPlus_GraphicsCreateFromHWND($h) Local $hPen = _GDIPlus_PenCreate(0xFF000000,2) Local $image = _GDIPlus_ImageLoadFromFile('H:\a\P5130021.jpg') Local $h = GUICtrlGetHandle($glblPic) Local $GraphicPic = _GDIPlus_GraphicsCreateFromHWND($h) _GDIPlus_GraphicsDrawImage($GraphicPic,$image,0,0) $gY0 = 67 $gY1 = 67 _GDIPlus_GraphicsClear($GraphicLine,0) _GDIPlus_GraphicsDrawLine($GraphicLine, 10, $gY0, 350, $gY1, $hPen) ; Loop until the user exits. While True If $gY0<>$oldY0 Or $gY1<>$oldY1 Then _GDIPlus_GraphicsClear($GraphicLine,0xFFD4D0C8) _GDIPlus_GraphicsDrawLine($GraphicLine, 10, $gY0, 590, $gY1, $hPen) $oldY0 = $gY0 $oldY1 = $gY1 Else Switch GUIGetMsg() Case $GUI_EVENT_CLOSE,$btn Exit EndSwitch EndIf WEnd ; Clean up resources _GDIPlus_PenDispose($hPen) _GDIPlus_GraphicsDispose($GraphicLine) _GDIPlus_Shutdown() EndFunc Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam Local Const $ymax=500 Local $vec = GUIGetCursorInfo($gForm1) If $vec[4] = $glblLine Or $vec[4]=$glblPic Then Local $iDelta = BitShift($wParam, 16) ; positive = up Local $iKeys = _WinAPI_LoWord($wParam) If BitAND($iKeys,$MK_CONTROL)=$MK_CONTROL Then If BitAND($iKeys,$MK_SHIFT)=$MK_SHIFT Then ; do nothing Else If $iDelta > 0 And $gY0>3 Then $gY0 -= 1 If $iDelta < 0 And $gY0<$ymax Then $gY0 += 1 EndIf Else If BitAND($iKeys,$MK_SHIFT)=$MK_SHIFT Then If $iDelta > 0 And $gY1>3 Then $gY1 -= 1 If $iDelta < 0 And $gY1<$ymax Then $gY1 += 1 Else If $iDelta > 0 And $gY0>3 Then $gY0 -= 1 If $iDelta < 0 And $gY0<$ymax Then $gY0 += 1 If $iDelta > 0 And $gY1>3 Then $gY1 -= 1 If $iDelta < 0 And $gY1<$ymax Then $gY1 += 1 EndIf EndIf EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_MOUSEWHEEL Some other questions:
      Do I really need GDI+, or is there a simpler way? My code creates Graphics (canvases?) from labels. Is this legitimate? I have found MSDN to be un-helpful in learning GDI+. Is there a better learning tool?
    • spudw2k
      By spudw2k
      Here's a fun tool I put together.  It's a Plasma sandbox.  More features to come.

      This page was a useful resource for learning about this kind of Plasma implementation.
      Warning! Not Epileptic Friendly (probably)! Use at own Risk!
      I tried to curve the "default/initial" Plasma patterns so they aren't too erratic.  That doesn't mean you can't alter the Plasmas to be more erratic.  If you are sensitive to flashing colors and lights, use due caution.  
      #Region - Includes and Globals #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <ComboConstants.au3> #include <GuiComboBox.au3> #include <SliderConstants.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <GDIPlus.au3> #include <Misc.au3> ;#include <Array.au3> Opt("GUIOnEventMode", 1) Local $hDLL = DllOpen("user32.dll") Global Const $iWinMinWidth = @DesktopWidth * .25 Global Const $iWinMinHeight = @DesktopHeight * .25 Global $bIsPlaying = True, $bIsDrawing = False Global $hTimerFPS Global $iRows = 16, $iCols = 16 Global $iDisplayPlasma = 0, $iSelectPlasma = 0 Global $aPlasmaShapes[4] = ["($iX)", "($iY)", "($iX + $iY)", "Sqrt(($iX * $iX) + ($iY * $iY))"] ;~ Global $aPlasmas[4][7] = [[0, Random(6, 14, 1), 0, 0, 1, 0, 0], [1, Random(6, 14, 1), 0, 0, 0, 0, 0], [2, Random(8, 16,1 ), 0, 0, 1, 0, 0], [3, Random(8, 16, 1), 0, 0, Random(0,1,1), 0, 0]] ;Sine Wave | Spread | Position | Rotation | Spread Motion | Position Motion | Rotation Motion Global $aPlasmas[4][7] = [[0, Random(6, 14, 1), 0, 0, 0, 0, 0], [1, Random(6, 14, 1), 0, 0, 0, 0, 0], [2, Random(8, 16,1 ), 0, 0, 0, 0, 0], [3, Random(8, 16, 1), 0, 0, 0, 0, 0]] ;Sine Wave | Spread | Position | Rotation | Spread Motion | Position Motion | Rotation Motion Global $aPallete[256] Global $aPalleteSettings[3][3] = [[0, 128, 128], [-1.75, 128, 128], [1.75, 128, 128]] ;Position | Spread | Value Global $aPalleteDefaults = $aPalleteSettings Global $iPalleteShift = 0, $bPalleteShift = True, $iPalletShiftDirection = -5 #EndRegion - Includes and Globals #Region - Main GUI Global $aGUI[1] = ["id|hWnd"] Global Enum $hGUI = 1, $idMnuFile, $idMnuFileExit, $idMnuFilePlay, $idMnuOptions, $idMnuOptionsPallete, $idMnuOptionsPalleteShift, $idMnuOptionsEditor, $idMnuOptionsZoom, $idMnuOptionsZoomIn, $idMnuOptionsZoomOut, $iGUILast ReDim $aGUI[$iGUILast] Global Const $sVersion = "0.1" Global Const $sTitle = "Plasma_kIt - Version " & $sVersion $aGUI[$hGUI] = GUICreate($sTitle, $iWinMinWidth, $iWinMinHeight, -1, -1, BitOR($WS_SIZEBOX, $WS_MAXIMIZEBOX, $WS_MINIMIZEBOX)) GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit") $aGUI[$idMnuFile] = GUICtrlCreateMenu("&File") $aGUI[$idMnuFilePlay] = GUICtrlCreateMenuItem("&Pause", $aGUI[$idMnuFile]) GUICtrlSetOnEvent(-1, "_PlayToggle") $aGUI[$idMnuFileExit] = GUICtrlCreateMenuItem("E&xit", $aGUI[$idMnuFile]) GUICtrlSetOnEvent(-1, "_Exit") $aGUI[$idMnuOptions] = GUICtrlCreateMenu("&Options") $aGUI[$idMnuOptionsPallete] = GUICtrlCreateMenuItem("Pallete Mixer", $aGUI[$idMnuOptions]) GUICtrlSetOnEvent(-1, "_GUIPallete_Show") $aGUI[$idMnuOptionsPalleteShift] = GUICtrlCreateMenuItem("Pallete Shift", $aGUI[$idMnuOptions]) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlSetOnEvent(-1, "_GUIPallete_ShiftToggle") $aGUI[$idMnuOptionsEditor] = GUICtrlCreateMenuItem("Plasma Editor", $aGUI[$idMnuOptions]) GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_Show") $aGUI[$idMnuOptionsZoom] = GUICtrlCreateMenu("Zoom", $aGUI[$idMnuOptions]) $aGUI[$idMnuOptionsZoomIn] = GUICtrlCreateMenuItem("Zoom In" & @TAB & "+", $aGUI[$idMnuOptionsZoom]) GUICtrlSetOnEvent(-1, "_Zoom") $aGUI[$idMnuOptionsZoomOut] = GUICtrlCreateMenuItem("Zoom Out" & @TAB & "-", $aGUI[$idMnuOptionsZoom]) GUICtrlSetOnEvent(-1, "_Zoom") _GDIPlus_Startup() ;Start GDI+ UDF Global Const $hDC = _WinAPI_GetDC($aGUI[$hGUI]) Global Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, @DesktopWidth, @DesktopHeight) Global Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Global Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap) $hBackbuffer = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) ;_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;Sets the graphics object rendering quality (antialiasing) $hBrush = _GDIPlus_BrushCreateSolid(0x00000000) ;Brush for Coloring/Painting LED Pixels Local $aAccelKeys[5][2] = [["{+}", $aGUI[$idMnuOptionsZoomIn]], ["{NUMPADADD}", $aGUI[$idMnuOptionsZoomIn]], ["{-}", $aGUI[$idMnuOptionsZoomOut]], ["{NUMPADSUB}", $aGUI[$idMnuOptionsZoomOut]], ["{pause}", $aGUI[$idMnuFilePlay]]] GUISetAccelerators($aAccelKeys) #EndRegion - Main GUI #Region - Pallete Mixer GUI Global $aGUIPallete[1] = ["id|hWnd"] Global Enum $hGUIPallete = 1, $idSliderRPosition, $idSliderRValue, $idSliderRSpread, $idSliderGPosition, $idSliderGValue, _ $idSliderGSpread, $idSliderBPosition, $idSliderBValue, $idSliderBSpread, $idBtnResetPallete, $iGUIPalleteLast ReDim $aGUIPallete[$iGUIPalleteLast] $aGUIPallete[$hGUIPallete] = GUICreate("Pallete Mixer", 338, 260, -1, -1) GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIPallete_Hide") $aGUIPallete[$idSliderRPosition] = GUICtrlCreateSlider(8, 132, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 20, -20) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderRValue] = GUICtrlCreateSlider(48, 56, 33, 73, BitOR($TBS_VERT, $TBS_ENABLESELRANGE)) GUICtrlSetLimit(-1, 128, 0) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderRSpread] = GUICtrlCreateSlider(8, 168, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 24, 2) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderGPosition] = GUICtrlCreateSlider(120, 132, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 20, -20) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderGValue] = GUICtrlCreateSlider(160, 56, 33, 73, BitOR($TBS_VERT, $TBS_ENABLESELRANGE)) GUICtrlSetLimit(-1, 128, 0) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderGSpread] = GUICtrlCreateSlider(120, 168, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 24, 2) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderBPosition] = GUICtrlCreateSlider(232, 132, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 20, -20) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") GUICtrlSetData(-1, 9) $aGUIPallete[$idSliderBValue] = GUICtrlCreateSlider(272, 56, 33, 73, BitOR($TBS_VERT, $TBS_ENABLESELRANGE)) GUICtrlSetLimit(-1, 128, 0) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") $aGUIPallete[$idSliderBSpread] = GUICtrlCreateSlider(232, 168, 97, 33, $TBS_ENABLESELRANGE) GUICtrlSetLimit(-1, 24, 2) GUICtrlSetData(-1, 11) ;~ GUICtrlSetOnEvent(-1, "_GUIPallete_SettingsChange") GUICtrlCreateLabel("RED", 46, 200, 30, 20) GUICtrlCreateLabel("GREEN", 150, 200, 38, 20) GUICtrlCreateLabel("BLUE", 268, 200, 30, 20) $aGUIPallete[$idBtnResetPallete] = GUICtrlCreateButton("Reset", 136, 236, 67, 17) GUICtrlSetOnEvent(-1, "_GUIPallete_Reset") GUISetAccelerators($aAccelKeys) Global Const $hDCPallete = _WinAPI_GetDC($aGUIPallete[$hGUIPallete]) Global Const $hHBitmapPallete = _WinAPI_CreateCompatibleBitmap($hDCPallete, 320, 40) Global Const $hDC_backbufferPallete = _WinAPI_CreateCompatibleDC($hDCPallete) Global Const $DC_objPallete = _WinAPI_SelectObject($hDC_backbufferPallete, $hHBitmapPallete) Global Const $hBackbufferPallete = _GDIPlus_GraphicsCreateFromHDC($hDC_backbufferPallete) Global $hBrushPallete = _GDIPlus_BrushCreateSolid(0xFF000000) ;~ _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;Sets the graphics object rendering quality (antialiasing) _GUIPallete_Update() _GUIPallete_Reset() #EndRegion - Pallete Mixer GUI #Region - Plasma Editor GUI Global $aGUIPlasmaEditor[1] = ["id|hWnd"] Global Enum $hGUIPlasmaEditor = 1, $idCmbPlasmaSelector, $idCmbPlasmaDisplay, $idBtnPlasmaAdd, $idBtnPlasmaDel, $idCmbPlasmaShape, $idSliderPlasmaSpread, $idCmbPlasmaSpread, $idSliderPlasmaRotation, $idCmbPlasmaRotation, $idSliderPlasmaPosition, $idCmbPlasmaPosition, $iGUIPlasmaEditorLast ReDim $aGUIPlasmaEditor[$iGUIPlasmaEditorLast] $aGUIPlasmaEditor[$hGUIPlasmaEditor] = GUICreate("Plasma Editor", 419, 323, -1, -1) GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIPlasmaEditor_Hide") GUICtrlCreateLabel("Display", 16, 8, 95, 17) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") $aGUIPlasmaEditor[$idCmbPlasmaDisplay] = GUICtrlCreateCombo("", 16, 24, 121, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "All Combined|Selected Plasma", "All Combined") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaDisplay") GUICtrlCreateLabel("Selected Plasma", 24, 96, 120, 17) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") $aGUIPlasmaEditor[$idBtnPlasmaAdd] = GUICtrlCreateButton("Add Plasma", 160, 16, 113, 33) GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaAddRem") GUICtrlSetState(-1, $GUI_DISABLE) $aGUIPlasmaEditor[$idBtnPlasmaDel] = GUICtrlCreateButton("Remove Plasma", 296, 16, 113, 33) GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaAddRem") GUICtrlSetState(-1, $GUI_DISABLE) GUICtrlCreateGroup("Plasma Controls", 8, 64, 401, 249) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") $aGUIPlasmaEditor[$idCmbPlasmaSelector] = GUICtrlCreateCombo("", 24, 112, 121, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Plasma #1|Plasma #2|Plasma #3|Plasma #4", "Plasma #1") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSelect") GUICtrlCreateLabel("Shape", 174, 96, 35, 17) $aGUIPlasmaEditor[$idCmbPlasmaShape] = GUICtrlCreateCombo("", 174, 112, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Horizontal|Vertical|Diagonal|Circular", "Horizontal") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetShape") GUICtrlCreateLabel("Spread", 24, 145, 38, 17) $aGUIPlasmaEditor[$idSliderPlasmaSpread] = GUICtrlCreateSlider(16, 160, 257, 25, $TBS_FIXEDLENGTH) GUICtrlSetLimit(-1, 255, 5) $aGUIPlasmaEditor[$idCmbPlasmaSpread] = GUICtrlCreateCombo("", 280, 160, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Static|Oscillate", "Static") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetSpread") GUICtrlCreateLabel("Rotation", 24, 201, 44, 17) GUICtrlSetState(-1, $GUI_DISABLE) $aGUIPlasmaEditor[$idSliderPlasmaRotation] = GUICtrlCreateSlider(16, 216, 257, 25, $TBS_FIXEDLENGTH) GUICtrlSetState(-1, $GUI_DISABLE) $aGUIPlasmaEditor[$idCmbPlasmaRotation] = GUICtrlCreateCombo("", 280, 216, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Static|Oscillate", "Static") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetRotation") GUICtrlSetState(-1, $GUI_DISABLE) GUICtrlCreateLabel("Position", 24, 257, 41, 17) GUICtrlSetState(-1, $GUI_DISABLE) $aGUIPlasmaEditor[$idSliderPlasmaPosition] = GUICtrlCreateSlider(16, 272, 257, 25, $TBS_FIXEDLENGTH) GUICtrlSetLimit(-1, 127, -127) GUICtrlSetState(-1, $GUI_DISABLE) $aGUIPlasmaEditor[$idCmbPlasmaPosition] = GUICtrlCreateCombo("", 280, 272, 113, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Static|Oscillate", "Static") GUICtrlSetOnEvent(-1, "_GUIPlasmaEditor_PlasmaSetPosition") GUICtrlSetState(-1, $GUI_DISABLE) GUICtrlCreateGroup("", -99, -99, 1, 1) _GUIPlasmaEditor_PlasmaSettingsLoad($iSelectPlasma) ;_GUIPlasmaEditor_PlasmaControlsLock() GUISetAccelerators($aAccelKeys) #EndRegion - Plasma Editor GUI #Region - Initialization and Main Loop GUIRegisterMsg($WM_GETMINMAXINFO, "_WM_GETMINMAXINFO") GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") GUISetState(@SW_SHOW, $aGUI[$hGUI]) While 1 If $bIsPlaying And Not $bIsDrawing Then _DrawScreen(_RenderPlasma()) Sleep(10) WEnd #EndRegion - Initialization and Main Loop #Region - Main GUI Functions Func _DrawScreen($aPixels) ;If Function called while Drawing Return 0 If $bIsDrawing Then Return 0 ;Set Drawing Status Indictaor $bIsDrawing = True ;Create Timer for Drawing Performance/Duration Local $hTimer = TimerInit() ;Erase Bitmap Graphic _GDIPlus_GraphicsClear($hBackbuffer, 0xFFFFFFFF) ;Capture Client Window Size $aWinClientSize = WinGetClientSize($aGUI[$hGUI]) ;Setup Variables Local $iPixelIndex = 0 Local $iCol = $iCols Local $iRow = $iRows Local $iWidth = $aWinClientSize[0] / $iCol Local $iHeight = $aWinClientSize[1] / $iRow ;Draw Pixel Grid (Top-Left to Bottom Right) For $iY = 0 To $iRow - 1 For $iX = 0 To $iCol - 1 Local $dARGB = $aPixels[$iPixelIndex] ;Set Brush Color _GDIPlus_BrushSetSolidColor($hBrush, $dARGB) ;Draw "Pixel" _GDIPlus_GraphicsFillRect($hBackbuffer, $iX * $iWidth, $iY * $iHeight, $iWidth, $iHeight, $hBrush) ;Increment Pixel Counter $iPixelIndex += 1 If $iPixelIndex = UBound($aPixels) Then $iPixelIndex = 0 Next Next ;Draw Bitmap to Screen _WinAPI_BitBlt($hDC, 0, 0, $aWinClientSize[0], $aWinClientSize[1], $hDC_backbuffer, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI ;FPS Counter $hTimer = TimerDiff($hTimer) ;~ ConsoleWrite("Whole Process time: " & Round($hTimer / 1000, 3) & @CRLF) If $bIsPlaying Then If TimerDiff($hTimerFPS) >= 998 Then Local $iFPS = Round(1000 / $hTimer, 2) WinSetTitle($aGUI[$hGUI], "", $sTitle & " (" & $iFPS & " FPS) " & $iCols & " x " & $iRows) $hTimerFPS = TimerInit() EndIf Else ;Show FPS in Window Title WinSetTitle($aGUI[$hGUI], "", $sTitle) EndIf $bIsDrawing = False EndFunc ;==>_DrawScreen Func _Exit() ; Clean up resources _GUIPallete_Exit() GUIDelete($aGUIPallete[$hGUIPallete]) GUIDelete($aGUIPlasmaEditor[$hGUIPlasmaEditor]) GUIDelete($aGUI[$hGUI]) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hBackbuffer) _WinAPI_SelectObject($hDC, $DC_obj) _WinAPI_DeleteObject($hHBitmap) _WinAPI_ReleaseDC($hGUI, $hDC) _GDIPlus_Shutdown() DllClose($hDLL) Exit EndFunc ;==>_Exit Func _PlayToggle() ;Toggle Play State If Not $bIsPlaying Then ;Start Playing $bIsPlaying = True $hTimerFPS = TimerInit() GUICtrlSetData($aGUI[$idMnuFilePlay], "&Pause") Else ;Stop Playing $bIsPlaying = False GUICtrlSetData($aGUI[$idMnuFilePlay], "&Play") EndIf EndFunc ;==>_PlayToggle Func _RenderPlasma() ;Setup Variables Local $aWorkPallete = $aPallete Local $iRow = $iRows Local $iCol = $iCols Local $iGridSize = $iRow * $iCol Local $aPixels[$iGridSize] Local $iIndex = 0 Local $iPlasma = 0 Local $iPlasmas Local $iDisplayPlasmaNumber = $iDisplayPlasma Local $iSine, $iSpread, $iPosition ;Loop Through Pixel Grid and Calculate Plasma(s) For $iY = 0 To $iRow - 1 For $iX = 0 To $iCol - 1 $iPlasmas = 0 If Not $iDisplayPlasmaNumber Then For $iZ = 0 To UBound($aPlasmas) - 1 $iSine = $aPlasmas[$iZ][0] ;Spread Motions If $aPlasmas[$iZ][4] Then $aPlasmas[$iZ][4] += ($aPlasmas[$iZ][1] * 0.00001125) $iSpread = -7*Sin($aPlasmas[$iZ][4])+9 Else $iSpread = $aPlasmas[$iZ][1] EndIf $iPosition = $aPlasmas[$iZ][2] $iPlasma = Execute("128.0 + (128.0 * Sin(" & $aPlasmaShapes[$iSine] & " / " & $iSpread & "))") $iPlasmas += $iPlasma Next Else $iSine = $aPlasmas[$iDisplayPlasmaNumber - 1][0] ;Spread Motions If $aPlasmas[$iDisplayPlasmaNumber - 1][4] Then $aPlasmas[$iDisplayPlasmaNumber - 1][4] += ($aPlasmas[$iDisplayPlasmaNumber - 1][1] * 0.005) $iSpread = Sin($aPlasmas[$iDisplayPlasmaNumber - 1][4])/2 Else $iSpread = $aPlasmas[$iDisplayPlasmaNumber - 1][1] EndIf $iPosition = $aPlasmas[$iDisplayPlasmaNumber - 1][2] ;$iPlasmas = Execute("128.0 + (128.0 * Sin(" & $aPlasmaShapes[$aPlasmas[$iDisplayPlasmaNumber - 1][0]] & " / " & $aPlasmas[$iDisplayPlasmaNumber - 1][1] & ") - " & $aPlasmas[$iDisplayPlasmaNumber - 1][2] & ")") $iPlasmas = Execute("128.0 + (128.0 * Sin(" & $aPlasmaShapes[$iSine] & " / " & $iSpread & "))") EndIf $iPlasma = Int($iPlasmas) ;Account for Pallete Shift $iPlasma += $iPalleteShift ;Wrap Pixel Pallete Color If $iPlasma >= 256 Then Do $iPlasma -= 256 Until $iPlasma < 256 EndIf If $iPlasma <= -1 Then Do $iPlasma += 256 Until $iPlasma > -1 EndIf ;Set Pixel Color value from Pallete $aPixels[$iIndex] = $aWorkPallete[$iPlasma] ;Increment Pixel Index Counter $iIndex += 1 If $iIndex = $iGridSize Then $iIndex = 0 Next Next ;Pallete Shift Logic If $bPalleteShift Then $iPalleteShift += $iPalletShiftDirection If $iPalleteShift >= 256 Then $iPalleteShift = 0 If $iPalleteShift <= -1 Then $iPalleteShift = 255 EndIf Return $aPixels EndFunc ;==>_RenderPlasma Func _WM_GETMINMAXINFO($hwnd, $Msg, $wParam, $lParam) ;Only Control Size of Main GUI If $hwnd <> $aGUI[$hGUI] Then Return Default $tagMaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam) DllStructSetData($tagMaxinfo, 7, $iWinMinWidth) ; min X DllStructSetData($tagMaxinfo, 8, $iWinMinHeight) ; min Y Return 0 EndFunc ;==>_WM_GETMINMAXINFO Func _WM_NOTIFY($hwnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") ;Local $tInfo If Not _IsPressed("01", $hDLL) Then Return Default Switch $iIDFrom Case $aGUIPallete[$idSliderRPosition] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(0, -1, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderRValue] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(0, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderRSpread] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(0, -1, "", GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderGPosition] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(1, -1, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderGValue] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(1, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderGSpread] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(1, -1, "", GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderBPosition] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(2, -1, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderBValue] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(2, GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPallete[$idSliderBSpread] Switch $iCode Case $NM_CUSTOMDRAW _GUIPallete_ColorSet(2, -1, "", GUICtrlRead($iIDFrom)) EndSwitch Return 0 Case $aGUIPlasmaEditor[$idSliderPlasmaSpread] Switch $iCode Case $NM_CUSTOMDRAW $aPlasmas[$iSelectPlasma][1] = 0.2 * GUICtrlRead($iIDFrom) EndSwitch Return 0 Case $aGUIPlasmaEditor[$idSliderPlasmaRotation] Switch $iCode Case $NM_CUSTOMDRAW EndSwitch Return 0 Case $aGUIPlasmaEditor[$idSliderPlasmaPosition] Switch $iCode Case $NM_CUSTOMDRAW $aPlasmas[$iSelectPlasma - 1][2] = GUICtrlRead($iIDFrom) EndSwitch Return 0 EndSwitch Return 0 EndFunc ;==>_WM_NOTIFY Func _Zoom() Local $bPlaying = $bIsPlaying If $bPlaying Then $bIsPlaying = False Local $iCtrlID = @GUI_CtrlId Switch $iCtrlID Case $aGUI[$idMnuOptionsZoomOut] $iCols += 2 $iRows += 2 If $iCols >= 4 * 8 Then $iCols = 4 * 8 If $iRows >= 4 * 8 Then $iRows = 4 * 8 Case $aGUI[$idMnuOptionsZoomIn] $iCols -= 2 $iRows -= 2 If $iCols <= 4 Then $iCols = 4 If $iRows <= 4 Then $iRows = 4 EndSwitch If $bPlaying Then $bIsPlaying = $bPlaying EndFunc ;==>_Zoom #EndRegion - Main GUI Functions #Region - Pallete Mixer GUI Functions Func _GUIPallete_ColorSet($iColor, $iValue = -1, $iPosition = "", $iSpread = "") If $iValue >= 0 Then $aPalleteSettings[$iColor][2] = (128.0 - $iValue) If $iPosition Then $aPalleteSettings[$iColor][0] = (0.25 * $iPosition) If $iSpread Then $aPalleteSettings[$iColor][1] = ($iSpread ^ 2) Return _GUIPallete_Update() EndFunc ;==>_GUIPallete_ColorSet Func _GUIPallete_Draw() ;Draw Color Pallete in Palette Mixer GUI _GDIPlus_GraphicsClear($hBackbufferPallete, 0xFF000000) Local $iX = 0 For $iColor = 1 To 256 Local $dARGB = $aPallete[$iColor - 1] ;Set Brush Color _GDIPlus_BrushSetSolidColor($hBrushPallete, $dARGB) ;Draw Color Bar to Bitmap _GDIPlus_GraphicsFillRect($hBackbufferPallete, $iX, 0, 320 / 256, 40, $hBrushPallete) $iX += (320 / 256) Next ;Write Bitmap to Screen Return _WinAPI_BitBlt($hDCPallete, 8, 8, 320, 40, $hDC_backbufferPallete, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI EndFunc ;==>_GUIPallete_Draw Func _GUIPallete_Exit() ; Clean up resources GUIDelete() _GDIPlus_BrushDispose($hBrushPallete) _GDIPlus_GraphicsDispose($hBackbufferPallete) _WinAPI_SelectObject($hDCPallete, $DC_objPallete) _WinAPI_DeleteObject($hHBitmapPallete) _WinAPI_ReleaseDC($aGUIPallete[$hGUIPallete], $hDCPallete) Return 1 EndFunc ;==>_GUIPallete_Exit Func _GUIPallete_Hide() Return GUISetState(@SW_HIDE, $aGUIPallete[$hGUIPallete]) EndFunc ;==>_GUIPallete_Hide Func _GUIPallete_Reset() $aPalleteSettings = $aPalleteDefaults GUICtrlSetData($aGUIPallete[$idSliderRPosition], $aPalleteSettings[0][0] / 0.25) GUICtrlSetData($aGUIPallete[$idSliderRValue], 128 - $aPalleteSettings[0][2]) GUICtrlSetData($aGUIPallete[$idSliderRSpread], Sqrt($aPalleteSettings[0][1])) GUICtrlSetData($aGUIPallete[$idSliderGPosition], $aPalleteSettings[1][0] / 0.25) GUICtrlSetData($aGUIPallete[$idSliderGValue], 128 - $aPalleteSettings[1][2]) GUICtrlSetData($aGUIPallete[$idSliderGSpread], Sqrt($aPalleteSettings[1][1])) GUICtrlSetData($aGUIPallete[$idSliderBPosition], $aPalleteSettings[2][0] / 0.25) GUICtrlSetData($aGUIPallete[$idSliderBValue], 128 - $aPalleteSettings[2][2]) GUICtrlSetData($aGUIPallete[$idSliderBSpread], Sqrt($aPalleteSettings[2][1])) Return _GUIPallete_Update() EndFunc ;==>_GUIPallete_Reset Func _GUIPallete_ShiftToggle() ;Toggle Pallete Shift Local $iCtrlState = GUICtrlRead(@GUI_CtrlId) If BitAND($iCtrlState, $GUI_CHECKED) Then ;Disable PalleteShift $bPalleteShift = False GUICtrlSetState(@GUI_CtrlId, $GUI_UNCHECKED) Else ;Enable PalleteShift $bPalleteShift = True GUICtrlSetState(@GUI_CtrlId, $GUI_CHECKED) EndIf EndFunc ;==>_GUIPallete_ShiftToggle Func _GUIPallete_Show() GUISetState(@SW_SHOW, $aGUIPallete[$hGUIPallete]) _GUIPallete_Draw() EndFunc ;==>_GUIPallete_Show Func _GUIPallete_Update() ;Re-Calculate Work Color Pallete For $iStep = 0 To 255 Local $iR = Int($aPalleteSettings[0][2] + ($aPalleteSettings[0][2] * Sin((3.1415 * $iStep / $aPalleteSettings[0][1]) - $aPalleteSettings[0][0]))) Local $iG = Int($aPalleteSettings[1][2] + ($aPalleteSettings[1][2] * Sin((3.1415 * $iStep / $aPalleteSettings[1][1]) - $aPalleteSettings[1][0]))) Local $iB = Int($aPalleteSettings[2][2] + ($aPalleteSettings[2][2] * Sin((3.1415 * $iStep / $aPalleteSettings[2][1]) - $aPalleteSettings[2][0]))) $aPallete[$iStep] = "0xFF" & Hex($iR, 2) & Hex($iG, 2) & Hex($iB, 2) Next Return _GUIPallete_Draw() EndFunc ;==>_GUIPallete_Update #EndRegion - Pallete Mixer GUI Functions #Region - Plasma Editor GUI Functions Func _GUIPlasmaEditor_Hide() GUISetState(@SW_HIDE, $aGUIPlasmaEditor[$hGUIPlasmaEditor]) EndFunc ;==>_GUIPlasmaEditor_Hide Func _GUIPlasmaEditor_PlasmaAddRem() EndFunc ;==>_GUIPlasmaEditor_PlasmaAddRem Func _GUIPlasmaEditor_PlasmaDisplay() Local $sSelection = GUICtrlRead($aGUIPlasmaEditor[$idCmbPlasmaDisplay]) If $sSelection = "All Combined" Then $iDisplayPlasma = 0 Else $iDisplayPlasma = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSelector])+1 EndIf Return $iDisplayPlasma EndFunc ;==>_GUIPlasmaEditor_PlasmaDisplay Func _GUIPlasmaEditor_PlasmaSelect() Local $sSelection = GUICtrlRead($aGUIPlasmaEditor[$idCmbPlasmaSelector]) $iSelectPlasma = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSelector]) _GUIPlasmaEditor_PlasmaDisplay() Return _GUIPlasmaEditor_PlasmaSettingsLoad($iSelectPlasma) EndFunc ;==>_GUIPlasmaEditor_PlasmaSelect Func _GUIPlasmaEditor_PlasmaSetPosition() EndFunc ;==>_GUIPlasmaEditor_PlasmaSetPosition Func _GUIPlasmaEditor_PlasmaSetRotation() EndFunc ;==>_GUIPlasmaEditor_PlasmaSetRotation Func _GUIPlasmaEditor_PlasmaSetShape() $aPlasmas[$iSelectPlasma][0] = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaShape]) EndFunc ;==>_GUIPlasmaEditor_PlasmaSetShape Func _GUIPlasmaEditor_PlasmaSetSpread() $aPlasmas[$iSelectPlasma][4] = _GUICtrlComboBox_GetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSpread]) EndFunc ;==>_GUIPlasmaEditor_PlasmaSetSpread Func _GUIPlasmaEditor_PlasmaSettingsLoad(ByRef $iPlasma) GUICtrlSetData($aGUIPlasmaEditor[$idSliderPlasmaSpread],$aPlasmas[$iPlasma][1]/0.2) _GUICtrlComboBox_SetCurSel($aGUIPlasmaEditor[$idCmbPlasmaShape],$aPlasmas[$iPlasma][0]) If $aPlasmas[$iPlasma][4] Then _GUICtrlComboBox_SetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSpread],1) Else _GUICtrlComboBox_SetCurSel($aGUIPlasmaEditor[$idCmbPlasmaSpread],0) EndIf Return 1 EndFunc ;==>_GUIPlasmaEditor_PlasmaSettingsLoad Func _GUIPlasmaEditor_Show() GUISetState(@SW_SHOW, $aGUIPlasmaEditor[$hGUIPlasmaEditor]) EndFunc ;==>_GUIPlasmaEditor_Show #EndRegion - Plasma Editor GUI Functions edit: Minor tweaks
    • timmalos
      By timmalos
      Hey all.
      I'm trying to know when my user clicks on a Rect drawn via GDI+. Everything is almost working except I have a strange behaviour in the "order" clicks are fired.
      I created a simplified code to help :
      #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <WinAPI.au3> #include <Array.au3> Opt("GUIOnEventMode", 1) ;0=disabled, 1=OnEvent mode enabled _GDIPlus_Startup() Global $hGUI, $hGraphics Global $iWidth = 1024, $iHeight = 762 createGUI() draw() While 1 Sleep(10) WEnd Func createGUI() $hGUI = GUICreate("Current CasparCG Output", $iWidth,$iHeight) GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents") GUISetBkColor(0x000000) GUISetState(@SW_SHOW) $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;sets the graphics object rendering quality (antialiasing) EndFunc ;==>Example Func draw() ;_WinAPI_draw($hGUI,"","",BitOR($RDW_ERASE,$RDW_INVALIDATE,$RDW_UPDATENOW)) _GDIPlus_GraphicsClear($hGraphics) $hFamily = _GDIPlus_FontFamilyCreate("Arial") $hFont = _GDIPlus_FontCreate($hFamily, 15, 1) $hPen = _GDIPlus_PenCreate(0xFFFEDCFF, 2) ;color format AARRGGBB (hex) $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, 1) $hBrushString = _GDIPlus_BrushCreateSolid(0xFFFFFFFF) Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF00FF) ;color format AARRGGBB (hex) For $i = 1 to 2 Local $x = 0.25 Local $y = 0.25 Local $w = 0.5 Local $h = 0.5 Local $title = "Layer "&$i If $x >= -1 And $x <= 1 Then $x *= $iWidth If $y >= -1 And $y <= 1 Then $y *= $iHeight If $w >= -1 And $w <= 1 Then $w *= $iWidth If $h >= -1 And $h <= 1 Then $h *= $iHeight $hItem = GUICtrlCreateLabel("", $x,$y,$w,$h) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) GUICtrlSetOnEvent($hItem,"_gui_layer_clicked") ConsoleWrite("Created label with handle="&$hItem&" $i= " & $i&@CRLF) _GDIPlus_GraphicsFillRect($hGraphics, $x, $y, $w, $h,$hBrush) _GDIPlus_GraphicsDrawRect($hGraphics, $x, $y, $w, $h,$hPen) $tLayout = _GDIPlus_RectFCreate($x, $y, $w, $h) $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $title, $hFont, $tLayout, $hFormat) _GDIPlus_GraphicsDrawStringEx($hGraphics, $title, $hFont, $aInfo[0], $hFormat, $hBrushString) Next _GDIPlus_BrushDispose($hBrush) _GDIPlus_PenDispose($hPen) _GDIPlus_FontDispose($hFont) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_BrushDispose($hBrushString) Return 1 EndFunc Func _gui_layer_clicked() ConsoleWrite("Clicked on " & @GUI_CtrlId&@CRLF) EndFunc Func SpecialEvents() Select Case @GUI_CtrlId = $GUI_EVENT_CLOSE ; Clean up resources _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() Exit EndSelect EndFunc ;==>SpecialEvents What happens there :
      We have two rectangles, with the one labelled "2" is front and, the one labelled "1" in background. However when we click, the fired label is the one created first (in the background) and not the second one (in the front).
      Is it normal ?
      If yes, is there any way to change this order ? If I create another label after a first one on the same coords, I would the second one to be fired instead of the first one (This is a simplified code I can't just invert the label order creation easily)
       
      Thanks for your help
       
    • InunoTaishou
      By InunoTaishou
      Struggling a bit to get this GDI+ function converted to AutoIt.
      #include <GDIPlus.au3> _GDIPlus_Startup() Global $hImage = _GDIPlus_ImageLoadFromFile("F:\DCIM\Camera\20170515_111804.jpg") Global $tBufferSize = DllStructCreate("uint") Global $tProperties = DllStructCreate("uint") _GDIPlus_GetPropertySize($hImage, $tBufferSize, $tProperties) Global $tAllItems = DllStructCreate("struct;char[" & DllStructGetData($tBufferSize, 1) & "];endstruct") _GDIPlus_GetAllPropertyItems($hImage, $tBufferSize, $tProperties, $tPropertyItem) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() Func _GDIPlus_GetAllPropertyItems(ByRef $hImage, Const $tTotalBufferSize, Const $tNumProperties, ByRef $tAllItems) If (Not IsDllStruct($tPropertyItem)) Then Return SetError(-1, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetAllPropertyItems", "hwnd", $hImage, "unit", DllStructGetData($tTotalBufferSize, 1), "uint", DllStructGetData($tNumProperties, 1), "ptr", DllStructGetPtr($tAllItems)) If (@error) Then Return SetError(@error, @extended, ConsoleWrite("@Error = " & @error & @LF)) If ($aResult[0]) Then Return SetError($aResult[0], @extended, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetAllPropertyItems Func _GDIPlus_GetPropertySize(Const ByRef $hImage, ByRef $tTotalBufferSize, ByRef $tNumProperties) If (Not IsDllStruct($tTotalBufferSize)) Then Return SetError(-1, 0, "") If (Not IsDllStruct($tNumProperties)) Then Return SetError(-2, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertySize", "hwnd", $hImage, "uint_ptr", DllStructGetPtr($tTotalBufferSize), "uint_ptr", DllStructGetPtr($tNumProperties)) If (@error) Then Return SetError(@error, @extended, "") If ($aResult[0]) Then Return SetError($aResult[0], 0, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetPropertySize Got the GetPropertySize function to work, gives me the correct buffer size and the property count, but I cannot figure out how to get the struct for the all items.
      Function on MSDN:
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms535372(v=vs.85).aspx
      Struct needed:
      PropertyItem class:
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms534493(v=vs.85).aspx
      Found other topics about this function in other languages where they used a blank string as the buffer, so I tried using a char array, which doesn't work. Just cannot figure out how to create the struct buffer to hold the data.
    • UEZ
      By UEZ
      Since I disovered FreeBasic I decided to create a DLL to implement much faster image processing functionality to AutoIt.
      Following functions are implemented yet:
      _GDIPlus_BitmapApplyFilter_BWJJNDithering _GDIPlus_BitmapApplyFilter_Cartoon1 _GDIPlus_BitmapApplyFilter_ColorAccent _GDIPlus_BitmapApplyFilter_Convolution_AnotherBlur _GDIPlus_BitmapApplyFilter_Convolution_BoxBlur _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection1 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection2 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection3 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection4 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection5 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection6 _GDIPlus_BitmapApplyFilter_Convolution_Emboss1 _GDIPlus_BitmapApplyFilter_Convolution_Emboss45Degree _GDIPlus_BitmapApplyFilter_Convolution_EmbossTopLeftBottomRight _GDIPlus_BitmapApplyFilter_Convolution_Gaussian3x3 _GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_1 _GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_2 _GDIPlus_BitmapApplyFilter_Convolution_GaussianBlur _GDIPlus_BitmapApplyFilter_Convolution_IntenseEmboss _GDIPlus_BitmapApplyFilter_Convolution_Kirsch _GDIPlus_BitmapApplyFilter_Convolution_Laplace1 _GDIPlus_BitmapApplyFilter_Convolution_Laplace2 _GDIPlus_BitmapApplyFilter_Convolution_Laplace3 _GDIPlus_BitmapApplyFilter_Convolution_LaplacianOfGaussian _GDIPlus_BitmapApplyFilter_Convolution_ManualMatrix _GDIPlus_BitmapApplyFilter_Convolution_MotionBlur _GDIPlus_BitmapApplyFilter_Convolution_Outline3x3 _GDIPlus_BitmapApplyFilter_Convolution_Prewitt _GDIPlus_BitmapApplyFilter_Convolution_Sharpen1 _GDIPlus_BitmapApplyFilter_Convolution_Sharpen2 _GDIPlus_BitmapApplyFilter_Convolution_Sobel _GDIPlus_BitmapApplyFilter_Convolution_SovelVsPrewitt _GDIPlus_BitmapApplyFilter_Convolution_TriangleBlur _GDIPlus_BitmapApplyFilter_Convolution_Unsharp _GDIPlus_BitmapApplyFilter_Convolution_Unsharp5x5 _GDIPlus_BitmapApplyFilter_Dilatation _GDIPlus_BitmapApplyFilter_DistortionBlur _GDIPlus_BitmapApplyFilter_Edges _GDIPlus_BitmapApplyFilter_Erosion _GDIPlus_BitmapApplyFilter_FishEye _GDIPlus_BitmapApplyFilter_Indexed _GDIPlus_BitmapApplyFilter_Jitter _GDIPlus_BitmapApplyFilter_Kuwahara _GDIPlus_BitmapApplyFilter_Linellism _GDIPlus_BitmapApplyFilter_Median _GDIPlus_BitmapApplyFilter_Median2 _GDIPlus_BitmapApplyFilter_OilPainting _GDIPlus_BitmapApplyFilter_PenSketch _GDIPlus_BitmapApplyFilter_PenSketch2 _GDIPlus_BitmapApplyFilter_Pixelate _GDIPlus_BitmapApplyFilter_Pointillism _GDIPlus_BitmapApplyFilter_RadialBlur _GDIPlus_BitmapApplyFilter_Raster _GDIPlus_BitmapApplyFilter_Swirl _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour _GDIPlus_BitmapApplyFilter_TiltShift _GDIPlus_BitmapApplyFilter_TimeWarp _GDIPlus_BitmapApplyFilter_Wave _GDIPlus_BitmapApplyFilter_XRay  
      Since I am absolutely a newbie in FreeBasic, the DLL may contain errors.  Please report any bug.
       
      FreeBasic source code can be found here: https://pastebin.com/Lugp6rCR
       
      To do:
      add function headers with descriptions speed-up FB code -> partly done add more filters -> ongoing  
      Credits to:
      Jakub Szymanowski rdc Dewald Esterhuizen Santhosh G_  Christian Graus www.gutgames.com  
      Have fun.
       
      Download link: 
       
      You can compare the speed with AutoIt version:
      #AutoIt3Wrapper_Version=b #include <Array.au3> #include <GDIPlus.au3> Global $sFile = FileOpenDialog("Select an image", "", "Images (*.jpg;*.png;*.gif;*.bmp)") If @error Then Exit _GDIPlus_Startup() Global Const $STM_SETIMAGE = 0x0172 Global Const $hImage = _GDIPlus_ImageLoadFromFile($sFile) Global Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Global Const $hGUI = GUICreate("GDI+ Image Filters", $iW * 2, $iH) Global $fProg = 0, $iEnd = $iW * $iH - 1 AdlibRegister("Progress", 490) Global $t = TimerInit() Global Const $hGDIBitmap = _GDIPlus_BitmapApplyFilter_Median($hImage, 4) ConsoleWrite(Round(TimerDiff($t) / 1000, 2) & " s / " & Round(TimerDiff($t) / 60000, 2) & " min" & @CRLF) Global Const $iPic = GUICtrlCreatePic("", 0, 0, $iW - 1, $iH - 1) Global Const $iPic_o = GUICtrlCreatePic("", $iW, 0, $iW - 1, $iH - 1) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap)) Global Const $hGDIBitmap2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic_o, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap2)) GUISetState() AdlibUnRegister("Progress") ToolTip("") Do Until GUIGetMsg() = -3 _GDIPlus_ImageDispose($hImage) _WinAPI_DeleteObject($hGDIBitmap) _WinAPI_DeleteObject($hGDIBitmap2) _GDIPlus_Shutdown() Exit Func Progress() ToolTip(Int($fProg / $iEnd * 100) & " % / " & Round(TimerDiff($t) / 60000, 2) & " min", MouseGetPos(0) + 30, MouseGetPos(1) + 30) EndFunc #Region Symmetric Nearest Neighbour Func _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour($hImage, $fRadius = 2, $bGDI = True) ;no alpha channel implemented yet Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iRowOffset, $iX, $iY, $c, $k, $sumR, $sumG, $sumB, $iCount, $xx, $yy, $iR, $iG, $iB, $iR1, $iG1, $iB1, $iR2, $iG2, $iB2, $x, $y For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW For $iX = 0 To $iW - 1 $sumR = 0 $sumG = 0 $sumB = 0 $iCount = 0 $c = DllStructGetData($tPixel, 1, $iRowOffset + $iX) $iR = BitShift(BitAND(0x00FF0000, $c), 16) $iG = BitShift(BitAND(0x0000FF00, $c), 8) $iB = BitAND(0x000000FF, $c) For $yy = -$fRadius To $fRadius For $xx = -$fRadius To $fRadius $k = $iX + $xx $x = $k < 0 ? 0 : $k > $iW - 1 ? $iW - 1 : $k $k = $iY + $yy $y = $k < 0 ? 0 : $k > $iH - 1 ? $iH - 1 : $k $c = DllStructGetData($tPixel, 1, $y * $iW + $x) $iR1 = BitShift(BitAND(0x00FF0000, $c), 16) $iG1 = BitShift(BitAND(0x0000FF00, $c), 8) $iB1 = BitAND(0x000000FF, $c) $k = $iX - $xx $x = $k < 0 ? 0 : $k > $iW - 1 ? $iW - 1 : $k $k = ($iY - $yy) $y = $k < 0 ? 0 : $k > $iH - 1 ? $iH - 1 : $k $c = DllStructGetData($tPixel, 1, $y * $iW + $x) $iR2 = BitShift(BitAND(0x00FF0000, $c), 16) $iG2 = BitShift(BitAND(0x0000FF00, $c), 8) $iB2 = BitAND(0x000000FF, $c) If __DeltaE($iR, $iG, $iB, $iR1, $iG1, $iB1) < __DeltaE($iR, $iG, $iB, $iR2, $iG2, $iB2) Then $sumR += $iR1 $sumG += $iG1 $sumB += $iB1 Else $sumR += $iR2 $sumG += $iG2 $sumB += $iB2 EndIf $iCount += 1 Next Next DllStructSetData($tPixel_Dest, 1, 0xFF000000 + Int($sumR / $iCount) * 0x10000 + Int($sumG / $iCount) * 0x100 + Int($sumB / $iCount), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_SNN" & $fRadius & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc Func __DeltaE($iR1, $iG1, $iB1, $iR2, $iG2, $iB2) Return Sqrt(($iR1 - $iR2) * ($iR1 - $iR2) + ($iG1 - $iG2) * ($iG1 - $iG2) + ($iB1 - $iB2) * ($iB1 - $iB2)) EndFunc #EndRegion #Region Jitter Func _GDIPlus_BitmapApplyFilter_Jitter($hImage, $iAmount = 20, $bGDI = True) Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iX, $iY, $iRowOffset, $fNX, $fNY For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 $fNX = $iX + Int((Random() - 0.5) * $iAmount) $fNX = $fNX < 1 ? 1 : $fNX > $iW - 1 ? $iW - 1 : $fNX $fNY = ($iY + Int((Random() - 0.5) * $iAmount)) $fNY = $fNY < 1 ? 1 : $fNY > $iH - 1 ? $iH - 1 : $fNY $fNY *= $iW DllStructSetData($tPixel_Dest, 1, DllStructGetData($tPixel, 1, $fNY + $fNX), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_Jitter" & $iAmount & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc #EndRegion #Region Median Func _GDIPlus_BitmapApplyFilter_Median($hImage, $fRadius = 3, $bGDI = True) Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iX, $iY, $iRowOffset For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 DllStructSetData($tPixel_Dest, 1, __Median_Value($iX, $iY, $fRadius, $tPixel, $iW, $iH), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_Median" & $fRadius & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc Func __Median_Value($iPosX, $iPosY, $fRadius, $tPixel, $iW, $iH) Local $iX, $iY, $aColors[1000], $iColors = 0, $iSize = $iW * $iH - 1, $iOff, $e For $iX = $iPosX - $fRadius To $iPosX + $fRadius For $iY = $iPosY - $fRadius To $iPosY + $fRadius $iOff = 1 + $iY * $iW + $iX $aColors[$iColors] = DllStructGetData($tPixel, 1, $iOff < 1 ? 1 : $iOff > $iSize ? $iSize : $iOff) $iColors += 1 Next Next ReDim $aColors[$iColors] ;~ _ArraySort($aColors, 0) $e = $iColors - 1 __ArrayQuickSort1D($aColors, 0, $e) Local $iMid = Floor($iColors / 2), $iMedian If BitAND($iColors, 1) Then $iMedian = Int($aColors[$iMid + 1]) Else $iMedian = Int(($aColors[$iMid] + $aColors[$iMid + 1]) / 2) EndIf Return $iMedian EndFunc #EndRegion