Shader coding with PB possible?

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

Re: Shader coding with PB possible?

Post by pjay »

When I was toying with the OpenGLGadget last year, I wrote a GLSL viewer that I think is similar to what you're after - no GLSL editing though (although it's displayed in an editorgadget), but it shouldn't be difficult to add if required.

Image

Download (Source and executable): https://dl.dropboxusercontent.com/u/600 ... 20GLSL.zip
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: Shader coding with PB possible?

Post by em_uk »

OH MY GOOD LORD!!!

That is EXACTLY what I was after! WOW!!!

Now do excuse me while I head over to my neighbours house to collect my socks, as they have been well and truly blown off!

My weekend has been made already and it's only Friday!

THANK YOU! :D :D :D :D

Edit : Samuel - thank you also for the description - that helps a lot. From having absolutely no idea about how shaders work and spending 3 days hammering the subject your explanations have helped immensely. Really appreciate your time :)
----

R Tape loading error, 0:1
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Shader coding with PB possible?

Post by applePi »

@pjay, i have said before a few hours that i dislike shaders, but your program produces infinity of unexpected beautiful graphics , i like the output of shader number 31
Thank you
Last edited by applePi on Sat May 02, 2015 6:42 am, edited 1 time in total.
User avatar
oreopa
Enthusiast
Enthusiast
Posts: 283
Joined: Sat Jun 24, 2006 3:29 am
Location: Edinburgh, Scotland.

Re: Shader coding with PB possible?

Post by oreopa »

Great thread and great program pjay. Informative stuff.
Proud supporter of PB! * Musician * C64/6502 Freak
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: Shader coding with PB possible?

Post by em_uk »

One last question (for now) @pjay - you included a Cube Physics example which uses what seems to be a personal include pjGL.pbi

It contains another (I'm such a beggar) include pjText which prints to OpenGL screen, is that include one you'd be willing to share? Or is it no use without the overall PureGL Project.

Or is that quite a simple procedure to work out?

Thanks again for the insight on the shader code. I'm still so very happy! (I can close Visual Studio for the foreseeable future ;)

:)
----

R Tape loading error, 0:1
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: Shader coding with PB possible?

Post by Comtois »

Thank you pjay, this is fantastic.
Please correct my english
http://purebasic.developpez.com/
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Shader coding with PB possible?

Post by applePi »

@em_uk , i have made an experiments using the shader in the link you have provided http://glslsandbox.com/e#24834.0 and it works with pjay program, some shaders hang my firefox , may be my system does not support it, but what works can be displayed in pjay program. here is i have tried this shader http://glslsandbox.com/e#24923.3 and saved it to file:
case02.frag (i have used notepad with save as all files and encoding ansi, it does not work when i saved it with PB ide as save type all files):

Code: Select all

//---------------------------------------------------------
// Shader:   IllustratedEquations.glsl               4/2015
//           http://glslsandbox.com/e#24891
// Original: https://www.shadertoy.com/view/MtBGDW
//           Created by sofiane benchaa - sben/2015 
// tags:     procedural, 2d, fractal, trigonometric, curve, complex, iterative
// info:     http://www.mathcurve.com/surfaces/tore/tn.shtml
//           http://xrt.wikidot.com/gallery:implicit
//---------------------------------------------------------

#ifdef GL_ES
precision mediump float; 
#endif

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

//---------------------------------------------------------
#define FIELD 28.0
#define ITERATION 12
#define CHANNEL bvec3(true,true,true)
#define PI4 0.7853981633974483
#define TONE vec3(0.299,0.587,0.114)

//just a line
float crossEQ(vec3 p,float t)
{
	float pv = p.x * p.y;
	return pv * pv;
}

// triangle
float triangleEQ( vec3 p, float t )
{
	return max(abs(p.x)*PI4+p.y*0.5,-p.y) - 0.1+ 0.2*sin(t);
}

//---------------------------------------------------------
// regular trifolium
// http://www.mathcurve.com/surfaces/tore/tn.shtml
// ((x^2+y^2)^2-x*(x^2-3*y^2))^2+z^2-0.008=0
float bretzTrifolEQ (vec3 p, float t)
{	
	float x2 = p.x*p.x;
	float y2 = p.y*p.y;
	float fv = (x2+y2)*(x2+y2)-p.x*(x2-3.0*y2);
	fv *= fv;
	fv += p.z * p.z;
	fv /= 0.008+0.006*sin(t);
	return fv;
}

