Da ich es für ein aktuelles Projekt benötige und sowieso schon lange Lust drauf hatte, habe ich eine kleine Lib geschrieben, die die Blitzeigenen 2D - Grafikbefehle komplett ersetzen soll.
Dabei wird die Grafikkarte genutzt, um gewisse Finessen wie Rotation und Skalierung hinzubiegen, und um den Zeichenprozess ein wenig zu beschleunigen (auf meinem Laptop ist selbst DrawBlock unendlich langsam, was jedes Blitzspiel mit den 2D - Befehlen für mich unspielbar macht).
Ich will keineswegs eine Konkurrenz zur Draw3D sein, da meine Lib längst nicht so viele Features hat wie die Draw3D.
Vielmehr soll es eine Alternative sein, die den Umstieg ein wenig leichter macht. Die Handhabung der Befehle ist mit einigen Einschränkungen exakt gleich wie bei den Standardbefehlen, es muss einfach ein kleines 3D an jeden Befehl angehängt werden (Okay, das hab ich mir von der Draw3D abgeschaut ).
Ob die Texturen eine 2er - Potenz Kantenlänge haben, ist egal, Fonts werden zur Laufzeit erstellt, das Koordinatensystem ist gleich wie bei Blitz und die Bilder werden in der Reihenfolge gerendert, wie sie gezeichnet werden - unabhängig von der Ladereihenfolge.
Leider musste ich für das letzte Feature auf Transparenz verzichten, ausserdem ist die Lib für 3D - Anwendungen unbrauchbar und nur für reines 2D gedacht.
Anders als in Blitz liefern jedoch die Befehle LoadImage3D und LoadAnimImage3D einen Type TImageClass3D und keinen Zahlenwert zurück - das erlaubt einem zwar direktere Kontrolle, allerdings ist die Definition der Variablen ein wenig komplizierter (wer Probleme damit hat, sollte einen Blick in die Beispiele werfen).
Ausserdem muss vor der Benutzung der Funktionen der Lib einmalig ein Init3D aufgerufen werden - Parameter sind Kamera, auf die gerendert werden soll, und die Auflösung.
Ansonsten brauchen die meisten Befehle keine Erklärung, da sie gleich funktionieren wie die Blitz - Befehle.
Allerdings konnte ich einige Funktionen nicht 1:1 nachbilden, was mit der inneren Struktur der Lib zusammenhängt.
Folgende Befehle funktionieren nicht exakt gleich wie der Befehl in Blitz:
- TileImage3D: Dieser Befehl tiled immer die ganze Textur - wenn das Bild nicht eine 2er - Potenz Kantenlänge hat oder per LoadAnimImage3D geladen wurde, ist die Funktion nicht zu empfehlen.
- LoadFont3D: Dieser Befehl ändert das momentan gesetzte Blitz - Interne Font. Kann ich leider nicht ändern.
- ScaleImage3D und RotateImage3D: Diese Befehle bearbeiten nicht die Textur direkt, sondern legen die Rotation bzw. Skalierung für DrawImage3D fest. Dabei wird immer um den mit HandleImage3D festgelegten Punkt gedreht bzw. skaliert.
- DrawImageRect3D missachtet ebenfalls Frames. Wird ein Rechteck grösser als das Bild angegeben, so tiled sich die Textur - allerdings auch wieder die gesamte Textur, hat das Bild also keine 2er - Potenz Kantenlänge, bleibt man lieber in den Grenzen des Bildes.
- Color3D: Die festgelegte Farbe wirkt sich auf alle gezeichneten Bilder aus. Der letzte Parameter, Alpha, hat normalerweise keine Auswirkungen, ausser in speziellen Fällen, dazu später mehr.
- Cls3D: MUSS unbedingt in der Hauptschleife ausgeführt werden - ansonsten erhält man irgendwann einen MAV bei RenderWorld, weil die Surface vollgelaufen ist.
Braucht man unbedingt Transparenz, so kann man manuell dem Mesh (befindet sich in ImageClass\Mesh) den EntityFX 1 + 2 + 16 + 32 verpassen.
Dann hat der Alpha - Parameter bei Color3D auch einen Sinn, allerdings muss man beachten, dass das das Sortieren für dieses Bild ausschaltet - sprich, die Zeichenreihenfolge ist für dieses Bild wieder von der Ladereihenfolge abhängig.
BlitzBasic: [AUSKLAPPEN] [EINKLAPPEN] Global DrawPivot, DrawCam, GraphicsX, GraphicsY, CurrFont.TFont3D, LastDrawn.TImageClass3D, DrawZ#, AutoMidH = False Global PrimitiveMesh, PrimitiveSurf, OriginX#, OriginY# Global DrawR = 255, DrawG = 255, DrawB = 255, DrawA# = 1 Global CameraCount, Cameras[ 64 ]
Type TImageClass3D Field Path$ Field TextureH Field Width Field Height Field TexWidth Field TexHeight Field Mesh Field Surface Field HandleX# Field HandleY# Field Rotation# Field ScaleX# Field ScaleY# Field FWidth Field FHeight Field FStart Field FCount Field FramesPerRow Field FramesPerColumn Field Animated End Type
Type TFont3D Field ImageClass.TImageClass3D Field CharWidth[ 255 ] Field Height End Type
Function Init3D( Is3D = False ) GraphicsX = GraphicsWidth() GraphicsY = GraphicsHeight() DrawCam = CreateCamera() CameraProjMode DrawCam, 2 CameraZoom DrawCam, 2/Float( GraphicsX ) CameraRange DrawCam, 1, 1001 If Is3D Then CameraProjMode DrawCam, 0 CameraClsMode DrawCam, False, True EndIf DrawPivot = CreatePivot( DrawCam ) TurnEntity DrawPivot, 180, 0, 0 PositionEntity DrawPivot, -GraphicsX/2., GraphicsY/2., 1000, True If Is3D Then PositionEntity DrawCam, -5000, -5000, -5000 PrimitiveMesh = CreateMesh( DrawPivot ) EntityFX PrimitiveMesh, 1 + 2 + 16 PrimitiveSurf = CreateSurface( PrimitiveMesh ) SetFont3D LoadFont3D( "", 15 ) End Function
Function LoadImage3D.TImageClass3D( Path$, AlphaEnabled = False, Flag = 4 ) ImageClass.TImageClass3D = New TImageClass3D PrepareTexture( ImageClass, Path$, Flag ) If ImageClass\TextureH Then ImageClass\Path$ = Path$ ImageClass\FWidth = ImageClass\Width ImageClass\FHeight = ImageClass\Height ImageClass\TexWidth = TextureWidth( ImageClass\TextureH ) ImageClass\TexHeight = TextureHeight( ImageClass\TextureH ) ImageClass\FramesPerRow = 1 ImageClass\FramesPerColumn = 1 ImageClass\Mesh = CreateMesh( DrawPivot ) ImageClass\Surface = CreateSurface( ImageClass\Mesh ) ImageClass\ScaleX# = 1 ImageClass\ScaleY# = 1 EntityTexture ImageClass\Mesh, ImageClass\TextureH EntityFX ImageClass\Mesh, 1 + 2 + 16 + 32*AlphaEnabled If AutoMidH Then MidHandle3D ImageClass Return ImageClass Else RuntimeError "Texture " + Path$ + " doesn't exist" EndIf End Function
Function LoadAnimImage3D.TImageClass3D( Path$, FWidth, FHeight, FFirst, FCount, AlphaEnabled = False, Flag = 4 ) ImageClass.TImageClass3D = New TImageClass3D PrepareTexture( ImageClass, Path$, Flag ) If ImageClass\TextureH Then ImageClass\Path$ = Path$ ImageClass\FWidth = FWidth ImageClass\FHeight = FHeight ImageClass\TexWidth = TextureWidth( ImageClass\TextureH ) ImageClass\TexHeight = TextureHeight( ImageClass\TextureH ) ImageClass\Mesh = CreateMesh( DrawPivot ) ImageClass\Surface = CreateSurface( ImageClass\Mesh ) ImageClass\FCount = FCount ImageClass\FramesPerRow = Floor( ImageClass\Width/Float( FWidth ) ) ImageClass\FramesPerColumn = Floor( ImageClass\Height/Float( FHeight ) ) ImageClass\Animated = True ImageClass\ScaleX# = 1 ImageClass\ScaleY# = 1 EntityTexture ImageClass\Mesh, ImageClass\TextureH, 0 EntityFX ImageClass\Mesh, 1 + 2 + 16 + 32*AlphaEnabled If AutoMidH Then MidHandle3D ImageClass Return ImageClass Else RuntimeError "Texture " + Path$ + " doesn't exist" EndIf End Function
Function LoadFont3D.TFont3D( Path$, Height = 12, Bold = False, Italic = False, Underline = False, AlphaEnabled = False, Flags = 4 ) Font.TFont3D = New TFont3D FontH = LoadFont( Path$, Height, Bold, Italic, Underline ) SetFont FontH For i = 0 To 255 Font\CharWidth[ i ] = StringWidth( Chr( i ) ) Next Font\Height = FontHeight() Image = CreateImage( 512, 512 ) SetBuffer ImageBuffer( Image ) For i = 0 To 255 X = ( i Mod 16 )*32 Y = Floor( i/16. )*32 Text X, Y, Chr( i ) Next SetBuffer BackBuffer() Add = MilliSecs() Mod 100 SaveImage Image, "__Temp" + Add + ".bmp" Font\ImageClass = LoadAnimImage3D( "__Temp" + Add + ".bmp", 32, 32, 0, 256, AlphaEnabled, Flags ) HandleImage3D Font\ImageClass, 0, 0 DeleteFile "__Temp" + Add + ".bmp" FreeImage Image FreeFont FontH Return Font End Function
Function SetFont3D( Font.TFont3D ) CurrFont = Font End Function
Function FontHeight3D() Return CurrFont\Height End Function
Function Text3D( X#, Y#, SourceString$, CenteredX = False, CenteredY = False ) X# = X# - Int( CenteredX*StringWidth3D( SourceString$ )*0.5 ) Y# = Y# - Int( CenteredY*FontHeight3D()*0.5 ) Local DrawX# = X# For i = 1 To Len( SourceString$ ) DrawImage3D CurrFont\ImageClass, DrawX#, Y#, Asc( Mid( SourceString$, i, 1 ) ) DrawX# = DrawX# + CurrFont\CharWidth[ Asc( Mid( SourceString$, i, 1 ) ) ] Next End Function
Function DrawImage3D( Class.TImageClass3D, X#, Y#, Frame = 0 ) X# = X# - Class\HandleX# - 0.5 + OriginX# Y# = Y# - Class\HandleY# - 0.5 + OriginY# V1X# = X# V2X# = X# + Class\FWidth V3X# = X# + Class\FWidth V4X# = X# V1Y# = Y# V2Y# = Y# V3Y# = Y# + Class\FHeight V4Y# = Y# + Class\FHeight If Class\Animated Then U1# = ( ( Frame + Class\FStart ) Mod Class\FramesPerRow )*Class\FWidth/Float( Class\TexWidth ) U2# = ( ( ( Frame + Class\FStart ) Mod Class\FramesPerRow ) + 1 )*Class\FWidth/Float( Class\TexWidth ) U3# = U2# U4# = U1# V1# = Floor( ( Frame + Class\FStart )/Float( Class\FramesPerRow ) )*Class\FHeight/Float( Class\TexHeight ) V2# = V1# V3# = Floor( ( Frame + Class\FStart )/Float( Class\FramesPerRow ) + 1 )*Class\FHeight/Float( Class\TexHeight ) V4# = V3# Else U1# = 0 U2# = 1 U3# = 1 U4# = 0 V1# = 0 V2# = 0 V3# = 1 V4# = 1 EndIf X# = X# + Class\HandleX# Y# = Y# + Class\HandleY# If Class\ScaleX# <> 1 Then V1X# = X# + ( V1X# - X# )*Class\ScaleX# V2X# = X# + ( V2X# - X# )*Class\ScaleX# V3X# = X# + ( V3X# - X# )*Class\ScaleX# V4X# = X# + ( V4X# - X# )*Class\ScaleX# EndIf If Class\ScaleY# <> 1 Then V1Y# = Y# + ( V1Y# - Y# )*Class\ScaleY# V2Y# = Y# + ( V2Y# - Y# )*Class\ScaleY# V3Y# = Y# + ( V3Y# - Y# )*Class\ScaleY# V4Y# = Y# + ( V4Y# - Y# )*Class\ScaleY# EndIf If Class\Rotation# <> 0 Then Radius1# = Sqr( ( V1X# - X# )*( V1X# - X# ) + ( V1Y# - Y# )*( V1Y# - Y# ) ) Radius2# = Sqr( ( V2X# - X# )*( V2X# - X# ) + ( V2Y# - Y# )*( V2Y# - Y# ) ) Radius3# = Sqr( ( V3X# - X# )*( V3X# - X# ) + ( V3Y# - Y# )*( V3Y# - Y# ) ) Radius4# = Sqr( ( V4X# - X# )*( V4X# - X# ) + ( V4Y# - Y# )*( V4Y# - Y# ) ) Angle1# = ATan2( V1Y# - Y#, V1X# - X# ) Angle2# = ATan2( V2Y# - Y#, V2X# - X# ) Angle3# = ATan2( V3Y# - Y#, V3X# - X# ) Angle4# = ATan2( V4Y# - Y#, V4X# - X# ) V1X# = X# + Radius1#*Cos( Angle1# - Class\Rotation# ) V2X# = X# + Radius2#*Cos( Angle2# - Class\Rotation# ) V3X# = X# + Radius3#*Cos( Angle3# - Class\Rotation# ) V4X# = X# + Radius4#*Cos( Angle4# - Class\Rotation# ) V1Y# = Y# + Radius1#*Sin( Angle1# - Class\Rotation# ) V2Y# = Y# + Radius2#*Sin( Angle2# - Class\Rotation# ) V3Y# = Y# + Radius3#*Sin( Angle3# - Class\Rotation# ) V4Y# = Y# + Radius4#*Sin( Angle4# - Class\Rotation# ) EndIf V1 = AddVertex( Class\Surface, V1X#, V1Y#, DrawZ#, U1#, V1# ) V2 = AddVertex( Class\Surface, V2X#, V2Y#, DrawZ#, U2#, V2# ) V3 = AddVertex( Class\Surface, V3X#, V3Y#, DrawZ#, U3#, V3# ) V4 = AddVertex( Class\Surface, V4X#, V4Y#, DrawZ#, U4#, V4# ) VertexColor Class\Surface, V1, DrawR, DrawG, DrawB, DrawA# VertexColor Class\Surface, V2, DrawR, DrawG, DrawB, DrawA# VertexColor Class\Surface, V3, DrawR, DrawG, DrawB, DrawA# VertexColor Class\Surface, V4, DrawR, DrawG, DrawB, DrawA# AddTriangle Class\Surface, V1, V2, V3 AddTriangle Class\Surface, V1, V3, V4 DrawZ# = DrawZ# + 0.001 End Function
Function DrawImageRect3D( Class.TImageClass3D, X#, Y#, RectX#, RectY#, RectW#, RectH# ) X# = X# - 0.5 + OriginX# Y# = Y# - 0.5 + OriginY# V1X# = X# V2X# = X# + RectW# V3X# = X# + RectW# V4X# = X# V1Y# = Y# V2Y# = Y# V3Y# = Y# + RectH# V4Y# = Y# + RectH# U1# = RectX#/Class\TexWidth U2# = ( RectX# + RectW# )/Class\TexWidth U3# = U2# U4# = U1# V1# = RectY#/Class\TexHeight V2# = V1# V3# = ( RectY# + RectH# )/Class\TexHeight V4# = V3# V1 = AddVertex( Class\Surface, V1X#, V1Y#, DrawZ#, U1#, V1# ) V2 = AddVertex( Class\Surface, V2X#, V2Y#, DrawZ#, U2#, V2# ) V3 = AddVertex( Class\Surface, V3X#, V3Y#, DrawZ#, U3#, V3# ) V4 = AddVertex( Class\Surface, V4X#, V4Y#, DrawZ#, U4#, V4# ) VertexColor Class\Surface, V1, DrawR, DrawG, DrawB, DrawA# VertexColor Class\Surface, V2, DrawR, DrawG, DrawB, DrawA# VertexColor Class\Surface, V3, DrawR, DrawG, DrawB, DrawA# VertexColor Class\Surface, V4, DrawR, DrawG, DrawB, DrawA# AddTriangle Class\Surface, V1, V2, V3 AddTriangle Class\Surface, V1, V3, V4 DrawZ# = DrawZ# + 0.001 End Function
Function TileImage3D( Class.TImageClass3D, X# = 0, Y# = 0 ) X# = X# - Class\HandleX# - 0.5 + OriginX# Y# = Y# - Class\HandleY# - 0.5 + OriginY# U1# = -X#/Float( Class\TexWidth ) U2# = ( GraphicsX - X# )/Float( Class\TexWidth ) U3# = U2# U4# = U1# V1# = -Y#/Float( Class\TexHeight ) V2# = V1# V3# = ( GraphicsY - Y# )/Float( Class\TexHeight ) V4# = V3# V1 = AddVertex( Class\Surface, 0, 0, DrawZ#, U1#, V1# ) V2 = AddVertex( Class\Surface, GraphicsX, 0, DrawZ#, U2#, V2# ) V3 = AddVertex( Class\Surface, GraphicsX, GraphicsY, DrawZ#, U3#, V3# ) V4 = AddVertex( Class\Surface, 0, GraphicsY, DrawZ#, U4#, V4# ) VertexColor Class\Surface, V1, DrawR, DrawG, DrawB, DrawA# VertexColor Class\Surface, V2, DrawR, DrawG, DrawB, DrawA# VertexColor Class\Surface, V3, DrawR, DrawG, DrawB, DrawA# VertexColor Class\Surface, V4, DrawR, DrawG, DrawB, DrawA# AddTriangle Class\Surface, V1, V2, V3 AddTriangle Class\Surface, V1, V3, V4 DrawZ# = DrawZ# + 0.001 End Function
Function MaskImage3D( Class.TImageClass3D, Red, Green, Blue ) LockBuffer TextureBuffer( Class\TextureH ) RGB = Red Shl 16 + Green Shl 8 + Blue For X = 0 To Class\Width - 1 For Y = 0 To Class\Height - 1 ARGB = ReadPixelFast( X, Y, TextureBuffer( Class\TextureH ) ) If ( ARGB And $FFFFFF ) = RGB Then WritePixelFast X, Y, RGB, TextureBuffer( Class\TextureH ) Else WritePixelFast X, Y, ( ARGB And $FFFFFF ) + $FF000000, TextureBuffer( Class\TextureH ) EndIf Next Next UnlockBuffer TextureBuffer( Class\TextureH ) End Function
Function HandleImage3D( Class.TImageClass3D, X#, Y# ) Class\HandleX# = X# Class\HandleY# = Y# End Function
Function RotateImage3D( Class.TImageClass3D, Angle# ) Class\Rotation# = Angle# End Function
Function ScaleImage3D( Class.TImageClass3D, ScaleX#, ScaleY# ) Class\ScaleX# = ScaleX# Class\ScaleY# = ScaleY# End Function
Function ResizeImage3D( Class.TImageClass3D, NewWidth#, NewHeight# ) Class\ScaleX# = NewWidth#/Class\FWidth Class\ScaleY# = NewHeight#/Class\FHeight End Function
Function MidHandle3D( Class.TImageClass3D ) Class\HandleX# = Class\FWidth/2. Class\HandleY# = Class\FHeight/2. End Function
Function AutoMidHandle3D( State ) AutoMidH = State End Function
Function ImageWidth3D( Class.TImageClass3D ) Return Class\FWidth End Function
Function ImageHeight3D( Class.TImageClass3D ) Return Class\FHeight End Function
Function ImageXHandle3D#( Class.TImageClass3D ) Return Class\HandleX# End Function
Function ImageYHandle3D#( Class.TImageClass3D ) Return Class\HandleY# End Function
Function ImageBuffer3D( Class.TImageClass3D ) Return TextureBuffer( Class\TextureH ) End Function
Function ImageRectOverlap3D( Class.TImageClass3D, IX#, IY#, X#, Y#, W#, H# ) V1X# = IX# - Class\HandleX# V2X# = IX# + Class\FWidth - Class\HandleX# V3X# = IX# + Class\FWidth - Class\HandleX# V4X# = IX# - Class\HandleX# V1Y# = IY# - Class\HandleY# V2Y# = IY# - Class\HandleY# V3Y# = IY# + Class\FHeight - Class\HandleY# V4Y# = IY# + Class\FHeight - Class\HandleY# If Class\ScaleX# <> 1 Then V1X# = IX# + ( V1X# - IX# )*Class\ScaleX# V2X# = IX# + ( V2X# - IX# )*Class\ScaleX# V3X# = IX# + ( V3X# - IX# )*Class\ScaleX# V4X# = IX# + ( V4X# - IX# )*Class\ScaleX# EndIf If Class\ScaleY# <> 1 Then V1Y# = IY# + ( V1Y# - IY# )*Class\ScaleY# V2Y# = IY# + ( V2Y# - IY# )*Class\ScaleY# V3Y# = IY# + ( V3Y# - IY# )*Class\ScaleY# V4Y# = IY# + ( V4Y# - IY# )*Class\ScaleY# EndIf If Class\Rotation# <> 0 Then Radius1# = Sqr( ( V1X# - IX# )*( V1X# - IX# ) + ( V1Y# - IY# )*( V1Y# - IY# ) ) Radius2# = Sqr( ( V2X# - IX# )*( V2X# - IX# ) + ( V2Y# - IY# )*( V2Y# - IY# ) ) Radius3# = Sqr( ( V3X# - IX# )*( V3X# - IX# ) + ( V3Y# - IY# )*( V3Y# - IY# ) ) Radius4# = Sqr( ( V4X# - IX# )*( V4X# - IX# ) + ( V4Y# - IY# )*( V4Y# - IY# ) ) Angle1# = ATan2( V1Y# - IY#, V1X# - IX# ) Angle2# = ATan2( V2Y# - IY#, V2X# - IX# ) Angle3# = ATan2( V3Y# - IY#, V3X# - IX# ) Angle4# = ATan2( V4Y# - IY#, V4X# - IX# ) V1X# = IX# + Radius1#*Cos( Angle1# - Class\Rotation# ) V2X# = IX# + Radius2#*Cos( Angle2# - Class\Rotation# ) V3X# = IX# + Radius3#*Cos( Angle3# - Class\Rotation# ) V4X# = IX# + Radius4#*Cos( Angle4# - Class\Rotation# ) V1Y# = IY# + Radius1#*Sin( Angle1# - Class\Rotation# ) V2Y# = IY# + Radius2#*Sin( Angle2# - Class\Rotation# ) V3Y# = IY# + Radius3#*Sin( Angle3# - Class\Rotation# ) V4Y# = IY# + Radius4#*Sin( Angle4# - Class\Rotation# ) EndIf V5X# = X# V6X# = X# + W# V7X# = X# + W# V8X# = X# V5Y# = Y# V6Y# = Y# V7Y# = Y# + H# V8Y# = Y# + H# If PointInRectangle( V1X#, V1Y#, V2X#, V2Y#, V3X#, V3Y#, V4X#, V4Y#, V5X#, V5Y# ) Then Return True If PointInRectangle( V1X#, V1Y#, V2X#, V2Y#, V3X#, V3Y#, V4X#, V4Y#, V6X#, V6Y# ) Then Return True If PointInRectangle( V1X#, V1Y#, V2X#, V2Y#, V3X#, V3Y#, V4X#, V4Y#, V7X#, V7Y# ) Then Return True If PointInRectangle( V1X#, V1Y#, V2X#, V2Y#, V3X#, V3Y#, V4X#, V4Y#, V8X#, V8Y# ) Then Return True If RectsOverlap( X#, Y#, W#, H#, V1X#, V1Y#, 1, 1 ) Then Return True If RectsOverlap( X#, Y#, W#, H#, V2X#, V2Y#, 1, 1 ) Then Return True If RectsOverlap( X#, Y#, W#, H#, V3X#, V3Y#, 1, 1 ) Then Return True If RectsOverlap( X#, Y#, W#, H#, V4X#, V4Y#, 1, 1 ) Then Return True End Function
Function ImagesOverlap3D( Class1.TImageClass3D, IX1#, IY1#, Class2.TImageClass3D, IX2#, IY2# ) V1X# = IX1# - Class1\HandleX# V2X# = IX1# + Class1\FWidth - Class1\HandleX# V3X# = IX1# + Class1\FWidth - Class1\HandleX# V4X# = IX1# - Class1\HandleX# V1Y# = IY1# - Class1\HandleY# V2Y# = IY1# - Class1\HandleY# V3Y# = IY1# + Class1\FHeight - Class1\HandleY# V4Y# = IY1# + Class1\FHeight - Class1\HandleY# If Class1\ScaleX# <> 1 Then V1X# = IX1# + ( V1X# - IX1# )*Class1\ScaleX# V2X# = IX1# + ( V2X# - IX1# )*Class1\ScaleX# V3X# = IX1# + ( V3X# - IX1# )*Class1\ScaleX# V4X# = IX1# + ( V4X# - IX1# )*Class1\ScaleX# EndIf If Class1\ScaleY# <> 1 Then V1Y# = IY1# + ( V1Y# - IY1# )*Class1\ScaleY# V2Y# = IY1# + ( V2Y# - IY1# )*Class1\ScaleY# V3Y# = IY1# + ( V3Y# - IY1# )*Class1\ScaleY# V4Y# = IY1# + ( V4Y# - IY1# )*Class1\ScaleY# EndIf If Class1\Rotation# <> 0 Then Radius1# = Sqr( ( V1X# - IX1# )*( V1X# - IX1# ) + ( V1Y# - IY1# )*( V1Y# - IY1# ) ) Radius2# = Sqr( ( V2X# - IX1# )*( V2X# - IX1# ) + ( V2Y# - IY1# )*( V2Y# - IY1# ) ) Radius3# = Sqr( ( V3X# - IX1# )*( V3X# - IX1# ) + ( V3Y# - IY1# )*( V3Y# - IY1# ) ) Radius4# = Sqr( ( V4X# - IX1# )*( V4X# - IX1# ) + ( V4Y# - IY1# )*( V4Y# - IY1# ) ) Angle1# = ATan2( V1Y# - IY1#, V1X# - IX1# ) Angle2# = ATan2( V2Y# - IY1#, V2X# - IX1# ) Angle3# = ATan2( V3Y# - IY1#, V3X# - IX1# ) Angle4# = ATan2( V4Y# - IY1#, V4X# - IX1# ) V1X# = IX1# + Radius1#*Cos( Angle1# - Class1\Rotation# ) V2X# = IX1# + Radius2#*Cos( Angle2# - Class1\Rotation# ) V3X# = IX1# + Radius3#*Cos( Angle3# - Class1\Rotation# ) V4X# = IX1# + Radius4#*Cos( Angle4# - Class1\Rotation# ) V1Y# = IY1# + Radius1#*Sin( Angle1# - Class1\Rotation# ) V2Y# = IY1# + Radius2#*Sin( Angle2# - Class1\Rotation# ) V3Y# = IY1# + Radius3#*Sin( Angle3# - Class1\Rotation# ) V4Y# = IY1# + Radius4#*Sin( Angle4# - Class1\Rotation# ) EndIf V5X# = IX2# - Class2\HandleX# V6X# = IX2# + Class2\FWidth - Class2\HandleX# V7X# = IX2# + Class2\FWidth - Class2\HandleX# V8X# = IX2# - Class2\HandleX# V5Y# = IY2# - Class2\HandleY# V6Y# = IY2# - Class2\HandleY# V7Y# = IY2# + Class2\FHeight - Class2\HandleY# V8Y# = IY2# + Class2\FHeight - Class2\HandleY# If Class2\ScaleX# <> 1 Then V5X# = IX2# + ( V5X# - IX2# )*Class2\ScaleX# V6X# = IX2# + ( V6X# - IX2# )*Class2\ScaleX# V7X# = IX2# + ( V7X# - IX2# )*Class2\ScaleX# V8X# = IX2# + ( V8X# - IX2# )*Class2\ScaleX# EndIf If Class2\ScaleY# <> 1 Then V5Y# = IY2# + ( V5Y# - IY2# )*Class2\ScaleY# V6Y# = IY2# + ( V6Y# - IY2# )*Class2\ScaleY# V7Y# = IY2# + ( V7Y# - IY2# )*Class2\ScaleY# V8Y# = IY2# + ( V8Y# - IY2# )*Class2\ScaleY# EndIf If Class2\Rotation# <> 0 Then Radius1# = Sqr( ( V5X# - IX2# )*( V5X# - IX2# ) + ( V5Y# - IY2# )*( V5Y# - IY2# ) ) Radius2# = Sqr( ( V6X# - IX2# )*( V6X# - IX2# ) + ( V6Y# - IY2# )*( V6Y# - IY2# ) ) Radius3# = Sqr( ( V7X# - IX2# )*( V7X# - IX2# ) + ( V7Y# - IY2# )*( V7Y# - IY2# ) ) Radius4# = Sqr( ( V8X# - IX2# )*( V8X# - IX2# ) + ( V8Y# - IY2# )*( V8Y# - IY2# ) ) Angle1# = ATan2( V5Y# - IY2#, V5X# - IX2# ) Angle2# = ATan2( V6Y# - IY2#, V6X# - IX2# ) Angle3# = ATan2( V7Y# - IY2#, V7X# - IX2# ) Angle4# = ATan2( V8Y# - IY2#, V8X# - IX2# ) V5X# = IX2# + Radius1#*Cos( Angle1# - Class2\Rotation# ) V6X# = IX2# + Radius2#*Cos( Angle2# - Class2\Rotation# ) V7X# = IX2# + Radius3#*Cos( Angle3# - Class2\Rotation# ) V8X# = IX2# + Radius4#*Cos( Angle4# - Class2\Rotation# ) V5Y# = IY2# + Radius1#*Sin( Angle1# - Class2\Rotation# ) V6Y# = IY2# + Radius2#*Sin( Angle2# - Class2\Rotation# ) V7Y# = IY2# + Radius3#*Sin( Angle3# - Class2\Rotation# ) V8Y# = IY2# + Radius4#*Sin( Angle4# - Class2\Rotation# ) EndIf If PointInRectangle( V1X#, V1Y#, V2X#, V2Y#, V3X#, V3Y#, V4X#, V4Y#, V5X#, V5Y# ) Then Return True If PointInRectangle( V1X#, V1Y#, V2X#, V2Y#, V3X#, V3Y#, V4X#, V4Y#, V6X#, V6Y# ) Then Return True If PointInRectangle( V1X#, V1Y#, V2X#, V2Y#, V3X#, V3Y#, V4X#, V4Y#, V7X#, V7Y# ) Then Return True If PointInRectangle( V1X#, V1Y#, V2X#, V2Y#, V3X#, V3Y#, V4X#, V4Y#, V8X#, V8Y# ) Then Return True If PointInRectangle( V5X#, V5Y#, V6X#, V6Y#, V7X#, V7Y#, V8X#, V8Y#, V1X#, V1Y# ) Then Return True If PointInRectangle( V5X#, V5Y#, V6X#, V6Y#, V7X#, V7Y#, V8X#, V8Y#, V2X#, V2Y# ) Then Return True If PointInRectangle( V5X#, V5Y#, V6X#, V6Y#, V7X#, V7Y#, V8X#, V8Y#, V3X#, V3Y# ) Then Return True If PointInRectangle( V5X#, V5Y#, V6X#, V6Y#, V7X#, V7Y#, V8X#, V8Y#, V4X#, V4Y# ) Then Return True End Function
Function StringWidth3D( SourceString$ ) For i = 1 To Len( SourceString$ ) StrWidth = StrWidth + CurrFont\CharWidth[ Asc( Mid( SourceString$, i, 1 ) ) ] Next Return StrWidth End Function
Function Rect3D( X#, Y#, Width#, Height#, Filled = True, Rotation# = 0, RotHandleX# = 0, RotHandleY# = 0 ) X# = X# - 0.5 + OriginX# Y# = Y# - 0.5 + OriginY# V1X# = X# V2X# = X# + Width# V3X# = X# + Width# V4X# = X# V1Y# = Y# V2Y# = Y# V3Y# = Y# + Height# V4Y# = Y# + Height# If Rotation# <> 0 Then X# = X# + RotHandleX# Y# = Y# + RotHandleY# Radius1# = Sqr( ( V1X# - X# )*( V1X# - X# ) + ( V1Y# - Y# )*( V1Y# - Y# ) ) Radius2# = Sqr( ( V2X# - X# )*( V2X# - X# ) + ( V2Y# - Y# )*( V2Y# - Y# ) ) Radius3# = Sqr( ( V3X# - X# )*( V3X# - X# ) + ( V3Y# - Y# )*( V3Y# - Y# ) ) Radius4# = Sqr( ( V4X# - X# )*( V4X# - X# ) + ( V4Y# - Y# )*( V4Y# - Y# ) ) Angle1# = ATan2( V1Y# - Y#, V1X# - X# ) Angle2# = ATan2( V2Y# - Y#, V2X# - X# ) Angle3# = ATan2( V3Y# - Y#, V3X# - X# ) Angle4# = ATan2( V4Y# - Y#, V4X# - X# ) V1X# = X# + Radius1#*Cos( Angle1# - Rotation# ) V2X# = X# + Radius2#*Cos( Angle2# - Rotation# ) V3X# = X# + Radius3#*Cos( Angle3# - Rotation# ) V4X# = X# + Radius4#*Cos( Angle4# - Rotation# ) V1Y# = Y# + Radius1#*Sin( Angle1# - Rotation# ) V2Y# = Y# + Radius2#*Sin( Angle2# - Rotation# ) V3Y# = Y# + Radius3#*Sin( Angle3# - Rotation# ) V4Y# = Y# + Radius4#*Sin( Angle4# - Rotation# ) EndIf If Not Filled Then TFormNormal V2X# - V1X#, V2Y# - V1Y#, 0, 0, 0 AX# = TFormedX() AY# = TFormedY() TFormNormal V3X# - V2X#, V3Y# - V2Y#, 0, 0, 0 BX# = TFormedX() BY# = TFormedY() TFormNormal V4X# - V3X#, V4Y# - V3Y#, 0, 0, 0 CX# = TFormedX() CY# = TFormedY() TFormNormal V1X# - V4X#, V1Y# - V4Y#, 0, 0, 0 DX# = TFormedX() DY# = TFormedY() V1 = AddVertex( PrimitiveSurf, V1X# - ( AY# + DY# )/2., V1Y# + ( AX# + DX# )/2., DrawZ# ) V2 = AddVertex( PrimitiveSurf, V2X# - ( AY# + BY# )/2., V2Y# + ( AX# + BX# )/2., DrawZ# ) V3 = AddVertex( PrimitiveSurf, V2X# + ( AY# + BY# )/2., V2Y# - ( AX# + BX# )/2., DrawZ# ) V4 = AddVertex( PrimitiveSurf, V1X# + ( AY# + DY# )/2., V1Y# - ( AX# + DX# )/2., DrawZ# ) V5 = AddVertex( PrimitiveSurf, V3X# - ( BY# + CY# )/2., V3Y# + ( BX# + CX# )/2., DrawZ# ) V6 = AddVertex( PrimitiveSurf, V3X# + ( BY# + CY# )/2., V3Y# - ( BX# + CX# )/2., DrawZ# ) V7 = AddVertex( PrimitiveSurf, V4X# - ( CY# + DY# )/2., V4Y# + ( CX# + DX# )/2., DrawZ# ) V8 = AddVertex( PrimitiveSurf, V4X# + ( CY# + DY# )/2., V4Y# - ( CX# + DX# )/2., DrawZ# ) VertexColor PrimitiveSurf, V1, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V2, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V3, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V4, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V5, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V6, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V7, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V8, DrawR, DrawG, DrawB, DrawA# AddTriangle PrimitiveSurf, V1, V2, V3 AddTriangle PrimitiveSurf, V1, V3, V4 AddTriangle PrimitiveSurf, V2, V5, V6 AddTriangle PrimitiveSurf, V2, V6, V3 AddTriangle PrimitiveSurf, V5, V7, V8 AddTriangle PrimitiveSurf, V5, V8, V6 AddTriangle PrimitiveSurf, V7, V1, V4 AddTriangle PrimitiveSurf, V7, V4, V8 Else V1 = AddVertex( PrimitiveSurf, V1X#, V1Y#, DrawZ# ) V2 = AddVertex( PrimitiveSurf, V2X#, V2Y#, DrawZ# ) V3 = AddVertex( PrimitiveSurf, V3X#, V3Y#, DrawZ# ) V4 = AddVertex( PrimitiveSurf, V4X#, V4Y#, DrawZ# ) VertexColor PrimitiveSurf, V1, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V2, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V3, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V4, DrawR, DrawG, DrawB, DrawA# AddTriangle PrimitiveSurf, V1, V2, V3 AddTriangle PrimitiveSurf, V1, V3, V4 EndIf DrawZ# = DrawZ# + 0.001 End Function
Function Line3D( X1#, Y1#, X2#, Y2#, Size# = 1 ) X1# = X1# + OriginX# Y1# = Y1# + OriginY# X2# = X2# + OriginX# Y2# = Y2# + OriginY# TFormNormal Y1# - Y2#, X2# - X1#, 0, 0, 0 V1X# = X1# + TFormedX()*Size#/2. V2X# = X2# + TFormedX()*Size#/2. V3X# = X2# - TFormedX()*Size#/2. V4X# = X1# - TFormedX()*Size#/2. V1Y# = Y1# + TFormedY()*Size#/2. V2Y# = Y2# + TFormedY()*Size#/2. V3Y# = Y2# - TFormedY()*Size#/2. V4Y# = Y1# - TFormedY()*Size#/2. V1 = AddVertex( PrimitiveSurf, V1X#, V1Y#, DrawZ# ) V2 = AddVertex( PrimitiveSurf, V2X#, V2Y#, DrawZ# ) V3 = AddVertex( PrimitiveSurf, V3X#, V3Y#, DrawZ# ) V4 = AddVertex( PrimitiveSurf, V4X#, V4Y#, DrawZ# ) VertexColor PrimitiveSurf, V1, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V2, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V3, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V4, DrawR, DrawG, DrawB, DrawA# AddTriangle PrimitiveSurf, V1, V2, V3 AddTriangle PrimitiveSurf, V1, V3, V4 DrawZ# = DrawZ# + 0.001 End Function
Function Oval3D( X#, Y#, Width#, Height#, Filled = True, StepSize = 10, Inline# = 2 ) X# = X# - 0.5 + OriginX# Y# = Y# - 0.5 + OriginY# If Filled Then Center = AddVertex( PrimitiveSurf, X# + Width#/2, Y# + Height#/2, DrawZ# ) VertexColor PrimitiveSurf, Center, DrawR, DrawG, DrawB, DrawA# Counter = 1 For A = 0 To 360 - StepSize V = AddVertex( PrimitiveSurf, X# + Width#/2 + Cos( A )*Width#/2, Y# + Height#/2 + Sin( A )*Height#/2, DrawZ# ) VertexColor PrimitiveSurf, V, DrawR, DrawG, DrawB, DrawA# If A > 0 Then AddTriangle PrimitiveSurf, Center, Center + Counter, Center + Counter - 1 Counter = Counter + 1 A = A + StepSize - 1 Next AddTriangle PrimitiveSurf, Center, Center + 1, Center + Counter - 1 Else V1 = AddVertex( PrimitiveSurf, X# + Width - Inline#/2, Y# + Height#/2, DrawZ# ) V2 = AddVertex( PrimitiveSurf, X# + Width + Inline#/2, Y# + Height#/2, DrawZ# ) VertexColor PrimitiveSurf, V1, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V2, DrawR, DrawG, DrawB, DrawA# StartV1 = V1 StartV2 = V2 For A = 0 To 360 - StepSize XCoord# = X# + Width#/2 + Cos( A )*Width#/2 YCoord# = Y# + Height#/2 + Sin( A )*Height#/2 TFormNormal XCoord# - X# - Width#/2, YCoord# - Y# - Height#/2, 0, 0, 0 V3 = AddVertex( PrimitiveSurf, XCoord# + TFormedX()*Inline#/2, YCoord# + TFormedY()*Inline#/2, DrawZ# ) V4 = AddVertex( PrimitiveSurf, XCoord# - TFormedX()*Inline#/2, YCoord# - TFormedY()*Inline#/2, DrawZ# ) VertexColor PrimitiveSurf, V3, DrawR, DrawG, DrawB, DrawA# VertexColor PrimitiveSurf, V4, DrawR, DrawG, DrawB, DrawA# AddTriangle PrimitiveSurf, V1, V3, V2 AddTriangle PrimitiveSurf, V1, V4, V3 V1 = V3 V2 = V4 A = A + StepSize - 1 Next AddTriangle PrimitiveSurf, V1, StartV2, V2 AddTriangle PrimitiveSurf, V1, StartV1, StartV2 EndIf DrawZ# = DrawZ# + 0.001 End Function
Function Color3D( R, G, B, A# = 1 ) DrawR = R DrawG = G DrawB = B DrawA# = A# End Function
Function Cls3D() For ImageClass.TImageClass3D = Each TImageClass3D ClearSurface ImageClass\Surface Next ClearSurface PrimitiveSurf DrawZ# = 0 Cls End Function
Function Origin3D( X#, Y# ) OriginX# = X# OriginY# = Y# End Function
Function FreeImage3D( Class.TImageClass3D ) FreeTexture Class\TextureH FreeEntity Class\Mesh Delete Class End Function
Function RenderWorld3D() RenderWorld For i = 0 To CameraCount - 1 CameraProjMode Cameras[ i ], 0 Next CameraProjMode DrawCam, 2 RenderWorld CameraProjMode DrawCam, 0 For i = 0 To CameraCount - 1 CameraProjMode Cameras[ i ], 1 Next End Function
Function AddCamera3D( Cam ) Cameras[ CameraCount ] = Cam CameraCount = CameraCount + 1 End Function
Function PrepareTexture( Class.TImageClass3D, Path$, Flags ) Img = LoadImage( Path$ ) Width = ImageWidth( Img ) Height = ImageHeight( Img ) NewWidth = 2^Ceil( Log( Width )/Log( 2 ) ) NewHeight = 2^Ceil( Log( Height )/Log( 2 ) ) If NewWidth <> Width Or NewHeight <> Height Then NewImg = CreateImage( NewWidth, NewHeight ) CopyRect 0, 0, Width, Height, 0, 0, ImageBuffer( Img ), ImageBuffer( NewImg ) Add = MilliSecs() SaveImage NewImg, "__Temp" + Add + ".bmp" FreeImage NewImg Class\TextureH = LoadTexture( "__Temp" + Add + ".bmp", Flags ) Class\Animated = True Else Class\TextureH = LoadTexture( Path$, Flags ) EndIf FreeImage Img Class\Width = Width Class\Height = Height DeleteFile "__Temp" + Add + ".bmp" End Function
Function SignedDistance#( X1#, Y1#, X2#, Y2#, X3#, Y3# ) NX# = Y1# - Y2# NY# = X2# - X1# W# = -( NX#*X1# + NY#*Y1# ) Return ( NX#*X3# + NY#*Y3 + W# )/Sqr( NX#*NX# + NY#*NY# ) End Function
Function PointInRectangle( X1#, Y1#, X2#, Y2#, X3#, Y3#, X4#, Y4#, X5#, Y5# ) If SignedDistance( X1#, Y1#, X2#, Y2#, X5#, Y5# ) <= 0 Then Return False If SignedDistance( X2#, Y2#, X3#, Y3#, X5#, Y5# ) <= 0 Then Return False If SignedDistance( X3#, Y3#, X4#, Y4#, X5#, Y5# ) <= 0 Then Return False If SignedDistance( X4#, Y4#, X1#, Y1#, X5#, Y5# ) <= 0 Then Return False Return True End Function
Paket mit Beispiel und richtig eingerücktem Code (HTML hat den Tabulator nicht so gerne ): Download
Momentan sind so ziemlich alle wichtigen Befehle drin, aber leider noch nicht alle - ein Teil ist unmöglich (wie ImagesCollide oder DrawBlock), für andere hatte ich einfach noch keine Zeit.
Ich wünsche nun viel Spass mit der Lib und hoffe auf ein wenig Feedback
|