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
      sometimes!
      Running the script below and entering a for All seems to work every time Running it and choosing 1 for One returns a gibberish string However with the same functions, I have seen it succeed when 1 is chosen, i.e. show the value for the test property ID 0x0103 as OLYMPUS DIGITAL CAMERA I have also seen GetOne() succeed when a diagnostic MsgBox() is added,  and when I include my debugging functions, so the problem appears to be a memory location being overwritten, probably in a DLLStruct.. call.
      I know that value OLYMPUS DIGITAL CAMERA is correct from Irfanview and from running GetAll().
      All but one of the _GDIPlus functions were written by ChrisL. I have modified those that returned a DLLStruct object such that they now return an array.
      Both getting one and getting  all involve calling _GDIPlus_ImageGetPropertyItemValue() which I wrote, so perhaps the problem partly lies with ChrisL's functions as modified.
      Suggestions?
      #include <GDIPlus.au3> #include <Array.au3> Opt('MustDeclareVars',1) ; #VARIABLES# =================================================================================================================== Global $GDIP_STATUS = 0 Global $GDIP_ERROR = 0 ; =============================================================================================================================== ; Property Item structure Global Const $tagGDIPPROPERTYITEM = _ "uint id;" & _ ; ID of this property "uint length;" & _ ; Length of the property value, in bytes "ushort type;" & _ ; Type of the value, as one of TAG_TYPE_XXX constants "ptr value;" ; property value ; Image property types constants ; Ref: https://www.media.mit.edu/pia/Research/deepview/exif.html Global Const $GDIP_PROPERTYTAGTYPEUBYTE = 1 Global Const $GDIP_PROPERTYTAGTYPEASCII = 2 Global Const $GDIP_PROPERTYTAGTYPEUSHORT = 3 Global Const $GDIP_PROPERTYTAGTYPEULONG = 4 Global Const $GDIP_PROPERTYTAGTYPEURATIONAL = 5 Global Const $GDIP_PROPERTYTAGTYPESBYTE = 6 Global Const $GDIP_PROPERTYTAGTYPEUNDEFINED = 7 Global Const $GDIP_PROPERTYTAGTYPESSHORT = 8 Global Const $GDIP_PROPERTYTAGTYPESLONG = 9 Global Const $GDIP_PROPERTYTAGTYPESRATIONAL = 10 Global Const $GDIP_PROPERTYTAGTYPESFLOAT = 11 Global Const $GDIP_PROPERTYTAGTYPEDFLOAT = 12 main() Func main() _GDIPlus_Startup() Local $hImage = _GDIPlus_ImageLoadFromFile('H:\b\PA160005 - Copy.JPG') Local $sAns = InputBox('','Enter 1 or a') If $sAns=1 Then GetOne($hImage) ElseIf $sAns='a' Then GetAll($hImage) EndIf _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() EndFunc Func GetOne($hImage) Local $vecPrim = _GDIPlus_ImageGetPropertyItem($hImage,0x010e) Local $vecUser[3] $vecUser[0] = '0x'&StringRight(Hex($vecPrim[0]),4) $vecUser[1] = $vecPrim[2] Local $vecVals = _GDIPlus_ImageGetPropertyItemValue($vecPrim[1],$vecPrim[2],$vecPrim[3]) $vecUser[2] = $vecVals[0] _ArrayDisplay($vecUser) EndFunc Func GetAll($hImage) Local $ar1 = _GDIPlus_ImageGetAllPropertyItems($hImage) Local $ar[UBound($ar1,1)][3] For $i = 1 To $ar1[0][0] $ar[$i][0] = '0x'&StringRight(Hex($ar1[$i][0]),4) $ar[$i][1] =$ar1[$i][2] $ar[$i][2] = (_GDIPlus_ImageGetPropertyItemValue($ar1[$i][1],$ar1[$i][2],$ar1[$i][3]))[0] Next _ArrayDisplay($ar) EndFunc ; #FUNCTION# ==================================================================================================================== ; Name...........: _GDIPlus_ImageGetAllPropertyItems ; Description ...: Gets all the property items (metadata) stored in an Image object ; Syntax.........: _GDIPlus_ImageGetAllPropertyItems($hImage) ; Parameters ....: $hImage - Pointer to an Image object ; Return values .: Success - Array containing the image property items: ; |[0][0] - Number of property items ; |[1][0] - Property item 1 identifier (see remarks) ; |[1][1] - Property item 1 value length, in bytes ; |[1][2] - Property item 1 value type ; |[1][1] - Property item 1 value pointer ; |. ; |. ; |[n][0] - Property item n identifier ; |[n][1] - Property item n value length, in bytes ; |[n][2] - Property item n value type ; |[n][1] - Property item n value pointer ; Possible property value types are: ; |1 - The value pointer points to an array of bytes ; |2 - The value pointer points to a null-terminated ASCII string ; |3 - The value pointer points to unsigned short ; |4 - The value pointer points to an unsigned long ; |5 - The value pointer points to an array of unsigned two longs (numerator, denominator) ; |7 - The value pointer points to an array of bytes of any type, or is unterminated string\ ; |8 - The value pointer points to signed short ; |9 - The value pointer points to a signed long ; |10 - The value pointer points to an array of signed two longs (numerator, denominator) ; |11 - The value pointer points to a float ; |12 - The value pointer points to a double ; Failure - -1 and either: ; |@error and @extended are set if DllCall failed ; |$GDIP_STATUS contains a non zero value specifying the error code ; |$GDIP_ERROR: ; | 1 - The _GDIPlus_ImageGetPropertySize function failed, $GDIP_STATUS contains the error code ; | 2 - The image contains no property items metadata ; | 3 - The _GDIPlus_ImageGetAllPropertyItems function failed, $GDIP_STATUS contains the error code ; Author.........: Authenticity ; Modified.......: c.haslam ; Remarks .......: The property item tag identifiers are declared in GDIPConstants.au3, those that start with $GDIP_PROPERTYTAG ; +The value size is given in bytes, divide this by the size of the data (4 for integers, 2 for shorts, etc..) ; Related .......: _GDIPlus_ImageGetPropertySize, _GDIPlus_ImageGetPropertyItemValue, _GDIPlus_ImageGetAllPropertyItems ; Link ..........; @@MsdnLink@@ GdipGetAllPropertyItems ; Example .......; No ; =============================================================================================================================== Func _GDIPlus_ImageGetAllPropertyItems($hImage) Local $iI, $iCount, $tBuffer, $pBuffer, $iBuffer, $tPropertyItem, $aSize, $aPropertyItems[1][1], $aResult $aSize = _GDIPlus_ImageGetPropertySize($hImage) If @error Then Return SetError(@error, @extended, -1) If $GDIP_STATUS Then $GDIP_ERROR = 1 Return -1 ElseIf $aSize[1] = 0 Then $GDIP_ERROR = 2 Return -1 EndIf $iBuffer = $aSize[0] $tBuffer = DllStructCreate("byte[" & $iBuffer & "]") $pBuffer = DllStructGetPtr($tBuffer) $iCount = $aSize[1] $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetAllPropertyItems", "hwnd", $hImage, "uint", $iBuffer, "uint", $iCount, "ptr", $pBuffer) If @error Then Return SetError(@error, @extended, -1) $GDIP_STATUS = $aResult[0] If $GDIP_STATUS Then $GDIP_ERROR = 3 Return -1 EndIf ReDim $aPropertyItems[$iCount + 1][4] $aPropertyItems[0][0] = $iCount For $iI = 1 To $iCount $tPropertyItem = DllStructCreate($tagGDIPPROPERTYITEM, $pBuffer) $aPropertyItems[$iI][0] = DllStructGetData($tPropertyItem, "id") $aPropertyItems[$iI][1] = DllStructGetData($tPropertyItem, "length") $aPropertyItems[$iI][2] = DllStructGetData($tPropertyItem, "type") $aPropertyItems[$iI][3] = DllStructGetData($tPropertyItem, "value") $pBuffer += DllStructGetSize($tPropertyItem) Next Return $aPropertyItems EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GDIPlus_ImageGetPropertyItemValue ; Description ...: Get property item values from fields in $tagGDIPPROPERTYITEM data ; Syntax ........: _GDIPlus_ImageGetPropertyItemValue($iLength, $iType, $pValue) ; Parameters ....: $iLength Length of the property value, in bytes ; |$iType Type of the value (a $GDIP_PROPERTYTAGTYPE* value - see GDIPConstants.au3) ; |$pValue Pointer to value ; Return values .: Success - An array ; | [0] value 1 ; | [1] value 2 (only for properties that have numerator and denominator) ; Failure - -1 ; Author ........: c.haslam ; Modified ......: ; Remarks........: If type is 7 ($GDIP_PROPERTYTAGTYPEUNDEFINED) value returned is an unsigned long. ; Depending on ID and originator of the image, value may actually be an unterminated string ; Related .......: _GDIPlus_ImageGetPropertyItem,_GDIPlus_ImageGetAllPropertyItems ; Link ..........: http://www.cipa.jp/std/documents/e/DC-008-Translation-2016-E.pdf, ; https://www.media.mit.edu/pia/Research/deepview/exif.html ; Example .......: No ; =============================================================================================================================== Func _GDIPlus_ImageGetPropertyItemValue($iLength, $iType, $pValue) Switch $iType Case $GDIP_PROPERTYTAGTYPEURATIONAL,$GDIP_PROPERTYTAGTYPESRATIONAL Local $aRet[2] Case Else Local $aRet[1] EndSwitch Switch $iType Case $GDIP_PROPERTYTAGTYPEUBYTE,$GDIP_PROPERTYTAGTYPESBYTE Local $tvalue = DllStructCreate('byte val',$pValue) $aRet[0] = $tvalue.val Case $GDIP_PROPERTYTAGTYPEASCII Local $tvalue = DllStructCreate('char val['&$iLength&']',$pValue) If @error Then MsgBox(0,@ScriptLineNumber,'@error='&@error) $aRet[0] = DllStructGetData($tvalue,'val') If @error Then MsgBox(0,@ScriptLineNumber,'@error='&@error) $aRet[0] = $tvalue.val Case $GDIP_PROPERTYTAGTYPEUSHORT Local $tvalue = DllStructCreate('ushort val',$pValue) $aRet[0] = $tvalue.val Case $GDIP_PROPERTYTAGTYPEULONG Local $tvalue = DllStructCreate('ulong val',$pValue) $aRet[0] = $tvalue.val Case $GDIP_PROPERTYTAGTYPEURATIONAL Local $tvalue = DllStructCreate('ulong val1;ulong val2',$pValue) $aRet[0] = $tvalue.val1 $aRet[1] = $tvalue.val2 Case $GDIP_PROPERTYTAGTYPESBYTE Local $tvalue = DllStructCreate('byte val',$pValue) $aRet[0] = $tvalue.val Case $GDIP_PROPERTYTAGTYPEUNDEFINED ; undefined, per specification, but may be a long but is sometimes a string Local $tvalue = DllStructCreate('ulong val',$pValue) $aRet[0] = $tvalue.val Case $GDIP_PROPERTYTAGTYPESSHORT Local $tvalue = DllStructCreate('short val',$pValue) $aRet[0] = $tvalue.val Case $GDIP_PROPERTYTAGTYPEULONG Local $tvalue = DllStructCreate('ulong val',$pValue) $aRet[0] = $tvalue.val Case $GDIP_PROPERTYTAGTYPESRATIONAL Local $tvalue = DllStructCreate('long val1;long val2',$pValue) $aRet[0] = $tvalue.val1 $aRet[1] = $tvalue.val2 Case $GDIP_PROPERTYTAGTYPESFLOAT Local $tvalue = DllStructCreate('float val',$pValue) $aRet[0] = $tvalue.val Case $GDIP_PROPERTYTAGTYPEDFLOAT Local $tvalue = DllStructCreate('double val',$pValue) $aRet[0] = $tvalue.val EndSwitch $tvalue = 0 Return $aRet EndFunc ; #FUNCTION# ==================================================================================================================== ; Name...........: _GDIPlus_ImageGetPropertyItem ; Description ...: Gets a specified property item (piece of metadata) from an Image object ; Syntax.........: _GDIPlus_ImageGetPropertyItem($hImage, $iPropID) ; Parameters ....: $hImage - Pointer to an Image object ; $iPropID - Identifier of the property item to be retrieved ; Return values .: Success - Array ; | [0] Property ID ; | [1] Property length ; | [2] Property type ; | [3] pointer to Property value ; Possible values of type are: ; |1 - The value pointer points to an array of bytes ; |2 - The value pointer points to a null-terminated ASCII string ; |3 - The value pointer points to unsigned short ; |4 - The value pointer points to an unsigned long ; |5 - The value pointer points to an array of unsigned two longs (numerator, denominator) ; |7 - The value pointer points to an array of bytes of any type, or is unterminated string\ ; |8 - The value pointer points to signed short ; |9 - The value pointer points to a signed long ; |10 - The value pointer points to an array of signed two longs (numerator, denominator) ; |11 - The value pointer points to a float ; |12 - The value pointer points to a double ; Failure - -1 and either: ; |@error and @extended are set if DllCall failed ; |$GDIP_STATUS contains a non-zero value specifying the error code ; |$GDIP_ERROR: ; | 1 - The _GDIPlus_ImageGetPropertyItemSize function failed, $GDIP_STATUS contains the error code ; | 2 - The specified property identifier does not exist in the image ; | 3 - The _GDIPlus_ImageGetPropertyItem function failed, $GDIP_STATUS contains the error code ; Author.........: Authenticity ; Modified.......: c.haslam ; Remarks .......: None ; Related .......: _GDIPlus_ImageGetPropertyIdList, _GDIPlus_ImageGetPropertyItemSize, _GDIPlus_ImageGetPropertyItemValue, ; $tagGDIPPROPERTYITEM ; Link ..........; @@MsdnLink@@ GdipGetPropertyItem http://www.cipa.jp/std/documents/e/DC-008-Translation-2016-E.pdf, ; https://www.media.mit.edu/pia/Research/deepview/exif.html ; Example .......; No ; =============================================================================================================================== Func _GDIPlus_ImageGetPropertyItem($hImage, $iPropID) Local $iBuffer, $tBuffer, $pBuffer, $tPropertyItem, $aResult $iBuffer = _GDIPlus_ImageGetPropertyItemSize($hImage, $iPropID) If @error Then Return SetError(@error, @extended, -1) If $GDIP_STATUS Then $GDIP_ERROR = 1 Return -1 ElseIf $iBuffer = 0 Then $GDIP_ERROR = 2 Return -1 EndIf $tBuffer = DllStructCreate("byte[" & $iBuffer & "]") $pBuffer = DllStructGetPtr($tBuffer) $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertyItem", "hwnd", $hImage, "uint", $iPropID, "uint", $iBuffer, "ptr", $pBuffer) If @error Then Return SetError(@error, @extended, -1) $GDIP_STATUS = $aResult[0] If $GDIP_STATUS Then $GDIP_ERROR = 3 Return -1 EndIf Local $tPropertyItem = DllStructCreate($tagGDIPPROPERTYITEM, $pBuffer) Local $aRet = [$tPropertyItem.id, $tPropertyItem.length,$tPropertyItem.type, $tPropertyItem.value] Return $aRet EndFunc ;==>_GDIPlus_ImageGetPropertyItem ; #FUNCTION# ==================================================================================================================== ; Name...........: _GDIPlus_ImageGetPropertySize ; Description ...: Gets the total size, in bytes, and the number of all the property items stored in an Image object ; Syntax.........: _GDIPlus_ImageGetPropertySize($hImage) ; Parameters ....: $hImage - Pointer to an Image object ; Return values .: Success - Array containing the total size and the number of property items: ; |[0] - Total size, in bytes, of the property items ; |[1] - Number of the property items ; Failure - -1 and either: ; |@error and @extended are set if DllCall failed ; |$GDIP_STATUS contains a non zero value specifying the error code ; Author.........: Authenticity ; Remarks .......: None ; Related .......: _GDIPlus_ImageGetPropertyIdList, _GDIPlus_ImageGetPropertyItem ; Link ..........; @@MsdnLink@@ GdipGetPropertyItemSize ; Example .......; No ; =============================================================================================================================== Func _GDIPlus_ImageGetPropertySize($hImage) Local $aSize[2], $aResult $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertySize", "hwnd", $hImage, "uint*", 0, "uint*", 0) If @error Then Return SetError(@error, @extended, -1) $GDIP_STATUS = $aResult[0] If $GDIP_STATUS Then Return -1 $aSize[0] = $aResult[2] $aSize[1] = $aResult[3] Return $aSize EndFunc ;==>_GDIPlus_ImageGetPropertySize ; #FUNCTION# ==================================================================================================================== ; Name...........: _GDIPlus_ImageGetPropertyItemSize ; Description ...: Gets the size, in bytes, of a specified property item of an Image object ; Syntax.........: _GDIPlus_ImageGetPropertyItemSize($hImage, $iPropID) ; Parameters ....: $hImage - Pointer to an Image object ; $iPropID - Identifier of the property item to be retrieved ; Return values .: Success - $tagGDIPPROPERTYITEM structure containing the property size, type and value pointer ; Failure - -1 and either: ; |@error and @extended are set if DllCall failed ; |$GDIP_STATUS contains a non zero value specifying the error code ; Author.........: Authenticity ; Remarks .......: None ; Related .......: _GDIPlus_ImageGetPropertyIdList, _GDIPlus_ImageGetPropertyItem ; Link ..........; @@MsdnLink@@ GdipGetPropertyItemSize ; Example .......; No ; =============================================================================================================================== Func _GDIPlus_ImageGetPropertyItemSize($hImage, $iPropID) Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertyItemSize", "hwnd", $hImage, "uint", $iPropID, _ "uint*", 0) If @error Then Return SetError(@error, @extended, -1) $GDIP_STATUS = $aResult[0] If $GDIP_STATUS Then Return -1 Return $aResult[3] EndFunc ;==>_GDIPlus_ImageGetPropertyItemSize  
    • c.haslam
      By c.haslam
      The following code is one of my many attempts to get the value of a string property from an image. It doesn't work. I know that IMAGEDESCRIPTION has a string value.
      In one of my many attempts, I did get the string OLYMPUS .., which I know is correct from IrfanView, but I can't get it again.
      How should I get this string?
       
      #include <GDIPlus.au3> Opt('MustDeclareVars',1) ; Property Item structure Global Const $tagGDIPPROPERTYITEM = _ "uint id;" & _ ; ID of this property "uint length;" & _ ; Length of the property value, in bytes "ushort type;" & _ ; Type of the value, as one of TAG_TYPE_XXX constants "ptr value;" ; property value Global Const $GDIP_PROPERTYTAGIMAGEDESCRIPTION = 0x010E ; #VARIABLES# =================================================================================================================== Global $ghGDIPMatrix = 0 Global $GDIP_STATUS = 0 Global $GDIP_ERROR = 0 Local $Dsk_ghImage _GDIPlus_Startup() $Dsk_ghImage = _GDIPlus_ImageLoadFromFile('H:\b\PA160005 - Copy.JPG') Local $propListVec = _GDIPlus_ImageGetPropertyIdList($Dsk_ghImage) Local $qProps = $propListVec[0] For $i = 1 To $qProps $propListVec[$i] = Hex($propListVec[$i]) While StringLeft($propListVec[$i],1)='0' $propListVec[$i] = StringMid($propListVec[$i],2) WEnd ConsoleWrite($propListVec[$i]&@CRLF) Next Local $tProp = _GDIPlus_ImageGetPropertyItem($Dsk_ghImage,$GDIP_PROPERTYTAGIMAGEDESCRIPTION) Local $len = $tProp.length Local $s = 'char str['&$len&']' Local $ptr = $tProp.value Local $tStr = DllStructCreate($s,$ptr) MsgBox(0,'@error',@error) Local $strval = DllStructGetData($tStr,'str') MsgBox(0,'','@error '&@error&' strval '&$strval) ; #FUNCTION# ==================================================================================================================== ; Name...........: _GDIPlus_ImageGetPropertyIdList ; Description ...: Gets a list of the property identifiers used in the metadata of an Image object ; Syntax.........: _GDIPlus_ImageGetPropertyIdList($hImage) ; Parameters ....: $hImage - Pointer to an Image object ; Return values .: Success - Array of property identifiers: ; |[0] - Number of property identifiers ; |[1] - Property identifier 1 ; |[2] - Property identifier 2 ; |[n] - Property identifier n ; Failure - -1 and either: ; |@error and @extended are set if DllCall failed ; |$GDIP_STATUS contains a non zero value specifying the error code ; |$GDIP_ERROR: ; | 1 - The _GDIPlus_ImageGetPropertyCount function failed, $GDIP_STATUS contains the error code ; | 2 - The image does not contain any property items ; | 3 - The _GDIPlus_ImageGetPropertyIdList function failed, $GDIP_STATUS contains the error code ; Author.........: Authenticity ; Remarks .......: The property item identifiers are declared in GDIPConstants.au3, those that start with $GDIP_PROPERTYTAGN* ; Related .......: _GDIPlus_ImageGetAllPropertyItems, _GDIPlus_ImageGetPropertyCount, _GDIPlus_ImageGetPropertyItem ; Link ..........; @@MsdnLink@@ GdipGetPropertyIdList ; Example .......; No ; =============================================================================================================================== Func _GDIPlus_ImageGetPropertyIdList($hImage) Local $iI, $iCount, $tProperties, $pProperties, $aProperties[1], $aResult $iCount = _GDIPlus_ImageGetPropertyCount($hImage) If @error Then Return SetError(@error, @extended, -1) If $GDIP_STATUS Then $GDIP_ERROR = 1 Return -1 ElseIf $iCount = 0 Then $GDIP_ERROR = 2 Return -1 EndIf $tProperties = DllStructCreate("uint[" & $iCount & "]") $pProperties = DllStructGetPtr($tProperties) $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertyIdList", "hwnd", $hImage, "int", $iCount, "ptr", $pProperties) If @error Then Return SetError(@error, @extended, -1) $GDIP_STATUS = $aResult[0] If $GDIP_STATUS Then $GDIP_ERROR = 3 Return -1 EndIf ReDim $aProperties[$iCount + 1] $aProperties[0] = $iCount For $iI = 1 To $iCount $aProperties[$iI] = DllStructGetData($tProperties, 1, $iI) Next Return $aProperties EndFunc ;==>_GDIPlus_ImageGetPropertyIdList ; #FUNCTION# ==================================================================================================================== ; Name...........: _GDIPlus_ImageGetPropertyItem ; Description ...: Gets a specified property item (piece of metadata) from an Image object ; Syntax.........: _GDIPlus_ImageGetPropertyItem($hImage, $iPropID) ; Parameters ....: $hImage - Pointer to an Image object ; $iPropID - Identifier of the property item to be retrieved ; Return values .: Success - $tagGDIPPROPERTYITEM structure containing the property size, type and value pointer ; Failure - -1 and either: ; |@error and @extended are set if DllCall failed ; |$GDIP_STATUS contains a non zero value specifying the error code ; |$GDIP_ERROR: ; | 1 - The _GDIPlus_ImageGetPropertyItemSize function failed, $GDIP_STATUS contains the error code ; | 2 - The specified property identifier does not exist in the image ; | 3 - The _GDIPlus_ImageGetPropertyItem function failed, $GDIP_STATUS contains the error code ; Author.........: Authenticity ; Remarks .......: None ; Related .......: _GDIPlus_ImageGetPropertyIdList, _GDIPlus_ImageGetPropertyItemSize, $tagGDIPPROPERTYITEM ; Link ..........; @@MsdnLink@@ GdipGetPropertyItem ; Example .......; No ; =============================================================================================================================== Func _GDIPlus_ImageGetPropertyItem($hImage, $iPropID) Local $iBuffer, $tBuffer, $pBuffer, $tPropertyItem, $aResult $iBuffer = _GDIPlus_ImageGetPropertyItemSize($hImage, $iPropID) If @error Then Return SetError(@error, @extended, -1) If $GDIP_STATUS Then $GDIP_ERROR = 1 Return -1 ElseIf $iBuffer = 0 Then $GDIP_ERROR = 2 Return -1 EndIf $tBuffer = DllStructCreate("byte[" & $iBuffer & "]") $pBuffer = DllStructGetPtr($tBuffer) $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertyItem", "hwnd", $hImage, "uint", $iPropID, "uint", $iBuffer, "ptr", $pBuffer) If @error Then Return SetError(@error, @extended, -1) $GDIP_STATUS = $aResult[0] If $GDIP_STATUS Then $GDIP_ERROR = 3 Return -1 EndIf $tPropertyItem = DllStructCreate($tagGDIPPROPERTYITEM, $pBuffer) Return $tPropertyItem EndFunc ;==>_GDIPlus_ImageGetPropertyItem ; #FUNCTION# ==================================================================================================================== ; Name...........: _GDIPlus_ImageGetPropertyCount ; Description ...: Gets the number of properties (pieces of metadata) stored in an Image object ; Syntax.........: _GDIPlus_ImageGetPropertyCount($hImage) ; Parameters ....: $hImage - Pointer to an Image object ; Return values .: Success - Number of property items store in the Image object ; Failure - -1 and either: ; |@error and @extended are set if DllCall failed ; |$GDIP_STATUS contains a non zero value specifying the error code ; Author.........: Authenticity ; Remarks .......: None ; Related .......: _GDIPlus_ImageGetAllPropertyItems, _GDIPlus_ImageGetPropertyIdList ; Link ..........; @@MsdnLink@@ GdipGetPropertyCount ; Example .......; No ; =============================================================================================================================== Func _GDIPlus_ImageGetPropertyCount($hImage) Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertyCount", "hwnd", $hImage, "uint*", 0) If @error Then Return SetError(@error, @extended, -1) $GDIP_STATUS = $aResult[0] If $GDIP_STATUS Then Return -1 Return $aResult[2] EndFunc ;==>_GDIPlus_ImageGetPropertyCount ; #FUNCTION# ==================================================================================================================== ; Name...........: _GDIPlus_ImageGetPropertyItemSize ; Description ...: Gets the size, in bytes, of a specified property item of an Image object ; Syntax.........: _GDIPlus_ImageGetPropertyItemSize($hImage, $iPropID) ; Parameters ....: $hImage - Pointer to an Image object ; $iPropID - Identifier of the property item to be retrieved ; Return values .: Success - $tagGDIPPROPERTYITEM structure containing the property size, type and value pointer ; Failure - -1 and either: ; |@error and @extended are set if DllCall failed ; |$GDIP_STATUS contains a non zero value specifying the error code ; Author.........: Authenticity ; Remarks .......: None ; Related .......: _GDIPlus_ImageGetPropertyIdList, _GDIPlus_ImageGetPropertyItem ; Link ..........; @@MsdnLink@@ GdipGetPropertyItemSize ; Example .......; No ; =============================================================================================================================== Func _GDIPlus_ImageGetPropertyItemSize($hImage, $iPropID) Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertyItemSize", "hwnd", $hImage, "uint", $iPropID, "uint*", 0) If @error Then Return SetError(@error, @extended, -1) $GDIP_STATUS = $aResult[0] If $GDIP_STATUS Then Return -1 Return $aResult[3] EndFunc ;==>_GDIPlus_ImageGetPropertyItemSize  
    • c.haslam
      By c.haslam
      I have found that:
      there are 276 functions in Authenticity's GDIP.au3 (written for 3.3.6.1) that are not in 3.3.14.2's GDIPlus.au3.  there are many constants in his GDIPConstants.au3 that are not in 3.3.14.2's GDIPlus.au3, but there are some that are. So:
      GDIP extras.au3 contains functions that are not in GDIPlus.au3. They have been extracted from GDIP.au3 The revised GDIPConstants.au3 has constants that are duplicates of those in GDIPlus.au3 commented out. They are attached.
      I have done limited testing on 3.3.14.2 with GDIP extras.au3 and the revised GDIPConstants.au3 included.
      I have undertaken this effort in thanks for the help with GDI+ that I have received on this form, especially from UEZ.
      Authenticity's thread is here. For those who do not 7zip, I am attaching his GDIP as a zip file. It contains many examples.
      GDIP33142.zip
      GDIPAuthenticity.zip
    • c.haslam
      By c.haslam
      UEZ has kindly provided me with code that rotates an image per a line: see here
      Because I want to trim a photograph after rotation, I need to crop the photo. I wrote code which calls _GDIPlus_GraphicsSetClipRect() to do this, but it places spurious stuff in the corners: see 2.jpg attached.
      I want only the trimmed photo to show.
      The original jpeg is also attached.
      The arguments to _GDIPlus_GraphicsSetClipRect() come from solving 2 simultaneous equations: if a and b are the width and height of the original photo, find x and y, the width and height of the rotated and cropped rectangle;
      a = x cos(ang) + y sin(ang)
      b = x sin(ang) + y cos(ang)
      My solution is:
      x = (b * sin(ang) - a*cos(ang)) / (sin(ang)^2 - (cos(ang)^2)
      y = (b * cos(ang) - a * sin(ang)) / (cos(ang)^2 - sin(ang)^2)
      To try to get a handle on the problem, I have temporarily added in several lines in Case $btn. In 2.jpg, you can see that the rectangle bounding the area to be retained is in the wrong place.
      The code is:
      #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 Global Const $fPi = ACos(-1), $fPi2 = $fPi / 2, $fRad = 180 / $fPi GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL") GUIRegisterMsg($WM_PAINT,'WM_PAINT') Global $gX0=10,$gX1=580,$gY0,$gY1,$gForm1,$glblPic,$iLW,$iLH,$iW,$iH Global $ghCanvas,$ghImage,$ghPen,$gGraphicPic,$ghBitmap,$ghMatrix,$ghImageClone,$ghGfxClone Global Const $kDegToRads = 3.14159/180 main() Func main() $gForm1 = GUICreate("Form1", 623, 601, 192, 114) $iLW = 589 $iLH = 500 $glblPic = GUICtrlCreateLabel("", 8, 8, $iLW, $iLH) Local $btn = GUICtrlCreateButton("Rotate", 472, 560, 65, 25) GUISetState(@SW_SHOW) Local $oldY0,$oldY1,$fAngle _GDIPlus_Startup() $ghPen = _GDIPlus_PenCreate(0xFF999999,2) $ghImage = _GDIPlus_ImageLoadFromFile('H:\b\pergola.jpg') Local $h = GUICtrlGetHandle($glblPic) $gGraphicPic = _GDIPlus_GraphicsCreateFromHWND($h) $gY0 = 400 $gY1 = 400 $iW = _GDIPlus_ImageGetWidth($ghImage) $iH = _GDIPlus_ImageGetHeight($ghImage) $ghBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH) $ghCanvas = _GDIPlus_ImageGetGraphicsContext($ghBitmap) $ghMatrix = _GDIPlus_MatrixCreate() ; Loop until the user exits. While True If $gY0<>$oldY0 Or $gY1<>$oldY1 Then Paint() $oldY0 = $gY0 $oldY1 = $gY1 Else Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $btn $ghImageClone=_GDIPlus_BitmapCreateFromScan0($iW, $iH) $ghGfxClone=_GDIPlus_ImageGetGraphicsContext($ghImageClone) _GDIPlus_MatrixTranslate($ghMatrix, $iW/2, $iH/2) $gY1 = 300 ; temp Local $ang = -Angle($gY1-$gY0, $gX1-$gX0) _GDIPlus_MatrixRotate($ghMatrix, $ang) ;~ _GDIPlus_MatrixRotate($ghMatrix, -Angle($gY1-$gY0, $gX1-$gX0)) _GDIPlus_MatrixTranslate($ghMatrix, -$iW/2, -$iH/2) _GDIPlus_GraphicsSetTransform($ghGfxClone, $ghMatrix) _GDIPlus_GraphicsDrawImageRect($ghGfxClone,$ghImage,0,0,$iW,$iH) Local $angRads = $ang*$kDegToRads Local $sinAng = Sin($angRads) Local $cosAng = Cos($angRads) Local $wid = ($iLH*$sinAng-$iLW*$cosAng)/($sinAng^2-$cosAng^2) Local $left = ($iLW-$wid)/2 Local $ht = ($iLH*$cosAng-$iLW*$sinAng)/($cosAng^2-$sinAng^2) Local $top = ($iLH-$ht)/2 _GDIPlus_GraphicsDrawRect($ghGfxClone,$left,$top,$wid,$ht,$ghPen) ; temp _GDIPlus_GraphicsSetClipRect($ghGfxClone,$left,$top,$wid,$ht,0) _GDIPlus_GraphicsDispose($ghGfxClone) $ghGfxClone=_GDIPlus_ImageGetGraphicsContext($ghImage) _GDIPlus_GraphicsClear($ghImage) _GDIPlus_GraphicsDrawImageRect($ghGfxClone,$ghImageClone,0,0,$iW,$iH) _GDIPlus_GraphicsDispose($ghGfxClone) _GDIPlus_ImageDispose($ghImageClone) $gy0 = 400 $gy1 = 400 Paint() _GDIPlus_ImageSaveToFile($ghImage,'H:\b\2.jpg') ; added - is rotated, with same size as original file EndSwitch EndIf WEnd ; Clean up resources _GDIPlus_MatrixDispose($ghMatrix) _GDIPlus_ImageDispose($ghCanvas) _GDIPlus_ImageDispose($ghImage) _GDIPlus_ImageDispose($ghBitmap) _GDIPlus_PenDispose($ghPen) _GDIPlus_GraphicsDispose($gGraphicPic) _GDIPlus_Shutdown() EndFunc Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam Local Const $kYmax=$iLH-1,$kDelta=2 Local $vec = GUIGetCursorInfo($gForm1) If $vec[4] = $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 -= $kDelta If $iDelta < 0 And $gY0<$kYmax Then $gY0 += $kDelta EndIf Else If BitAND($iKeys,$MK_SHIFT)=$MK_SHIFT Then If $iDelta > 0 And $gY1>3 Then $gY1 -= $kDelta If $iDelta < 0 And $gY1<$kYmax Then $gY1 += $kDelta Else If $iDelta > 0 And $gY0>3 Then $gY0 -= $kDelta If $iDelta < 0 And $gY0<$kYmax Then $gY0 += $kDelta If $iDelta > 0 And $gY1>3 Then $gY1 -= $kDelta If $iDelta < 0 And $gY1<$kYmax Then $gY1 += $kDelta EndIf EndIf EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_MOUSEWHEEL Func Paint() _GDIPlus_GraphicsClear($ghCanvas,0) _GDIPlus_GraphicsDrawImageRect($ghCanvas, $ghImage, 0,0, $iLW, $iLH) _GDIPlus_GraphicsDrawLine($ghCanvas, $gX0, $gY0, $gX1, $gY1, $ghPen) _GDIPlus_GraphicsDrawImageRect($gGraphicPic, $ghBitmap, 0, 0, $iW, $iH) EndFunc Func WM_PAINT() _WinAPI_RedrawWindow($gForm1, 0, 0, $RDW_UPDATENOW) Paint() _WinAPI_RedrawWindow($gForm1, 0, 0, $RDW_VALIDATE) EndFunc Func Angle($y, $x) ;return value is in degree Local Const $fPi = ACos(-1), $fPi2 = ACos(-1) / 2, $fRad = 180 / $fPi Switch True Case ($x > 0) Return ATan($y / $x) * $fRad Case ($x < 0 And $y >= 0) Return ATan($y / $x + $fPi) * $fRad Case ($x < 0 And $y < 0) Return ATan($y / $x - $fPi) * $fRad Case ($x = 0 And $y > 0) Return $fPi2 * $fRad Case ($x = 0 And $y < 0) Return -$fPi2 * $fRad Case ($x = 0 And $y = 0) Return 0 EndSwitch EndFunc I also don't understand how the rotated picture gets displayed. There are graphics objects, graphics contexts and PDI+ bitmaps. How are they related?
      Help would be much appreciated.


    • UEZ
      By UEZ
      Here a small tool I wrote to update my Sysinternal tools collection without the need to download always the whole package or visiting the site to check for updates. I know that there are several tools available (also some tools written in AutoIt) but here another one for the collection. It was good exercise for me to code it.
       
       
        
       
       
      Some files from cannot be downloaded although they are visible on the web site!
       
      Here the download link of the source code only: AutoIt Sysinternal Tools Synchronizer v0.99.1 build 2017-10-23 beta.7z  (1353 downloads previously)
      -=> Requires AutoIt version 3.3.13.20 or higher / tested on Win8.1 real machine and some VMs: Win7 / Vista / Win10
       
      Compiled exe only: @MediaFire
       
      Just select the Sysinternal Tools folder or create one and press the synchronize button to download the selected items. Click on AutoIt label (near to left upper corner) to open menu.
       
      Special thanks to LarsJ, Melba23 and mesale0077 for their help. 
       
      I've still some ideas to implement which are more gimmick related, so it is not finished yet...
      If you want to add your language please check out #Region Language. Thanks. 
       
      Please report any bug or if you have any suggestions.
       
      The language of the tool tip from each of the executable in the left list view were automatically created using Google translator and weren't checked for correctness.
       
      Br,
      UEZ