// Bretzel6
// ((x^2+y^2/4-1)*(x*x/4+y*y-1))^2-z^2=0.1
float bretzel6EQ(vec3 p,float t)
{	
	float x2 = p.x*p.x;
	float y2 = p.y*p.y;
	float fv = (x2+y2/4.-1.)*(x2/4.+y2-1.);
	fv *= fv;
	fv += p.z*p.z;
	fv /= 0.06+0.04*sin(t);
	return fv;
}

// quad torus
// (x^2*(1-x^2)^2*(4-x^2)^3-20*y^2)^2+80*z^2=22
float quadTorusEQ(vec3 p,float t)
{
	float x2 = p.x*p.x;
	float y2 = p.y*p.y;
	float fv = x2*pow(1.0-x2,2.)*pow(4.0-x2,3.0)-20.0*y2;
	fv *= fv;
	fv += 1.0*(p.z*p.z);
	fv /= 22.0 + 16.*sin(t);
	return fv;
}
//lemniscat Bernoulli
// ((x^2+y^2)^2-x^2+y^2)^2+z^2=0.01
float bretzBernEQ(vec3 p,float t)
{
	float x2 = p.x*p.x;
	float y2 = p.y*p.y;
	float fv = ((x2+y2)*(x2+y2)-x2+y2);
	fv *= fv;
	fv /= 0.02 + 0.01*sin(t);
	return fv;
}

// animated calamari
float pieuvreEQ(vec3 p,float t)
{
	float fv = p.x;
	fv = (p.y+length(p*fv)-cos(t+p.y));
	fv = (p.y+length(p*fv)-cos(t+p.y));
	fv = (p.y+length(p*fv)-0.5*cos(t+p.y));
	fv *= fv*0.1;
	return fv;
}

//---------------------------------------------------------
//iterative equations

//mandelbrot
float mandelbrotEQ(vec3 c,float t)
{
	vec4 z = vec4(c,0.0);
	vec3 zi = vec3(0.0);
	for(int i=0; i<ITERATION; ++i)
	{
		zi.x = (z.x*z.x-z.y*z.y);
		zi.y = 2.*(z.x*z.y);
		zi.xyz += c;
		if(dot(z.xy,z.xy)>4.0)break;
		z.w++;
		z.xyz=zi;
	}
	z.w /= float(ITERATION);
	return 1.0-z.w;
}

//---------------------------------------------------------
// wolf face
float wolfFaceEQ(vec3 p,float t)
{
	vec2 fx = p.xy;
	p=(abs(p*2.0+sin(t)*0.7));
	const float j=float(ITERATION);
	vec2 ab = vec2(2.0-p.x);
	for(float i=0.0; i<j; i++)
	{
		ab+=(p.xy)-cos(length(p));
		p.y+=sin(ab.x-p.z)*0.5;
		p.x+=sin(ab.y)*0.5;
		p-=(p.x+p.y);
		p+=(fx.y+cos(fx.x));
		ab += vec2(p.y);
	}
	p /= FIELD;
	return p.x + p.x + p.y;
}

// dog face
float dogFaceEQ(vec3 p,float t)
{
	vec2 fx = p.xy;
	p=(abs(p*2.0)+sin(t)*0.2);
	const float j=float(ITERATION);
	vec2 ab = vec2(2.0-p.x);
	for(float i=0.0; i<j; i++)
	{		
		ab+=p.xy+cos(length(p));
		p.y+=sin(ab.x-p.z)*0.5;
		p.x+=sin(ab.y)*0.5;
		p-=(p.x+p.y);
		p-=((fx.y)-cos(fx.x));
	}
	p /= FIELD;
	return p.x + p.x + p.y;
}

