Shader coding with PB possible?

Everything related to 3D programming
pjay
Enthusiast
Enthusiast
Posts: 175
Joined: Thu Mar 30, 2006 11:14 am

Re: Shader coding with PB possible?

Post by pjay »

Many of the OpenGL commands that you pass strings to will need modifying, this is due to PB switching to Unicode strings internally.

Changing:

Code: Select all

Prototype.i glGetUniformLocation(Program.i, name.s)
to:

Code: Select all

Prototype.i glGetUniformLocation(Program.i, name.p-ascii)
should fix the black screen issue.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Shader coding with PB possible?

Post by applePi »

Thank you pjay for the info, i was about to despair, but now after modifications the shaders works okay in PB 5.5
Joubarbe
Enthusiast
Enthusiast
Posts: 555
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Shader coding with PB possible?

Post by Joubarbe »

Someone has a final code working for that and current version 5.73?
mpz
Enthusiast
Enthusiast
Posts: 494
Joined: Sat Oct 11, 2008 9:07 pm
Location: Germany, Berlin > member German forum

Re: Shader coding with PB possible?

Post by mpz »

Hi Joubabe,

which code do you exactly means? We have much good shader codes here.

For examples mandelbrot/julia
https://www.purebasic.fr/english/viewtopic.php?t=78328

I have the shader code with 43 shader of Pj actualised for windows/MAC and ubunto. i hope it helps

Only Sourcecode
https://c.web.de/@334971174352067001/yz ... 4Q6bgZqEnw

Greetings Michael

