[SOLVED] pass information to GLSL shader`s

Just starting out? Need help? Post your questions and find answers here.
omnikam
User
User
Posts: 27
Joined: Sat Apr 15, 2017 10:58 am

[SOLVED] pass information to GLSL shader`s

Post by omnikam »

Just wondering if anyone knows how to make changes in real time to fragments shaders?
For example if i wanted to change "COLOR_MASKS[0] = vec3( 0.20, 0.30, 1.0 );" to "COLOR_MASKS[0] = vec3( 1.0, 0.0, 1.0 );" though my main program
I could edit the nurbs. txt in real time, but dont believe this is the right answer
Im guessing id use glGetUniformLocation() followed by glUniform()
It`s just that ive never used them before so im not sure how they are used in this situation
I think i have worked it out if for example i had in my fragment shader uniform time, and i wanted to pass a number to it. In my tests this seems to work

Code: Select all

Global.l a : Global time : a=10
System\Shader_Uniform_Time = glGetUniformLocation(System\Shader_Program, "time")
glUniform1f(System\Shader_Uniform_Time,1+a/60)
The code bellow compiles on 5.44 with create uni-code exe disabled

Code: Select all

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
  fragtext.s
  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 test()
        System\fragtext = PeekS(? Nurbs) 
    ;MessageRequester("hilfe", System\hilfetext, 0)
    ;Debug System\hilfetext.s
EndProcedure
Procedure Init_Main()
  Protected MyLoop.i
    System\Width.i = 1024
  System\Height = 480
  System\Shader_Width = 640
  System\Shader_Height = 480
  OpenWindow(#Window_Main,0,0,System\Width,System\Height,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  OpenGLGadget(#Gad_OpenGL,0,0,System\Shader_Width,System\Shader_Height,#PB_OpenGL_Keyboard)
  ComboBoxGadget(#Gad_ShaderSelector_Combo,System\Shader_Width+4,2,System\Width - (System\Shader_Width+8),24)
  For MyLoop = 1 To 1
    AddGadgetItem(#Gad_ShaderSelector_Combo,-1,"Shader: "+Str(MyLoop))
  Next
  SetGadgetState(#Gad_ShaderSelector_Combo,0)
  EditorGadget(#Gad_Editor,System\Shader_Width+4,30,System\Width - (System\Shader_Width+8),System\Height-30)
  System\App_StartTime = ElapsedMilliseconds()
  System\Shader_Vertex_Text = "attribute vec3 position;"
  System\Shader_Vertex_Text + "attribute vec2 surfacePosAttrib;"
  System\Shader_Vertex_Text + "varying vec2 surfacePosition;"
  System\Shader_Vertex_Text + "	void main() {"
  System\Shader_Vertex_Text + "		surfacePosition = surfacePosAttrib;"
  System\Shader_Vertex_Text + "		gl_Position = vec4( position, 1.0 );"
  System\Shader_Vertex_Text + "	}"
EndProcedure
test()
Init_Main()
;{ Opengl shader setup & routines
#GL_VERTEX_SHADER = $8B31
#GL_FRAGMENT_SHADER = $8B30
Prototype glCreateShader(type.l)
Prototype glCreateProgram()
Prototype glCompileShader(shader.l)
Prototype glLinkProgram(shader.l)
Prototype glUseProgram(shader.l)
Prototype glAttachShader(Program.l, shader.l)
Prototype glShaderSource(shader.l, numOfStrings.l, *strings, *lenOfStrings) : 
Prototype.i glGetUniformLocation(Program.i, name.s)
Prototype glUniform1i(location.i, v0.i)
Prototype glUniform2i(location.i, v0.i, v1.i)
Prototype glUniform1f(location.i, v0.f)
Prototype glUniform2f(location.i, v0.f, v1.f)
Prototype glGetShaderInfoLog(shader.i, bufSize.l, *length_l, *infoLog)
Global glCreateShader.glCreateShader = wglGetProcAddress_("glCreateShader")
Global glCreateProgram.glCreateProgram = wglGetProcAddress_("glCreateProgram")
Global glCompileShader.glCompileShader = wglGetProcAddress_("glCompileShader")
Global glLinkProgram.glLinkProgram = wglGetProcAddress_("glLinkProgram")
Global glUseProgram.glUseProgram = wglGetProcAddress_("glUseProgram")
Global glAttachShader.glAttachShader = wglGetProcAddress_("glAttachShader")
Global glShaderSource.glShaderSource = wglGetProcAddress_("glShaderSource")
Global glGetUniformLocation.glGetUniformLocation = wglGetProcAddress_("glGetUniformLocation")
Global glUniform1i.glUniform1i = wglGetProcAddress_("glUniform1i")
Global glUniform2i.glUniform2i = wglGetProcAddress_("glUniform2i")
Global glUniform1f.glUniform1f = wglGetProcAddress_("glUniform1f")
Global glUniform2f.glUniform2f = wglGetProcAddress_("glUniform2f")
Global glGetShaderInfoLog.glGetShaderInfoLog = wglGetProcAddress_("glGetShaderInfoLog")
Procedure Shader_Compile_Link_Use(Vertex.s,Fragment.s,Use.i=1)
  Protected VertShader.i, FragShader.i, *TxtPointer, Program.i
  Protected Textlength.i, Mytext.s = Space(1024)
    ;/ Compile Vertex shader
  VertShader.i = glCreateShader(#GL_VERTEX_SHADER)
  *TxtPointer = @Vertex
  glShaderSource(VertShader, 1, @*TxtPointer, #Null)
  glCompileShader(VertShader)
  Debug "Vert: "+VertShader
  glGetShaderInfoLog(VertShader,1023,@Textlength,@Mytext)
  Debug MyText
  ;/ Compile Fragment Shader
  FragShader.i = glCreateShader(#GL_FRAGMENT_SHADER)
  *TxtPointer = @Fragment
  glShaderSource(FragShader, 1, @*TxtPointer, #Null)
  glCompileShader(FragShader)
  Debug "Frag: "+FragShader
  glGetShaderInfoLog(FragShader,1023,@Textlength,@Mytext)
  Debug MyText
  ;/ Create Shader Program
  Program = glCreateProgram()
  glAttachShader(Program,VertShader)
  Debug "Attached Vert Shader"
  glAttachShader(Program,FragShader)
  Debug "Attached Frag Shader"
  glLinkProgram(Program)
  Debug "Link program"
  If Use = 1
    glUseProgram(Program)
  EndIf
  ProcedureReturn Program  
EndProcedure
;}
Procedure Shader_Set(Fragment.i)
  If System\Shader_Program <> 0 ;/ delete the previous shaders
    glUseProgram(0);
  EndIf
    Select Fragment
    Case 0
      System\Shader_Fragment_Text =  System\fragtext;"uniform float time;"+Chr(10)
     EndSelect
  System\Shader_Program = Shader_Compile_Link_Use(System\Shader_Vertex_Text,System\Shader_Fragment_Text)
  If System\Shader_Program = 0
    MessageRequester("Unsupported Device?","No Shader Support Available",#PB_MessageRequester_Ok)
    End
  EndIf
  ;/ store shader uniform locations
  Debug "Shader: "+System\Shader_Program
  System\Shader_Uniform_Time = glGetUniformLocation(System\Shader_Program, "time")
  System\Shader_Uniform_Mouse = glGetUniformLocation(System\Shader_Program, "mouse")
  System\Shader_Uniform_Resolution = glGetUniformLocation(System\Shader_Program, "resolution")
  System\Shader_Uniform_SurfacePosition.i = glGetUniformLocation(System\Shader_Program, "surfacePosition")
  Debug "Time location: "+System\Shader_Uniform_Time
  Debug "Mouse location: "+System\Shader_Uniform_Mouse
  Debug "Res location: "+System\Shader_Uniform_Resolution
  Debug "SurfacePos location: "+System\Shader_Uniform_SurfacePosition
  SetGadgetText(#Gad_Editor,System\Shader_Fragment_Text)
EndProcedure
Shader_Set(0)
Procedure Render()
  ;/ set shader Uniform values
  glUniform2f(System\Shader_Uniform_Resolution,System\Shader_Width,System\Shader_Height)
  glUniform1f(System\Shader_Uniform_Time,(System\App_CurrentTime-System\App_StartTime) / 1000.0)
  glUniform2i(System\Shader_Uniform_SurfacePosition.i,1.0,1.0)
   glBegin_(#GL_QUADS)
    glVertex2f_(-1,-1) 
    glVertex2f_( 1,-1) 
    glVertex2f_( 1, 1) 
    glVertex2f_(-1, 1) 
  glEnd_()           
  System\Frames + 1
  If System\App_CurrentTime > System\FPS_Timer
    System\FPS = System\Frames
    System\Frames = 0
    System\FPS_Timer = System\App_CurrentTime  + 1000
    SetWindowTitle(#Window_Main,"GLSL Testing 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 
DataSection 
  Nurbs: 
  IncludeBinary "nurbs.txt" 
  Data.b 0 
EndDataSection 
nurbs.txt

Code: Select all

#define NUMmb 16
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
uniform sampler2D color_texture;
float  rn(float xx){
float x0=floor(xx);
        float x1=x0+1.;
        float v0 = fract(sin(x0*.4686)*3718.927+x0);          
        return v0;
}
void main( void ) {
	float ts = time *.6;//time scaled
	gl_FragColor = texture2D(color_texture, gl_TexCoord[0].st);
	vec3 COLOR_MASKS[16];//blob colors
	COLOR_MASKS[0] = vec3( 0.20, 0.30, 1.0 );
  	COLOR_MASKS[1] = vec3( 0.53, 0.85, 0.25 );
  	COLOR_MASKS[2] = vec3( 1.0, 0.56, 0.15 );
  	COLOR_MASKS[3] = vec3( 1.0, 0.0, 0.3 );
  	COLOR_MASKS[4] = vec3( 0.05, 0.55, .30 );
	COLOR_MASKS[5] = vec3( 0.5, 1.0, .40 );
  	COLOR_MASKS[6] = vec3( 1.0, 0.15, 1.0 );
  	COLOR_MASKS[7] = vec3( .20, .30, 0.5 );
  	COLOR_MASKS[8] = vec3( .350, 1.0, 0.5 );
  	COLOR_MASKS[9] = vec3( .70, .60, 0.5 );
  	COLOR_MASKS[10] = vec3( .34, 1., 0.5 );
  	COLOR_MASKS[11] = vec3( .20, .50, 0.5 );
  	COLOR_MASKS[12] = vec3( 0.60, .10, 0.65 );
  	COLOR_MASKS[13] = vec3( .40, .40, 0.85 );
  	COLOR_MASKS[14] = vec3( 1.0, .30, 0.35 );
  	COLOR_MASKS[15] = vec3( 1.0, 0.0, 0.5 );
		//screen space
	vec2 fragP = ( gl_FragCoord.xy / resolution.xy );
	vec2 fragPN = fragP * 2. - 1.; //-1 1
	float as = resolution.x/resolution.y;
	fragPN.x *= as; //aspect
	vec2 mouseP =fragP * 2. - 1.; //-1 1 fragP - mouse; //mouse
	float vH = 10.0;//camera disance - fov
	vec3 vD = normalize(vec3(-fragPN,vH));//view dir
	vec3 lD = normalize(vec3(cos(time),.750,sin(time)));//light dir	
	//vec3 ld = normalize(vec3(.7, .750,2.));
	vec2 mbPos[NUMmb];
	vec3 nn = vec3(.0);
	vec3 cc = vec3(.0);
	for(int i=0; i<NUMmb; i++){
		float rn1 = rn(float(i+54));
		float rn2 = rn(float(i-222));
		float rn3 = rn(float(i-262));
                mbPos[i] = vec2(
			//(rn(float(i+556))*2.-1.)*as,
			//rn(float(i+344))*2.-1.
			sin(rn1*6.14+ts * rn2)*as,
			cos(rn2*6.14+ts * rn3)
			   	);
			mbPos[i] = fragPN - mbPos[i]*.8;
		float rr = cos(rn3*6.28+ts * rn1)*.2+.5;
		mbPos[i] *= rr*20.;//blob coord
		//float sq = float( //quad
		//	(mbPos[i].x<1.&&mbPos[i].x>-1.)&&
		//	(mbPos[i].y<1.&&mbPos[i].y>-1.)
		//);
		float bL = length( mbPos[i] );//bl length
		float bA = smoothstep( 1.0, 0.97, bL );
		float bH = exp(-bL*2.15678);
		vec3 bN = vec3(mbPos[i]*.3*bH,bH-.01);
		vec3 bC=COLOR_MASKS[i];
		bC*=bH;
		//mbPos[i] = mbPos[i]*2.-1.;
		//d += bC;		
		//d += vec3(sq,bH,bA);		
		nn += vec3(mbPos[i]*.5*bH,bH);
		cc += bC;
	}
	//gl_FragColor = vec4(cc,1.);
	//return;
	//mblb
	vec2 mB = fragPN - (200*2.-1.)*vec2(as,1.);
	mB*=6.;
	float mBL = length( mB );
	float mBH = exp(-mBL*2.15678);
	vec3 mBN = vec3(mB*.5*mBH, mBH);
	vec3 mBC = vec3(1.,.0,.0);
	mBC*=mBH;
	//float sq = float( //quad
		//	(mB.x<1.&&mB.x>-1.)
		//	&&
		//	(mB.y<1.&&mB.y>-1.)
		//);
	//gl_FragColor = vec4(mBN,1.);
	//return;
	nn+=mBN;
	vec3 n = normalize( vec3(nn.x,nn.y,nn.z-.01) );
	float aB = smoothstep(0.0,.01,n.z);
	cc+=mBC;
	cc/=nn.z;
	//n *= aB;
	float ndl = dot(n,lD)*.5+.5;//wrap	
	//float ndl = dot(n,lD);//wrap
	ndl = ndl*.7+.3;
	vec3 h = normalize(vD+lD);
	float ndh = dot(n,h);
	ndh = ndh*.5+.5;
	ndh = pow(ndh,70.5)*.35;
	vec3 fc = cc*ndl+ndh;
	float frs = dot(n,vD);
	frs = 1.0-clamp(frs,.0,1.);
	frs = pow(frs,2.0);
	frs = frs*.4+.121;
	fc+=frs;
	float color = 0.0;
	gl_FragColor = vec4( fc*aB, 1.);
}