//---------------------------------------------------------
vec3 computeColor(float fv)
{
	vec3 color = vec3(vec3(CHANNEL)*TONE);
	color -= (fv);
	color.r += color.g*2.0;
	color.g += color.b;
	return clamp(color,(0.0),(1.0));
}
//---------------------------------------------------------
void main() 
{
	float ratio = resolution.y / resolution.x;
	vec2 position = ( gl_FragCoord.xy / resolution.xy )-vec2(0.5, 0.9*ratio);
	position.y *= ratio;
	vec3 p = position.xyx*FIELD;
    
	p.z = 2.0*FIELD*0.5;
	vec3 color = computeColor(wolfFaceEQ(p+vec3(7.0, -1.0, 0.2),time));
	p.z = 0.0;  
	color += computeColor(dogFaceEQ(p*2.0+vec3(0.0,-3.0, 0.0),time));
	color += computeColor(mandelbrotEQ(p+vec3(-5.0,-4.0, 0.0),time));
 
	color += computeColor(triangleEQ(p+vec3(-4.0,-1.0, 0.0),time));
	color += computeColor(crossEQ(p+vec3(+2.3, 6.0, 0.0),time));

	color += computeColor(quadTorusEQ(p+vec3(-5.0, 1.0, 0.0),time));
	color += computeColor(bretzTrifolEQ(p+vec3(-6.0, 3.0, 0.0),time));
	color += computeColor(bretzel6EQ(p+vec3(-7.4, -2.0, 0.0),time));
	color += computeColor(bretzBernEQ(p+vec3(-4.0, 3.0, 0.0),time));
    	color += computeColor(pieuvreEQ(p*2.5+vec3(-4.0, 4.0, 0.0),time));
	gl_FragColor = vec4( color, 1.0 );
}
and then use that file in pjay program :

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 42
    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

      ReadFile(1,"case02.frag", #PB_Ascii  ) 
      For i=1 To 195
        System\Shader_Fragment_Text + ReadString(1)  +#CRLF$
      Next
      CloseFile(1)
      
      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 

it will show animated shapes:
Image
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: Shader coding with PB possible?

Post by em_uk »

Hi applePi

Yes it's a great bit of code by pjay.

I was up until 4am, I've added a scintilla gadget, live editing, saving/loading, drag and drop support, music playback and an FFT float sent to the shader so it can react to music!

:)

Image
----

R Tape loading error, 0:1
User avatar
DK_PETER
Addict
Addict
Posts: 904
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Shader coding with PB possible?

Post by DK_PETER »

Here's a WindowedScreen() version with load/save and test current script.

Link's gone
Last edited by DK_PETER on Thu Jun 04, 2015 4:06 pm, edited 3 times in total.
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
[blendman]
Enthusiast
Enthusiast
Posts: 297
Joined: Thu Apr 07, 2011 1:14 pm
Location: 3 arks
Contact:

Re: Shader coding with PB possible?

Post by [blendman] »

Hi

Thanks for this great code !

I have added a simple save/load and Runshader system (I have delete all the previous shader, but you can add them in this code) :

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 = "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, 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 
And some shader examples:
Blob

Code: Select all

// Blobs by @paulofalcao
uniform float time;
uniform vec2 resolution;

 
float makePoint(float x,float y,float fx,float fy,float sx,float sy,float t){
   float xx=x+sin(t*fx)*sx;
   float yy=y+cos(t*fy)*sy;
   return 1.0/sqrt(xx*xx+yy*yy);
}

void main( void ) {
	
   vec2 p=(gl_FragCoord.xy/resolution.x)*2.0-vec2(1.0,resolution.y/resolution.x);
   
   p=p*2.0;
   
   float x=p.x;
   float y=p.y;

   float a=
       makePoint(x,y,3.3,2.9,0.3,0.3,time);
   a=a+makePoint(x,y,1.9,2.0,0.4,0.4,time);
   a=a+makePoint(x,y,0.8,0.7,0.4,0.5,time);
   a=a+makePoint(x,y,2.3,0.1,0.6,0.3,time);
   a=a+makePoint(x,y,0.8,1.7,0.5,0.4,time);
   a=a+makePoint(x,y,0.3,1.0,0.4,0.4,time);
   a=a+makePoint(x,y,1.4,1.7,0.4,0.5,time);
   a=a+makePoint(x,y,1.3,2.1,0.6,0.3,time);
   a=a+makePoint(x,y,1.8,1.7,0.5,0.4,time);   
   
   float b=
       makePoint(x,y,1.2,1.9,0.3,0.3,time);
   b=b+makePoint(x,y,0.7,2.7,0.4,0.4,time);
   b=b+makePoint(x,y,1.4,0.6,0.4,0.5,time);
   b=b+makePoint(x,y,2.6,0.4,0.6,0.3,time);
   b=b+makePoint(x,y,0.7,1.4,0.5,0.4,time);
   b=b+makePoint(x,y,0.7,1.7,0.4,0.4,time);
   b=b+makePoint(x,y,0.8,0.5,0.4,0.5,time);
   b=b+makePoint(x,y,1.4,0.9,0.6,0.3,time);
   b=b+makePoint(x,y,0.7,1.3,0.5,0.4,time);

   float c=
       makePoint(x,y,3.7,0.3,0.3,0.3,time);
   c=c+makePoint(x,y,1.9,1.3,0.4,0.4,time);
   c=c+makePoint(x,y,0.8,0.9,0.4,0.5,time);
   c=c+makePoint(x,y,1.2,1.7,0.6,0.3,time);
   c=c+makePoint(x,y,0.3,0.6,0.5,0.4,time);
   c=c+makePoint(x,y,0.3,0.3,0.4,0.4,time);
   c=c+makePoint(x,y,1.4,0.8,0.4,0.5,time);
   c=c+makePoint(x,y,0.2,0.6,0.6,0.3,time);
   c=c+makePoint(x,y,1.3,0.5,0.5,0.4,time);
   
   vec3 d=vec3(a,b,c)/32.0;
   
   gl_FragColor = vec4(d.x,d.y,d.z,1.0);
}
Flame :

