After searching the forum and tested many GL codes, i have discovered how Sprites are handled in purebasic in Opengl sub.
So i wrote my own LoadGLSprite and DrawGLSprite procedures to handle more efficiently sprites.
The trick is that sprites are just textures witch are stored in GL mode by handles. these hundles can be binded by calling SpriteID(Spritenumber)
Features :
-Now we can display sprites with tint , transparency , rotation , scale , all and parts = in one procedure
-Notice that the same handle returned by load procedure can be used in default DisplaySprite procedure
-Works fine with Engine3D initialized
Works fine in PB 5.30 Windows 8, OpenGL subsysem
Please test other versions if you have time, and feedback
Code: Select all
Procedure.l LoadGLSprite(spname.s,mode.l)
Protected sp1.l=LoadSprite(#PB_Any,spname,mode)
glEnable_(#GL_TEXTURE_2D)
StartDrawing(SpriteOutput(sp1))
glBindTexture_(#GL_TEXTURE_2D, SpriteID(sp1))
If SpriteDepth(sp1)=32
glTexImage2D_(#GL_TEXTURE_2D, 0, 4, SpriteWidth(sp1), SpriteHeight(sp1), 0, #GL_BGRA_EXT, #GL_UNSIGNED_BYTE, DrawingBuffer())
Else
glTexImage2D_(#GL_TEXTURE_2D, 0, 3, SpriteWidth(sp1), SpriteHeight(sp1), 0, #GL_BGRA_EXT, #GL_UNSIGNED_BYTE, DrawingBuffer())
EndIf
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_NEAREST)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_NEAREST)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_WRAP_S, #GL_CLAMP)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_WRAP_T, #GL_CLAMP)
StopDrawing()
ProcedureReturn sp1
EndProcedure
; a procedure to test dimensions
Procedure.l Cadrer(x.l,min.l,max.l)
If x>=max:ProcedureReturn max:EndIf
If x=<min:ProcedureReturn min:EndIf
ProcedureReturn x
EndProcedure
; x,y coordinates where to put sprite
; xp,yp coordinates where to begin sprite part ;
; wp,hp : width and height of sprite part ;
; if part coordinates are set to 0,0,0,0 then all the sprite will be drawn
; sc is the scale of the sprite or its part
; rot is the rotation of the sprite or its part
; col is the tint (you can have RGB values)
; alp is the transparency (0=invisible ; 255 is full opaque) , it is practicle for fading effect
Procedure DrawGlSprite(tex.l,x.l,y.l,xp.l=0,yp.l=0,wp.l=0,hp.l=0,sc.f=1,rot.f=0,col.l=#White,alp.l=255)
;here we bind the preloaded sprite texture by calling spriteid(tex)
glEnable_(#GL_TEXTURE_2D) : glBindTexture_(#GL_TEXTURE_2D,SpriteID(tex))
; we get the width and height
glGetTexLevelParameteriv_(#GL_TEXTURE_2D, 0, #GL_TEXTURE_WIDTH, @w)
glGetTexLevelParameteriv_(#GL_TEXTURE_2D, 0, #GL_TEXTURE_HEIGHT, @h)
xp=Cadrer(xp,0,w)
yp=Cadrer(yp,0,h)
wp=Cadrer(wp,0,w)
hp=Cadrer(hp,0,h)
If xp=0 And wp=0:wp=w:EndIf
If yp=0 And hp=0:hp=h:EndIf
sh.l=WindowHeight(0)
sw.l=WindowWidth(0)
;setting envirenment
glEnable_(#GL_BLEND)
glDepthFunc_(#GL_LEQUAL)
glBlendFunc_(#GL_SRC_ALPHA, #GL_ONE_MINUS_SRC_ALPHA)
glPopMatrix_()
glMatrixMode_(#GL_PROJECTION)
glDisable_(#GL_DEPTH)
glLoadIdentity_()
gluPerspective_(58.1, WindowWidth(0)/WindowHeight(0)*0.75, 0, 60.0)
glPushMatrix_()
; apply the rotation and scale
glRotatef_(rot,0,0,1)
glScalef_(sc,sc,1)
glTranslatef_(CameraX(cam)-0.5,CameraY(cam)-0.5,CameraZ(cam)-0.9)
Protected x1.f=x/sW
Protected x2.f=(x+wp)/sW
;drawing the sprite or the part of it
glBegin_(#GL_QUADS)
glColor4f_(Red(col)/255,Green(col)/255,Blue(col)/255,alp/255)
glTexCoord2f_(xp/w,(h-yp)/h) : glVertex2f_(x1, (sh-y)/sh)
glTexCoord2f_((xp+wp)/w,(h-yp)/h) : glVertex2f_(x2,(sh-y)/sh)
glTexCoord2f_((xp+wp)/w,(h-yp-hp)/h) : glVertex2f_(x2, (sh-y-hp)/sh)
glTexCoord2f_(xp/w,(h-hp-yp)/h) : glVertex2f_(x1, (sh-y-hp)/sh)
glEnd_()
glPopMatrix_()
glDisable_(#GL_TEXTURE_2D)
EndProcedure
exemple using it
Code: Select all
InitEngine3D()
OpenWindow(0, 270, 100, 800, 600, "Sprite OpenGL demo")
Add3DArchive(#PB_Compiler_Home + "", #PB_3DArchive_FileSystem)
Parse3DScripts()
InitSprite()
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0) , WindowHeight(0))
UsePNGImageDecoder(); use PNG images to hundle alphachannel and avoid transparent color handling
Global sp.l
sp=LoadGLSprite("SomeFile.png",#PB_Sprite_AlphaBlending) ; replace SomeFile.png by your own png file
cam.l=CreateCamera(#PB_Any,0,0,100,100)
repeat
CameraBackColor(Cam,RGB(0,255,55))
RenderWorld()
DrawGlSprite(sp,450,60,0,0,150,150,1.1,0,RGB(255,0,0),150);draws a part of a sprite scaled , red tinted and semi transparent
FlipBuffers()
Until WaitWindowEvent() = #PB_Event_CloseWindow