It is my second post in this forum.
After long nights of testing and coding, i made some discoverings in purebasic langage (hidden concepts) that i just wanted to share with community
The post is about how to deal in OpenGL env with new 2D functions and just keep using the native purebasic 2D functions.
1- A new Drawsprite and DrawSpriteRect : with Rotation,tinting, alpha, and scaling all in one function. GREAT! but the very exciting thing is that we no more deal with purebasic sprites, but rather than that messy purebasic concept we will draw directily purebasic loaded TEXTURES!!
Why textures?
because we use them for 3D functions : imagine that rather than having 3 different concepts : images, sprites, textures, we just can have one thing, no convertions, no confusing variables anymore. just one only concept for 2D an 3D functions in the same loop.!
2- A new runtime super fast Render to texture function with no shaders use, at all, simple as SartRTT(Texture) then StopRTT()...an between them all the 2D drawings (ie Drawsprite, drawspriterect, DrawRect...)
First lets start by setting Env
Code: Select all
InitEngine3D()
Add3DArchive(GetTemporaryDirectory(),#PB_3DArchive_FileSystem)
Add3DArchive(GetCurrentDirectory(),#PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home, #PB_3DArchive_FileSystem)
Parse3DScripts()
InitSprite()
InitMouse()
InitKeyboard()
OpenWindow(0, 0, 0, 800, 600, "New OpenGL",#PB_Window_Tool)
res.l=OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0,0,0,#PB_Screen_NoSynchronization)
Global sh.l=WindowHeight(0)
Global sw.l=WindowWidth(0)
Global Fbo.l ; this is a framebuffer to use later with textures (dont bother about him)
UsePNGImageDecoder()
; now the GL setting
glViewport_(0, 0,WindowWidth(0),WindowHeight(0))
; Set current Mode to projection(ie: 3d)
glMatrixMode(#GL_PROJECTION)
;'Load identity matrix to projection matrix
glLoadIdentity()
;'Set gluPerspective params
Aspect.f = WindowWidth(0)/WindowHeight(0);
;'use glu Perspective to set our 3d frustum dimension up
gluPerspective_(45.0, aspect, 1.0, 60.0)
;'Modelview mode ie. Matrix that does things to anything we draw as in lines, points, tris, etc.
glMatrixMode(#GL_MODELVIEW)
;'load identity(clean) matrix to modelview
glLoadIdentity()
glShadeModel(#GL_SMOOTH) ; 'set shading to smooth(try GL_FLAT)
glClearColor(0.0, 0.0, 0.0, 1.0); 'set Clear color to BLACK
glClearDepth(1.0) ; 'Set Depth buffer to 1(z-Buffer)
glDisable(#GL_DEPTH_TEST) ; 'Disable Depth Testing so that our z-buffer works
;'compare each incoming pixel z value with the z value present in the depth buffer
;'LEQUAL means than pixel is drawn if the incoming z value is less than
;'or equal to the stored z value
glDepthFunc(#GL_LEQUAL)
;'have one or more material parameters track the current color
;'Material is your 3d model
glEnable(#GL_COLOR_MATERIAL)
; 'Enable Texturing
glEnable(#GL_TEXTURE_2D)
;'Tell openGL that we want the best possible perspective transform
glHint(#GL_PERSPECTIVE_CORRECTION_HINT, #GL_NICEST)
;'Disable Backface culling
glDisable (#GL_CULL_FACE)
glPolygonMode(#GL_FRONT,#GL_FILL)
;enable blending For transparency
glEnable(#GL_BLEND)
glBlendFunc(#GL_SRC_ALPHA,#GL_ONE_MINUS_SRC_ALPHA)
glDisable(#GL_DEPTH_TEST )
glEnable(#GL_ALPHA_TEST )
glAlphaFunc(#GL_GREATER, 0)
glDisable(#GL_STENCIL_TEST)
glDisable(#GL_TEXTURE_1D)
glDisable(#GL_LOGIC_OP)
glDisable(#GL_DITHER)
glDisable(#GL_FOG)
glHint(#GL_POINT_SMOOTH_HINT, #GL_FASTEST)
glHint(#GL_LINE_SMOOTH_HINT , #GL_FASTEST)
glPointSize( 1 )
glLineWidth( 1 )
Code: Select all
cam=CreateCamera(-1, 0, 0, 100, 100)
light=CreateLight(-1,RGB(255, 255, 255),13*32,320,32*12,#PB_Light_Directional)
SetLightColor(light, #PB_Light_SpecularColor, RGB(255,255,255))
LightLookAt(light, 0, 10, 0)
AmbientColor(RGB(150, 150, 150))
MoveCamera(cam,0,180,180);
CameraLookAt(cam,0,0,0)
where the purebasic compiler will store the data. in another word : lets hack the system and get the internal Opengl ID of the loaded texture in order to use it for all the drawing functions and at hte same time , keep ist use also for native 3D functions. we will have a unique ID for the texture.
Code: Select all
Procedure.l LoadTextur(texN.s)
Protected glsp.l
glEnable_(#GL_TEXTURE_2D)
ME.l=Loadimage(-1,TexN) ;load the image the normal way
If ME=0:Debug(TexN +" not found"):ProcedureReturn -1:EndIf
w=ImageWidth(ME):h=ImageHeight(ME)
ttx.l=CreateTexture(-1,w,h)
glGetIntegerv_(#GL_TEXTURE_BINDING_2D, @glsp) ; => here is the trick = we just get the internal ID of the last created texture (this
; ID is set by the OpenGl driver itself by using the
; glgentextures function
FreeTexture(ttx); we release the created texture because we dont need a different ID (whitch is given by purebasic not OpenGL driver)
CreateTexture(glsp,w,h); now that we know whitch ID is internal we create a pb texture with the same ID just to have the same ID
; for all the functions (3D native, and new ones)
; here we tell the GL driver about the internal format, clipping, filtering , width, height.. of the texture
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_WRAP_S, #GL_CLAMP_TO_BORDER)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_WRAP_T, #GL_CLAMP_TO_BORDER)
glTexImage2D(#GL_TEXTURE_2D, 0, 4, w,h, 0, #GL_BGRA_EXT, #GL_UNSIGNED_BYTE, #Null)
; here we will store the image into the texture
StartDrawing(TextureOutput(glsp))
DrawingMode(#PB_2DDrawing_AlphaBlend)
DrawAlphaImage(ImageID(ME),0,0)
StopDrawing()
; dont forget to free the image
freeimage(ME)
ProcedureReturn glsp
EndProcedure
;We are done. Now we can use our texture for every thing : u just have to load any image
Global Tx1.l=Loadtextur("someimage.png")
Code: Select all
Procedure DrawSprite(tex.l,x.f,y.f,col.l=$FFFFFFFF,rot.f=0,sc.f=1)
If sc=<0:ProcedureReturn :EndIf
glEnable_(#GL_TEXTURE_2D) : glBindTexture_(#GL_TEXTURE_2D,tex)
Protected w.l,h.l
glGetTexLevelParameteriv(#GL_TEXTURE_2D,0,#GL_TEXTURE_WIDTH, @w)
glGetTexLevelParameteriv(#GL_TEXTURE_2D,0,#GL_TEXTURE_HEIGHT, @h)
glRotatef_(rot,0,0,1)
If sc>0:glScalef_(sc,sc,1):x/sc:y/sc:EndIf
cx1.f=0
cx2.f=1
cy1.f=1
cy2.f=0
x1.f=x
x2.f=x+w
y2.f=y+h
y1.f=y
glColor4ub(Red(col),Green(col),Blue(col),Alpha(col))
glBegin_(#GL_QUADS)
glTexCoord2f(cx1,cy2);
glVertex2i(x1,y1);
glTexCoord2f(cx1,cy1);
glVertex2i(x1,y2);
glTexCoord2f(cx2,cy1);
glVertex2i(x2,y2);
glTexCoord2f(cx2,cy2);
glVertex2i(x2,y1); ;
glEnd_()
glPopMatrix()
glDisable_(#GL_TEXTURE_2D)
EndProcedure
mix 2D and 3D stuff
Code: Select all
Procedure Begin2D()
glDisable(#GL_DEPTH_TEST)
glDisable (#GL_CULL_FACE)
glEnable(#GL_BLEND)
glBlendFunc(#GL_SRC_ALPHA,#GL_ONE_MINUS_SRC_ALPHA)
glDisable(#GL_DEPTH_TEST )
glEnable(#GL_ALPHA_TEST )
glAlphaFunc(#GL_GREATER, 0)
glDisable(#GL_STENCIL_TEST)
glDisable(#GL_TEXTURE_1D)
glDisable(#GL_LIGHTING)
glDisable(#GL_LOGIC_OP)
glDisable(#GL_DITHER)
glDisable(#GL_FOG)
glHint(#GL_POINT_SMOOTH_HINT, #GL_FASTEST)
glHint(#GL_LINE_SMOOTH_HINT , #GL_FASTEST)
glPointSize( 1 )
glLineWidth( 1 )
Dim ViewPort.i(3)
glGetIntegerv_(#GL_VIEWPORT, @ViewPort(0))
glMatrixMode_(#GL_PROJECTION)
glPushMatrix_()
glLoadIdentity_()
glOrtho_(0, ViewPort(2),ViewPort(3),0,0, -1)
glMatrixMode_(#GL_MODELVIEW)
glPushMatrix_()
glLoadIdentity_()
EndProcedure
Procedure End2D()
glMatrixMode(#GL_PROJECTION)
glPopMatrix()
glMatrixMode(#GL_MODELVIEW)
glPopMatrix()
EndProcedure
Code: Select all
Repeat
ExamineKeyboard()
; 3D Stuff comes HERE
RenderWorld()
;2D Stuff comes HERE
Begin2D()
DrawSprite(tx1,200,0,RGBA($ff,$ff,$ff,200))
End2D()
Flipbuffers()
Until KeyboardPushed(#PB_Key_Escape)
Just try it and tell me your feedback
The DrawSpriteRect, DrawRect, StartRTT function will come in next posts.
Tested on Purebasic 5.3 Windows 8 64bit
Dont know about other versions