Code: Select all

// code by shadertoy ?
uniform vec2 resolution;
uniform float time;


float snoise(vec3 uv, float res)
{
	const vec3 s = vec3(1e0, 1e2, 1e3);
	
	uv *= res;
	
	vec3 uv0 = floor(mod(uv, res))*s;
	vec3 uv1 = floor(mod(uv+vec3(1.), res))*s;
	
	vec3 f = fract(uv); f = f*f*(3.0-2.0*f);

	vec4 v = vec4(uv0.x+uv0.y+uv0.z, uv1.x+uv0.y+uv0.z,
		      	  uv0.x+uv1.y+uv0.z, uv1.x+uv1.y+uv0.z);

	vec4 r = fract(sin(v*1e-1)*1e3);
	float r0 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);
	
	r = fract(sin((v + uv1.z - uv0.z)*1e-1)*1e3);
	float r1 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);
	
	return mix(r0, r1, f.z)*2.-1.;
}

void main(void) 
{
	vec2 p = -.5 + gl_FragCoord.xy / resolution.xy;
	p.x *= resolution.x/resolution.y;
	
	float color = 3.0 - (3.*length(2.*p));
	
	vec3 coord = vec3(atan(p.x,p.y)/6.2832+.5, length(p)*.4, .5);
	
	for(int i = 1; i <= 7; i++)
	{
		float power = pow(2.0, float(i));
		color += (1.5 / power) * snoise(coord + vec3(0.,-time*.05, time*.01), power*16.);
	}
	gl_FragColor = vec4( color, pow(max(color,0.),2.)*0.4, pow(max(color,0.),3.)*0.15 , 1.0);
}
Seascape :

Code: Select all

// "Seascape" by Alexander Alekseev aka TDM - 2014
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
uniform vec2 resolution;
uniform float time;
uniform vec4 mouse;


const int NUM_STEPS = 8;
const float PI	 	= 3.1415;
const float EPSILON	= 1e-3;
float EPSILON_NRM	= 0.1 / resolution.x;

// sea
const int ITER_GEOMETRY = 3;
const int ITER_FRAGMENT = 5;
const float SEA_HEIGHT = 0.6;
const float SEA_CHOPPY = 4.0;
const float SEA_SPEED = 0.8;
const float SEA_FREQ = 0.16;
const vec3 SEA_BASE = vec3(0.1,0.19,0.22);
const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6);
float SEA_TIME = time * SEA_SPEED;
mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);

// math
mat3 fromEuler(vec3 ang) {
	vec2 a1 = vec2(sin(ang.x),cos(ang.x));
    vec2 a2 = vec2(sin(ang.y),cos(ang.y));
    vec2 a3 = vec2(sin(ang.z),cos(ang.z));
    mat3 m;
    m[0] = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);
	m[1] = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x);
	m[2] = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);
	return m;
}
float hash( vec2 p ) {
	float h = dot(p,vec2(127.1,311.7));	
    return fract(sin(h)*43758.5453123);
}
float noise( in vec2 p ) {
    vec2 i = floor( p );
    vec2 f = fract( p );	
	vec2 u = f*f*(3.0-2.0*f);
    return -1.0+2.0*mix( mix( hash( i + vec2(0.0,0.0) ), 
                     hash( i + vec2(1.0,0.0) ), u.x),
                mix( hash( i + vec2(0.0,1.0) ), 
                     hash( i + vec2(1.0,1.0) ), u.x), u.y);
}