and here the shader editor code actualised and working on windows/MAC and ubunto

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
Enumeration ;/ Menu
  #Menu_Open
  #Menu_Save
  #Menu_Run
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)
  
  If CreateMenu(0, WindowID(#Window_Main))
    MenuTitle("File")
    MenuItem(#Menu_Open,"Open")
    MenuItem(#Menu_Save,"Save")
    MenuBar()
    MenuItem(#Menu_Run,"Run Shader")
    
  EndIf
  
  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)
AddGadgetItem(#Gad_ShaderSelector_Combo,-1,"Shader: "+Str(1)) 

  
  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 = "#version 330"+Chr(10) ; MPz Changed for better graficcard support 
  System\Shader_Vertex_Text + "in vec3 position;"+Chr(10)
  System\Shader_Vertex_Text + " void main() {"+Chr(10)
  System\Shader_Vertex_Text + " gl_Position = vec4( position, 1.0 );"+Chr(10)
  System\Shader_Vertex_Text + " };"+Chr(10)

  ;System\Shader_Vertex_Text = "attribute vec3 position;" ; Alternate code works good with linux
  ;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

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS

  ImportC "-framework OpenGL"
    glCreateShader(type.l) As "_glCreateShader" 
    glCreateProgram() As "_glCreateProgram"
    glDeleteShader(shader.l) As "_glDeleteShader"
    glCompileShader(shader.l) As  "_glCompileShader"
    glLinkProgram(shader.l) As "_glLinkProgram" 
    glUseProgram(shader.l) As "_glUseProgram" 
    glAttachShader(Program.l, shader.l) As  "_glAttachShader"
    glShaderSource(shader.l, numOfStrings.l, *strings, *lenOfStrings) As  "_glShaderSource"
    glGetUniformLocation(Program.i, name.p-ascii) As  "_glGetUniformLocation"
    glUniform1i(location.i, v0.i) As "_glUniform1i"
    glUniform2i(location.i, v0.i, v1.i) As  "_glUniform2i"
    glUniform1f(location.i, v0.f) As  "_glUniform1f"
    glUniform1d(location.i, v0.d) As  "_glUniform1d"
    glUniform2f(location.i, v0.f, v1.f) As  "_glUniform2f"
    glUniform2d(location.i, v0.d, v1.d) As  "_glUniform2d"
    glGetShaderInfoLog(shader.i, bufSize.l, *length_l, *infoLog) As  "_glGetShaderInfoLog"
  EndImport

CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux
  
  ImportC "/usr/lib/x86_64-linux-gnu/libGL.so"
    glCreateShader(type.l)
    glCreateProgram()
    glDeleteShader(shader.l)
    glCompileShader(shader.l)
    glLinkProgram(shader.l)
    glUseProgram(shader.l)
    glAttachShader(Program.l, shader.l)
    glShaderSource(shader.l, numOfStrings.l, *strings, *lenOfStrings) : 
    glGetUniformLocation(Program.i, name.p-ascii)
    glUniform1i(location.i, v0.i)
    glUniform2i(location.i, v0.i, v1.i)
    glUniform1f(location.i, v0.f)
    glUniform1d(location.i, v0.d)
    glUniform2f(location.i, v0.f, v1.f)
    glUniform2d(location.i, v0.d, v1.d)
    glGetShaderInfoLog(shader.i, bufSize.l, *length_l, *infoLog)
  EndImport


CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
  
Prototype glCreateShader(type.l)
Prototype glCreateProgram()
Prototype glDeleteShader(shader.l)
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 glGetUniformLocation(Program.i, name.p-ascii)
Prototype glUniform1i(location.i, v0.i)
Prototype glUniform2i(location.i, v0.i, v1.i)
Prototype glUniform1f(location.i, v0.f)
Prototype glUniform1d(location.i, v0.d)
Prototype glUniform2f(location.i, v0.f, v1.f)
Prototype glUniform2d(location.i, v0.d, v1.d)
Prototype glGetShaderInfoLog(shader.i, bufSize.l, *length_l, *infoLog)
Global glCreateShader.glCreateShader             = wglGetProcAddress_("glCreateShader")
Global glCreateProgram.glCreateProgram           = wglGetProcAddress_("glCreateProgram")
Global glDeleteShader.glDeleteShader             = wglGetProcAddress_("glDeleteShader")
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 glUniform1d.glUniform1d                   = wglGetProcAddress_("glUniform1d")
Global glUniform2f.glUniform2f                   = wglGetProcAddress_("glUniform2f")
Global glUniform2d.glUniform2d                   = wglGetProcAddress_("glUniform2d")
Global glGetShaderInfoLog.glGetShaderInfoLog     = wglGetProcAddress_("glGetShaderInfoLog")

CompilerEndIf


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 = Ascii(Vertex)
  glShaderSource(VertShader, 1, @*TxtPointer, #Null)
  glCompileShader(VertShader)
  glGetShaderInfoLog(VertShader,1023,@Textlength,@Mytext)
  Debug "VertexShader: "+PeekS(@Mytext,1023,#PB_Ascii)
  ;/ Compile Fragment Shader
  FragShader.i = glCreateShader(#GL_FRAGMENT_SHADER)
  *TxtPointer = Ascii(Fragment)
  glShaderSource(FragShader, 1, @*TxtPointer, #Null)
  glCompileShader(FragShader)
  glGetShaderInfoLog(FragShader,1023,@Textlength,@Mytext)
  Debug "FragmentShader: "+PeekS(@Mytext,1023,#PB_Ascii)
  
  
  ;/ Create Shader Program
  Program = glCreateProgram()
  glAttachShader(Program,VertShader)
  glAttachShader(Program,FragShader)
  glLinkProgram(Program)
  
  If Use = 1
    glUseProgram(Program)
  EndIf
  
  ProcedureReturn Program  
EndProcedure
;}

Procedure Shader_Set(Fragment.i, shader$="")
  
  If System\Shader_Program <> 0 ;/ delete the previous shaders
    glUseProgram(0);
  EndIf
  
  If Fragment = -2 ; run the shader    
    System\Shader_Fragment_Text = GetGadgetText(#Gad_Editor)    
  ElseIf Fragment = -1 ; load the shader
      System\Shader_Fragment_Text = shader$+Chr(10)
  Else
    
   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
  
  EndIf

  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

Procedure OpenShader()
  Define filename$ ="", txt$ = ""
  
  filename$ = OpenFileRequester("Open shader","","All|*.*",0)
  
  If filename$ <> ""
    
    If ReadFile(0, filename$) 
      While Eof(0) = 0           
        txt$ + ReadString(0) +Chr(10) 
      Wend
      CloseFile(0)  
      Shader_Set(-1,txt$)

    Else
      MessageRequester("Information","Impossible d'ouvrir le fichier!")
    EndIf

  EndIf
  
EndProcedure
Procedure SaveShader()
  Define filename$ =""
  
  filename$ = SaveFileRequester("Save","","txt|*.txt",0)
  
  If filename$ <> ""
    
    If OpenFile(0, filename$) 
      WriteStringN(0, GetGadgetText(#Gad_Editor))
      CloseFile(0)
    EndIf
    
  EndIf
  
EndProcedure
Procedure RunShader()
  
  Shader_Set(-2)
  
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_Menu
        Select EventMenu()
          Case #Menu_Open
            OpenShader()
          Case #Menu_Save
            SaveShader()
          Case #Menu_Run
            RunShader()
            
        EndSelect
        
      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 mpz on Mon Dec 13, 2021 11:00 am, edited 3 times in total.
Working on - MP3D Library - PB 5.73 version ready for download
Joubarbe
Enthusiast
Enthusiast
Posts: 555
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Shader coding with PB possible?

Post by Joubarbe »

Thank you mpz. The source code with all the examples included is working fine, but the copy-paste code doesn't work for me, the screen is black, even after loading several different shader files.
mpz
Enthusiast
Enthusiast
Posts: 494
Joined: Sat Oct 11, 2008 9:07 pm
Location: Germany, Berlin > member German forum

Re: Shader coding with PB possible?

Post by mpz »

Hello Joubarbe,

Please test the blob, Flame, Seascape shader from here
https://www.purebasic.fr/english/viewto ... 22#p465522

If you dont see anything it could be an graficcard problem, then use the following parts in code of the shader editor (line 82-88 cut and paste these part)

Code: Select all

  System\Shader_Vertex_Text = "#version 330"+Chr(10)
  System\Shader_Vertex_Text + "in vec3 position;"+Chr(10)
  System\Shader_Vertex_Text + " void main() {"+Chr(10)
  System\Shader_Vertex_Text + " gl_Position = vec4( position, 1.0 );"+Chr(10)
  System\Shader_Vertex_Text + " };"+Chr(10)
 


If you use web shader in the shader editor:
You have to adjust shader from the web, because there are different in and outputs here.I can't help you much, but it is important to use the

uniform vec2 resolution;
uniform float time;
uniform vec4 mouse;

correctly in the webshader. i think they are small adjustments to do...

greetings
Michael
Working on - MP3D Library - PB 5.73 version ready for download
Joubarbe
Enthusiast
Enthusiast
Posts: 555
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Shader coding with PB possible?

Post by Joubarbe »

Replacing lines 82-88 helped, now it's working fine :)

Thank you, and thank you also for your work on your game engine!
Post Reply