how can i get the GDI+ declaration functions\types?
how can i get the GDI+ declaration functions\types?
i have find these module: https://github.com/tannerhelland/pd2...rc/GDIPlus.bas
but some types are missed
for now, i only need the GDIPlus_DrawImage() for draw an image using points array.... but maybe there is a complete declaration function\type file
Re: how can i get the GDI+ declaration functions\types?
thank you so much for all
now how can i learn using that functions?
i have a C\C++ tutorial\pdf from MSDN, but they have some differences from C\C++ to VB6.
i need understand, for now, the GdipDrawImagePointsI() or GdipDrawImagePoints()(what changes is from Float to Long):
Code:
Public Declare Function GdipDrawImagePointsI Lib "gdiplus" (ByVal graphics As Long, ByVal image As Long, dstpoints As POINTL, ByVal count As Long) As GpStatus
how the dstpoints works? is just the 4 points?
from the Master Visual Basic 2010 book: "VB 2010 at Work: The ImageCube Project
As discussed earlier in this tutorial, the DrawImage method can render images on any parallelogram,
not just a rectangle, with the necessary distortion. A way to look at these images is not
as distorted images, but as perspective images. Looking at a printout from an unusual angle is
equivalent to rendering an image within a parallelogram. Imagine a cube with a different image
glued on each side. To display such a cube on your monitor, you must calculate the coordinates
of the cube’s edges and then use these coordinates to define the parallelograms on which each
image will be displayed. Figure 4.16 shows a cube with a different image on each side."
and
"Graphics.DrawImage(img, points())
The array holds three points, which are the top-left, top-right, and bottom-left corners of the
parallelogram. The fourth point is determined uniquely by the other three, and you need not
supply it. The ImageCube sample project, shown later in this tutorial, uses this overloaded form
of the DrawImage method to draw a cube with a different image on each face.
Another interesting form of the method allows you to set the attributes of the image:
Graphics.DrawImage(image, points(), srcRect, units, attributes)
The first two arguments are the same as in the previous forms of the method. The srcRect
argument is a rectangle that specifies the portion of image to draw, and units is a constant
of the GraphicsUnit enumeration. It determines how the units of the rectangle are measured
(pixels, inches, and so on). The last argument is an ImageAttributes object that contains information
about the attributes of the image you want to change (such as the gamma value, and a
transparent color value or color key). The properties of the ImageAttributes class are discussed
shortly."
my question is: "The array holds three points, which are the top-left, top-right, and bottom-left corners of the
parallelogram. The fourth point is determined uniquely by the other three, and you need not
supply it."
can i add the 4 point?
i'm getting problems on other different code, that's why i'm asking.
thank you so much for all
Re: how can i get the GDI+ declaration functions\types?
Originally Posted by joaquim
can i add the 4 point?
i'm getting problems on other different code, that's why i'm asking.
thank you so much for all
You can add 4th point but most probably it will be ignored. The text explicitly states that the API can draw parallelograms which are uniquely defined by only 3 points. The API might ignore the extra point of it might explicitly fail, both behaviors are to be expected.
What is not expected is to actually *use* the 4-th point and skew the image into a random quadrilateral.
Re: how can i get the GDI+ declaration functions\types?
It is difficult to get documentation on GdiPlus - which is a pity because it offers an awful lot of useful high quality graphic functions. If you don't mind PowerBasic-style declarations: José Roca's help file is an excellent resource
Re: how can i get the GDI+ declaration functions\types?
How about a phony TrapezoidBlt() operation? Simplistic and assumes an upright position but you could rotate by adding a PlgBlt() step.
Code:
Option Explicit
'Faux "TrapezoidBlt" operation.
'
'Quick and dirty: Two PictureBox controls AutoRedraw = True to use their DCs.
' Picture1 prefilled with a bitmap to blit.
Private Enum StretchBltModes
[_SBMFAILED] = 0
BLACKONWHITE = 1
WHITEONBLACK = 2
COLORONCOLOR = 3
HALFTONE = 4
End Enum
Private Declare Function SetStretchBltMode Lib "gdi32" ( _
ByVal hDC As Long, _
ByVal StretchMode As StretchBltModes) As StretchBltModes
Private Declare Function StretchBlt Lib "gdi32" ( _
ByVal hdcDest As Long, _
ByVal nXOriginDest As Long, _
ByVal nYOriginDest As Long, _
ByVal nWidthDest As Long, _
ByVal nHeightDest As Long, _
ByVal hdcSrc As Long, _
ByVal nXOriginSrc As Long, _
ByVal nYOriginSrc As Long, _
ByVal nWidthSrc As Long, _
ByVal nHeightSrc As Long, _
Optional ByVal dwRop As RasterOpConstants = vbSrcCopy) As Long
Private Declare Function TransparentBlt Lib "msimg32" ( _
ByVal hdcDest As Long, _
ByVal nXOriginDest As Long, _
ByVal nYOriginDest As Long, _
ByVal nWidthDest As Long, _
ByVal hHeightDest As Long, _
ByVal hdcSrc As Long, _
ByVal nXOriginSrc As Long, _
ByVal nYOriginSrc As Long, _
ByVal nWidthSrc As Long, _
ByVal nHeightSrc As Long, _
ByVal crTransparent As Long) As Long
Private Sub TrapezoidBlt(ByVal PctTop As Single, ByVal TranspColor As Long)
Dim ScanLines As Long
Dim FullWidth As Long
Dim ScanWidth As Single
Dim ScanLeft As Single
Dim Delta As Single
Dim sbmOrig As StretchBltModes
Dim ScanLine As Long
With Picture1
Picture2.Width = .Width
Picture2.Height = .Height
ScanLines = ScaleY(.ScaleHeight, .ScaleMode, vbPixels)
FullWidth = ScaleX(.Width, ScaleMode, vbPixels)
ScanWidth = .ScaleWidth * PctTop / 100
ScanLeft = (.ScaleWidth - ScanWidth) / 2
Delta = ScanLeft / ScanLines
Picture2.BackColor = TranspColor
sbmOrig = SetStretchBltMode(Picture2.hDC, HALFTONE)
For ScanLine = 0 To ScanLines - 1
StretchBlt Picture2.hDC, _
ScaleX(ScanLeft, .ScaleMode, vbPixels), _
ScanLine, _
ScaleX(ScanWidth, .ScaleMode, vbPixels), _
1, _
.hDC, _
0, _
ScanLine, _
FullWidth, _
1
ScanLeft = ScanLeft - Delta
ScanWidth = ScanWidth + 2 * Delta
Next
End With
SetStretchBltMode Picture2.hDC, sbmOrig
TransparentBlt hDC, _
0, _
0, _
ScaleX(ScaleWidth, ScaleMode, vbPixels), _
ScaleY(ScaleHeight, ScaleMode, vbPixels), _
Picture2.hDC, _
0, _
0, _
FullWidth, _
ScanLines, _
TranspColor
End Sub
Private Sub Form_Resize()
If WindowState <> vbMinimized Then
AutoRedraw = True
Cls
TrapezoidBlt 40, &H10101
AutoRedraw = False
End If
End Sub
Re: how can i get the GDI+ declaration functions\types?
Originally Posted by joaquim
...
from the Master Visual Basic 2010 book: "VB 2010 at Work: The ImageCube Project
As discussed earlier in this tutorial, the DrawImage method can render images on any parallelogram,
not just a rectangle, with the necessary distortion. A way to look at these images is not
as distorted images, but as perspective images. Looking at a printout from an unusual angle is
equivalent to rendering an image within a parallelogram. Imagine a cube with a different image
glued on each side. To display such a cube on your monitor, you must calculate the coordinates
of the cube’s edges and then use these coordinates to define the parallelograms on which each
image will be displayed. Figure 4.16 shows a cube with a different image on each side."
...
i'm getting problems on other different code, that's why i'm asking.
thank you so much for all
You will get the same code problems using GDI+ as you do now using plgblt, since you are doing the same operation. The DrawImage with an array of points just allows you to do a parallelogram blit at a higher level, and within the GDI+ drawing space (i.e. in the current Graphics object context with the active graphics matrix in play).
The use of the word "perspective images" in the book is misleading. It is not a perspective image. A parallelogram image is isometric.
You can draw isometric blocks, so there is no Z-depth foreshortening nor is there perspective depth calculations to squeeze or expand the texture along the length of the Z axis to give you that perspective view.
If you want to use the parallelogram to draw isometric surfaces, then you can simplify your code and remove the extra perspective calculations done at the end of your coordinate conversions.
If you want to actually draw a texture with perspective then you need to abandon the parallelogram. You are not drawing parallelograms, you are drawing trapezoids. I'm not sure how many hundreds of times over the last 10 years of your posts we have to say this. I know language is one problem, but parallelograms and trapezoids are geometric terms and should be applicable and describe in most any higher level school curriculum regardless of the native language it is taught in.
If you want to draw a maze like game, with floor, ceiling and walls, then the code dilettante gave is like the first step in mapping a texture to a trapezoid shape.
The part that is missing from dilettante's code is a compensation in the loop for depth. The texture is "spread" evenly across the top to bottom of the trapezoid (i.e. the value delta is a constant, and used in directly indexing into the source texture).
You could use plgblt in place of stretchblt in dilettante's code, which would allow drawing at other angles, as dilettante says, but if you want to stay level and run around a maze like world, this isn't necessary.
The plgblt, even used as a direct replacement in dilettante's code, is many times slower than using stretchblt, so I would avoid using it if possible.
For perspective, the index into the source texture needs to be calculated for each line (horizontal line in this case) based on z-depth of that line.
Depending on the values you use, for the closest end of the trapezoid (the bottom), you might be blitting the same line of pixels from the source texture, so the texture is "stretched" at the close end, and gets less stretched as you go up the trapezoid until it is one to one for a while, and then starts skipping lines of the source, so the image shrinks vertically as it continues filling the trapezoid.
That is what you need to do. There isn't an Windows API call that will do that for you.
There is a GDI+ call to draw a graphics path with perspective, and that is the closest that a Windows API comes to drawing with perspective. But you can't use a graphics path to draw an image with perspective. The path has perspective, but not the brush that fills the path.
Last edited by passel; Oct 19th, 2020 at 12:15 PM.
"Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930
Re: how can i get the GDI+ declaration functions\types?
passel that's why i'm using the GDI+, but seems that you have right: i don't understand what i'm missing... sorry.
i did i new function that works draw an image:
Code:
Private Function DrawImage(filename As String, hdc As Long, x As Long, y As Long) As Boolean
On Error Resume Next
Dim GDIsi As GdiplusStartupInput, gToken As Long, hGraphics As Long, hBitmap As Long
GDIsi.GdiplusVersion = 1&
GdiplusStartup gToken, GDIsi
If Err Then
Err.Clear
Exit Function
ElseIf gToken = 0& Then
Exit Function
End If
On Error GoTo 0
Call GdipCreateFromHDC(hdc, hGraphics)
If hGraphics Then
Call GdipLoadImageFromFile(StrPtr(filename), hBitmap)
If hBitmap Then
GdipDrawImage hGraphics, hBitmap, x, y
GdipDisposeImage hBitmap
DrawImage = True
End If
GdipDeleteGraphics hGraphics
End If
GdiplusShutdown gToken
End Function
the image is drawed correctly..
yesterday i did a new function for use the points:
Code:
Private Function DrawImagePoints(filename As String, hdc As Long, Points() As POINTL) As Boolean
On Error Resume Next
Dim GDIsi As GdiplusStartupInput, gToken As Long, hGraphics As Long, hBitmap As Long
GDIsi.GdiplusVersion = 1&
GdiplusStartup gToken, GDIsi
If Err Then
Err.Clear
Exit Function
ElseIf gToken = 0& Then
Exit Function
End If
On Error GoTo 0
Call GdipCreateFromHDC(Me.hdc, hGraphics)
If hGraphics Then
Call GdipLoadImageFromFile(StrPtr(filename), hBitmap)
If hBitmap Then
GdipDrawImagePointsI hGraphics, hBitmap, Points(0), 3
GdipDisposeImage hBitmap
DrawImagePoints = True
End If
GdipDeleteGraphics hGraphics
End If
GdiplusShutdown gToken
End Function
//how i use it:
Dim s(4) As POINTL
s(0).x = Points(0).x
s(0).y = Points(0).y
s(1).x = Points(1).x
s(1).y = Points(1).y
s(2).x = Points(3).x
s(2).y = Points(3).y
s(0).x = Points(0).x
s(0).y = Points(0).y
DrawImagePoints "C:\Users\Joaquim Jesus\Documents\Visual Basic 6\World3D\tijolo.jpg", Me.hdc, s
Me.Refresh
the image isn't showed... seems the 'hGraphics' isn't created or something...
what you can tell me?
thanks for the link LaVolte
Re: how can i get the GDI+ declaration functions\types?
Code:
Private Sub DrawPlane(Position As Position3D, size As Size3D, Rotation As Angle3D, WorldSize As Size3D)
Dim Points(4) As POINTAPI
Dim NewPoint As POINTAPI
Dim NewPosition3D(4) As Position3D
Dim RotatedPosition As Position3D
'Rotate from player position:
With Player1.Position
FillPosition3D RotatedPosition, Player1.Position.x + Player1.size.Width / 2, Player1.Position.y + Player1.size.Height / 2, Player1.Position.Z + Player1.size.ZDepth / 2 'Camera Position
End With
'Get the four vectors
'Floor:
'Vector1: low-left
FillPosition3D NewPosition3D(0), Position.x, Position.y, Position.Z + size.ZDepth
NewPosition3D(0) = Rotate(NewPosition3D(0), Rotation, RotatedPosition)
'Vector2: upper-left
FillPosition3D NewPosition3D(1), Position.x + size.Width, Position.y, Position.Z + size.ZDepth
NewPosition3D(1) = Rotate(NewPosition3D(1), Rotation, RotatedPosition)
'Vector3: upper-right
FillPosition3D NewPosition3D(2), Position.x + size.Width, Position.y, Position.Z
NewPosition3D(2) = Rotate(NewPosition3D(2), Rotation, RotatedPosition)
'Vector4: low-right
FillPosition3D NewPosition3D(3), Position.x, Position.y, Position.Z
NewPosition3D(3) = Rotate(NewPosition3D(3), Rotation, RotatedPosition)
'Testing if the plane is on screen:
If ((IsOnCamera(NewPosition3D(0), camera1.Position, camera1.size) = False) _
And (IsOnCamera(NewPosition3D(1), camera1.Position, camera1.size) = False) _
And (IsOnCamera(NewPosition3D(2), camera1.Position, camera1.size) = False) _
And (IsOnCamera(NewPosition3D(3), camera1.Position, camera1.size) = False)) Then
'Exit Sub
End If
If (IsOnCamera(NewPosition3D(0), camera1.Position, camera1.size) = False) Then
' NewPosition3D(0) = GetInCamVector(NewPosition3D(0), NewPosition3D(1))
End If
If (IsOnCamera(NewPosition3D(1), camera1.Position, camera1.size) = False) Then
'NewPosition3D(1) = GetInCamVector(NewPosition3D(1), NewPosition3D(0))
End If
If (IsOnCamera(NewPosition3D(2), camera1.Position, camera1.size) = False) Then
'NewPosition3D(2) = GetInCamVector(NewPosition3D(1), NewPosition3D(2))
'NewPosition3D(2).X = NewPosition3D(3).X
End If
If (IsOnCamera(NewPosition3D(3), camera1.Position, camera1.size) = False) Then
'NewPosition3D(3) = NewPosition3D(0)
'NewPosition3D(3).X = NewPosition3D(2).X
End If
'Convert all 3D vectors to 2D vectors(for screen):
Dim I As Integer
For I = 0 To UBound(Points)
Points(I) = ConvertPositon3DTo2D(NewPosition3D(I), WorldSize)
Next I
'change the brush and pen:
FillStyle = vbFSSolid
'FillColor = vbRed
'Draw the polygn:
DrawStyle = DrawStyleConstants.vbInvisible
Polygon Me.hdc, Points(0), 4
'draw the texture:
Dim TexturePoints(3) As POINTAPI
TexturePoints(0) = Points(0) 'upper-left
TexturePoints(1) = Points(1) 'upper-right
TexturePoints(2) = Points(3) 'lower-left
Label2.Caption = "TexturePoints(0): (" + CStr(TexturePoints(0).x) + ", " + CStr(TexturePoints(0).y) + ")"
Label2.Caption = Label2.Caption + vbNewLine + "TexturePoints(1): (" + CStr(TexturePoints(1).x) + ", " + CStr(TexturePoints(1).y) + ")"
Label2.Caption = Label2.Caption + vbNewLine + "TexturePoints(2): (" + CStr(TexturePoints(2).x) + ", " + CStr(TexturePoints(2).y) + ")"
Label3.Caption = "Points(0): (" + CStr(Points(0).x) + ", " + CStr(Points(0).y) + ")"
Label3.Caption = Label3.Caption + vbNewLine + "Points(1): (" + CStr(Points(1).x) + ", " + CStr(Points(1).y) + ")"
Label3.Caption = Label3.Caption + vbNewLine + "Points(2): (" + CStr(Points(2).x) + ", " + CStr(Points(2).y) + ")"
Label3.Caption = Label3.Caption + vbNewLine + "Points(3): (" + CStr(Points(3).x) + ", " + CStr(Points(3).y) + ")"
Dim s(4) As POINTL
s(0).x = Points(0).x
s(0).y = Points(0).y
s(1).x = Points(1).x
s(1).y = Points(1).y
s(2).x = Points(3).x
s(2).y = Points(3).y
s(0).x = Points(0).x
s(0).y = Points(0).y
'If (PlgBlt(Me.hDC, TexturePoints(0), Picture1.hDC, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, &O0, &O0, &O0) = 0) Then MsgBox CStr(GetLastError())
DrawImagePoints "C:\Users\Joaquim Jesus\Documents\Visual Basic 6\World3D\tijolo.jpg", Me.hdc, s
Me.Refresh
End Sub
Code:
Private Function ConvertPositon3DTo2D(Position As Position3D, World3DSize As Size3D) As POINTAPI
Dim ConvertedPosition As POINTAPI
Dim PosZZDepth As Long
Dim Width As Double
Dim Height As Double
'sum Z position with cam world distance:
PosZZDepth = Position.Z + World3DSize.distance
If (PosZZDepth = 0) Then PosZZDepth = 1 'avoiding division by zero
'getting center of the screen center:
If (World3DSize.Width = 0) Then World3DSize.Width = 1 'avoiding division by zero
Width = World3DSize.Width / 2
If (World3DSize.Height = 0) Then World3DSize.Height = 1 'avoiding division by zero
Height = World3DSize.Height / 2
'avoid drawing on back of the camera:
If (PosZZDepth <= World3DSize.distance) Then
PosZZDepth = 1
'World3DSize.distance = 1
End If
'convert 3D(X, Y, Z) to 2D(X,Y):
'ConvertedX = (ActualX * CamDistance /(CamDistance + ZPosition)) + HalfCenterOfWidth
'ConvertedY = (ActualY * CamDistance /(CamDistance + ZPosition)) + HalfCenterOfHeight
ConvertedPosition.x = (Position.x * World3DSize.distance / PosZZDepth) + Width
ConvertedPosition.y = (Position.y * World3DSize.distance / PosZZDepth) + Height
ConvertPositon3DTo2D = ConvertedPosition
End Function
Private Function ConvertDegreesToRadians(Rotation As Angle3D) As Angle3D
Dim deg2Rad As Double
deg2Rad = Pi / 180
ConvertDegreesToRadians.x = Rotation.x * deg2Rad
ConvertDegreesToRadians.y = Rotation.y * deg2Rad
ConvertDegreesToRadians.Z = Rotation.Z * deg2Rad
End Function
Private Function Rotate(Position As Position3D, Rotation As Angle3D, PositionRotated As Position3D) As Position3D
Dim ConvertedPosition As Position3D
Dim RotationInRads As Angle3D
RotationInRads = ConvertDegreesToRadians(Rotation)
ConvertedPosition = Position
ConvertedPosition.x = Position.x - PositionRotated.x
ConvertedPosition.y = Position.y - PositionRotated.y 'reversed because Y increments down
ConvertedPosition.Z = Position.Z - PositionRotated.Z
Dim T As Position3D
'Z axis (Roll)
T = ConvertedPosition
ConvertedPosition.x = T.x * Cos(RotationInRads.Z) - T.y * Sin(RotationInRads.Z)
ConvertedPosition.y = T.x * Sin(RotationInRads.Z) + T.y * Cos(RotationInRads.Z)
'X axis (Pitch)
T = ConvertedPosition
ConvertedPosition.y = T.y * Cos(RotationInRads.x) - T.Z * Sin(RotationInRads.x)
ConvertedPosition.Z = T.y * Sin(RotationInRads.x) + T.Z * Cos(RotationInRads.x)
'Y axis (Yaw)
T = ConvertedPosition
ConvertedPosition.x = T.Z * Sin(RotationInRads.y) + T.x * Cos(RotationInRads.y)
ConvertedPosition.Z = T.Z * Cos(RotationInRads.y) - T.x * Sin(RotationInRads.y)
'Go back to the new position:
ConvertedPosition.x = ConvertedPosition.x + PositionRotated.x
ConvertedPosition.y = ConvertedPosition.y + PositionRotated.y
ConvertedPosition.Z = ConvertedPosition.Z + PositionRotated.Z
Rotate = ConvertedPosition
End Function
Re: how can i get the GDI+ declaration functions\types?
Code:
On Error GoTo 0
Call GdipCreateFromHDC(Me.hdc, hGraphics)
If hGraphics Then
Call GdipLoadImageFromFile(StrPtr(filename), hBitmap)
If hBitmap Then
MsgBox "hey" 'ins't called
GdipDrawImagePointsI hGraphics, hBitmap, Points(0), 3
the message box isn't showed.. the image is on disk.. but i use the 'images' folder
Re: how can i get the GDI+ declaration functions\types?
Originally Posted by joaquim
Code:
On Error GoTo 0
Call GdipCreateFromHDC(Me.hdc, hGraphics)
If hGraphics Then
Call GdipLoadImageFromFile(StrPtr(filename), hBitmap)
If hBitmap Then
MsgBox "hey" 'ins't called
GdipDrawImagePointsI hGraphics, hBitmap, Points(0), 3
the message box isn't showed.. the image is on disk.. but i use the 'images' folder
If the image file cannot be opened exclusively by GDI+ (i.e., open it and lock it), then GdipLoadImageFromFile fails. The error code of 3 does not always mean "out of memory". It seems that GDI+ uses that error code like VB uses error code 5 "Invalid procedure call or argument"
Insomnia is just a byproduct of, "It can't be done"
Re: how can i get the GDI+ declaration functions\types?
For reference, GdipDrawImagePointsI can also fail if the passed points all lie on (or nearly on) the same line.
This case wouldn't be unexpected for arbitrary 3D projections, but as already pointed out by many, GdipDrawImagePointsI is not a useful API for this anyway.
(You can also review GDI+ flat function calls declares via MSDN, which is probably preferable as Jose Roca's documentation is not always accurate.)
The value of the count parameter must equal 3 to specify the coordinates of the upper-left corner, upper-right corner, and lower-left corner of the parallelogram. The coordinate of the lower-right corner is calculated using the three given coordinates, the width, and the height of the image. The portion of the source image to be drawn is scaled to fit the parallelogram.
Re: how can i get the GDI+ declaration functions\types?
wow.. the DrawImage():
Code:
Private Function DrawImage(FileName As String, hDC As Long, x As Long, y As Long) As Boolean
On Error Resume Next
Dim GDIsi As GDIPlusStartupInput, gToken As Long, hGraphics As Long, hBitmap As Long
GDIsi.GDIPlusVersion = 1&
GdiplusStartup gToken, GDIsi
If Err Then
Err.Clear
Exit Function
ElseIf gToken = 0& Then
Exit Function
End If
On Error GoTo 0
Call GdipCreateFromHDC(hDC, hGraphics)
If hGraphics Then
Call GdipLoadImageFromFile(StrPtr(FileName), hBitmap)
If hBitmap Then
GdipDrawImage hGraphics, hBitmap, x, y
GdipDisposeImage hBitmap
DrawImage = True
End If
GdipDeleteGraphics hGraphics
End If
GdiplusShutdown gToken
End Function
works on a new project... but not on my project
i will test the DrawImagePoints() on new project.
the only difference is that i use a timer on my 3D project.. somethings make me confused
Re: how can i get the GDI+ declaration functions\types?
i found the big problem: everyone can make their own types\enums\consts names... and if i'm not prepared for it, i can make some problems.
is there anyway for we detect these type of errors?
now the DrawImagePoints() give me the image, but, like passel said, i get the same result.
Code:
Private Function DrawImagePoints(FileName As String, hDC As Long, ByRef Points() As POINTL) As Boolean
On Error Resume Next
Dim GDIsi As GDIPlusStartupInput, gToken As Long, hGraphics As Long, hBitmap As Long
GDIsi.GDIPlusVersion = 1&
GdiplusStartup gToken, GDIsi
Dim status As GpStatus
If Err Then
Err.Clear
Exit Function
ElseIf gToken = 0& Then
Exit Function
End If
On Error GoTo 0
Call GdipCreateFromHDC(Me.hDC, hGraphics)
If hGraphics Then
status = GdipLoadImageFromFile(StrPtr(FileName), hBitmap)
If hBitmap Then
GdipDrawImagePointsI hGraphics, hBitmap, Points(0), 3
GdipDisposeImage hBitmap
DrawImagePoints = True
End If
GdipDeleteGraphics hGraphics
End If
GdiplusShutdown gToken
End Function
result: https://imgur.com/a/hypD7cp
the image is showed, but the 4 point, like with PlgBlt(), isn't correctly calculated
what i did wrong? the passel had said something about it, but i still confused
Re: how can i get the GDI+ declaration functions\types?
Originally Posted by joaquim
...
the image is showed, but the 4 point, like with PlgBlt(), isn't correctly calculated
what i did wrong? the passel had said something about it, but i still confused
What you did wrong is try to fill a trapezoid area using a parallelogram shape.
A trapezoid shape is not a parallelogram shape.
Those are geometric figures. Look them up.
A trapezoid is not a parallelogram.
A trapezoid is not a parallelogram.
A trapezoid is not a parallelogram.
If you used code based on dilettante's in post #7, you could at least fill the trapezoid with the texture.
It won't be adjusted for depth, but it will at least fill the trapezoid shape so do what you're trying to do with plgblt.
Last edited by passel; Oct 22nd, 2020 at 07:02 AM.
"Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930
The points define the red trapezoid, wide at the bottom, narrow at the top. Just try to "fill" the brick pattern with red in the image to visualize the trapezoid.
"Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930
Re: how can i get the GDI+ declaration functions\types?
Just as a quick example of compensating for depth, I modified dilettante's code, using the percentage value he used (currently 40%, i.e. the top of the trapezoid is 40% of the size of the bottom of the trapezoid) to modify the source scanline picked to be drawn to the destination scanline.
So, rather than being a 1 to 1 ratio over the entire length from top to bottom, the source scanline is incrementing at a greater ratio (1 to 1.4) at the top and reaches 1 to 1 at the bottom.
This compresses (vertically) the image at the top, and is the source's full pixel size for the last line at the bottom.
This is a bit arbitrary, using the percentage size difference between top and bottom to represent the scaling due to Z depth in 3D, but it is representative of the desired result in a fairly easy computation.
I just added a scale factor (ScanZ) and a value to decrement the scale factor linearly by (ScanZDec). The Z-depth perspective calculation is a straight division by z depth, so the result is analogous.
The updated trapezoidBlt sub, of the code in post #7.
Code:
Private Sub TrapezoidBlt(ByVal PctTop As Single, ByVal TranspColor As Long)
Dim ScanLines As Long
Dim FullWidth As Long
Dim ScanWidth As Single
Dim ScanLeft As Single
Dim Delta As Single
Dim sbmOrig As StretchBltModes
Dim ScanLine As Long
Dim ScanZ As Single
Dim ScanZDec As Single
With Picture1
Picture2.Width = .Width
Picture2.Height = .Height
ScanLines = ScaleY(.ScaleHeight, .ScaleMode, vbPixels)
Debug.Print ScanLines
FullWidth = ScaleX(.Width, ScaleMode, vbPixels)
ScanWidth = .ScaleWidth * PctTop / 100
ScanLeft = (.ScaleWidth - ScanWidth) / 2
Delta = ScanLeft / ScanLines
Picture2.BackColor = TranspColor
sbmOrig = SetStretchBltMode(Picture2.hDC, HALFTONE)
ScanZ = 1 + (PctTop / 100)
ScanZDec = (PctTop / 100) / ScanLines
For ScanLine = 0 To ScanLines - 1
StretchBlt Picture2.hDC, _
ScaleX(ScanLeft, .ScaleMode, vbPixels), _
ScanLine, _
ScaleX(ScanWidth, .ScaleMode, vbPixels), _
1, _
.hDC, _
0, _
ScanLine * ScanZ, _
FullWidth, _
1
ScanLeft = ScanLeft - Delta
ScanWidth = ScanWidth + 2 * Delta
ScanZ = ScanZ - ScanZDec
Next
End With
SetStretchBltMode Picture2.hDC, sbmOrig
TransparentBlt hDC, _
0, _
0, _
ScaleX(ScaleWidth, ScaleMode, vbPixels), _
ScaleY(ScaleHeight, ScaleMode, vbPixels), _
Picture2.hDC, _
0, _
0, _
FullWidth, _
ScanLines, _
TranspColor
End Sub
The difference may appear subtle at first, but look at how the lines of text align from left to right image, especially at the bottom, i.e. you have four lines on the left in the space taken by three lines on the right.
Last edited by passel; Oct 22nd, 2020 at 08:47 AM.
"Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930
Re: how can i get the GDI+ declaration functions\types?
My hack was just a hack, but at least this improves it if perspective is what you're after. Sounds like a reasonable assumption though.
I haven't seen another simple way to blit to a trapezoid though outside of using some 3D library. Oddly enough many video cards do seem to support trapezoids. Weird that GDI never supported it.
Code:
/* Device Capability Masks: */
:
:
/* Polygonal Capabilities */
#define PC_NONE 0 /* Polygonals not supported */
#define PC_POLYGON 1 /* Can do polygons */
#define PC_RECTANGLE 2 /* Can do rectangles */
#define PC_WINDPOLYGON 4 /* Can do winding polygons */
#define PC_TRAPEZOID 4 /* Can do trapezoids */
#define PC_SCANLINE 8 /* Can do scanlines */
#define PC_WIDE 16 /* Can do wide borders */
#define PC_STYLED 32 /* Can do styled borders */
#define PC_WIDESTYLED 64 /* Can do wide styled borders */
#define PC_INTERIORS 128 /* Can do interiors */
#define PC_POLYPOLYGON 256 /* Can do polypolygons */
#define PC_PATHS 512 /* Can do paths */
Re: how can i get the GDI+ declaration functions\types?
ok.. i need understand: what is the difference between trapezoid and parallelogram shapes?
PctTop is what? the start position? i need understand the start positions and their width's for i use the function....
Re: how can i get the GDI+ declaration functions\types?
Originally Posted by The trick
What's about Direct3D? You can render any 3D polygon:
...
This is an on-going, multiyear project.
Originally Posted by joaquim
i want draw the image\cube using Geometric Math for learn it. i know that theres several libraries for it... but i want to learn draw the cube, camera and the move....
"Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930
Re: how can i get the GDI+ declaration functions\types?
Made it less "jagged" on the ends.
First thing to do is change all the "Twips" in the forms to "pixels". Both picture-boxes AND the form itself.
Changed singles to doubles and added Int(double math), to force it to whole-pixels instead of error-prone floats. Also changed the slightly slower /2 into *0.5 which is a float, and /100 into *0.01 which is also a little faster. (Multiplication is faster than division and float to float is faster than int to float. 2 is assumed to be an int/long, unless you add # so it is 2# or add an actual decimal place to the number.)
The jagged edges were from nasty "bankers rounding"... as well as horrible float to long conversion. (Int is safe for most screens)
Code:
Private Sub TrapezoidBlt(ByVal PctTop As Single, ByVal TranspColor As Long)
Dim ScanLines As Long
Dim FullWidth As Long
Dim ScanWidth As Double
Dim ScanLeft As Double
Dim Delta As Double
Dim sbmOrig As StretchBltModes
Dim ScanLine As Long
Dim ScanZ As Double
Dim ScanZDec As Double
With Picture1
Picture2.Width = .Width
Picture2.Height = .Height
ScanLines = ScaleY(.ScaleHeight, .ScaleMode, vbPixels)
'Debug.Print ScanLines
FullWidth = ScaleX(.Width, ScaleMode, vbPixels)
ScanWidth = .ScaleWidth * PctTop * 0.01
ScanLeft = (.ScaleWidth - ScanWidth) * 0.5
Delta = ScanLeft / ScanLines
Picture2.BackColor = TranspColor
sbmOrig = SetStretchBltMode(Picture2.hDC, HALFTONE)
ScanZ = 1 + (PctTop * 0.01)
ScanZDec = (PctTop * 0.01) / ScanLines
For ScanLine = 0 To ScanLines - 1
StretchBlt Picture2.hDC, _
Int(ScaleX(ScanLeft, .ScaleMode, vbPixels)), _
ScanLine, _
Int(ScaleX(ScanWidth, .ScaleMode, vbPixels)), _
1, _
.hDC, _
0, _
Int(ScanLine * ScanZ), _
FullWidth, _
1
ScanLeft = ScanLeft - Delta
ScanWidth = ScanWidth + 2 * Delta
ScanZ = ScanZ - ScanZDec
Next
End With
SetStretchBltMode Picture2.hDC, sbmOrig
TransparentBlt hDC, _
0, _
0, _
Int(ScaleX(ScaleWidth, ScaleMode, vbPixels)), _
Int(ScaleY(ScaleHeight, ScaleMode, vbPixels)), _
Picture2.hDC, _
0, _
0, _
FullWidth, _
ScanLines, _
TranspColor
End Sub
Ten years later and this code is still going strong.
Last edited by ISAWHIM; Jan 7th, 2023 at 11:32 AM.
Re: how can i get the GDI+ declaration functions\types?
Hi
Create a path object with GdipCreatePath, draw something in the phat object with the appropriate GDI+ Phat APIs. e.g. with GdipAddPathString a text. You can then manipulate the phat object with GdipWarpPath. A simple example is here: https://www.activevb.de/tipps/vb6tipps/tipp0672.html