// lighting
float diffuse(vec3 n,vec3 l,float p) {
    return pow(dot(n,l) * 0.4 + 0.6,p);
}
float specular(vec3 n,vec3 l,vec3 e,float s) {    
    float nrm = (s + 8.0) / (3.1415 * 8.0);
    return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;
}

// sky
vec3 getSkyColor(vec3 e) {
    e.y = max(e.y,0.0);
    vec3 ret;
    ret.x = pow(1.0-e.y,2.0);
    ret.y = 1.0-e.y;
    ret.z = 0.6+(1.0-e.y)*0.4;
    return ret;
}

// sea
float sea_octave(vec2 uv, float choppy) {
    uv += noise(uv);        
    vec2 wv = 1.0-abs(sin(uv));
    vec2 swv = abs(cos(uv));    
    wv = mix(wv,swv,wv);
    return pow(1.0-pow(wv.x * wv.y,0.65),choppy);
}

float map(vec3 p) {
    float freq = SEA_FREQ;
    float amp = SEA_HEIGHT;
    float choppy = SEA_CHOPPY;
    vec2 uv = p.xz; uv.x *= 0.75;
    
    float d, h = 0.0;    
    for(int i = 0; i < ITER_GEOMETRY; i++) {        
    	d = sea_octave((uv+SEA_TIME)*freq,choppy);
    	d += sea_octave((uv-SEA_TIME)*freq,choppy);
        h += d * amp;        
    	uv *= octave_m; freq *= 1.9; amp *= 0.22;
        choppy = mix(choppy,1.0,0.2);
    }
    return p.y - h;
}

float map_detailed(vec3 p) {
    float freq = SEA_FREQ;
    float amp = SEA_HEIGHT;
    float choppy = SEA_CHOPPY;
    vec2 uv = p.xz; uv.x *= 0.75;
    
    float d, h = 0.0;    
    for(int i = 0; i < ITER_FRAGMENT; i++) {        
    	d = sea_octave((uv+SEA_TIME)*freq,choppy);
    	d += sea_octave((uv-SEA_TIME)*freq,choppy);
        h += d * amp;        
    	uv *= octave_m; freq *= 1.9; amp *= 0.22;
        choppy = mix(choppy,1.0,0.2);
    }
    return p.y - h;
}

vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {  
    float fresnel = 1.0 - max(dot(n,-eye),0.0);
    fresnel = pow(fresnel,3.0) * 0.65;
        
    vec3 reflected = getSkyColor(reflect(eye,n));    
    vec3 refracted = SEA_BASE + diffuse(n,l,80.0) * SEA_WATER_COLOR * 0.12; 
    
    vec3 color = mix(refracted,reflected,fresnel);
    
    float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0);
    color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten;
    
    color += vec3(specular(n,l,eye,60.0));
    
    return color;
}

// tracing
vec3 getNormal(vec3 p, float eps) {
    vec3 n;
    n.y = map_detailed(p);    
    n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y;
    n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y;
    n.y = eps;
    return normalize(n);
}

float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) {  
    float tm = 0.0;
    float tx = 1000.0;    
    float hx = map(ori + dir * tx);
    if(hx > 0.0) return tx;   
    float hm = map(ori + dir * tm);    
    float tmid = 0.0;
    for(int i = 0; i < NUM_STEPS; i++) {
        tmid = mix(tm,tx, hm/(hm-hx));                   
        p = ori + dir * tmid;                   
    	float hmid = map(p);
		if(hmid < 0.0) {
        	tx = tmid;
            hx = hmid;
        } else {
            tm = tmid;
            hm = hmid;
        }
    }
    return tmid;
}

