OpenGL create Sprite from Image?

Just starting out? Need help? Post your questions and find answers here.
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

OpenGL create Sprite from Image?

Post by nco2k »

with dx i can use:

Code: Select all

...
StartDrawing(SpriteOutput(#Sprite))
DrawImage(ImageID(#Image), x, y)
StopDrawing()
...
but since SpriteOutput() is not supported in ogl, i need a workaround... any ideas?

c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Post by Foz »

You could do some preprocessing - use DX to create the sprites, then save the sprites to disk in a builder app, and then you can load them in your program with just LoadSprite()
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

I have done a simple method for SpriteGLOutput:

Code: Select all

EnableExplicit
; Structure from http://www.purebasic.fr/english/viewtopic.php?t=19908
Structure PB_Sprite
  Texture.l     ; SpriteID
  Width.w       ; Current width of the sprite (could change if ClipSprite() is used)
  Height.w      ; Current height of the sprite (could change if ClipSprite() is used)
  Depth.w       ; depth of the file. (in bits)
  Mode.w        ; Sprite mode, as described in LoadSprite()
  FileName.l    ; Pointer on the filename, if any
  RealWidth.w   ; Original width of the sprite when it was loaded
  RealHeight.w  ; Original height of the sprite when it was loaded
  ClipX.w       ; X offset if ClipSprite()
  ClipY.w       ; Y offset if ClipSprite()
EndStructure

CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
ImportC "/usr/lib/libGL.so"
  glBindTexture_(a.l, b.l) As "glBindTexture"
  glTexImage2D_(a.l,b.l,c.l,d.l,e.l,f.l,g.l,h.l,i.l) As "glTexImage2D"
  glGetTexImage_(a.l,b.l,c.l,d.l,e.l) As "glGetTexImage"
EndImport
CompilerEndIf

Global *sprite2DDrawing.PB_Sprite
Global image2DDrawing.l = -1

#GL_TEXTURE_RECTANGLE_ARB = $84F5
#GL_RGBA = $1908
#GL_UNSIGNED_BYTE = $1401

Procedure StopDrawingGL()
  Protected mx.l, my.l
  Protected color.l
  Protected *mem.BYTE, *cursor.BYTE
  
  StopDrawing()

  If IsImage(image2DDrawing) And image2DDrawing <> -1
    StartDrawing(ImageOutput(image2DDrawing))
    *mem = AllocateMemory(*sprite2DDrawing\Width * *sprite2DDrawing\Height * 32)
    If *mem
      *cursor = *mem
      For my = 1 To *sprite2DDrawing\Height
        For mx = 0 To *sprite2DDrawing\Width - 1
          color = Point(mx, *sprite2DDrawing\Height - my)
          *cursor\b = Red(color) & $FF
          *cursor + 1
          *cursor\b = Green(color) & $FF
          *cursor + 1
          *cursor\b = Blue(color) & $FF
          *cursor + 2
        Next mx
      Next my

      glBindTexture_(#GL_TEXTURE_RECTANGLE_ARB, *sprite2DDrawing\Texture)
      glTexImage2D_(#GL_TEXTURE_RECTANGLE_ARB, 0, #GL_RGBA, *sprite2DDrawing\Width, *sprite2DDrawing\Height, 0, #GL_RGBA, #GL_UNSIGNED_BYTE, *mem)

      FreeMemory(*mem)
    Else
      Debug "Error: Can't allocate (enough) memory."
    EndIf
    StopDrawing()
  Else
    Debug "Error: Image doesn't exist."
  EndIf
EndProcedure

Procedure SpriteGLOutput(Sprite.l)
  Protected *mem.BYTE, *cursor.BYTE
  Protected mx.l, my.l
  Protected color.q

  *sprite2DDrawing = IsSprite(Sprite)

  If *sprite2DDrawing
    *mem = AllocateMemory(*sprite2DDrawing\Width * *sprite2DDrawing\Height * 32)
    If *mem

      glBindTexture_(#GL_TEXTURE_RECTANGLE_ARB, *sprite2DDrawing\Texture)
      glGetTexImage_(#GL_TEXTURE_RECTANGLE_ARB, 0, #GL_RGBA, #GL_UNSIGNED_BYTE, *mem)

      If IsImage(image2DDrawing) = 0 Or image2DDrawing = -1
        image2DDrawing = CreateImage(#PB_Any, *sprite2DDrawing\Width, *sprite2DDrawing\Height, 32)
      Else
        ResizeImage(image2DDrawing, *sprite2DDrawing\Width, *sprite2DDrawing\Height, #PB_Image_Raw)
      EndIf

      If IsImage(image2DDrawing) And image2DDrawing <> -1
        *cursor = *mem

        StartDrawing(ImageOutput(image2DDrawing))
        For my = 0 To *sprite2DDrawing\Height - 1
          For mx = 0 To *sprite2DDrawing\Width - 1
            color = RGB(0, 0, *cursor\b & $FF)
            *cursor + 1
            color + RGB(0, *cursor\b & $FF, 0)
            *cursor + 1
            color + RGB(*cursor\b & $FF, 0, 0)
            *cursor + 2

            Plot(mx, my, color)
          Next mx
        Next my
        StopDrawing()

        FreeMemory(*mem)

        ProcedureReturn ImageOutput(image2DDrawing)
      Else
        Debug "Error: Can't create image."
      EndIf

      FreeMemory(*mem)
    Else
      Debug "Error: Can't allocate (enough) memory."
    EndIf
    
  Else
    Debug "Error: Sprite doesn't exist."
  EndIf

  ProcedureReturn 0
EndProcedure

InitSprite()
InitKeyboard()

OpenWindow(0, 0, 0, 640, 480, "Test")
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 1, 0, 0)

CreateSprite(0, 256, 256)

StartDrawing(SpriteGLOutput(0))
Box(0, 0, 256, 256, RGB(255, 0, 0))
Box(128, 0, 128, 128, RGB(0, 0, 255))
Box(0, 128, 128, 128, RGB(0, 0, 255))
StopDrawingGL()

; And we can do it again ...
StartDrawing(SpriteGLOutput(0))
Circle(64, 64, 64, RGB(255, 255, 0))
StopDrawingGL()

Repeat
  ClearScreen(0)
  DisplaySprite(0, 0, 0)
  FlipBuffers()

  ExamineKeyboard()
  Delay(10)
  WindowEvent()
Until KeyboardPushed(#PB_Key_Escape)

CloseScreen()
First I wanted to go through DrawingInfoStruct, but then I noticed that I don't know the exact parameters for the release procedure.

Well now you have a solution for singlethreaded applications.

Don't forget enabling the OpenGL Subsystem!
[EDIT]
Small correction: On linux/mac you need to import those 3 functions. But I think on mac you have to change libGL.so to somewhat else.
Last edited by DarkDragon on Sat Jun 21, 2008 12:17 pm, edited 1 time in total.
bye,
Daniel
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Post by nco2k »

thanks dd, i will take a look. :)

c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Post by Foz »

That's very impressive. :!:

Please ignore my suggestion :)
Post Reply