Jump to content
Sign in to follow this  
Starg

Simple 3D Graphics with GDI+

Recommended Posts

UEZ

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
Starg

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
tirpider

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
Starg

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
Starg

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
UEZ

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
tirpider

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
Starg

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
tirpider

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
Starg

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
DatMCEyeBall

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
Starg

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
Danyfirex

Very nice work. thank you.

regards

Share this post


Link to post
Share on other sites
DatMCEyeBall

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
Starg

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
Starg

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
DatMCEyeBall

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  

  • Similar Content

    • Pricehacker
      By Pricehacker
      Hello,
      I am making a program where the button is an image that "changes" when specific conditions are fullfilled. Problem is that these images have different dimensions and when a smaller picture is displayed over a bigger one both will be seen, therefore i would like the images to be hidden, invincible or, alternatively, deleted.
      I have tried using _GDIPlus_GraphicsClear() with no luck
      However that might just be me not using it right as im quite new to autoit
      Here is the code if you want to test run it:
      Thanks to everyone helping!
    • UEZ
      By UEZ
      Here another example to mark the desktop to get the marked region for capturing. This example is not perfect and not very fast (room for improvements).
      ;coded by UEZ build 2018-09-25 beta #include <APISysConstants.au3> #include <Array.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WinAPIGdi.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> Global $__g_hGUI_MarkArea, $__g_hGUI_Bg, $__g_iLabel_TL, $__g_iLabel_TM, $__g_iLabel_TR, $__g_iLabel_LM, $__g_iLabel_RM, $__g_iLabel_BL, $__g_iLabel_BM, _ $__g_iLabel_BR, $__g_iOldCursor, $__g_iW, $__g_iH, $__g_iColor_ResizeDots = 0xFFFFFF, $__g_iBorder = 4, $__g_bSelectionDone = False Global $aRect = _GDIPlus_MarkScreenRegionAnimated() _ArrayDisplay($aRect, "Marked area coordinates") Func _GDIPlus_MarkScreenRegionAnimated($bAnim = True) _GDIPlus_Startup() Local Const $hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]") Local Const $aFullScreen = WinGetPos($hFullScreen) $__g_hGUI_Bg = GUICreate("", $aFullScreen[2], $aFullScreen[3], $aFullScreen[0], $aFullScreen[1], BitOR($WS_CLIPCHILDREN, $WS_POPUP), $WS_EX_TOPMOST) ;to avoid cursor flickering and for proper control read WinSetTrans($__g_hGUI_Bg, "", 0x01) $__g_hGUI_MarkArea = GUICreate("", 1, 1, -1, -1, $bAnim ? $WS_POPUP : BitOR($WS_POPUP, $WS_BORDER), BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED), $__g_hGUI_Bg) GUISetBkColor(0xABCDEF, $__g_hGUI_MarkArea) If Not $bAnim Then $__g_iColor_ResizeDots = 0xFF0000 $__g_iLabel_TL = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top left GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_TM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_TR = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top right GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_LM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;left mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_RM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;right mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BL = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom left GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BR = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom right GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) GUISetState(@SW_SHOWNA, $__g_hGUI_Bg) GUISetState(@SW_SHOW, $__g_hGUI_MarkArea) $__g_iOldCursor = MouseGetCursor() GUISetCursor(3, 1, $__g_hGUI_Bg) GUISetCursor(3, 1, $__g_hGUI_MarkArea) _WinAPI_SetLayeredWindowAttributes($__g_hGUI_MarkArea, 0xABCDEF, 0xF0) Local $aMPos, $aPrevMPos[2] = [MouseGetPos(0) + 1, MouseGetPos(1) + 1], $iID, $aCI, $iX, $iY, $aOldWinPos, $aOldMPos, $bMoved Do Switch GUIGetMsg() Case $GUI_EVENT_CLOSE If $bAnim Then GUIRegisterMsg($WM_TIMER, "") DllCall("user32.dll", "bool", "KillTimer", "hwnd", $__g_hGUI_MarkArea, "uint_ptr", $iID) GUIRegisterMsg($WM_ERASEBKGND, "") EndIf _GDIPlus_Shutdown() Local $aResult = WinGetPos($__g_hGUI_MarkArea) $aResult[2] = WinGetClientSize($__g_hGUI_MarkArea)[0] $aResult[3] = WinGetClientSize($__g_hGUI_MarkArea)[1] GUIDelete($__g_hGUI_MarkArea) GUIDelete($__g_hGUI_Bg) Return $aResult EndSwitch $aMPos = MouseGetPos() If ($aMPos[0] <> $aPrevMPos[0] Or $aMPos[1] <> $aPrevMPos[1]) And (Not $__g_bSelectionDone) Then WinMove($__g_hGUI_MarkArea, "", $aMPos[0], $aMPos[1]) $aPrevMPos = $aMPos EndIf $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) If $aCI[2] And (Not $__g_bSelectionDone) Then $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If $bAnim Then GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND") GUIRegisterMsg($WM_TIMER, "PlayBorderAnim") $iID = DllCall("User32.dll", "uint_ptr", "SetTimer", "hwnd", $__g_hGUI_MarkArea, "uint_ptr", 1, "uint", 50, "ptr", 0)[0] EndIf While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) $aMPos = MouseGetPos() $__g_iW = Abs($aMPos[0] - $aGUIStartPos[0]) + 1 $__g_iH = Abs($aMPos[1] - $aGUIStartPos[1]) + 1 If $aMPos[0] < $aGUIStartPos[0] Then $iX = $aMPos[0] Else $iX = $aGUIStartPos[0] EndIf If $aMPos[1] < $aGUIStartPos[1] Then $iY = $aMPos[1] Else $iY = $aGUIStartPos[1] EndIf WinMove($__g_hGUI_MarkArea, "", $iX, $iY, $__g_iW, $__g_iH) UpdateCtrlPos($bAnim) WEnd $__g_bSelectionDone = True GUISetCursor(3, 1, $__g_hGUI_MarkArea) ElseIf $aCI[3] And $__g_bSelectionDone Then $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If _WinAPI_PtInRectEx(MouseGetPos(0), MouseGetPos(1), $aGUIStartPos[0], $aGUIStartPos[1], $aGUIStartPos[0] + $aGUIStartPos[2], $aGUIStartPos[1] + $aGUIStartPos[3]) Then $aMPos = MouseGetPos() $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) While $aCI[3] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aGUIStartPos[0] - ($aMPos[0] - MouseGetPos(0)), $aGUIStartPos[1] - ($aMPos[1] - MouseGetPos(1)), $__g_iW, $__g_iH) GUISetCursor(0, 1, $__g_hGUI_Bg) GUISetCursor(0, 1, $__g_hGUI_MarkArea) WEnd GUISetCursor(3, 1, $__g_hGUI_Bg) GUISetCursor(3, 1, $__g_hGUI_MarkArea) EndIf EndIf If $__g_bSelectionDone Then $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) If @error Then ContinueLoop Switch $aCI[4] Case $__g_iLabel_TL GUISetCursor(12, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), MouseGetPos(1), $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BR GUISetCursor(12, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_TR GUISetCursor(10, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], MouseGetPos(1), $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BL GUISetCursor(10, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), $aOldWinPos[1], $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_LM GUISetCursor(13, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), $aOldWinPos[1], $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3]) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_RM GUISetCursor(13, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3]) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_TM GUISetCursor(11, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], MouseGetPos(1), $aOldWinPos[2], $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BM GUISetCursor(11, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2], $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case Else GUISetCursor(3, 1, $__g_hGUI_MarkArea) EndSwitch EndIf Until False EndFunc ;==>_GDIPlus_MarkScreenRegionAnimated Func UpdateCtrlPos($bAnim = True) Local Const $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If $__g_bSelectionDone And $bAnim Then GUIRegisterMsg($WM_TIMER, "") $__g_iW = $aGUIStartPos[2] $__g_iH = $aGUIStartPos[3] ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TL, 0, 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TM, ($__g_iW - $__g_iBorder) / 2, 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TR, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_LM, 0, ($__g_iH - $__g_iBorder) / 2, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_RM, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), ($__g_iH - $__g_iBorder) / 2, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BL, 0, ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BM, ($__g_iW - $__g_iBorder) / 2, ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BR, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) If $__g_bSelectionDone And $bAnim Then GUIRegisterMsg($WM_TIMER, "PlayBorderAnim") EndFunc ;==>UpdateCtrlPos Func PlayBorderAnim() Local $aWinPos = WinGetClientSize($__g_hGUI_MarkArea), $iW = $aWinPos[0], $iH = $aWinPos[1] Local Static $fOffset = 0 Local Const $iSize = $__g_iBorder / 2 Local Const $hDC = _WinAPI_GetDC($__g_hGUI_MarkArea) Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap) Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) Local Const $hPen = _GDIPlus_PenCreate(0xFF0178D7, $iSize), $hPen2 = _GDIPlus_PenCreate(0xFFFFFFFF, $iSize), _ $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000 + $__g_iColor_ResizeDots), $hPen3 = _GDIPlus_PenCreate(0xFF000000) _GDIPlus_PenSetDashStyle($hPen, $GDIP_DASHSTYLEDASHDOT) _GDIPlus_GraphicsClear($hCanvas, 0xFFABCDEF) ;for faster performance direct dll calls DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen2, "float", 1 + $iSize, "float", 1 + $iSize, "float", $iW - 2 * $iSize - 2, "float", $iH - 2 * $iSize - 2) DllCall($__g_hGDIPDll, "int", "GdipSetPenDashOffset", "handle", $hPen, "float", $fOffset) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen, "float", 1 + $iSize, "float", 1 + $iSize, "float", $iW - 2 * $iSize - 2, "float", $iH - 2 * $iSize - 2) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) / 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) / 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) / 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) / 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY) $fOffset += 0.5 _GDIPlus_GraphicsDispose($hCanvas) _WinAPI_SelectObject($hDC_backbuffer, $DC_obj) _WinAPI_DeleteDC($hDC_backbuffer) _WinAPI_DeleteObject($hHBitmap) _WinAPI_ReleaseDC($__g_hGUI_MarkArea, $hDC) _GDIPlus_PenDispose($hPen) _GDIPlus_PenDispose($hPen2) _GDIPlus_PenDispose($hPen3) _GDIPlus_BrushDispose($hBrush) EndFunc ;==>PlayBorderAnim Func WM_ERASEBKGND($hWnd, $iMsgm, $wParam, $lParam) ;suppress repainting to avoid flickering but causes some other side effects #forceref $iMsgm, $wParam, $lParam Local Const $hBrush = _WinAPI_CreateSolidBrush(0xEFCDAB) ;BGR format ;~ _WinAPI_RedrawWindow($__g_hGUI_MarkArea, 0, 0, BitOR($RDW_NOERASE, $RDW_NOCHILDREN, $RDW_NOFRAME, $RDW_VALIDATE)) _WinAPI_SetClassLongEx($__g_hGUI_MarkArea, $GCL_HBRBACKGROUND, $hBrush) _WinAPI_DeleteObject($hBrush) Return 0 EndFunc ;==>WM_ERASEBKGND  
      Just press the lmb and move your mouse. When lmb is released you can adjust the size of the window by dragging the white rectangle to any direction. Rmb will move the marked area.
      Press ESC to get the coordinates of the marked region.
      If you have any improvements, please post it here.
       
      Tested on Win10 x64 only.
       
    • JoeWagner
      By JoeWagner
      I'm building a tool to remotely monitor CPU usage on my server.
      I have a working tool but I have a few issues I'd like some help with.
      1. The app uses more system memory on a continual growth rate...  It eventually starts displaying strange artifacts and the background flashes between black and and white behind the GDI+ elements.  I determined this couldn't be left to run for any amount of time (greater than 15-20 minutes) - Very frustrating.
      I suspect it's because it keeps drawing new GDI+ elements to replace the previous cycle ... the $bar1 = "" is enough to remove the image and allow the new image to be drawn there, but I don't have a handle for the original GDI+ element to throw it away... Not sure where they go...
      I also suspect there could be a better way to do what I'm doing here, but from a problem solving perspective - this is what I came up with - I will accept suggestions for how better to accomplish the same / better or acceptable results  
      I will not however accept corrections on grammar, punctuation or commenting - I didn't comment this as I was going, I use the variables that make sense to me (or as they were when I lifted them from the scraps I found on the internet) and you can never be too careful with punctuation.
      2. I have a WMI query that is used to remotely pull the CPU data from the server - if I supply the wrong credentials the app crashes... I tried to make it show an error and go back to allow me to try again ... doesn't work. Any help with catching that error and preventing the crash would be super helpful. (works great if the credentials are correct; domain or local)
       
      The whole thing below... 
      #include <Date.au3> #include <WindowsConstants.au3> #include <GuiConstantsEX.au3> #include <EditConstants.au3> #include <ButtonConstants.au3> #include <GDIPlus.au3> Global $__g_hGDIPDll Global $graph[21] Global $timer, $timeout = 500 Global $hFlag = 0 $timer = TimerInit() $main = GUICreate("CPU Graph", 125, 220, Default, Default, Default, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) $bar1 = GUICtrlCreatePic("", 10, 10, 5, 100) $bar2 = GUICtrlCreatePic("", 15, 10, 5, 100) $bar3 = GUICtrlCreatePic("", 20, 10, 5, 100) $bar4 = GUICtrlCreatePic("", 25, 10, 5, 100) $bar5 = GUICtrlCreatePic("", 30, 10, 5, 100) $bar6 = GUICtrlCreatePic("", 35, 10, 5, 100) $bar7 = GUICtrlCreatePic("", 40, 10, 5, 100) $bar8 = GUICtrlCreatePic("", 45, 10, 5, 100) $bar9 = GUICtrlCreatePic("", 50, 10, 5, 100) $bar10 = GUICtrlCreatePic("", 55, 10, 5, 100) $bar11 = GUICtrlCreatePic("", 60, 10, 5, 100) $bar12 = GUICtrlCreatePic("", 65, 10, 5, 100) $bar13 = GUICtrlCreatePic("", 70, 10, 5, 100) $bar14 = GUICtrlCreatePic("", 75, 10, 5, 100) $bar15 = GUICtrlCreatePic("", 80, 10, 5, 100) $bar16 = GUICtrlCreatePic("", 85, 10, 5, 100) $bar17 = GUICtrlCreatePic("", 90, 10, 5, 100) $bar18 = GUICtrlCreatePic("", 95, 10, 5, 100) $bar19 = GUICtrlCreatePic("", 100, 10, 5, 100) $bar20 = GUICtrlCreatePic("", 105, 10, 5, 100) $host = GUICtrlCreateInput("Host", 10, 115, 100, 20, $ES_AUTOHSCROLL) $user = GUICtrlCreateInput("User", 10, 140, 100, 20, $ES_AUTOHSCROLL) GUICtrlSetFont(-1, 8, 400) $pass = GUICtrlCreateInput("Pass", 10, 165, 100, 20, BitOR($ES_PASSWORD,$ES_AUTOHSCROLL)) GUICtrlSetFont(-1, 8, 400) $start = GUICtrlCreateButton("Start", 10, 190, 100, 20, $BS_DEFPUSHBUTTON) GUISetState() While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop If $msg = $start Then ConnectWMI() If $hFlag = 1 Then If TimerDiff($timer) > $timeout Then UpdateGraph() EndIf WEnd Func ConnectWMI() Global $hostname = GUICtrlRead($host) If Ping($hostname, 2000) = 0 Then Msgbox(0, "Error", "Unable to reach specified host") Return 0 EndIf Local $usr = GUICtrlRead($user) Local $pwd = GUICtrlRead($pass) Global $objSWbemLocator = ObjCreate("WbemScripting.SWbemLocator") Global $objWMIService = $objSWbemLocator.ConnectServer($hostname, "root\cimv2", $usr, $pwd) If @error Then Msgbox(0, "Error", "Unable to connect to the Host with the supplied credentials") Return 0 EndIf $hFlag = 1 UpdateGraph() EndFunc Func UpdateGraph() $usage = _Processor_Usage() For $i = 1 to 19 $graph[$i] = $graph[$i+1] Next $graph[20] = $usage GUICtrlSetImage($bar1, "") CreateBar($bar1, $graph[1]) GUICtrlSetImage($bar2, "") CreateBar($bar2, $graph[2]) GUICtrlSetImage($bar3, "") CreateBar($bar3, $graph[3]) GUICtrlSetImage($bar4, "") CreateBar($bar4, $graph[4]) GUICtrlSetImage($bar5, "") CreateBar($bar5, $graph[5]) GUICtrlSetImage($bar6, "") CreateBar($bar6, $graph[6]) GUICtrlSetImage($bar7, "") CreateBar($bar7, $graph[7]) GUICtrlSetImage($bar8, "") CreateBar($bar8, $graph[8]) GUICtrlSetImage($bar9, "") CreateBar($bar9, $graph[9]) GUICtrlSetImage($bar10, "") CreateBar($bar10, $graph[10]) GUICtrlSetImage($bar11, "") CreateBar($bar11, $graph[11]) GUICtrlSetImage($bar12, "") CreateBar($bar12, $graph[12]) GUICtrlSetImage($bar13, "") CreateBar($bar13, $graph[13]) GUICtrlSetImage($bar14, "") CreateBar($bar14, $graph[14]) GUICtrlSetImage($bar15, "") CreateBar($bar15, $graph[15]) GUICtrlSetImage($bar16, "") CreateBar($bar16, $graph[16]) GUICtrlSetImage($bar17, "") CreateBar($bar17, $graph[17]) GUICtrlSetImage($bar18, "") CreateBar($bar18, $graph[18]) GUICtrlSetImage($bar19, "") CreateBar($bar19, $graph[19]) GUICtrlSetImage($bar20, "") CreateBar($bar20, $graph[20]) $timer = TimerInit() EndFunc Func _Processor_Usage() Dim $Col_Items = $objWMIService.ExecQuery('SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor', 'WQL') Local $Obj_Item For $Obj_Item In $Col_Items Return $Obj_Item.PercentProcessorTime Next EndFunc Func CreateBar($target, $value) Local $width=5, $height=2 _GDIPlus_Startup() $hImage = DLL_BitmapCreate($width, $height*50) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage) _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 2) ;100 If $value > 98 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF00F2F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $width, $height, $hBrush) EndIf ;98 If $value > 96 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF0182C") _GDIPlus_GraphicsFillRect($hGraphic, 0, 2, $width, $height, $hBrush) EndIf ;96 If $value > 94 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF0212A") _GDIPlus_GraphicsFillRect($hGraphic, 0, 4, $width, $height, $hBrush) EndIf ;94 If $value > 92 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF02B28") _GDIPlus_GraphicsFillRect($hGraphic, 0, 6, $width, $height, $hBrush) EndIf ;92 If $value > 90 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF03426") _GDIPlus_GraphicsFillRect($hGraphic, 0, 8, $width, $height, $hBrush) EndIf ;90 If $value > 88 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF03E24") _GDIPlus_GraphicsFillRect($hGraphic, 0, 10, $width, $height, $hBrush) EndIf ;88 If $value > 86 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF04722") _GDIPlus_GraphicsFillRect($hGraphic, 0, 12, $width, $height, $hBrush) EndIf ;86 If $value > 84 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF05120") _GDIPlus_GraphicsFillRect($hGraphic, 0, 14, $width, $height, $hBrush) EndIf ;84 If $value > 82 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF05A1D") _GDIPlus_GraphicsFillRect($hGraphic, 0, 16, $width, $height, $hBrush) EndIf ;82 If $value > 80 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF0641B") _GDIPlus_GraphicsFillRect($hGraphic, 0, 18, $width, $height, $hBrush) EndIf ;80 If $value > 78 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF06D19") _GDIPlus_GraphicsFillRect($hGraphic, 0, 20, $width, $height, $hBrush) EndIf ;78 If $value > 76 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF07717") _GDIPlus_GraphicsFillRect($hGraphic, 0, 22, $width, $height, $hBrush) EndIf ;76 If $value > 74 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF08015") _GDIPlus_GraphicsFillRect($hGraphic, 0, 24, $width, $height, $hBrush) EndIf ;74 If $value > 72 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF08A13") _GDIPlus_GraphicsFillRect($hGraphic, 0, 26, $width, $height, $hBrush) EndIf ;72 If $value > 70 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF09311") _GDIPlus_GraphicsFillRect($hGraphic, 0, 28, $width, $height, $hBrush) EndIf ;70 If $value > 68 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF09311") _GDIPlus_GraphicsFillRect($hGraphic, 0, 30, $width, $height, $hBrush) EndIf ;68 If $value > 66 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFF09D0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 32, $width, $height, $hBrush) EndIf ;66 If $value > 64 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFECA20F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 34, $width, $height, $hBrush) EndIf ;64 If $value > 62 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFE8A80F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 36, $width, $height, $hBrush) EndIf ;62 If $value > 60 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFE5AD0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 38, $width, $height, $hBrush) EndIf ;60 If $value > 58 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFE1B30F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 40, $width, $height, $hBrush) EndIf ;58 If $value > 56 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFDEB80F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 42, $width, $height, $hBrush) EndIf ;56 If $value > 54 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFDABE0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 44, $width, $height, $hBrush) EndIf ;54 If $value > 52 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFD6C30F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 46, $width, $height, $hBrush) EndIf ;52 If $value > 50 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFCFCE0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 48, $width, $height, $hBrush) EndIf ;50 If $value > 48 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFCCD40F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 50, $width, $height, $hBrush) EndIf ;48 If $value > 46 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFC8D90F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 52, $width, $height, $hBrush) EndIf ;46 If $value > 44 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFC4DF0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 54, $width, $height, $hBrush) EndIf ;44 If $value > 42 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFC1E40F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 56, $width, $height, $hBrush) EndIf ;42 If $value > 40 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFBDEA0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 58, $width, $height, $hBrush) EndIf ;40 If $value > 38 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFBAF00F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 60, $width, $height, $hBrush) EndIf ;38 If $value > 36 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFBAF00F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 62, $width, $height, $hBrush) EndIf ;36 If $value > 34 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFADEF0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 64, $width, $height, $hBrush) EndIf ;34 If $value > 32 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFFA1EE0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 66, $width, $height, $hBrush) EndIf ;32 If $value > 30 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF94ED0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 68, $width, $height, $hBrush) EndIf ;30 If $value > 28 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF88ED0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 70, $width, $height, $hBrush) EndIf ;28 If $value > 26 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF7CEC0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 72, $width, $height, $hBrush) EndIf ;26 If $value > 24 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF6FEB0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 74, $width, $height, $hBrush) EndIf ;24 If $value > 22 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF63EA0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 76, $width, $height, $hBrush) EndIf ;22 If $value > 20 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF56EA0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 78, $width, $height, $hBrush) EndIf ;20 If $value > 18 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF56EA0F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 80, $width, $height, $hBrush) EndIf ;18 If $value > 16 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF4AE90F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 82, $width, $height, $hBrush) EndIf ;16 If $value > 14 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF3EE80F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 84, $width, $height, $hBrush) EndIf ;14 If $value > 12 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF31E70F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 86, $width, $height, $hBrush) EndIf ;12 If $value > 10 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF25E70F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 88, $width, $height, $hBrush) EndIf ;10 If $value > 8 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF18E60F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 90, $width, $height, $hBrush) EndIf ;8 If $value > 6 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF0CE50F") _GDIPlus_GraphicsFillRect($hGraphic, 0, 92, $width, $height, $hBrush) EndIf ;6 If $value > 4 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF00E510") _GDIPlus_GraphicsFillRect($hGraphic, 0, 94, $width, $height, $hBrush) EndIf ;4 If $value > 2 Then $hBrush = _GDIPlus_BrushCreateSolid("0xFF00E509") _GDIPlus_GraphicsFillRect($hGraphic, 0, 96, $width, $height, $hBrush) EndIf ;2 $hBrush = _GDIPlus_BrushCreateSolid("0xFF00E509") _GDIPlus_GraphicsFillRect($hGraphic, 0, 98, $width, $height, $hBrush) $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) GUICtrlSendMsg($target, 0x172, 0, $hBitmap) _WinAPI_DeleteObject($hBitmap) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() EndFunc ;==>_CreateBar Func DLL_BitmapCreate($width, $height) Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $width, "int", $height, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0) Return $aResult[6] EndFunc ;==>DLL_BitmapCreate  
       
    • UEZ
      By UEZ
      AutoIt Windows Screenshooter
      Key Features:
      takes easily a screenshot from any visible window capture any region of the desktop incl. freehand capturing capture GUI controls and GUI menus separately capture a marked area every x seconds for a duration of y seconds create a GIF animation from saved frames (Vista or higher os required) capture to AVI file (without audio!) takes a screenshot from web sites (available only on Win7+ os and when Aero is enabled) put images to clipboard to paste to other applications easily color picker save image in different formats and also to PDF! add timestamp to saved images simple image editing options: greyscale, b&w, invert, rotate +-90° send image to printer and default email client preview of captured screens incl. zoom option multi monitor support display pixel color under mouse ruler basic image editor (paint, highlight, ellipse, rectangle, text and some graphic FX) watermark captured image no 3rd party tools or DLLs used - pure AutoIt! fully portable - no installation is needed multi language feature (Eng, Ger, Tur, Fra and Rus only) To do:
      capture content of scrollable window/control capture cascaded menus Due to DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0) limitation some windows cannot be captured properly (GDI+, ProgDVB, etc.) but can take screenshots of hidden windows. One workaround is to use full screen capturing (F11/F12) or "Grab Screen" function! Or try double click with rmb on listview items (beta).
      Download source code (6295 downloads previously):  AutoIt Windows Screenshooter v1.81 Build 2018-08-12.7z (version 3.3.12.0+ needed!)
      You are not allowed to sell this code or just parts of it in a commercial project or modify it and distribute it with a different name!
      Download compiled Exe only: 4shared / Media Fire / Softpedia (1.54mb)
      Distributing copies of the program in compiled format (exe) must be free of any fee!
      -----> click here to Donate!  
       
      (Current donators: 1. Cuong N.) 
      It is designed for Win7+ operating systems with AERO enabled! E.g. on WinXP machines some functions are not working properly and might crash the application!
      AV scanners may have a negative impact the execution of compiled exe and might report any malware. I guarantee that there is no malicious code in the source code / exe!!! 
      Main GUI:

       
       
      About Intro:

       
       
      Basic Image Editor:

       
       
      Watermark:

       
       
      Click link for an enhanced version of Watermark Image.
      Credits:
      main code by UEZ additional code (alphabetical order) by Authenticity, AutoItObject Team, Eemuli, Eukalyptus, funkey, _Kurt, martin, monoceres, ProgAndy, taietel, trancexx, Ward, wolf9228 and Yashied! mesale0077 for turkish translation wakillon for french translation AZJIO for russian translation Keys:
      Main GUI:
      User your mouse to scroll preview window or
      Numpad 8: Scroll preview window up
      Numpad 2: Scroll preview window down
      Numpad 4: Scroll preview window left
      Numpad 6: Scroll preview window right
      Numpad +: zoom in preview window or mousewheel down
      Numpad -: zoom out preview window or mousewheel up
      F1: capture again on last position
      F5: refresh Windows Name list
      PRINTSCREEN: take screenshot from whole screen
      ALT+PRINTSCR: take a screenshot from active window
      F10: Undo made changes with Image Editing function
      F11: take screenshot from whole screen incl mouse cursor
      F12: take screenshot from whole screen
      Ctrl+Alt+F9 start "Grab Screen" mode
      Ctrl+Alt+F12: take a screenshot from active window using alternative screenshot functionality (beta)!
      Ctrl+r: call ruler
      Ctrl+s: save current displayed image
      Ctrl+x: exit program
      ctrl+w: call web grab input field (availabe only when Aero is enabled)
      Ctrl+i: call image editor
      Ctrl+m: call watermark editor
      Ctrl+z: undo
      Only available on Vista+ os: double click with rmb on list items to use alternative screenshot functionality (beta)!
      When 'Grab Screen' is clicked you can hold down the ctrl key to switch to 'grab controls' mode. Control under mouse will be framed red.
      ctrl + shift will take the screenshot of appropriate control. To capture GUI menues you can press rmb which simulates the lmb. When a menu is opened press shift additionaly to capture it.
      Press and hold only the shift key to capture any region on the desktop using freehand capturing - release it so capture marked regions!
      Or just mark resizeable area which you want to grab. Press CTRL key to grab marked area or right mouse button to capture the marked area every x seconds for a duration of y seconds.
      When saving the image just enter the extension you whish to use (*.jpg;*.png;*.bmp;*.gif;*.tif;*.pdf). Big thanks to taietel for his PDF UDF!
      Image Editor:
      s: save
      c: copy
      n: send
      h: highlighter
      p: pen
      r: rectangle
      e: ellipse
      a: arrow
      o: color
      t: text
      g: text config
      Ctrl+z: undo
      Watermark editor:
      Ctrl+z: undo
       
      To start the app minimized just call it "Windows Screenshooter.exe /min"
      Maybe it is useful for someone...
      Any kind of comment is welcome.
      Br,
      UEZ
      Change log:
       
    • c.haslam
      By c.haslam
      I think that _GDIPlus_ImageGetPropertyItem should return a Property Item that can readily be set as a property of another image. Why would one want to do this? A script might (as one of mine does) edit an image of a .jpg file then write the result to a .jpg file. In editing it, in my case, the number of horizontal and vertical pixels change, and the date/time edited should be set as a property. All other property items remain the same. Other GDI+ users may change other properties.
      So an approach is to copy all the property items from image1 to image2, then update a few properties.
      M$ provides a Property Item class (id, length, pointer to an array of values) but _GDIPlus_ImageGetPropertyItem returns something different.
      I think that, wherever reasonable, UDFs that are wrappers for M$ methods should work like M$'s methods. _GDIPlus_ImageGetPropertyItem does not do this:
      While M$ returns 2 values for a value that is a ratio of 2 numbers,  _GDIPlus_ImageGetPropertyItem returns numerator/denominator as a single value (often a Double). _GDIPlus_ImageSetPropertyItem (when included in GDIPlus.au3) will be unable to set ratio property items properly because it cannot know what the numerator and denominator are. So copying such property items will not work properly. M$ has a Void* buffer where the buffer is an array of values but _GDIPlus_ImageGetPropertyItem() returns the values in the same 1-d array as id, length and type. M$'s approach produces a 1-d array with the same number of elements for all property items while _GDIPlus_ImageGetPropertyItem produces a 1-d array with various numbers of elements. To me, this is not good programming practice. For a photo from a Sony camera, the worst case has 1-d array with 67 elements. When combined into a 2-d array with the property items of all properties, there are 66 rows and 67 columns, with many elements not used. So I suggest that _GDIPlus_ImageGetPropertyItem look like this:
      ; #FUNCTION# ==================================================================================================================== ; Name ..........: cGDIPlus_ImageGetPropertyItem ; Description ...: Gets a specified property item (piece of meta data) from an Image object ; Syntax ........: cGDIPlus_ImageGetPropertyItem($hImage, $iPropID) ; Parameters ....: $hImage - Pointer to an image object ; $iPropID - Identifier of the property item to be retrieved ; Return values .: Success: Array containing the values of the property item ; [0] - identifier ; [1] - size, in bytes, of the value array ; [2] - type of value(s) in the value array ; [3] - value array ; Failure: Sets the @error flag to non-zero, @extended may contain GPSTATUS error code ($GPID_ERR*). ; Author ........: Eukalyptus ; Modified ......: c.haslam ; Remarks .......: types: unsigned byte = 1, ASCII string = 2, unsigned short = 3, unsigned long = 4, ; unsinged rational = 5, undefined = 7, signed long = 9, signed rational = 10 ; Related .......: _GDIPlus_ImageGetPropertyIdList ; Link ..........: https://msdn.microsoft.com/en-us/library/windows/desktop/ms535390(v=vs.85).aspx, ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms534493(v=vs.85).aspx, ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms534414(v=vs.85).aspx ; Example .......: Yes ; =============================================================================================================================== Func cGDIPlus_ImageGetPropertyItem($hImage, $iPropID) Local $iSize = __GDIPlus_ImageGetPropertyItemSize($hImage, $iPropID) If @error Then Return SetError(@error, @extended, -1) Local $tBuffer = DllStructCreate("byte[" & $iSize & "];") Local $pBuffer = DllStructGetPtr($tBuffer) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetPropertyItem", "handle", $hImage, "uint", _ $iPropID, "uint", $iSize, "struct*", $tBuffer) If @error Then Return SetError(@error, @extended, -1) If $aResult[0] Then Return SetError(10, $aResult[0], False) Local $tPropertyItem = DllStructCreate("int id; int length; short type; ptr pvalue;", $pBuffer) Local $iBytes = DllStructGetData($tPropertyItem, "length") Local $pValue = DllStructGetData($tPropertyItem, "pvalue") Local $aRet[4] Local $type = DllStructGetData($tPropertyItem,'type') Local $tValues, $iValues Switch $type Case 2 ;ASCII String $iValues = 1 $tValues = DllStructCreate("char[" & $iBytes & "];", $pValue) Case 3 ;Array of UShort $iValues = Int($iBytes / 2) $tValues = DllStructCreate("ushort[" & $iValues & "];", $pValue) Case 4, 5 ;Array of UInt / Fraction $iValues = Int($iBytes / 4) $tValues = DllStructCreate("uint[" & $iValues & "];", $pValue) Case 9, 10 ;Array of Int / Fraction $iValues = Int($iBytes / 4) $tValues = DllStructCreate("int[" & $iValues & "];", $pValue) Case Else ;Array of Bytes $iValues = 1 $tValues = DllStructCreate("byte[" & $iBytes & "];", $pValue) EndSwitch $aRet[0] = DllStructGetData($tPropertyItem,'id') $aRet[1] = $iBytes $aRet[2] = $type Local $aVals[$iValues] If $type=2 Or $type=7 Then ; ASCII string or undefined $aVals[0] = DllStructGetData($tValues,1) Else For $i = 0 To $iValues-1 $aVals[$i] = DllStructGetData($tValues,1,$i+1) Next EndIf $aRet[3] = $aVals Return $aRet EndFunc And here is an example:
      #include <GDIPlus.au3> #include <Array.au3> Example() Func Example() _GDIPlus_Startup() Local $hImage = _GDIPlus_ImageLoadFromFile(RegRead((@AutoItX64 = True ? "HKLM\SOFTWARE\Wow6432Node\AutoIt v3\AutoIt" : "HKLM\SOFTWARE\AutoIt v3\AutoIt"), "InstallDir") & "\Examples\GUI\Torus.png") If @error Then _GDIPlus_Shutdown() MsgBox(16, "", "An error has occured - unable to load image!", 30) Return False EndIf Local $ar = _GDIPlus_ImageGetPropertyIdList($hImage) Local $vPropNbrs[UBound($ar,1)-1] ; Extract ID numbers For $i = 1 To UBound($ar,1)-1 $vPropNbrs[$i-1] = $ar[$i][0] Next ; Get all property items Local $aPropItems[UBound($vPropNbrs)][4],$vPropItem For $i = 0 To UBound($vPropNbrs)-1 $vPropItem = cGDIPlus_ImageGetPropertyItem($hImage,$vPropNbrs[$i]) For $j = 0 To 3 $aPropItems[$i][$j] = $vPropItem[$j] Next Next ; Collapse values arrays so _ArrayDisplay can display them Local $ar = $aPropItems For $i = 0 To UBound($aPropItems,1)-1 $ar[$i][0] = '0x'&Hex($ar[$i][0],4) $ar[$i][3] = '' For $j = 0 To UBound($aPropItems[$i][3])-1 $ar[$i][3] &= ($aPropItems[$i][3])[$j]&'|' Next $ar[$i][3] = StringTrimRight($ar[$i][3],1) Next _ArrayDisplay($ar) _GDIPlus_Shutdown() EndFunc Unfortunately this example (based on one now in the Help) does not exercise most of the item types, but I do not know of a file with EXIF metadata that is on most PCs. I have tested this code by updating and adding property items to torus.jpg and to a photo taken by a Sony camera. The code for implementing and calling _GDIPlus_ImageSetPropertyItem will be fairly simple [see below].
       
      Your thoughts?
       
×