Transform sprite with OpenGL

Share your advanced PureBasic knowledge/code with the community.
User avatar
Demivec
Addict
Addict
Posts: 4085
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Transform sprite with OpenGL

Post by Demivec »

I finally figured out how to do Sprite Transforms with PureBasic's TransformSprite() command when using OpenGL. These have always been possible with DirectX. It works only with 2D transformations for now, the work continues for 3D transformations. The code I've included here shows 2D transformations.

Here is some old test code that I've shared at various times in the forum that I have now updated to handle the changes. It shows a variety of sprite transforms and also allows an interactive transformation of a sprite (on the lower right of window). The window lists what the transformations being shown should be doing so that you will know it's function correctly even if you have nothing to compare it too. I was only able to test things in Windows but if someone could give some feedback on how it works with other OS's (using OpenGL) it would be appreciated.

Transformations with OpenGL allow the sprite to be flipped to see the 'backside' but DirectX doesn't. I have only tried a few of the sample code in the forum that allows some things with DirectX but nothing has worked as a drop in replacement in the sample code below.

Please let me know of any errors or bugs.

Code: Select all

;Program description: Sprite transformation effects
;Author: Demivec
;Written for: Originally for PB 4.61, with Windows OS, may not function correctly for other OS but hopefully does.
;Date Written: 2 July 2012
;     Updated: 4 October 2015 for PB 5.40b8 and added some additional features.
;Last Updated: 28 February 2019 for PB 5.70 and added some additional features so it works for OpenGL.