// main
void main(void) {
	vec2 uv = gl_FragCoord.xy / resolution.xy;
    uv = uv * 2.0 - 1.0;
    uv.x *= resolution.x / resolution.y;    
    float _time = time * 0.3 + mouse.x*0.01;
        
    // ray
    vec3 ang = vec3(sin(_time*3.0)*0.1,sin(_time)*0.2+0.3,_time);    
    vec3 ori = vec3(0.0,3.5,_time*5.0);
    vec3 dir = normalize(vec3(uv.xy,-2.0)); dir.z += length(uv) * 0.15;
    dir = normalize(dir) * fromEuler(ang);
    
    // tracing
    vec3 p;
    heightMapTracing(ori,dir,p);
    vec3 dist = p - ori;
    vec3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM);
    vec3 light = normalize(vec3(0.0,1.0,0.8)); 
             
    // color
    vec3 color = mix(
        getSkyColor(dir),
        getSeaColor(p,n,light,dir,dist),
    	pow(smoothstep(0.0,-0.05,dir.y),0.3));
        
    // post
	gl_FragColor = vec4(pow(color,vec3(0.75)), 1.0);
}
Do you know a way to not "erase" the canvas, to use this canvas for a paint application for example ?
User avatar
[blendman]
Enthusiast
Enthusiast
Posts: 297
Joined: Thu Apr 07, 2011 1:14 pm
Location: 3 arks
Contact:

Re: Shader coding with PB possible?

Post by [blendman] »

DK_PETER wrote:Here's a WindowedScreen() version with load/save and test current script.

link removed..
HI

I'm interested about your technic, could you please send me the link to do shader with windowedscreen ?
Thanks a lot.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Shader coding with PB possible?

Post by applePi »

