Ich habe mal das alte (und auch falsche) Beispiel von mir überarbeitet, hier die neue Methode:
Code: Alles auswählen
Procedure HyperTransformSprite(Sprite.i, Width.f, Height.f, Depth.f, Roll.f, Yaw.f, Pitch.f, AlignX.f=0.5, AlignY.f=0.5)
Protected CosZ.f = Cos(Radian(Roll)), CosY.f = Cos(Radian(Yaw)), CosX.f = Cos(Radian(Pitch))
Protected SinZ.f = Sin(Radian(Roll)), SinY.f = Sin(Radian(Yaw)), SinX.f = Sin(Radian(Pitch))
Protected A11.f = CosY*CosZ, A12.f = -CosY*SinZ, A13.f = SinY
Protected A21.f = SinX*SinY*CosZ+CosX*SinZ, A22.f = -SinX*SinY*SinZ+CosX*CosZ, A23.f = -SinX*CosY
Protected A31.f = -CosX*SinY*CosZ+SinX*SinZ, A32.f = CosX*SinY*SinZ+SinX*CosZ, A33.f = CosX*CosY
Protected U0.f = -AlignX*Width, U1.f = (1-AlignX)*Width
Protected V0.f = -AlignY*Height, V1.f = (1-AlignY)*Height
Protected Z1.f = U0*A31 + V0*A32 + Depth
Protected Y1.f = ( U0*A21 + V0*A22 ) * Depth / Z1
Protected X1.f = ( U0*A11 + V0*A12 ) * Depth / Z1
Protected Z2.f = U1*A31 + V0*A32 + Depth
Protected Y2.f = ( U1*A21 + V0*A22 ) * Depth / Z2
Protected X2.f = ( U1*A11 + V0*A12 ) * Depth / Z2
Protected Z3.f = U1*A31 + V1*A32 + Depth
Protected Y3.f = ( U1*A21 + V1*A22 ) * Depth / Z3
Protected X3.f = ( U1*A11 + V1*A12 ) * Depth / Z3
Protected Z4.f = U0*A31 + V1*A32 + Depth
Protected Y4.f = ( U0*A21 + V1*A22 ) * Depth / Z4
Protected X4.f = ( U0*A11 + V1*A12 ) * Depth / Z4
TransformSprite(Sprite, X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3, X4, Y4, Z4)
EndProcedure
InitSprite()
InitNetwork()
UseJPEGImageDecoder()
Enumeration
#Window
#Sprite
EndEnumeration
OpenWindow(#Window, 0, 0, 800, 600, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)
SpriteQuality(#PB_Sprite_BilinearFiltering)
CatchSprite(#Sprite, ReceiveHTTPMemory("http://data.unionbytes.de/convergence_by_rahll.jpg"))
Repeat
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
End
Case #Null
Break
EndSelect
ForEver
ClearScreen(0)
HyperTransformSprite(#Sprite, 160, 100, 300, ElapsedMilliseconds()/10, 0, 0)
DisplaySprite(#Sprite, 200, 150)
HyperTransformSprite(#Sprite, 160, 100, 300, 0, Sin(ElapsedMilliseconds()/1000)*70, 0)
DisplaySprite(#Sprite, 600, 150)
HyperTransformSprite(#Sprite, 160, 100, 300, 0, 0, Sin(ElapsedMilliseconds()/1000)*70)
DisplaySprite(#Sprite, 200, 450)
HyperTransformSprite(#Sprite, 160, 100, 300, ElapsedMilliseconds()/10, 0, -40, 1.0, 0.0)
DisplaySprite(#Sprite, 600, 450)
FlipBuffers()
ForEver
Die Funktion heißt HyperTransformSprite()
Übergeben wird dort die Breite, Höhe und eine "fiktive" Tiefe (die die Verzerrung beeinflusst, hohe Werte sind weniger perspektivisch).
Danach kommen die Rotationsachsen mit Z, Y und X Winkel.
Natürlich sollte man bei der Funktion beachten, dass PureBasic nicht die "Rückseite" des Sprites darstellt, also Winkel außerhalb von 90° unsichtbar sind.
Edit: Code Update auf Rotationszentrum