EnableExplicit
CompilerIf Defined(Point, #PB_Structure) = 0
  Structure Point
    x.i
    y.i
  EndStructure
CompilerEndIf

Structure Point_f
  x.f
  y.f
EndStructure

Enumeration sprites
  #spr_pb
  #spr_corner
  #spr_text_1
  #spr_text_2
  #spr_text_3
  #spr_text_4
  #spr_mousePointer
  #spr_text_descript_1
  #spr_text_descript_2
  #spr_text_descript_3
  #spr_text_descript_4
  #spr_text_descript_5
  #spr_text_descript_6
  #spr_text_descript_7
  #spr_text_descript_8
  #spr_text_descript_9
  #spr_text_descript_10
  #spr_text_descript_11
  #spr_text_descript_12
EndEnumeration

;check if OpenGL or DirectX is being used for sprites, best guess and not well tested ;)
CompilerIf (#PB_Compiler_OS = #PB_OS_Linux Or #PB_Compiler_OS = #PB_OS_MacOS)
  #pb_sprite_subsystem = "OpenGL" 
CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
  CompilerIf Subsystem("OpenGL")
    #pb_sprite_subsystem = "OpenGL"
  CompilerElse
    #pb_sprite_subsystem = "DirectX"
  CompilerEndIf
CompilerElse
  #pb_sprite_subsystem = "Unknown"
CompilerEndIf

Enumeration fonts
  #font_large
  #font_small
EndEnumeration

Enumeration windows
  #win_main  
EndEnumeration

Procedure handleError(value, text.s = "Unknown Error.")
  If value = 0
    MessageRequester("Error", text)
    End
  EndIf
EndProcedure

;macro to correct 2D sprite Transforms for OpenGL by manipulation of corner coordinate data
Macro TransformSprite2D(spriteID,x1, y1, x2, y2, x3, y3, x4, y4)
  CompilerIf #pb_sprite_subsystem = "OpenGL"
    TransformSprite(spriteID,x1, y1, x2, -(y3) + (y1) + (y4), x3, -(y2) + (y1) + (y4), x4, y4)
  CompilerElse
    TransformSprite(spriteID,x1, y1, x2, y2, x3, y3, x4, y4)
  CompilerEndIf
EndMacro
;macro to correct 3D sprite Transforms for OpenGL by manipulation of corner coordinate data
Macro TransformSprite3D(spriteID,x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4)
  CompilerIf #pb_sprite_subsystem = "OpenGL"
    TransformSprite(spriteID,x1, y1, z1, x2, -(y3) + (y1) + (y4), z2, x3, -(y2) + (y1) + (y4), z3, x4, y4, z4)
  CompilerElse
    TransformSprite(spriteID,x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4)
  CompilerEndIf
EndMacro
;macro to ensure transparent sprite colors work for OpenGL by altering the color, then using the correct color
Macro TransparentSpriteColorOK(spriteID, color)
  CompilerIf #pb_sprite_subsystem = "OpenGL"
    TransparentSpriteColor(spriteID, color - 1)
  CompilerEndIf
  TransparentSpriteColor(spriteID, color)
EndMacro


;Sprite info: (width, height) = original dimensions, (newWidth, newHeight) = zoom dimensions,
; degree = rotation amount, (cx,cy) = center point for rotation
Procedure MakeSpriteTransformation(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
  Protected.Point_f p1, p2, p3, p4
  Protected.f wf = width / newWidth, hf = height / newHeight

  If degree = 0
    ;simple transformation: no rotation, only zooming and translation movements possible 
    p1\x = ((       -cx) / wf) - 0.5: p1\y = ((        -cy) / hf) - 0.5
    p2\x = ((width - cx) / wf) - 0.5: p2\y = ((        -cy) / hf) - 0.5
    p3\x = ((width - cx) / wf) - 0.5: p3\y = ((height - cy) / hf) - 0.5
    p4\x = ((       -cx) / wf) - 0.5: p4\y = ((height - cy) / hf) - 0.5
    
  Else
    ;more complex transformation: rotation (around point cx,cy) and zooming possible 
    Protected.f angCos = Cos(Radian(degree)), angSin = Sin(Radian(degree))
    Protected.f v1, v2, v3, v4, v5, v6, v7, v8
    
    v1 = -cx * angCos: v3 = -cy * angSin
    v2 = -cx * angSin: v4 = -cy * angCos
    
    v6 = (width - cx) * angCos: v7 = (height - cy) * angSin
    v5 = (width - cx) * angSin: v8 = (height - cy) * angCos
    p1\x = ((v1 - v3) / wf) - 0.5: p1\y = ((v4 + v2) / hf) - 0.5
    p2\x = ((v6 - v3) / wf) - 0.5: p2\y = ((v4 + v5) / hf) - 0.5
    p3\x = ((v6 - v7) / wf) - 0.5: p3\y = ((v8 + v5) / hf) - 0.5
    p4\x = ((v1 - v7) / wf) - 0.5: p4\y = ((v8 + v2) / hf) - 0.5
  EndIf  
  
  TransformSprite2D(spriteID, p1\x, p1\y, p2\x, p2\y,  p3\x, p3\y,  p4\x, p4\y)
EndProcedure

;iso (squish) rotated clockwise degrees
Procedure MakeSpriteIsoClockwise(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
EndProcedure

;iso (squish) rotated counter-clockwise degrees
Procedure  MakeSpriteIsoCounterClockwise(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, 360 - degree, newWidth, newHeight)
EndProcedure  

Procedure MakeSpriteRotate(SpriteID, cx, cy, degree)
  Protected width = SpriteWidth(SpriteID), height = SpriteHeight(SpriteID)
  ZoomSprite(SpriteID, #PB_Default, #PB_Default)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, degree, width, height)
EndProcedure

Procedure MakeSpriteZoomHorizontal(SpriteID, cx, cy, newWidth)
  Protected width = SpriteWidth(SpriteID), height = SpriteHeight(SpriteID)
  ZoomSprite(SpriteID, #PB_Default, #PB_Default)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, 0, newWidth, height)
EndProcedure

Procedure MakeSpriteZoomVertical(SpriteID, cx, cy, newHeight)
  Protected width = SpriteWidth(SpriteID), height = SpriteHeight(SpriteID)
  ZoomSprite(SpriteID, #PB_Default, #PB_Default)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, 0, width, newHeight)
EndProcedure

Procedure MakeSpriteNormal(SpriteID, cx = 0, cy = 0)
  Protected width = SpriteWidth(SpriteID), height = SpriteHeight(SpriteID)
  ZoomSprite(SpriteID, #PB_Default, #PB_Default)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, 0, width, height)
EndProcedure


handleError(InitSprite(), "Can't open screen & sprite enviroment.")
handleError(InitMouse(), "Can't initialize mouse handler.")
handleError(InitKeyboard(), "Can't initialize keyboard handler.")
handleError(OpenWindow(#win_main, 0, 0, 800, 600, "Sprite Transformations (" + #pb_sprite_subsystem + ")",
                       #PB_Window_SystemMenu | #PB_Window_ScreenCentered), "Can't open window.")
handleError(OpenWindowedScreen(WindowID(#win_main), 0, 0, 800, 600, 0, 0, 0), "Can't open windowed screen.")

handleError(LoadFont(#font_large, "Arial", 36), "Unable to load font.")
handleError(LoadFont(#font_small, "Arial", 8), "Unable to load font.")
handleError(CreateSprite(#spr_pb, 64, 64), "Sprite creation failed.")
handleError(StartDrawing(SpriteOutput(#spr_pb)), "Can't draw on sprite.")
  Box(0,0,64,64,RGB($FF,$FF,$00))
  DrawingMode(#PB_2DDrawing_Outlined)
  DrawingFont(FontID(#font_large))
  DrawText(0,0,"PB",RGB($FF,$00,$00))
  Box(0,0,64,64,RGB($00,$00,$FF))
  LineXY( 0,0,64,64,RGB($00,$00,$FF))
  LineXY(64,0, 0,64,RGB($00,$00,$FF))
StopDrawing()

handleError(CreateSprite(#spr_mousePointer, 8, 8, #PB_Sprite_AlphaBlending), "Sprite creation failed.")
handleError(StartDrawing(SpriteOutput(#spr_mousePointer)), "Can't draw on sprite.")
  FrontColor(RGB($00,$FF,$FF))
  LineXY(0,0, OutputWidth() - 1,OutputHeight() - 1)
  LineXY(0,0, 0,OutputHeight() - 3)
  LineXY(0,0, OutputWidth() - 3,0)
StopDrawing()
TransparentSpriteColorOK(#spr_mousePointer, RGB($00,$00,$00))
  

handleError(CreateSprite(#spr_corner, 8, 8, #PB_Sprite_AlphaBlending), "Sprite creation failed.")
handleError(StartDrawing(SpriteOutput(#spr_corner)), "Can't draw on sprite.")
  Box(0, 0, OutputWidth(), OutputHeight(), RGB($00, $FF, $00))
StopDrawing()
TransparentSpriteColorOK(#spr_corner, RGB($00,$00,$00))

DataSection
  cornerCoordinates:
  Data.i 0,0, 64,0, 64,64, 0,64
  textDescriptions:
  Data.s "Standard","Rotate around center", "Rotate off center"
  Data.s "Horizontal zoom","Vertical zoom"
  Data.s "Horizontal iso squish (zoom) + rotate","Vertical iso squish (zoom) + rotate"
  Data.s "Horizontal iso squish + overall zoom + rotate","Vertical iso squish + overall zoom + rotate"
  Data.s "Horizontal variable iso squish + rotate","Vertical variable iso squish + rotate"
  Data.s "Custom sprite transformation, drag numbered corners to transform"
EndDataSection

Dim corner.Point(3)
Define customSpritePosX = 500, customSpritePosY = 425, i
Restore cornerCoordinates
For i = 0 To 3
  handleError(CreateSprite(#spr_text_1 + i, 8, 16, #PB_Sprite_AlphaBlending), "Sprite creation failed.")
  handleError(StartDrawing(SpriteOutput(#spr_text_1 + i)), "Can't draw on sprite.")
    DrawingMode(#PB_2DDrawing_Outlined)
    DrawingFont(FontID(#font_small))
    DrawText(0, 0, Str(i + 1), RGB($FF,$FF,$FF), RGB($00,$00,$00))
  StopDrawing()
  TransparentSpriteColorOK(#spr_text_1 + i, RGB($00,$00,$00))
  Read.i corner(i)\x: corner(i)\x + customSpritePosX
  Read.i corner(i)\y: corner(i)\y + customSpritePosY
Next

Define tmp$
Restore textDescriptions
For i = 0 To 11
  Read.s tmp$
  handleError(CreateSprite(#spr_text_descript_1 + i, 6 * Len(tmp$), 16, #PB_Sprite_AlphaBlending), "Sprite creation failed.")
  handleError(StartDrawing(SpriteOutput(#spr_text_descript_1 + i)), "Can't draw on sprite.")
    DrawingMode(#PB_2DDrawing_Outlined)
    DrawingFont(FontID(#font_small))
    DrawText(0, 0, tmp$, RGB($FF,$FF,$FF), RGB($00,$00,$00))
  StopDrawing()
  TransparentSpriteColorOK(#spr_text_descript_1 + i, RGB($00,$00,$00))
Next
  
Define direction = 2
Define pb_sprite_size = SpriteHeight(#spr_pb)
Define zoomX     = SpriteWidth(#spr_pb)  ;initial zoom sizes
Define zoomY     = SpriteHeight(#spr_pb) 
Define angle, newWidth, newHeight, displayRow, event, i

ReleaseMouse(1)
Define mouseIsReleased = #True, dragCorner = -1
Repeat
  Repeat
    event = WindowEvent()
    Select event 
      Case #PB_Event_CloseWindow
        End 
    EndSelect
  Until event = 0
    
  FlipBuffers() 
  ClearScreen(RGB($40, $40, $40))
  
  displayRow = 70
  MakeSpriteNormal(#spr_pb, 32, 32) ;normal appearance
  DisplaySprite(#spr_pb, 100, displayRow) ;location is needed because display location was not part of transformation
  DisplayTransparentSprite(#spr_text_descript_1, 100 - (pb_sprite_size + SpriteWidth(#spr_text_descript_1)) / 4, displayRow + pb_sprite_size * 0.75)
  
  MakeSpriteRotate(#spr_pb, 32, 32, angle) ;rotate around center
  DisplaySprite(#spr_pb, 200, displayRow)
  DisplayTransparentSprite(#spr_text_descript_2, 200 - (pb_sprite_size + SpriteWidth(#spr_text_descript_2)) / 4, displayRow + pb_sprite_size * 0.75)
  MakeSpriteRotate(#spr_pb, 16, 16, angle) ;rotate around non-center point
  DisplaySprite(#spr_pb, 350, displayRow)
  DisplayTransparentSprite(#spr_text_descript_3, 350 - (pb_sprite_size + SpriteWidth(#spr_text_descript_3)) / 4, displayRow + pb_sprite_size * 0.75)
  newWidth = zoomX: newHeight = zoomX
  MakeSpriteZoomHorizontal(#spr_pb, 32, 32, newWidth) ;zoom horizontally
  DisplaySprite(#spr_pb, 500, displayRow)
  DisplayTransparentSprite(#spr_text_descript_4, 500 - (pb_sprite_size + SpriteWidth(#spr_text_descript_4)) / 4, displayRow + pb_sprite_size * 0.75)
  MakeSpriteZoomVertical(#spr_pb, 32, 32, newHeight) ;zoom vertically
  DisplaySprite(#spr_pb, 600, displayRow)
  DisplayTransparentSprite(#spr_text_descript_5, 600 - (pb_sprite_size + SpriteWidth(#spr_text_descript_5)) / 4, displayRow + pb_sprite_size * 0.75)
  
  displayRow = 170
  MakeSpriteIsoCounterClockwise(#spr_pb, 64, 64, 32, 32, angle, 64, 32) ;squished vertically
  DisplaySprite(#spr_pb, 150, displayRow)
  DisplayTransparentSprite(#spr_text_descript_6, 150 - (pb_sprite_size + SpriteWidth(#spr_text_descript_6)) / 4, displayRow + pb_sprite_size * 0.50)
  displayRow = 260
  MakeSpriteIsoCounterClockwise(#spr_pb, 64, 64, 32, 32, angle, 32, 64) ;squished horizontally
  DisplaySprite(#spr_pb, 150, displayRow)
  DisplayTransparentSprite(#spr_text_descript_7, 150 - (pb_sprite_size + SpriteWidth(#spr_text_descript_7)) / 4, displayRow + pb_sprite_size * 0.75)
  
  displayRow = 280
  MakeSpriteIsoClockwise(#spr_pb, 64, 64, 32, 32, angle, 2 * zoomX, 1 * zoomX) ;squished vertically and zoomed
  DisplaySprite(#spr_pb, 675 - zoomY * 0.5, displayRow - zoomY * 0.5)
  DisplayTransparentSprite(#spr_text_descript_8, 650 - (pb_sprite_size + SpriteWidth(#spr_text_descript_8)) / 3, displayRow + pb_sprite_size * 0.75)
  MakeSpriteIsoClockwise(#spr_pb, 64, 64, 32, 32, angle, 1 * zoomX, 2 * zoomX) ;squished horizontally and zoomed
  DisplaySprite(#spr_pb, 425 - zoomY * 0.5, displayRow - zoomY * 0.5)
  DisplayTransparentSprite(#spr_text_descript_9, 400 - (pb_sprite_size + SpriteWidth(#spr_text_descript_9)) / 3, displayRow + pb_sprite_size * 0.75)
  
  displayRow = 380
  MakeSpriteIsoCounterClockwise(#spr_pb, 64, 64, 32, 32, angle, 64, 20 + zoomX / 2) ;squishiness varying vertically
  DisplaySprite(#spr_pb, 150, displayRow)
  DisplayTransparentSprite(#spr_text_descript_10, 150 - (pb_sprite_size + SpriteWidth(#spr_text_descript_10)) / 4, displayRow + pb_sprite_size * 0.75)
  displayRow = 490
  MakeSpriteIsoCounterClockwise(#spr_pb, 64, 64, 32, 32, angle, 20 + zoomX / 2, 64) ;squishiness varying horizontally
  DisplaySprite(#spr_pb, 150, displayRow)
  DisplayTransparentSprite(#spr_text_descript_11, 150 - (pb_sprite_size + SpriteWidth(#spr_text_descript_11)) / 4, displayRow + pb_sprite_size * 0.75)
  
 
  ExamineMouse()
  
  ;handle screen mouse activation/deactivation
  If MouseX() < 2 Or MouseX() > ScreenWidth() - 3 Or MouseY() < 2 Or MouseY() > ScreenHeight() -3
    ReleaseMouse(1): mouseIsReleased = #True
  EndIf
  
  If WindowMouseX(#win_main) >= 2 And
         WindowMouseX(#win_main) < WindowWidth(#win_main, #PB_Window_InnerCoordinate) - 2 And
         WindowMouseY(#win_main) >= 2 And
         WindowMouseY(#win_main) < WindowHeight(#win_main, #PB_Window_InnerCoordinate) - 2
    ReleaseMouse(0): mouseIsReleased = #False
    MouseLocate(WindowMouseX(#win_main), WindowMouseY(#win_main))
  EndIf
  
  ;handle corner dragging for deformable sprite
  If Not mouseIsReleased
    If MouseButton(#PB_MouseButton_Left)
      If dragCorner = -1
        For i = 0 To 3
          If SpriteCollision(#spr_corner, corner(i)\x, corner(i)\y, #spr_mousePointer, MouseX(), MouseY())
            dragCorner = i
            MouseDeltaX(): MouseDeltaY() ;reset these values for further reads
            Break
          EndIf
        Next
      Else
        corner(dragCorner)\x + MouseDeltaX(): corner(dragCorner)\y + MouseDeltaY()  
      EndIf
    ElseIf dragCorner <> -1
      corner(dragCorner)\x + MouseDeltaX(): corner(dragCorner)\y + MouseDeltaY()  
      dragCorner = -1 ;signal that no corner is being dragged      
    EndIf
  EndIf
  TransformSprite2D(#spr_pb, corner(0)\x,corner(0)\y, corner(1)\x,corner(1)\y, corner(2)\x,corner(2)\y, corner(3)\x,corner(3)\y)
  DisplaySprite(#spr_pb, 0, 0)  ;drawn at location 0,0 because sprite location is part of transformation
  DisplayTransparentSprite(#spr_text_descript_12, customSpritePosX - (pb_sprite_size + SpriteWidth(#spr_text_descript_12)) / 4, customSpritePosY + pb_sprite_size * 1.5, 180)
  
  ;display corners for dragging
  For i = 0 To 3
    DisplayTransparentSprite(#spr_corner, corner(i)\x, corner(i)\y, 128)
    DisplayTransparentSprite(#spr_text_1 + i, corner(i)\x + 8, corner(i)\y)
  Next
  If Not mouseIsReleased: DisplayTransparentSprite(#spr_mousePointer, MouseX(), MouseY()): EndIf
  
  ;update animation attributes
  angle + 1: If angle > 360: angle = 0: EndIf
  zoomX + direction

  If zoomX > 100  : direction = -2 : EndIf
  If zoomX < 20   : direction =  2 : EndIf
  
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Escape): Break: EndIf
  Delay(1)
ForEver
@Edit: Made a small correction to text to report that only the 2D transformations are working and they are what is demonstrated in the code above. 3D is still a work in progress.

@Edit2: Made a cosmetic change by renaming the constant #pb_subsystem to #pb_sprite_subsystem.
Last edited by Demivec on Mon Mar 04, 2019 6:34 am, edited 2 times in total.
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Transform sprite with OpenGL

Post by Olliv »

Good work I can read. Your code converts specific functions to native function, calculating each corner.

Why do not you test directly OpenGL rendering?

Is it by refusing of too much non-native calls ?
Is it to maintain cross-platform subsystem ?
Or, is it just by checking what a native process can do of better ?
User avatar
Demivec
Addict
Addict
Posts: 4085
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Transform sprite with OpenGL

Post by Demivec »

Olliv wrote:Why do not you test directly OpenGL rendering?

Is it by refusing of too much non-native calls ?
Is it to maintain cross-platform subsystem ?
Or, is it just by checking what a native process can do of better ?
You have asked many questions that have the same answer.

First, I am not against using OpenGL directly but I haven't yet gotten around to exploring with it yet.

For the other questions, PureBasic has had a TransformSprite() command for many years that has had limited functional use for OpenGL. It should allow rotation, scaling and translating a sprite's texture but has only been able to do some scaling. By figuring out how to work around the problems in how it operates with coordinate data when using OpenGL it adds another functional tool to make thngs easier. It also stands to make a common working solution when doing things in a cross-platform manner and it's already a part of PureBasic.

I am still of the opinion that the functioning I've coded above could be implemented natively in PureBasic as either a correction of a bug (if it turns out to be one in OpenGL's implementation of TransformSprite()) or as an additional feature to add the missing functionality for OpenGL.

Essentially there are only a few macros and a series of compiler comparisons to determine some information regarding the subsystem being used for sprites. I've dropped those things into other example code on the forum and it works for both OpenGL and DirectX code that uses TransformSprite() and needs only a little bit more modification to indicate the use of one of the two macros written for each of the states possible with the overloaded nature of TransformSprites() supplied parameters.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Transform sprite with OpenGL

Post by Kwai chang caine »

Very nice, works fine here
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Transform sprite with OpenGL

Post by Olliv »

I thank your patience, knowing I cannot execute your code in the right version.

When Idle helped me nine years ago, he shew me such a detail to have same on Opengl as DirectX.

But I remember a difference between OGL and DX.
Your code is certainly a good evolving to check this difference.


So... When you draw a simple grid in a texture. i.e. 4*4 case, and you apply it with native TransformSprite with 3D coordinates, DirectX will calculate the perspective effect, not OpenGL.

Could you confirm this difference ?

(Perspective is a reducing of deeper distances.) If the same problem exists again, I think we have not the choice to use OpenGL only directly to set up this characteristic.
User avatar
Demivec
Addict
Addict
Posts: 4085
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Transform sprite with OpenGL

Post by Demivec »

Olliv wrote:But I remember a difference between OGL and DX.
Your code is certainly a good evolving to check this difference.


So... When you draw a simple grid in a texture. i.e. 4*4 case, and you apply it with native TransformSprite with 3D coordinates, DirectX will calculate the perspective effect, not OpenGL.

Could you confirm this difference ?

(Perspective is a reducing of deeper distances.) If the same problem exists again, I think we have not the choice to use OpenGL only directly to set up this characteristic.
I have performed some rigorous testing just today on the perspective effect when using 'Z' coordinates for both DirectX and OpenGL so I could make an accurate comparison. Sadly it appears that the 'Z' coordinates have absolutely no effect on a sprites texture. This means there will be undesirable warping that will prevent a more natural perspective effect when the sprite is not rectangular. This is fine for 2D but not 3D.

It is sad that PureBasic doesn't seem to have a solution for this itself. Fortunately I can get a lot done with only 2D transforms. I am still going to investigate other possible solutions including native OpenGL commands to deal with the 3D transforms.
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Transform sprite with OpenGL

Post by Olliv »

I preferred you check this not to waste time.

But, do not be sad for that.

OpenGL is good. It seems to be difficult to set up, but not really.

Keep your whole code : you could (later) test EXE and DLL sizes between direct OGL and screen sprite.

Just test to open two gadgets OpenGL. on the screen.
User avatar
RSBasic
Moderator
Moderator
Posts: 1218
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: Transform sprite with OpenGL

Post by RSBasic »

Thank you very mich. Nice functions. Very nice!
Image
Image
Post Reply