OpenGLGadget - drawing sprite (perfect pixel)

Share your advanced PureBasic knowledge/code with the community.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

OpenGLGadget - drawing sprite (perfect pixel)

Post by eddy »

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
Last edited by eddy on Fri Jun 05, 2015 2:52 pm, edited 1 time in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by DK_PETER »

Sadly I find the gl_commands extremely tedious/daunting to work with.
But I do appreciate small examples like this.

Thanks Eddy.
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by em_uk »

This looks really interesting.

@eddy : would the be of any use to draw 2d graphics onto a gl rendered scene such as a pixel shader background? Like what what is in this thread : http://www.purebasic.fr/english/viewtop ... 36&t=62179

I did try and try to display on top of a shader drawn object but failed miserably!

:)
----

R Tape loading error, 0:1
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by eddy »

DK_PETER wrote:Sadly I find the gl_commands extremely tedious/daunting to work with.
But I do appreciate small examples like this.

Thanks Eddy.
What bothers me is that the code is already obsolete if I want to target OpenGl 4. :?
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by Samuel »

I tweaked your texture procedure a little.
You can use 24 or 32 bit images with it. Just make sure your image depth matches the ImageType.i you're sending to the procedure. Otherwise Opengl will look in the wrong place and you'll get a seriously messed up texture.

I also removed the array within the procedure. I prefer having the procedure just return the texture id and then I can store it into an array, structure, or whatever I need at the time.
Plus, it's a little safer in my eyes because you're not creating a bunch of texture names and then possibly not using all of them.

If you wish to use it then you'll need to add these constants at top of your code.

Code: Select all

#GL_BGR = $80E0
#GL_BGRA = $80E1
#IMG_Depth24 = 0
#IMG_Depth32 = 1
Altered load texture procedure.

Code: Select all