[blendman] writes: Do you know a way to not "erase" the canvas, to use this canvas for a paint application for example ?
to use this canvas for a paint application for example: i guess you mean to save the opengl graphics such as this Glsl scenes to picture
here is a working solution but (works in the dark): ie the graphics run in the background but we can't see, the only way to see it is to press space key to save the opengl glsl scene to a picture, (it is may be a small thing i miss)
the solution:
replacing the opengl gadget with the purebasic classic old way to display opengl
ie we use:
OpenWindowedScreen
InitEngine3D()
InitSprite()
CreateCamera
CreateRenderTexture
with #PB_Texture_AutomaticUpdate):
such as:
CreateRenderTexture(9, CameraID(0), CameraViewWidth(0), CameraViewHeight(0), #PB_Texture_AutomaticUpdate)
SaveRenderTexture

RenderWorld()
FlipBuffers()


when we use #PB_Texture_AutomaticUpdate we can't see the glsl graphics on the screen
press space key to save consecutive images to testxxx.png, or replace KeyboardReleased with KeyboardPushed to save avalanche of pictures. hope some one help i miss something small for sure to not see the graphics on the screen.
this is code of [blendman] changed a little by adding the above additions and removing the openGL gadget, now comment line 311 :CreateRenderTexture(9, CameraID(0), CameraViewWidth(0), CameraViewHeight(0), #PB_Texture_AutomaticUpdate)
run it again and you will see the graphics but can't save it, will give error. . the code have used also SaveRenderTexture.pb example (there is also CreateRenderTexture.pb)
change Library subsystem to OpenGL

Code: Select all

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

;EnableExplicit
InitEngine3D()
InitKeyboard()
InitSprite()
InitMouse()

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  CompilerIf Subsystem("OpenGL") = #False
    MessageRequester("Error", "Please set the Library subsystem to OpenGL from IDE : Compiler... Compiler Options")
    End
  CompilerEndIf
CompilerEndIf

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_SystemMenu)
  OpenWindowedScreen(WindowID(#Window_Main), 0, 0, WindowWidth(#Window_Main)-170, WindowHeight(#Window_Main), 0, 0, 0)
  
  CreateCamera(0,0,0,100,100)
  MoveCamera(0,0,0,20,#PB_Absolute)
  CameraLookAt(0, 0, 0, 0)
  
  ;CreateCamera(1, 0, 0, 100, 100)
  ;MoveCamera(1, 90, 60, 0, #PB_Absolute)
  ;CameraLookAt(1, 0, 0, 0)
  ;CameraFOV(1, 80)

  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 = "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, 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)
      
  FlipBuffers()
  
EndProcedure


CreateRenderTexture(9, CameraID(0), CameraViewWidth(0), CameraViewHeight(0), #PB_Texture_AutomaticUpdate)
;CreateMaterial(9, TextureID(9))

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()
  
  RenderWorld()
  Render()
    
  ExamineKeyboard()
If KeyboardReleased(#PB_Key_Space)
   
   No + 1
   SaveRenderTexture(9, "test2" + Str(No) + ".png")    
EndIf
  
Until System\Exit 
User avatar
[blendman]
Enthusiast
Enthusiast
Posts: 297
Joined: Thu Apr 07, 2011 1:14 pm
Location: 3 arks
Contact:

Re: Shader coding with PB possible?

Post by [blendman] »

Hi ApplePi

Thank you very much for your example.
Unfortunately, I have an IMA on the line 152 :

Code: Select all

  VertShader.i = glCreateShader(#GL_VERTEX_SHADER)

I have another question :
is there a way to use your technic (rendertotexture/camera) to simple render sprite on this texture, but without "erase" the texture on each frame (to paint on it) ?
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Shader coding with PB possible?

Post by applePi »

[blendman], the error in line 152 happened with me also if the Library subsystem are not set to OpenGL
Image
i am using windows xp, and when library subsystem set to opengl it works without errors.
now i have made a work around like that in the official examples: make second camera so we can see what happened on the screen and when we want to save textures we free the second camera (so the render to screen stop while rendering to texture continue) then we SaveRenderTexture(1, "test" + Str(No) + ".png") , the first texture are empty.png while the rest are test1.png test2.png ... etc. and can be converted to animated gif using a free http://sourceforge.net/projects/gifapp/ ... ifApp-1.3/
if you want to continue watching the screen create the second camera again: look the code from line 369
i am still trying to do the same thing with usual opengl screens and does not succeed until now while it works with glsl, may be something small. but at least we are able to save the gorgeous GLSL beautiful graphics. i saw your post in games forum and will post if succeeded.

set the Library subsystem to opengl ,, press space key to save textures, press "Z" key to watch the screen again ...

Code: Select all

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

;EnableExplicit
InitEngine3D()
InitKeyboard()
InitSprite()
InitMouse()

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  CompilerIf Subsystem("OpenGL") = #False
    MessageRequester("Error", "Please set the Library subsystem to OpenGL from IDE : Compiler... Compiler Options")
    End
  CompilerEndIf
CompilerEndIf

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_SystemMenu)
  OpenWindowedScreen(WindowID(#Window_Main), 0, 0, WindowWidth(#Window_Main)-170, WindowHeight(#Window_Main), 0, 0, 0)
  
    CreateCamera(1, 0, 0, 100, 100)
    MoveCamera(1, -100, 120, 190, #PB_Absolute)
    CameraLookAt(1, 0, 0, 0)
    
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 90, 60, 0, #PB_Absolute)
    CameraLookAt(0, 0, 0, 0)
    CameraFOV(0, 80)
    CameraProjectionMode(0, #PB_Camera_Perspective)

    ;Miroir
    ;CreateRenderTexture(1, CameraID(0), 800, 600)
    CreateRenderTexture(1, CameraID(0), CameraViewWidth(0), CameraViewHeight(0), #PB_Texture_AutomaticUpdate)
    CreateMaterial(1, TextureID(1))
    
  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 = "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, 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)
      
  ;FlipBuffers()
  
EndProcedure

;CreateRenderTexture(1, CameraID(0), CameraViewWidth(0), CameraViewHeight(0), #PB_Texture_AutomaticUpdate)
;CreateMaterial(9, TextureID(9))

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()
  
  RenderWorld()
  Render()
  FlipBuffers()
    
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Space)
    t+1
    
   If flag=0 
     FreeCamera(1)
     flag=1
   EndIf
   
   If t=1
     
     SaveRenderTexture(1, "empty.png") 
   Else
   
   No + 1
   SaveRenderTexture(1, "test" + Str(No) + ".png") 
   
 EndIf
 
  EndIf
 If KeyboardReleased(#PB_Key_Z)
   If IsCamera(1) = 0
   flag=0 : t=0
   CreateCamera(1, 0, 0, 100, 100)
   EndIf
 EndIf
 
  
Until System\Exit 
User avatar
DK_PETER
Addict
Addict
Posts: 904
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Shader coding with PB possible?

Post by DK_PETER »

@[blendman]
Don't compile with unicode checked.
Last edited by DK_PETER on Thu Jun 04, 2015 4:06 pm, edited 1 time in total.
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.
Post Reply