After Discovering the beautiful world of GLSL shaders`s i wanted to be able to render Gfx on top of it, A nice logo for example? Thus began the quest, and after what seemed like forever i achieved my goal
This Project has evolved a lot and so ive updated the scope to include a scroller.
I learned so much on this project, pushed by inc to work out solution`s to problems i have grown in confidence.
Credit to Pjay for his original GLSL shader compiler and Samual from purebasic forum for his excellent image to Gltexture procedure and enhancement to Pjay`s code
The goal of this project was not to use other people's shaders in my demo's, the goal was how to incorporate textured logo's while using glsl shaders, this later expanded to a scroller, my intentions is to leave code that will help other's trying to combine shaders with textured quads. It must be added that the scroller was pulled straight out of pjays Vroom remake
The attachment contains everything needed to compile, Just 2 warnings
You must disable make unicode exe from compile options
You will need PureBasic 5,44 or 5.40 tested it on latest 5.60, but it wont work
; deactivate Create Unicode Executable in Compiler
;EnableExplicit
#WindowWidth=640 : #WindowHeight = 240 : #TopBorder = 18 : #BottomBorder = 18 : #ActualWindowHeight = 240*2
InitSound()
CatchMusic(1,?music,?musend-?music); Get our Music
MusicVolume(1,10);
UsePNGImageDecoder()
Enumeration ;/ Window
#Window_Main
EndEnumeration
Enumeration ;/ Gadget
#Gad_OpenGL
EndEnumeration
Structure System
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
fragtext.s
EndStructure
Global System.System
Structure Scrolltext
Letter_Texture_Pos.f
Letter_Texture_Posy.f
X.l
EndStructure
Structure Copper
length.l
r.c[1000]
g.c[1000]
b.c[1000]
RGB.i[1000]
EndStructure
;
Procedure test() ;Load our fragment shader from our included binardy text file
System\fragtext = PeekS(? Nurbs)
EndProcedure
#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)
Declare CompileShader(VertexShader.s, FragmentShader.s)
Declare FreeShaderSourceBuf(*p)
Declare GetShaderSourceBuf(*shader)
Declare Render()
Declare SetupOpenGL()
Declare SetupGLTexture(ImageHandle.i); test
Define.i CTR
Define.i Event
Global.i Image1
Global.i Texture1
Global.i font
Global.i Texture
Global Quit.i, DrawnFrames.i, Offset.f, Font_Lookup_Text.S, MyLoop.i, Copper1.Copper, Max_Balls = 100, BallSpeed.f=0.04
Global ST_Base1.f,ST_Base2.f, ST_Next.i, ST_FontWidth.w = 30, ST_Texture_Width.f = 0.0625, ST_Font_Gap.w = 2, ST_Text.S, ST_Position.i, ST_Delay_Scroller.i, Pages.i = 6
Global Colours.i, Page.i, Current_Page.i = 1, Current_Letter.i, Page_Swap_Duration.i = 280, Page_Swap_Time.i = 200, Current_Line.i, Current_Letter.i, PT_Delay.i=1, PT_Update.i
Global Dim MiniText.s(Pages,3,40), Dim Text_Page.s(3,40), NewList Scrolltext.Scrolltext()
Global Font_Lookup_Text.S = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.!:,'?-£$/[]+ "
Global ST_Text = " AFTER MANY MANY DAYS OF TRIAL AND ERROR EVERYTHING IS WORKING ILL LEAVE IT TO OTHERS TO FINE TUNE APPHA BLENDING WAS A PROBLEM BUT I WORKED IT OUT CASE CLOSED"
Define.i EveryOther, Event.i, SoundAvailable.i
;Now we create textures which can be used for rendering with OpenGL.
;{ Window, OpenGL + other bits setup
OpenWindow(#Window_Main, 0, 0, #WindowWidth, #ActualWindowHeight,"test",#PB_Window_ScreenCentered|#PB_Window_BorderLess)
OpenGLGadget(0, 0, 0,WindowWidth(0),WindowHeight(0),#PB_OpenGL_Keyboard|#PB_OpenGL_FlipSynchronization|#PB_OpenGL_8BitStencilBuffer|#PB_Window_BorderLess)
SetGadgetAttribute(#Gad_OpenGL,#PB_OpenGL_Cursor,#PB_Cursor_Invisible)
SetWindowPos_(WindowID(0),#HWND_TOPMOST,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE)
;
glEnable_(#GL_BLEND) : glBlendFunc_(#GL_SRC_ALPHA, #GL_ONE_MINUS_SRC_ALPHA);
glDepthMask_(#GL_FALSE) : glDisable_(#GL_DEPTH_TEST)
glEnable_(#GL_CULL_FACE) : glCullFace_(#GL_BACK)
glMatrixMode_(#GL_PROJECTION): glLoadIdentity_()
glDisable_(#GL_LIGHTING)
glOrtho_(0, #WindowWidth-1, 0, #WindowHeight-1, 0, 1)
;/ read copperlist
Restore Copperlist: ;copd:
Read.w Copper1\length
For MyLoop=1 To Copper1\length
Read.B Copper1\r[MyLoop] : Read.B Copper1\g[MyLoop] : Read.B Copper1\b[MyLoop]
Copper1\r[MyLoop] * 15 : Copper1\r[MyLoop] * 1.133
Copper1\g[MyLoop] * 15 : Copper1\g[MyLoop] * 1.133
Copper1\b[MyLoop] * 15 : Copper1\b[MyLoop] * 1.133
Next
ShowCursor_(0)
test(): ;Fragment shader text
PlayMusic(1)
;}
;THIS IS FOR OUR LOGO ONLY; USES A DIFFERENT PROCEDURE TO THE SCROLLER TEXTURE
;Load images
Image1 = CatchImage(#PB_Any, ?MyLogo)
;Now we create textures which can be used For rendering With OpenGL.
Texture1 = SetupGLTexture(Image1)
;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)+
; "gl_TexCoord[0] = gl_MultiTexCoord0; );"+Chr(10)+
"}"
System\Shader_Fragment_Text = System\fragtext;"uniform float time;"+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
EndWith
Procedure SmallFontText() ;/ updates the draws the top ticker-text
Protected X.i, Y.i, SmT_YSize.i = 9, Smt_Ypos.i, Letter.s, Lup.l, txPos.f, txPosY.f, ST_Xpos.f, ST_Width.i
If DrawnFrames > Page_Swap_Time
;/ swap between the two pages
PT_Update-1
If PT_Update < 1
Current_Letter+1
If Current_Letter = 41 : Current_Letter = 0 : : Current_Line + 1 : EndIf
If Current_Line < 4
Text_Page.S(Current_Line,Current_Letter) = MiniText(Current_Page,Current_Line,Current_Letter)
EndIf
If Current_Line = 4 : Current_Line = 0 : Page_Swap_Time = DrawnFrames + Page_Swap_Duration : Current_Page + 1 : EndIf
If Current_Page > Pages : Current_Page = 1 : EndIf
PT_Update = PT_Delay
PT_Delay + 1
If PT_Delay = 3 : PT_Delay = 1 : EndIf
EndIf
EndIf
;/ render
glEnable_(#GL_TEXTURE_2D) : glBindTexture_(#GL_TEXTURE_2D,Smallfont)
glBegin_(#GL_QUADS)
glColor4f_(1.0,1.0,1.0,1.0)
For Y=0 To 3
For X=1 To 40
Smt_Ypos = 201-(Y*(SmT_YSize))
Letter.s = Text_Page(Y,X)
If Letter <> "" And Letter <> " "
Lup.l = FindString("ABCDEFGHIJKLMNOPQRSTUVWXYZ!0123456789'()@,.-:;<>?ccccccccccccccccccc ",Letter.s,0)-1
txPos.f = (Lup*8)/256.0
ST_Xpos = ((X-1)*16)+0 : ST_Width = 15
txPosY.f = 0
If txPos.f > 1-0.03125
txPosY.f = 0.03124
txPos - 1
EndIf
glTexCoord2f_(txPos,txPosY+0) :glVertex2i_(ST_Xpos,Smt_Ypos+SmT_YSize-1)
glTexCoord2f_(txPos,txPosY+0.027343) :glVertex2i_(ST_Xpos,Smt_Ypos)
glTexCoord2f_(txPos+0.027343,txPosY+0.027343) :glVertex2i_(ST_Xpos+ST_Width,Smt_Ypos)
glTexCoord2f_(txPos+0.027343,txPosY+0) :glVertex2i_(ST_Xpos+ST_Width,Smt_Ypos+SmT_YSize-1)
EndIf
Next
Next
glEnd_()
EndProcedure
;Texture Procedure for Logo, Could have done away with the other but it would have taken time, plus this procedure requies fliping the image
;and i didnt want to have to rewrite the scroller texture handler
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
;/ *** Texture loading / processing Font textueing
Procedure LoadTexture_(Texture.i) ; Returns the texture for an OpenGL application
Protected Width.i, Height.i, NWidth.i, NHeight.i, X.i, Y.i, Colour.i, I.i, R.i, G.i, B.i, Tex.i
If Texture = 0 : CatchImage(1, ?Bigtext) : EndIf
If Texture = 3 : CatchImage(1, ?Smallfont): EndIf
Width = ImageWidth(1)
Height = ImageHeight(1)
NWidth = Width : NHeight = Height
If NWidth > NHeight : NHeight = NWidth : EndIf ;/ had to force equal width / height due to compatability issues
If NHeight > NWidth : NWidth = NHeight : EndIf ;/
Dim ImageData.c(NWidth * NHeight * 4)
ImageD = ImageDepth(Texture, #PB_Image_InternalDepth)
StartDrawing(ImageOutput(1))
For Y=0 To NHeight-1
For X=0 To NWidth-1
If Y>Height-1 Or X>Width
Colour = 0 ;/ speeds up loading
Else
Colour = Point(X,Y)
r=Red(Colour) : g=Green(Colour) : b=Blue(Colour)
ImageData(i)=b : i+1
ImageData(i)=g : i+1
ImageData(i)=r : i+1
ImageData(i)= 255
EndIf
If r<15 And g<15 And b<15 : ImageData(i)=0 : EndIf
i+1
Next
Next
StopDrawing()
glGenTextures_(1, @tex.i)
glBindTexture_(#GL_TEXTURE_2D, tex)
If ImageD = 32
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
Else
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_NEAREST)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_NEAREST)
glTexParameteri_(#GL_TEXTURE_2D,#GL_TEXTURE_WRAP_S, #GL_CLAMP)
glTexParameteri_(#GL_TEXTURE_2D,#GL_TEXTURE_WRAP_T, #GL_CLAMP)
EndIf
If ImageD = 32
glTexImage2D_(#GL_TEXTURE_2D, 0,4 , NWidth, NHeight, 0, #GL_BGRA, #GL_UNSIGNED_BYTE, @ImageData());
Else
glTexImage2D_(#GL_TEXTURE_2D, 0, #GL_RGBA, NWidth, NHeight, 0, #GL_BGRA_EXT, #GL_UNSIGNED_BYTE, @ImageData());
EndIf
FreeImage(1)
Dim ImageData(0)
ProcedureReturn tex
EndProcedure
Procedure CopperTexture_() ; Returns the OpenGL texture
Protected Height.i, X.i, Y.i, I.i, Tex.i
Height = Copper1\length
Dim ImageData.c(Height*Height*4)
For Y=1 To Height
For X=1 To Height
ImageData(i)=Copper1\b[Y] : i+1
ImageData(i)=Copper1\g[Y] : i+1
ImageData(i)=Copper1\r[Y] : i+1
ImageData(i)=255 : i+1
Next
Next
glGenTextures_(1, @tex)
glBindTexture_(#GL_TEXTURE_2D, tex)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_NEAREST)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_NEAREST)
glTexParameteri_(#GL_TEXTURE_2D,#GL_TEXTURE_WRAP_S, #GL_CLAMP)
glTexParameteri_(#GL_TEXTURE_2D,#GL_TEXTURE_WRAP_T, #GL_CLAMP)
glTexImage2D_(#GL_TEXTURE_2D, 0, #GL_RGBA, Height, Height, 0, #GL_BGRA_EXT, #GL_UNSIGNED_BYTE, @ImageData());
Dim ImageData(0)
ProcedureReturn tex
EndProcedure
Global MyTexture.i = LoadTexture_(0), Smallfont.i = LoadTexture_(3), CopperTexture.i = CopperTexture_()
Procedure Rainbow_Copper() ;/ draws the rainbow texture over the stencil mask
glEnable_(#GL_TEXTURE_2D) : glBindTexture_(#GL_TEXTURE_2D,CopperTexture)
glBegin_(#GL_QUADS)
glColor4f_(1.0,1.0,1.0,1.0)
glTexCoord2f_(0,0) :glVertex2i_(0,171)
glTexCoord2f_(0,0.45) :glVertex2i_(0,41)
glTexCoord2f_(1,0.45) :glVertex2i_(#WindowWidth,41)
glTexCoord2f_(1,0) :glVertex2i_(#WindowWidth,171)
glEnd_()
glDisable_(#GL_STENCIL_TEST)
EndProcedure
Procedure Draw_ScrollText() ;/ updates and draws the scrolltext on to the stencil buffer
Protected letter$, Mult.i, YPos.i, YSize.i, Timmy.f, X.i, tY.f, TopM.f, BotM.f, HySize.f
glEnable_(#GL_BLEND) : glBlendFunc_(#GL_SRC_ALPHA, #GL_ONE_MINUS_SRC_ALPHA);
glColorMask_(#GL_FALSE, #GL_FALSE, #GL_FALSE, #GL_FALSE);
glDepthMask_(#GL_TRUE);
glEnable_(#GL_STENCIL_TEST);
glStencilFunc_(#GL_ALWAYS, 1, $FFFFFFFF);
glStencilOp_(#GL_REPLACE, #GL_REPLACE, #GL_REPLACE);
glEnable_(#GL_ALPHA_TEST)
glAlphaFunc_(#GL_GREATER ,0.0)
;/ update
If ST_Delay_Scroller = 0
ForEach ScrollText()
scrolltext()\X - 2
If scrolltext()\X < -ST_FontWidth : DeleteElement(scrolltext()) : EndIf
Next
If DrawnFrames >= ST_Next; And ST_Delay_Scroller = 0
ST_Position + 1 : If ST_Position > Len(ST_Text) : ST_Position = 0 : EndIf
letter$ = Mid(ST_Text,ST_Position,1)
If letter$ = "|" : ST_Delay_Scroller = 100 : ST_Next + 100: letter$ = " " : EndIf
If letter$<>" "
AddElement(scrolltext())
scrolltext()\X = #WindowWidth
scrolltext()\Letter_Texture_Pos = FindString(Font_Lookup_Text,letter$,0)-1
Mult = Int(scrolltext()\Letter_Texture_Pos / 16)
scrolltext()\Letter_Texture_Pos = scrolltext()\Letter_Texture_Pos - (Mult*16)
scrolltext()\Letter_Texture_Posy = Mult;*16
EndIf
ST_Next + (ST_FontWidth/2) + ST_Font_Gap
EndIf
Else
ST_Delay_Scroller - 1
EndIf
;/ render
glEnable_(#GL_TEXTURE_2D) : glBindTexture_(#GL_TEXTURE_2D,MyTexture)
glBegin_(#GL_QUADS)
YPos = #WindowHeight/2.4 : YSize = 32 : ST_Base1.f + 0.08 : ST_Base2.f + 0.14
glColor4f_(1.0,1.0,1.0,1.0)
timmy.f = Sin(offset/30.0)*0.5
ForEach Scrolltext()
X = scrolltext()\X
tY.f=(Sin(ST_Base1+(X/120))*(#WindowHeight/(5.5+timmy))) ; ;Y.f=(Sin(base2+((X+20)/50))-Sin(base1+(X/40)))*80 ;/ double base
YSize = 14 + (Sin(ST_Base2+X/360.0)*7.0)
HySize.f = YSize/2.0
TopM.f = 0.0580 : BotM.f = 0.005
;/ top
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos),(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+0.0585) : glVertex2i_(X,(tY+YPos-HySize)-1)
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos)+0.0585,(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+0.0585) : glVertex2i_(X+ST_FontWidth+2,(tY+YPos-HySize)-1)
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos)+0.0585,(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+TopM) : glVertex2i_(X+ST_FontWidth+2,(tY+YPos-HySize))
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos),(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+TopM) : glVertex2i_(X,(tY+YPos-HySize))
;/ middle
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos),(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+TopM) : glVertex2i_(X,tY+YPos-HySize)
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos)+0.0585,(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+TopM) : glVertex2i_(X+ST_FontWidth+2,tY+YPos-HySize)
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos)+0.0585,(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+BotM) : glVertex2i_(X+ST_FontWidth+2,tY+YPos+YSize)
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos),(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+BotM) : glVertex2i_(X,tY+YPos+YSize)
;/ bottom
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos),(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+BotM) : glVertex2i_(X,tY+YPos+YSize)
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos)+0.0585,(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+BotM) : glVertex2i_(X+ST_FontWidth+2,tY+YPos+YSize)
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos)+0.0585,(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+0.000) : glVertex2i_(X+ST_FontWidth+2,tY+YPos+YSize+2)
glTexCoord2f_((ST_Texture_Width*scrolltext()\Letter_Texture_Pos),(ST_Texture_Width*scrolltext()\Letter_Texture_Posy)+0.000) : glVertex2i_(X,tY+YPos+YSize+2)
Next
glEnd_()
glDisable_(#GL_TEXTURE_2D) : glColorMask_(#GL_TRUE, #GL_TRUE, #GL_TRUE, #GL_TRUE);
glStencilFunc_(#GL_EQUAL, 1, $FFFFFFFF) : glStencilOp_(#GL_KEEP, #GL_KEEP, #GL_KEEP);
EndProcedure
;LOGO QUADS AND TEXTURE BINDING
Procedure Draw_My_Logo() ;/ Create Our Quad Draw Then Bind Our Nice LOGO Texture
glEnable_(#GL_TEXTURE_2D) :
glBindTexture_(#GL_TEXTURE_2D,Texture1); Texture created
glMatrixMode_(#GL_TEXTURE);
glLoadIdentity_()
;
glScalef_(1.0, -1.0, 1.0);; Flips the texture right way up
glBegin_(#GL_QUADS)
glTexCoord2f_(0,1) :
glVertex2i_(159,50)
glTexCoord2f_(1,1) :
glVertex2i_(500,50)
glTexCoord2f_(1,0) :
glVertex2i_(500,150)
glTexCoord2f_(0,0) :
glVertex2i_(159,150)
glEnd_()
glDisable_(#GL_TEXTURE_2D)
glLoadIdentity_();
EndProcedure
;\\\\\\\\\MAIN LOOP\\\\\\\\\
;{/ Main Loop
Repeat
Event = WindowEvent()
System\MouseX = WindowMouseX(#Window_Main)
System\MouseY = WindowMouseY(#Window_Main)
System\App_CurrentTime = ElapsedMilliseconds()
Render() ;Shader rendering
Draw_ScrollText() ;/ Main Scroller
Rainbow_Copper() ;/ Colour the scroller
Draw_My_Logo() ;/ Draw Our Nice Logo
;/ Update the BorderLines colour position
everyother = 1 - everyother : If everyother : offset.f + 1 : EndIf
;/ Flip buffers
DrawnFrames + 1
a=a+0.1
SetGadgetAttribute(#Gad_OpenGL,#PB_OpenGL_FlipBuffers,#True)
Repeat ;/ check for escape key & clear other events
Event = WindowEvent()
Select Event
Case #PB_Event_Gadget ;/ must be our opengl gadget
If EventType() = #PB_EventType_KeyDown
If GetGadgetAttribute(#Gad_OpenGL,#PB_OpenGL_Key ) = #VK_ESCAPE
Quit = #True
EndIf
EndIf
EndSelect
Until Not Event
glClear_(#GL_COLOR_BUFFER_BIT | #GL_STENCIL_BUFFER_BIT)
Until Quit = #True
;}
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, 0.1)
glUseProgram(System\Shader_Program)
;/ set shader Uniform values
glUniform2f(System\Shader_Uniform_Resolution, 640, 480)
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)
EndProcedure
DataSection
Smallfont:
IncludeBinary "SmallFont.bmp"
Smalltextend:
Bigtext:
IncludeBinary "Font.bmp"
Bigtextend:
MyLogo:
IncludeBinary "9.png"
MyLogoEnd:
Nurbs:
IncludeBinary "Fire2.txt"
NurbsEnd:
Data.b 0
music:
IncludeBinary"pop.mod"
musend:
CopperList:
Data.w 256
Data.B $F,$3,$0 ,$F,$4,$0 ,$F,$5,$0 ,$F,$6,$0 ,$F,$7,$0 ,$F,$8,$0 ,$F,$9,$0 ,$F,$A,$0 ,$F,$B,$0 ,$F,$C,$0
Data.B $F,$D,$0 ,$F,$E,$0 ,$F,$F,$0 ,$E,$F,$0 ,$D,$F,$0 ,$C,$F,$0 ,$B,$F,$0 ,$A,$F,$0 ,$9,$F,$0 ,$8,$F,$0
Data.B $7,$F,$0 ,$6,$F,$0 ,$5,$F,$0 ,$4,$F,$0 ,$3,$F,$0 ,$2,$F,$0 ,$1,$F,$0 ,$0,$F,$0 ,$0,$F,$1 ,$0,$F,$2
Data.B $0,$F,$3 ,$0,$F,$4 ,$0,$F,$5 ,$0,$F,$6 ,$0,$F,$7 ,$0,$F,$8 ,$0,$F,$9 ,$0,$F,$A ,$0,$F,$B ,$0,$F,$C
Data.B $0,$F,$D ,$0,$F,$E ,$0,$F,$F ,$0,$E,$F ,$0,$D,$F ,$0,$C,$F ,$0,$B,$F ,$0,$A,$F ,$0,$9,$F ,$0,$8,$F
Data.B $0,$7,$F ,$0,$6,$F ,$0,$5,$F ,$0,$4,$F ,$0,$3,$F ,$0,$2,$F ,$0,$1,$F ,$0,$0,$F ,$1,$0,$F ,$2,$0,$F
Data.B $3,$0,$F ,$4,$0,$F ,$5,$0,$F ,$6,$0,$F ,$7,$0,$F ,$8,$0,$F ,$9,$0,$F ,$A,$0,$F ,$B,$0,$F ,$C,$0,$F
Data.B $D,$0,$F ,$E,$0,$F ,$F,$0,$F ,$F,$0,$E ,$F,$0,$D ,$F,$0,$C ,$F,$0,$B ,$F,$0,$A ,$F,$0,$9 ,$F,$0,$8
Data.B $F,$0,$7 ,$F,$0,$6 ,$F,$0,$5 ,$F,$0,$4 ,$F,$0,$3 ; ,$F,$0,$2 ,$F,$0,$1 ,$F,$0,$0 ,$F,$1,$0 ,$F,$2,$0
Data.B $F,$3,$0 ,$F,$4,$0 ,$F,$5,$0 ,$F,$6,$0 ,$F,$7,$0 ,$F,$8,$0 ,$F,$9,$0 ,$F,$A,$0 ,$F,$B,$0 ,$F,$C,$0
Data.B $F,$D,$0 ,$F,$E,$0 ,$F,$F,$0 ,$E,$F,$0 ,$D,$F,$0 ,$C,$F,$0 ,$B,$F,$0 ,$A,$F,$0 ,$9,$F,$0 ,$8,$F,$0
Data.B $7,$F,$0 ,$6,$F,$0 ,$5,$F,$0 ,$4,$F,$0 ,$3,$F,$0 ,$2,$F,$0 ,$1,$F,$0 ,$0,$F,$0 ,$0,$F,$1 ,$0,$F,$2
Data.B $0,$F,$3 ,$0,$F,$4 ,$0,$F,$5 ,$0,$F,$6 ,$0,$F,$7 ,$0,$F,$8 ,$0,$F,$9 ,$0,$F,$A ,$0,$F,$B ,$0,$F,$C
Data.B $0,$F,$D ,$0,$F,$E ,$0,$F,$F ,$0,$E,$F ,$0,$D,$F ,$0,$C,$F ,$0,$B,$F ,$0,$A,$F ,$0,$9,$F ,$0,$8,$F
Data.B $0,$7,$F ,$0,$6,$F ,$0,$5,$F ,$0,$4,$F ,$0,$3,$F ,$0,$2,$F ,$0,$1,$F ,$0,$0,$F ,$1,$0,$F ,$2,$0,$F
Data.B $3,$0,$F ,$4,$0,$F ,$5,$0,$F ,$6,$0,$F ,$7,$0,$F ,$8,$0,$F ,$9,$0,$F ,$A,$0,$F ,$B,$0,$F ,$C,$0,$F
Data.B $D,$0,$F ,$E,$0,$F ,$F,$0,$F ,$F,$0,$E ,$F,$0,$D ,$F,$0,$C ,$F,$0,$B ,$F,$0,$A ,$F,$0,$9 ,$F,$0,$8
Data.B $F,$0,$7, $F,$0,$6, $F,$0,$5, $F,$0,$4, $F,$0,$3, $F,$0,$2, $F,$0,$1, $F,$0,$0, $F,$1,$0, $F,$2,$0 ;- padded so the colours flow a bit bitter between lists.
Data.B $F,$3,$0 ,$F,$4,$0 ,$F,$5,$0 ,$F,$6,$0 ,$F,$7,$0 ,$F,$8,$0 ,$F,$9,$0 ,$F,$A,$0 ,$F,$B,$0 ,$F,$C,$0
Data.B $F,$D,$0 ,$F,$E,$0 ,$F,$F,$0 ,$E,$F,$0 ,$D,$F,$0 ,$C,$F,$0 ,$B,$F,$0 ,$A,$F,$0 ,$9,$F,$0 ,$8,$F,$0
Data.B $7,$F,$0 ,$6,$F,$0 ,$5,$F,$0 ,$4,$F,$0 ,$3,$F,$0 ,$2,$F,$0 ,$1,$F,$0 ,$0,$F,$0 ,$0,$F,$1 ,$0,$F,$2
Data.B $0,$F,$3 ,$0,$F,$4 ,$0,$F,$5 ,$0,$F,$6 ,$0,$F,$7 ,$0,$F,$8 ,$0,$F,$9 ,$0,$F,$A ,$0,$F,$B ,$0,$F,$C
Data.B $0,$F,$D ,$0,$F,$E ,$0,$F,$F ,$0,$E,$F ,$0,$D,$F ,$0,$C,$F ,$0,$B,$F ,$0,$A,$F ,$0,$9,$F ,$0,$8,$F
Data.B $0,$7,$F ,$0,$6,$F ,$0,$5,$F ,$0,$4,$F ,$0,$3,$F ,$0,$2,$F ,$0,$1,$F ,$0,$0,$F ,$1,$0,$F ,$2,$0,$F
Data.B $3,$0,$F ,$4,$0,$F ,$5,$0,$F ,$6,$0,$F ,$7,$0,$F ,$8,$0,$F ,$9,$0,$F ,$A,$0,$F ,$B,$0,$F ,$C,$0,$F
Data.B $D,$0,$F ,$E,$0,$F ,$F,$0,$F ,$F,$0,$E ,$F,$0,$D ,$F,$0,$C ,$F,$0,$B ,$F,$0,$A ,$F,$0,$9 ,$F,$0,$8
Data.B $F,$0,$7 ,$F,$0,$6 ,$F,$0,$5 ,$F,$0,$4 ,$F,$0,$3 ; ,$F,$0,$2 ,$F,$0,$1 ,$F,$0,$0 ,$F,$1,$0 ,$F,$2,$0
Data.B $F,$3,$0 ,$F,$4,$0 ,$F,$5,$0 ,$F,$6,$0 ,$F,$7,$0 ,$F,$8,$0 ,$F,$9,$0 ,$F,$A,$0 ,$F,$B,$0 ,$F,$C,$0
Data.B $F,$D,$0 ,$F,$E,$0 ,$F,$F,$0 ,$E,$F,$0 ,$D,$F,$0 ,$C,$F,$0 ,$B,$F,$0 ,$A,$F,$0 ,$9,$F,$0 ,$8,$F,$0
Data.B $7,$F,$0 ,$6,$F,$0 ,$5,$F,$0 ,$4,$F,$0 ,$3,$F,$0 ,$2,$F,$0 ,$1,$F,$0 ,$0,$F,$0 ,$0,$F,$1 ,$0,$F,$2
Data.B $0,$F,$3 ,$0,$F,$4 ,$0,$F,$5 ,$0,$F,$6 ,$0,$F,$7 ,$0,$F,$8 ,$0,$F,$9 ,$0,$F,$A ,$0,$F,$B ,$0,$F,$C
Data.B $0,$F,$D ,$0,$F,$E ,$0,$F,$F ,$0,$E,$F ,$0,$D,$F ,$0,$C,$F ,$0,$B,$F ,$0,$A,$F ,$0,$9,$F ,$0,$8,$F
Data.B $0,$7,$F ,$0,$6,$F ,$0,$5,$F ,$0,$4,$F ,$0,$3,$F ,$0,$2,$F ,$0,$1,$F ,$0,$0,$F ,$1,$0,$F ,$2,$0,$F
;Data.B $F,$0,$7,
EndDataSection