OpenGLGadget - drawing sprite (perfect pixel)
Posted: Thu Jun 04, 2015 11:32 pm
				
				Just an OpenGL code to emulate sprite drawing
			Code: Select all
;DOCS:
; http:;//www.gamedev.net/page/resources/_/technical/opengl/rendering-efficient-2d-sprites-in-opengl-using-r2429
; https://open.gl/textures
#GL_TEXTURE_RECTANGLE_NV=$84F5
#GL_CLAMP_TO_EDGE=$812F
Global Dim glTextureIDs.i(0)
Global screenGL, screenColor=RGBA(0, 0, 0, 0)
Global glSpriteTexture, w, h, tint=RGB(255, 255, 255)
Global scaleX.f=1.0, scaleY.f=1.0
Procedure SetupGL(screenW, screenH)
   
   glMatrixMode_(#GL_PROJECTION)
   glLoadIdentity_()
   glOrtho_(0, screenW, 0, screenH, -5.0, 5.0)
   
   glMatrixMode_(#GL_MODELVIEW)
   glLoadIdentity_()
   
   glEnable_(#GL_CULL_FACE)
   
   glPushAttrib_(#GL_DEPTH_BUFFER_BIT | #GL_LIGHTING_BIT);
   
   glDisable_(#GL_DEPTH_TEST)
   
   glDisable_(#GL_LIGHTING)
   
   glDisable_(#GL_BLEND)
EndProcedure
Procedure.i LoadTextureGL(image)
   ;// Generate 100 texture IDs (only one time)
   If ArraySize(glTextureIDs())=0
      ReDim glTextureIDs(100)
      glGenTextures_(ArraySize(glTextureIDs()), @glTextureIDs())
   EndIf
   Static glTextureID=0
   
   ;// Enable the texture rectangle extension
   glEnable_(#GL_TEXTURE_RECTANGLE_NV)
   
   ;// Bind the texture using #GL_TEXTURE_RECTANGLE_NV
   glTextureID + 1
   glBindTexture_(#GL_TEXTURE_RECTANGLE_NV, glTextureIDs(glTextureID))
   
   ;// Enable NEAREST filtering on this texture (for old school style)
   glTexParameteri_(#GL_TEXTURE_RECTANGLE_NV, #GL_TEXTURE_MIN_FILTER, #GL_NEAREST)
   glTexParameteri_(#GL_TEXTURE_RECTANGLE_NV, #GL_TEXTURE_MAG_FILTER, #GL_NEAREST)
   glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_WRAP_S, #GL_CLAMP_TO_EDGE);
   glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_WRAP_T, #GL_CLAMP_TO_EDGE);
   
   ;// Write the 32-bit RGBA texture buffer To video memory
   StartDrawing(ImageOutput(image))
   glTexImage2D_(#GL_TEXTURE_RECTANGLE_NV, 0, #GL_RGBA, ImageWidth(image), ImageHeight(image), 0, #GL_BGRA_EXT, #GL_UNSIGNED_BYTE, DrawingBuffer())
   StopDrawing()
   
   ProcedureReturn glTextureIDs(glTextureID)
EndProcedure
Procedure RenderGL()
   ;black background
   glClearColor_(Red(screenColor) / 255.0, Green(screenColor) / 255.0, Blue(screenColor) / 255.0, Alpha(screenColor) / 255.0)
   glClear_(#GL_COLOR_BUFFER_BIT)
   
   ;// Bind the texture To the polygons
   glBindTexture_(#GL_TEXTURE_RECTANGLE_NV, glSpriteTexture)
   
   ;// Set the primitive color To white
   glColor3f_(Red(tint) / 255.0, Green(tint) / 255.0, Blue(tint) / 255.0)
   
   ;// Rescale sprite _(optional)
   glScalef_(scaleX, scaleY, 0.0)
      
   ;// Blend the color key into oblivion! _(optional)
   glEnable_(#GL_BLEND)
   glBlendFunc_(#GL_SRC_ALPHA, #GL_ONE_MINUS_SRC_ALPHA)
   
   ;// Move everything on the right
   glTranslatef_(1, 0, 0)
   
   ;// Render a quad
   ;// Instead of the using _(s,t) coordinates, With the  #GL_NV_texture_rectangle
   ;// extension, you need To use the actual dimensions of the texture.
   ;// This makes using 2D sprites For games And emulators much easier now
   ;// that you won't have to convert :)   
   glBegin_(#GL_QUADS)
   glTexCoord2i_(0, 0) : glVertex2i_(0, 0)
   glTexCoord2i_(w, 0) : glVertex2i_(w, 0)
   glTexCoord2i_(w, h) : glVertex2i_(w, h)
   glTexCoord2i_(0, h) : glVertex2i_(0, h)
   glEnd_()
   
   SetGadgetAttribute(screenGL, #PB_OpenGL_FlipBuffers, #True)
EndProcedure
win=OpenWindow(#PB_Any, 0, 0, 800, 512, "OpenGL 2D Sprite", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
screenGL=OpenGLGadget(#PB_Any, 0, 0, WindowWidth(win), WindowHeight(win))
screenW=GadgetWidth(screenGL)
screenH=GadgetHeight(screenGL)
SetupGL(screenW, screenH)
;Create Image Texture (caution, size must be a power of 2: 16, 32, 64, 128, 256, 512, 1024, 2048 ...)
w=512 : h=512
image=CreateImage(#PB_Any, w, h, 32, RGB(150, 0, 0)) ; red background
If StartDrawing(ImageOutput(image))   
   FrontColor(RGB(0, 255, 255)) ; cyan plots
   Plot(0, 1)
   Plot(1, 0)
   Plot(OutputWidth()-1, OutputHeight()-1)
   Plot(OutputWidth()-2, OutputHeight()-2)
   Plot(OutputWidth()-3, OutputHeight()-3)
   StopDrawing()
   
   glSpriteTexture=LoadTextureGL(image)
EndIf
;Init and Start rendering (about 60 fps)
BindEvent(#PB_Event_Timer, @RenderGL())
AddWindowTimer(win, 1, 16)
Repeat: Until WaitWindowEvent()=#PB_Event_CloseWindow