Procedure.i LoadTextureGL(ImageHandle.i, ImageType.i)
  
  Define.i ImageW, ImageH
  Define.i MemoryAddress
  Define.i glTextureID
  
  If IsImage(ImageHandle) = 0
    ProcedureReturn #False
  EndIf
  
  ImageW = ImageWidth(ImageHandle)
  ImageH = ImageHeight(ImageHandle)
  
  StartDrawing(ImageOutput(ImageHandle))
    MemoryAddress = DrawingBuffer()
  StopDrawing()
  
  If MemoryAddress = 0
    ProcedureReturn #False
  EndIf
  
  ;// Enable the texture rectangle extension
  glEnable_(#GL_TEXTURE_RECTANGLE_NV)
  
  glGenTextures_(1, @glTextureID)
  glBindTexture_(#GL_TEXTURE_RECTANGLE_NV, glTextureID)
  
  If ImageType = 1 ;32 bit images
    glTexImage2D_(#GL_TEXTURE_RECTANGLE_NV, 0, 4, ImageW, ImageH, 0, #GL_BGRA, #GL_UNSIGNED_BYTE, MemoryAddress)
  Else ;24 bit images
    glTexImage2D_(#GL_TEXTURE_RECTANGLE_NV, 0, 3, ImageW, ImageH, 0, #GL_BGR, #GL_UNSIGNED_BYTE, MemoryAddress)
  EndIf
    
  ;// 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)
    
  ProcedureReturn glTextureID
   
EndProcedure
eddy wrote: What bothers me is that the code is already obsolete if I want to target OpenGl 4. :?
Legacy OpenGL was made obsolete for good reasons though. :)
omnikam
User
User
Posts: 27
Joined: Sat Apr 15, 2017 10:58 am

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by omnikam »

Samuel wrote:I tweaked your texture procedure a little.
You can use 24 or 32 bit images with it. Just make sure your image depth matches the ImageType.i you're sending to the procedure. Otherwise Opengl will look in the wrong place and you'll get a seriously messed up texture.

I also removed the array within the procedure. I prefer having the procedure just return the texture id and then I can store it into an array, structure, or whatever I need at the time.
Plus, it's a little safer in my eyes because you're not creating a bunch of texture names and then possibly not using all of them.

If you wish to use it then you'll need to add these constants at top of your code.

Code: Select all

#GL_BGR = $80E0
#GL_BGRA = $80E1
#IMG_Depth24 = 0
#IMG_Depth32 = 1
Altered load texture procedure.

Code: Select all

Procedure.i LoadTextureGL(ImageHandle.i, ImageType.i)
  
  Define.i ImageW, ImageH
  Define.i MemoryAddress
  Define.i glTextureID
  
  If IsImage(ImageHandle) = 0
    ProcedureReturn #False
  EndIf
  
  ImageW = ImageWidth(ImageHandle)
  ImageH = ImageHeight(ImageHandle)
  
  StartDrawing(ImageOutput(ImageHandle))
    MemoryAddress = DrawingBuffer()
  StopDrawing()
  
  If MemoryAddress = 0
    ProcedureReturn #False
  EndIf
  
  ;// Enable the texture rectangle extension
  glEnable_(#GL_TEXTURE_RECTANGLE_NV)
  
  glGenTextures_(1, @glTextureID)
  glBindTexture_(#GL_TEXTURE_RECTANGLE_NV, glTextureID)
  
  If ImageType = 1 ;32 bit images
    glTexImage2D_(#GL_TEXTURE_RECTANGLE_NV, 0, 4, ImageW, ImageH, 0, #GL_BGRA, #GL_UNSIGNED_BYTE, MemoryAddress)
  Else ;24 bit images
    glTexImage2D_(#GL_TEXTURE_RECTANGLE_NV, 0, 3, ImageW, ImageH, 0, #GL_BGR, #GL_UNSIGNED_BYTE, MemoryAddress)
  EndIf
    
  ;// 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)
    
  ProcedureReturn glTextureID
   
EndProcedure


Sorry to reopen an old thread but i felt it more relevant to continue the discussion :D
How would i go about loading an image, such as a jpeg or png onto the OpenGlGadget?
Is there a way to convert the information(jpen/png) and send it to gltexture?
I only ask because i know not and want to learn, is it possible?

__________________________________________________
Quote tags repaired
26.04.2017
RSBasic
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by Samuel »

I found one of my old examples that might be of use to you. It shows how to create a texture from an image and then how to apply it to a 2D quad using legacy OpenGL.
To makes things easier I updated the SetupGLTexture procedure by removing the Image Type requirement. Now it just grabs the image depth and creates the texture accordingly. If you have any questions just ask.

Code: Select all

EnableExplicit

UsePNGImageDecoder()
UseJPEGImageDecoder()

;-CONSTANTS
Enumeration
  #MainWindow
  #OpenGLGadget
EndEnumeration

;These two GL constants are used for texture creation. Don't change their values.
#GL_BGR = $80E0
#GL_BGRA = $80E1


;-STRUCTURES
Structure Integer2
  X.i
  Y.i
EndStructure
Global.Integer2 WindowDim
WindowDim\X = 1024
WindowDim\Y = 720


;-GLOBALS
Global.i Image1, Image2
Global.i Texture1, Texture2

;-DEFINES
Define.i Event
Define.i WindowFlags = #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget


;-DECLARES
Declare Render()
Declare Render2DQuad(OGLTexture.i, StartX.d, StartY.d, Width.i, Height.i, Z.d)
Declare SetupOpenGL()
Declare SetupGLTexture(ImageHandle.i)


;-MAIN WINDOW
If OpenWindow(#MainWindow, 0, 0, WindowDim\X, WindowDim\Y, "OpenGL Example", WindowFlags)
  If OpenGLGadget(#OpenGLGadget, 0, 0, WindowDim\X, WindowDim\Y) = 0
    End
  EndIf
  
  ;This procedure sets up the rendering system to mimic the standard Purebasic drawing system.
  SetupOpenGL()
  
  ;Load images.
  Image1 = LoadImage(#PB_Any, #PB_Compiler_Home+"\Examples\3D\Data\Textures\ogrelogo-small.jpg")
  Image2 = LoadImage(#PB_Any, #PB_Compiler_Home+"\Examples\3D\Data\Textures\grass1.png")
  
  ;Now we create textures which can be used for rendering with OpenGL.
  Texture1 = SetupGLTexture(Image1)
  Texture2 = SetupGLTexture(Image2)
  
  ;-MAIN REPEAT
  Repeat
    Event = WaitWindowEvent()
    
    Render()
    SetGadgetAttribute(#OpenGLGadget, #PB_OpenGL_FlipBuffers, #True)

  Until Event = #PB_Event_CloseWindow
EndIf
End

Procedure Render()
  
  ;Clearing buffers and resetting clear color to remove old graphics from the last frame.
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glClearColor_(0.2, 0.2, 0.2, 1.0)
  
  ;## DRAWING TEXTURES/IMAGES
  ;First enable the Texture system.
  glEnable_(#GL_TEXTURE_2D)
  
  ;This procedure will create a quad and apply a texture to it.
  ;The Texture variable contains the texture created earlier using SetupGLTexture().
  Render2DQuad(Texture1, 0, 0, ImageWidth(Image1), ImageHeight(Image1), -2)
  Render2DQuad(Texture2, 0, 0, ImageWidth(Image2), ImageHeight(Image2), -1) 
  
  ;After all the textures have been displayed disable the texture system.
  ;Otherwise it will conflict with the non texture graphics.
  glDisable_(#GL_TEXTURE_2D)
  
EndProcedure

Procedure Render2DQuad(OGLTexture.i, StartX.d, StartY.d, Width.i, Height.i, Z.d)
  
  ;The texture is first bound which tells OpenGL to use this texture for any future rendering.
  glBindTexture_(#GL_TEXTURE_2D, OGLTexture)
  glBegin_(#GL_QUADS)
    glColor4f_   (1,1,1,1)
    glNormal3f_  (0,0,1.0)
    glTexCoord2f_(1.0,1.0)
    glVertex3f_  (StartX+Width,StartY,Z)
    glTexCoord2f_(0.0,1.0)
    glVertex3f_  (StartX,StartY,Z)
    glTexCoord2f_(0.0,0.0)
    glVertex3f_  (StartX,StartY+Height,Z)
    glTexCoord2f_(1.0,0.0)
    glVertex3f_  (StartX+Width,StartY+Height,Z)
  glEnd_()

EndProcedure

Procedure SetupOpenGL()
  
  glMatrixMode_(#GL_PROJECTION)

  glOrtho_(0.0, WindowDim\X, WindowDim\Y, 0.0, -1000.0, 1000.0)
  
  glMatrixMode_(#GL_MODELVIEW)
  
  glEnable_(#GL_DEPTH_TEST)
  
  glEnable_(#GL_BLEND)
  glBlendFunc_(#GL_SRC_ALPHA, #GL_ONE_MINUS_SRC_ALPHA)
	
EndProcedure

Procedure SetupGLTexture(ImageHandle.i)
  
  Define.i ImageW, ImageH, ImageD
  Define.i MemoryAddress
  Define.i TextureHandle

  If IsImage(ImageHandle) = 0
    ProcedureReturn #False
  EndIf
  
  ImageD = ImageDepth(ImageHandle, #PB_Image_InternalDepth)
  
  StartDrawing(ImageOutput(ImageHandle))
    MemoryAddress = DrawingBuffer()
  StopDrawing()
  
  If MemoryAddress = 0
    ProcedureReturn #False
  EndIf
  
  glGenTextures_(1, @TextureHandle)
  glBindTexture_(#GL_TEXTURE_2D, TextureHandle)
  
  ImageW = ImageWidth(ImageHandle)
  ImageH = ImageHeight(ImageHandle)
  
  If ImageD = 32
    glTexImage2D_(#GL_TEXTURE_2D, 0, 4, ImageW, ImageH, 0, #GL_BGRA, #GL_UNSIGNED_BYTE, MemoryAddress)
  Else
    glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageW, ImageH, 0, #GL_BGR, #GL_UNSIGNED_BYTE, MemoryAddress)
  EndIf
  
  glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
  glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
  
  ProcedureReturn TextureHandle
  
EndProcedure
omnikam
User
User
Posts: 27
Joined: Sat Apr 15, 2017 10:58 am

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by omnikam »

Samuel wrote:I found one of my old examples that might be of use to you. It shows how to create a texture from an image and then how to apply it to a 2D quad using legacy OpenGL.
To makes things easier I updated the SetupGLTexture procedure by removing the Image Type requirement. Now it just grabs the image depth and creates the texture accordingly. If you have any questions just ask.
Thank you, very detailed and informative :) i was considering using code suggested by applePi

Code: Select all

*Buffer(i) = EncodeImage(i)
glTexImage2D_(#GL_TEXTURE_2D,...., *Buffer(i)+57)
Could you perhaps tell me after looking at the following code if there is a way to use your method to create a quad with texture from a image to display on the OpenGLGadget in this code. Everything i try results in a termination
The code runs a GLSL shader in a OpenGLGadget, Im trying to render an image onto a small quad that will display in front of the shader
I didnt include my code because it was a mess, Would your image to glquad work in this instance, and if so, what would be involved in the pipeline?
I ask because i know not, but i want to learn :wink:
All credit goes to Pjay for posting his original work

Code: Select all

;/ GLSL example to test new OpenGLGadget - PJ 06/2014.

EnableExplicit

Enumeration ;/ Window
  #Window_Main
EndEnumeration
Enumeration ;/ Gadget
  #Gad_OpenGL
  #Gad_Editor
  #Gad_ShaderSelector_Combo
EndEnumeration

Structure System
  Width.i
  Height.i
  Shader_Width.i
  Shader_Height.i
  Event.i
  Exit.i
  MouseX.i
  MouseY.i
  
  App_CurrentTime.i
  App_StartTime.i
  Editor_LastText.s
  
  Shader_Vertex_Text.s
  Shader_Fragment_Text.s
  Shader_Vertex.i
  Shader_Fragment.i
  Shader_Program.i
  
  Shader_Uniform_Time.i
  Shader_Uniform_Resolution.i
  Shader_Uniform_Mouse.i
  Shader_Uniform_SurfacePosition.i
  
  FPS_Timer.i
  Frames.i
  FPS.i
EndStructure

Global System.System

Procedure Init_Main()
  Protected MyLoop.i
  
  System\Width.i = 1024
  System\Height = 480
  System\Shader_Width = 640
  System\Shader_Height = 480
  
  OpenWindow(#Window_Main,0,0,System\Width,System\Height,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  OpenGLGadget(#Gad_OpenGL,0,0,System\Shader_Width,System\Shader_Height,#PB_OpenGL_Keyboard)
  ComboBoxGadget(#Gad_ShaderSelector_Combo,System\Shader_Width+4,2,System\Width - (System\Shader_Width+8),24)
  For MyLoop = 1 To 1
    AddGadgetItem(#Gad_ShaderSelector_Combo,-1,"Shader: "+Str(MyLoop))
  Next
  
  SetGadgetState(#Gad_ShaderSelector_Combo,0)
  EditorGadget(#Gad_Editor,System\Shader_Width+4,30,System\Width - (System\Shader_Width+8),System\Height-30)
  
  System\App_StartTime = ElapsedMilliseconds()
  
  
  System\Shader_Vertex_Text = "attribute vec3 position;"
  System\Shader_Vertex_Text + "attribute vec2 surfacePosAttrib;"
  System\Shader_Vertex_Text + "varying vec2 surfacePosition;"
  System\Shader_Vertex_Text + "	void main() {"
  System\Shader_Vertex_Text + "		surfacePosition = surfacePosAttrib;"
  System\Shader_Vertex_Text + "		gl_Position = vec4( position, 1.0 );"
  System\Shader_Vertex_Text + "	}"
EndProcedure

Init_Main()

;{ Opengl shader setup & routines

#GL_VERTEX_SHADER = $8B31
#GL_FRAGMENT_SHADER = $8B30

Prototype glCreateShader(type.l)
Prototype glCreateProgram()
Prototype glCompileShader(shader.l)
Prototype glLinkProgram(shader.l)
Prototype glUseProgram(shader.l)
Prototype glAttachShader(Program.l, shader.l)
Prototype glShaderSource(shader.l, numOfStrings.l, *strings, *lenOfStrings) : 
Prototype.i glGetUniformLocation(Program.i, name.s)
Prototype glUniform1i(location.i, v0.i)
Prototype glUniform2i(location.i, v0.i, v1.i)
Prototype glUniform1f(location.i, v0.f)
Prototype glUniform2f(location.i, v0.f, v1.f)
Prototype glGetShaderInfoLog(shader.i, bufSize.l, *length_l, *infoLog)

Global glCreateShader.glCreateShader = wglGetProcAddress_("glCreateShader")
Global glCreateProgram.glCreateProgram = wglGetProcAddress_("glCreateProgram")
Global glCompileShader.glCompileShader = wglGetProcAddress_("glCompileShader")
Global glLinkProgram.glLinkProgram = wglGetProcAddress_("glLinkProgram")
Global glUseProgram.glUseProgram = wglGetProcAddress_("glUseProgram")
Global glAttachShader.glAttachShader = wglGetProcAddress_("glAttachShader")
Global glShaderSource.glShaderSource = wglGetProcAddress_("glShaderSource")
Global glGetUniformLocation.glGetUniformLocation = wglGetProcAddress_("glGetUniformLocation")
Global glUniform1i.glUniform1i = wglGetProcAddress_("glUniform1i")
Global glUniform2i.glUniform2i = wglGetProcAddress_("glUniform2i")
Global glUniform1f.glUniform1f = wglGetProcAddress_("glUniform1f")
Global glUniform2f.glUniform2f = wglGetProcAddress_("glUniform2f")
Global glGetShaderInfoLog.glGetShaderInfoLog = wglGetProcAddress_("glGetShaderInfoLog")

Procedure Shader_Compile_Link_Use(Vertex.s,Fragment.s,Use.i=1)
  Protected VertShader.i, FragShader.i, *TxtPointer, Program.i
  Protected Textlength.i, Mytext.s = Space(1024)
  
  ;/ Compile Vertex shader
  VertShader.i = glCreateShader(#GL_VERTEX_SHADER)
  *TxtPointer = @Vertex
  glShaderSource(VertShader, 1, @*TxtPointer, #Null)
  glCompileShader(VertShader)
  Debug "Vert: "+VertShader
  glGetShaderInfoLog(VertShader,1023,@Textlength,@Mytext)
  Debug MyText
  ;/ Compile Fragment Shader
  FragShader.i = glCreateShader(#GL_FRAGMENT_SHADER)
  *TxtPointer = @Fragment
  glShaderSource(FragShader, 1, @*TxtPointer, #Null)
  glCompileShader(FragShader)
  Debug "Frag: "+FragShader
  glGetShaderInfoLog(FragShader,1023,@Textlength,@Mytext)
  Debug MyText
  
  ;/ Create Shader Program
  Program = glCreateProgram()
  glAttachShader(Program,VertShader)
  Debug "Attached Vert Shader"
  glAttachShader(Program,FragShader)
  Debug "Attached Frag Shader"
  glLinkProgram(Program)
  Debug "Link program"
  
  If Use = 1
    glUseProgram(Program)
  EndIf
  
  ProcedureReturn Program  
EndProcedure
;}

Procedure Shader_Set(Fragment.i)
  If System\Shader_Program <> 0 ;/ delete the previous shaders
    glUseProgram(0);
  EndIf
  
  Select Fragment
    Case 0
      System\Shader_Fragment_Text = "uniform float time;"+Chr(10)
      System\Shader_Fragment_Text + "uniform vec2 resolution;"+Chr(10)
      System\Shader_Fragment_Text + ""+Chr(10)
      System\Shader_Fragment_Text + "void main( void ) {"+Chr(10)
      System\Shader_Fragment_Text + "	vec2 p = ( gl_FragCoord.xy / resolution.xy ) - 0.2;"+Chr(10)
      System\Shader_Fragment_Text + "	float sx = 0.3 * (p.x + 0.8) * sin( 3.0 * p.x - 1. * time);"+Chr(10)
      System\Shader_Fragment_Text + "	float dy = 4./ ( 123. * abs(p.y - sx));"+Chr(10)
      System\Shader_Fragment_Text + "	dy += 1./ (160. * length(p - vec2(p.x, 0.)));"+Chr(10)
      System\Shader_Fragment_Text + "	gl_FragColor = vec4( (p.x + 0.1) * dy, 0.3 * dy, dy, 2.1 );"+Chr(10)
      System\Shader_Fragment_Text + "}"+Chr(10)
     
  EndSelect
  
  System\Shader_Program = Shader_Compile_Link_Use(System\Shader_Vertex_Text,System\Shader_Fragment_Text)
  If System\Shader_Program = 0
    MessageRequester("Unsupported Device?","No Shader Support Available",#PB_MessageRequester_Ok)
    End
  EndIf
  
  ;/ store shader uniform locations
  Debug "Shader: "+System\Shader_Program
  System\Shader_Uniform_Time = glGetUniformLocation(System\Shader_Program, "time")
  System\Shader_Uniform_Mouse = glGetUniformLocation(System\Shader_Program, "mouse")
  System\Shader_Uniform_Resolution = glGetUniformLocation(System\Shader_Program, "resolution")
  System\Shader_Uniform_SurfacePosition.i = glGetUniformLocation(System\Shader_Program, "surfacePosition")
  Debug "Time location: "+System\Shader_Uniform_Time
  Debug "Mouse location: "+System\Shader_Uniform_Mouse
  Debug "Res location: "+System\Shader_Uniform_Resolution
  Debug "SurfacePos location: "+System\Shader_Uniform_SurfacePosition
  
  SetGadgetText(#Gad_Editor,System\Shader_Fragment_Text)
EndProcedure

Shader_Set(0)

Procedure Render()
  ;/ set shader Uniform values
  glUniform2f(System\Shader_Uniform_Resolution,System\Shader_Width,System\Shader_Height)
  glUniform1f(System\Shader_Uniform_Time,(System\App_CurrentTime-System\App_StartTime) / 1000.0)
  glUniform2i(System\Shader_Uniform_SurfacePosition.i,1.0,1.0)
  
  glBegin_(#GL_QUADS)
    glVertex2f_(-1,-1) 
    glVertex2f_( 1,-1) 
    glVertex2f_( 1, 1) 
    glVertex2f_(-1, 1) 
  glEnd_()           
  
  System\Frames + 1
  If System\App_CurrentTime > System\FPS_Timer
    System\FPS = System\Frames
    System\Frames = 0
    System\FPS_Timer = System\App_CurrentTime  + 1000
    SetWindowTitle(#Window_Main,"GLSL Testing - PJ 07/06/2014 - FPS: "+Str(System\FPS))
  EndIf
  
  SetGadgetAttribute(#Gad_OpenGL,#PB_OpenGL_FlipBuffers,1)
  
EndProcedure
Repeat
  Repeat
    System\Event = WindowEvent()
    Select System\Event
      Case #PB_Event_CloseWindow
        System\Exit = #True
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #Gad_ShaderSelector_Combo
            Select EventType()
              Case #PB_EventType_Change
                Debug "Set to: "+GetGadgetState(#Gad_ShaderSelector_Combo)
                Shader_Set(GetGadgetState(#Gad_ShaderSelector_Combo))
            EndSelect
          Case #Gad_OpenGL
            Select EventType()
              Case #PB_EventType_MouseMove
                System\MouseX = GetGadgetAttribute(#Gad_OpenGL,#PB_OpenGL_MouseX)
                System\MouseY = GetGadgetAttribute(#Gad_OpenGL,#PB_OpenGL_MouseY)
                glUniform2f(System\Shader_Uniform_Mouse,System\MouseX / System\Shader_Width,(System\Shader_Height-System\MouseY) / System\Shader_Height)
            EndSelect
        EndSelect
    EndSelect
    
  Until System\Event = 0
  
  System\App_CurrentTime = ElapsedMilliseconds()
  
  Render()
  
Until System\Exit 

Last edited by omnikam on Sun Apr 16, 2017 10:34 pm, edited 1 time in total.
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by walbus »

Very interesting demo code
But, primary, i self think, for mostly basic like simple using to complicated, to raw.

I mean herewith, only one needed code line for output a sprite an a target, is optimal
omnikam
User
User
Posts: 27
Joined: Sat Apr 15, 2017 10:58 am

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by omnikam »

walbus wrote:Very interesting demo code
But, primary, i self think, for mostly basic like simple using to complicated, to raw.

I mean herewith, only one needed code line for output a sprite an a target, is optimal
Sorry the code i posted was not complete, ive added the missing code, so now it will compile and run, but you must turn off make unicode exe in the compiler options
A normal sprite wont render to openglgadgrt, in this instant, im looking at creating a small quad in the Active gadget and using method mentioned above to texture a image to the quad, the image must appear in front of the shader, perhaps opening a second openglgadget will do?
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by Samuel »

Maybe an example like this will help a little bit more? It shows how you can render textured quads on top of your shader.
I also changed your compile procedure a bit. This new one supports Unicode and ASCII and it will also free up the unneeded shader resources after creating the shader program.

Code: Select all

EnableExplicit

UsePNGImageDecoder()
UseJPEGImageDecoder()

Enumeration ;/ Window
  #Window_Main
EndEnumeration
Enumeration ;/ Gadget
  #Gad_OpenGL
  #Gad_Editor
  #Gad_ShaderSelector_Combo
EndEnumeration

Structure System
  Width.i
  Height.i
  Shader_Width.i
  Shader_Height.i
  Event.i
  Exit.i
  MouseX.i
  MouseY.i
  
  App_CurrentTime.i
  App_StartTime.i
  Editor_LastText.s
  
  Shader_Vertex_Text.s
  Shader_Fragment_Text.s
  Shader_Vertex.i
  Shader_Fragment.i
  Shader_Program.i
  
  Shader_Uniform_Time.i
  Shader_Uniform_Resolution.i
  Shader_Uniform_Mouse.i
  Shader_Uniform_SurfacePosition.i
  
  FPS_Timer.i
  Frames.i
  FPS.i
EndStructure

Global System.System

#GL_VERTEX_SHADER = $8B31
#GL_FRAGMENT_SHADER = $8B30

#GL_BGR = $80E0
#GL_BGRA = $80E1

Prototype glCreateShader(type.l)
Prototype glCreateProgram()
Prototype glCompileShader(shader.l)
Prototype glDeleteShader(ShaderObj.i)
Prototype glLinkProgram(shader.l)
Prototype glUseProgram(shader.l)
Prototype glAttachShader(Program.l, shader.l)
Prototype glShaderSource(shader.l, numOfStrings.l, *strings, *lenOfStrings) : 
Prototype glGetUniformLocation(Program.i, name.s)
Prototype glUniform1i(location.i, v0.i)
Prototype glUniform2i(location.i, v0.i, v1.i)
Prototype glUniform1f(location.i, v0.f)
Prototype glUniform2f(location.i, v0.f, v1.f)
Prototype glGetShaderInfoLog(shader.i, bufSize.l, *length_l, *infoLog)

System\Width  = 1024
System\Height = 480
System\Shader_Width = 640
System\Shader_Height = 480

Declare CompileShader(VertexShader.s, FragmentShader.s)
Declare FreeShaderSourceBuf(*p)
Declare GetShaderSourceBuf(*shader)
Declare Render()
Declare Render2DQuad(OGLTexture.i, StartX.d, StartY.d, Width.i, Height.i, Z.d)
Declare SetupGLTexture(ImageHandle.i)
Declare SetupOpenGL()

Define.i CTR
Define.i Event

Global.i Image1, Image2
Global.i Texture1, Texture2

;-MAIN WINDOW
OpenWindow(#Window_Main,0,0,System\Width,System\Height,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
OpenGLGadget(#Gad_OpenGL,0,0,System\Shader_Width,System\Shader_Height,#PB_OpenGL_Keyboard)
ComboBoxGadget(#Gad_ShaderSelector_Combo,System\Shader_Width+4,2,System\Width - (System\Shader_Width+8),24)
For CTR = 1 To 1
  AddGadgetItem(#Gad_ShaderSelector_Combo,-1,"Shader: "+Str(CTR))
Next

SetGadgetState(#Gad_ShaderSelector_Combo,0)
EditorGadget(#Gad_Editor,System\Shader_Width+4,30,System\Width - (System\Shader_Width+8),System\Height-30)

SetupOpenGL()

;Load images.
Image1 = LoadImage(#PB_Any, #PB_Compiler_Home+"Examples\3D\Data\Textures\ogrelogo-small.jpg")
Image2 = LoadImage(#PB_Any, #PB_Compiler_Home+"Examples\3D\Data\Textures\grass1.png")

;Now we create textures which can be used for rendering with OpenGL.
Texture1 = SetupGLTexture(Image1)
Texture2 = SetupGLTexture(Image2)

;Get OpenGL functions
Global glCreateShader.glCreateShader = wglGetProcAddress_("glCreateShader")
Global glCreateProgram.glCreateProgram = wglGetProcAddress_("glCreateProgram")
Global glCompileShader.glCompileShader = wglGetProcAddress_("glCompileShader")
Global glDeleteShader.glDeleteShader = wglGetProcAddress_("glDeleteShader")
Global glLinkProgram.glLinkProgram = wglGetProcAddress_("glLinkProgram")
Global glUseProgram.glUseProgram = wglGetProcAddress_("glUseProgram")
Global glAttachShader.glAttachShader = wglGetProcAddress_("glAttachShader")
Global glShaderSource.glShaderSource = wglGetProcAddress_("glShaderSource")
Global glGetUniformLocation.glGetUniformLocation = wglGetProcAddress_("glGetUniformLocation")
Global glUniform1i.glUniform1i = wglGetProcAddress_("glUniform1i")
Global glUniform2i.glUniform2i = wglGetProcAddress_("glUniform2i")
Global glUniform1f.glUniform1f = wglGetProcAddress_("glUniform1f")
Global glUniform2f.glUniform2f = wglGetProcAddress_("glUniform2f")
Global glGetShaderInfoLog.glGetShaderInfoLog = wglGetProcAddress_("glGetShaderInfoLog")

;Store the shaders within string variables.
System\Shader_Vertex_Text = "attribute vec3 position;"+Chr(10)+
                            "attribute vec2 surfacePosAttrib;"+Chr(10)+
                            "varying vec2 surfacePosition;"+Chr(10)+
                            "void main() {"+Chr(10)+
                            "    surfacePosition = surfacePosAttrib;"+Chr(10)+
                            "    gl_Position = vec4( position, 1.0 );"+Chr(10)+
                            "}"

System\Shader_Fragment_Text = "uniform float time;"+Chr(10)+
                              "uniform vec2 resolution;"+Chr(10)+
                              "void main( void ) {"+Chr(10)+
                              "    vec2 p = ( gl_FragCoord.xy / resolution.xy ) - 0.2;"+Chr(10)+
                              "    float sx = 0.3 * (p.x + 0.8) * sin( 3.0 * p.x - 1. * time);"+Chr(10)+
                              "    float dy = 4./ ( 123. * abs(p.y - sx));"+Chr(10)+
                              "    dy += 1./ (160. * length(p - vec2(p.x, 0.)));"+Chr(10)+
                              "    gl_FragColor = vec4( (p.x + 0.1) * dy, 0.3 * dy, dy, 2.1 );"+Chr(10)+
                              "}"

;Setup system data
With System
  \Shader_Program = CompileShader(\Shader_Vertex_Text, \Shader_Fragment_Text)
  glUseProgram(\Shader_Program)  
  
  If System\Shader_Program = 0
    MessageRequester("Unsupported Device?","No Shader Support Available",#PB_MessageRequester_Ok)
    End
  EndIf
  
  \App_StartTime = ElapsedMilliseconds()
  
  ;/ store shader uniform locations
  Debug "Shader: "+\Shader_Program
  \Shader_Uniform_Time = glGetUniformLocation(\Shader_Program, "time")
  \Shader_Uniform_Mouse = glGetUniformLocation(\Shader_Program, "mouse")
  ;resolution is blacking out the shader not really sure why.
  ;\Shader_Uniform_Resolution = glGetUniformLocation(\Shader_Program, "resolution")
  \Shader_Uniform_SurfacePosition = glGetUniformLocation(\Shader_Program, "surfacePosition")
  Debug "Time location: "+\Shader_Uniform_Time
  Debug "Mouse location: "+\Shader_Uniform_Mouse
  Debug "Res location: "+\Shader_Uniform_Resolution
  Debug "SurfacePos location: "+\Shader_Uniform_SurfacePosition
  
  SetGadgetText(#Gad_Editor,\Shader_Fragment_Text)
EndWith

;-MAIN REPEAT
Repeat
  
  Event = WindowEvent()
  
  System\MouseX = WindowMouseX(#Window_Main)
  System\MouseY = WindowMouseY(#Window_Main)
  
  System\App_CurrentTime = ElapsedMilliseconds()
  Render()
  
Until Event = #PB_Event_CloseWindow
End

Procedure CompileShader(VertexShader.s, FragmentShader.s)
  
  Define.i shader_program
  Define.i vs, fs
  Define.i *vbuff, *fbuff
  
  *vbuff = GetShaderSourceBuf(@VertexShader)
  *fbuff = GetShaderSourceBuf(@FragmentShader)
  
  vs = glCreateShader(#GL_VERTEX_SHADER)
  glShaderSource(vs, 1, @*vbuff, #Null)
  glCompileShader(vs)
  
  fs = glCreateShader(#GL_FRAGMENT_SHADER)
  glShaderSource(fs, 1, @*fbuff, #Null)
  glCompileShader(fs)   
  
  shader_program = glCreateProgram()
  glAttachShader(shader_program, fs)
  glDeleteShader(fs)
  glAttachShader(shader_program, vs)
  glDeleteShader(vs)
  glLinkProgram(shader_program)

  FreeShaderSourceBuf(*vbuff)
  FreeShaderSourceBuf(*fbuff)
  
  ProcedureReturn shader_program
  
EndProcedure

Procedure FreeShaderSourceBuf(*p)
  
  CompilerIf #PB_Compiler_Unicode   
    If *p
      FreeMemory(*p)
    EndIf
  CompilerEndIf
  
EndProcedure

Procedure GetShaderSourceBuf(*shader)
  
  Protected *p, l, t$
 
  CompilerIf #PB_Compiler_Unicode
    
    t$ = PeekS(*shader, -1) : l = Len(t$)
    *p = AllocateMemory(l + SizeOf(Character))
    If *p
      PokeS(*p, t$, l, #PB_Ascii)
    EndIf
    
  CompilerElse 
    
    *p = *shader
    
  CompilerEndIf

  ProcedureReturn *p

EndProcedure

Procedure Render()
  
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glClearColor_(0.2, 0.2, 0.2, 1.0)
  
  glUseProgram(System\Shader_Program)
  ;/ set shader Uniform values
  glUniform2f(System\Shader_Uniform_Resolution,System\Shader_Width,System\Shader_Height)
  glUniform1f(System\Shader_Uniform_Time,(System\App_CurrentTime-System\App_StartTime)/1000)
  glUniform2i(System\Shader_Uniform_SurfacePosition,System\MouseX,System\MouseY)
  
  glBegin_(#GL_QUADS) 
    glVertex3f_(-1,-1,0) 
    glVertex3f_( 1,-1,0) 
    glVertex3f_( 1, 1,0) 
    glVertex3f_(-1, 1,0) 
  glEnd_()           
  glUseProgram(0)
  
  ;## DRAWING TEXTURES/IMAGES
  ;First enable the Texture system.
  glEnable_(#GL_TEXTURE_2D)
  
  ;This procedure will create a quad and apply a texture to it.
  ;The Texture variable contains the texture created earlier using SetupGLTexture().
  Render2DQuad(Texture1, 0, 0, ImageWidth(Image1), ImageHeight(Image1), 1)
  Render2DQuad(Texture2, 0, 0, ImageWidth(Image2), ImageHeight(Image2), 2) 
  
  ;After all the textures have been displayed disable the texture system.
  ;Otherwise it will conflict with the non texture graphics.
  glDisable_(#GL_TEXTURE_2D)
  
  System\Frames + 1
  If System\App_CurrentTime > System\FPS_Timer
    System\FPS = System\Frames
    System\Frames = 0
    System\FPS_Timer = System\App_CurrentTime  + 1000
    SetWindowTitle(#Window_Main,"GLSL Testing - PJ 07/06/2014 - FPS: "+Str(System\FPS))
  EndIf
  
  SetGadgetAttribute(#Gad_OpenGL, #PB_OpenGL_FlipBuffers, #True)
  
EndProcedure

Procedure Render2DQuad(OGLTexture.i, StartX.d, StartY.d, Width.i, Height.i, Z.d)
  
  ;The texture is first bound which tells OpenGL to use this texture for any future rendering.
  glBindTexture_(#GL_TEXTURE_2D, OGLTexture)
  glBegin_(#GL_QUADS)
    glColor4f_   (1,1,1,1)
    glNormal3f_  (0,0,1.0)
    glTexCoord2f_(1.0,1.0)
    glVertex3f_  (StartX+Width,StartY,Z)
    glTexCoord2f_(0.0,1.0)
    glVertex3f_  (StartX,StartY,Z)
    glTexCoord2f_(0.0,0.0)
    glVertex3f_  (StartX,StartY+Height,Z)
    glTexCoord2f_(1.0,0.0)
    glVertex3f_  (StartX+Width,StartY+Height,Z)
  glEnd_()

EndProcedure

Procedure SetupGLTexture(ImageHandle.i)
  
  Define.i ImageW, ImageH, ImageD
  Define.i MemoryAddress
  Define.i TextureHandle

  If IsImage(ImageHandle) = 0
    ProcedureReturn #False
  EndIf
  
  ImageD = ImageDepth(ImageHandle, #PB_Image_InternalDepth)
  
  StartDrawing(ImageOutput(ImageHandle))
    MemoryAddress = DrawingBuffer()
  StopDrawing()
  
  If MemoryAddress = 0
    ProcedureReturn #False
  EndIf
  
  glGenTextures_(1, @TextureHandle)
  glBindTexture_(#GL_TEXTURE_2D, TextureHandle)
  
  ImageW = ImageWidth(ImageHandle)
  ImageH = ImageHeight(ImageHandle)
  
  If ImageD = 32
    glTexImage2D_(#GL_TEXTURE_2D, 0, 4, ImageW, ImageH, 0, #GL_BGRA, #GL_UNSIGNED_BYTE, MemoryAddress)
  Else
    glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageW, ImageH, 0, #GL_BGR, #GL_UNSIGNED_BYTE, MemoryAddress)
  EndIf
  
  glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
  glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
  
  ProcedureReturn TextureHandle
  
EndProcedure

Procedure SetupOpenGL()
  
  glMatrixMode_(#GL_PROJECTION)

  glOrtho_(0.0, System\Shader_Width, System\Shader_Height, 0.0, -1000.0, 1000.0)
  
  glMatrixMode_(#GL_MODELVIEW)
  
  glEnable_(#GL_DEPTH_TEST)
  
  glEnable_(#GL_BLEND)
  glBlendFunc_(#GL_SRC_ALPHA, #GL_ONE_MINUS_SRC_ALPHA)
	
EndProcedure
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by walbus »

Very nice !
omnikam
User
User
Posts: 27
Joined: Sat Apr 15, 2017 10:58 am

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by omnikam »

Samuel :lol: :D :mrgreen: You are a Pure Genius, Lovely work to study, thank you
ps. i did notice that the shader will only animate if the compiler option turns off make unicode exe
omnikam
User
User
Posts: 27
Joined: Sat Apr 15, 2017 10:58 am

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by omnikam »

Samuel wrote:Maybe an example like this will help a little bit more? It shows how you can render textured quads on top of your shader.
I also changed your compile procedure a bit. This new one supports Unicode and ASCII and it will also free up the unneeded shader resources after creating the shader program.
Another question, Im tying to do away with

Code: Select all

Image2 =  LoadImage (#PB_Any, #PB_Compiler_Home+"Examples\pacelogo2fpl6y.png")
and instead use

Code: Select all

DataSection
    Logo:
    IncludeBinary "pacelogo2fpl6y.png"
  EndDataSection 
So i changed the loadimage to

Code: Select all

CatchImage(0, ?Logo)

    Image2 = ?Logo         
Unfortunately im getting an error on this line

Code: Select all

 Render2DQuad(Texture2, 150, 90, ImageWidth(Image2), ImageHeight(Image2), 2)

[00:23:30] [ERROR] The specified #Image is not initialised.
[00:23:33] The Program was killed.

Not sure as to why?
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: OpenGLGadget - drawing sprite (perfect pixel)

Post by Samuel »

This works for me.

Code: Select all

Image2 = CatchImage(#PB_Any, ?Logo)
The number you were using to identify your image was 0, but then you were storing the data label instead of the image identifier. I use #PB_Any because it will return an auto generated number that is not already in use.

This code should work as well, but it's one extra line of work.

Code: Select all

CatchImage(0, ?Logo)
Image2 = 0
If you still can't get it to work. Then maybe your image path is incorrect because of wrong default directory.
Post Reply