shater vert and frag example

BlitzMax Forums/BlitzMax OpenGL Programming/shater vert and frag example

tom speed made a nice file to help with shaders so I had a twiddle with it, had to change a few bits because of how bmax has progressed recently

heres the results of my experiments, I hope you find it useful.

test.frag
uniform vec4 color;

varying vec2 vPosition;
varying vec3 vNormal;


void main(void)
{

   float diffuse = 0.3 + 0.5 * dot(vNormal.xy, vNormal.xy);

   // Create a grid pattern

   vec2 fp=fract(4.0*vPosition.xy);
   fp *= (1.0 - fp);
   gl_FragColor = color * (fp.x + fp.y +1.0) * diffuse;

}

test.vert
//uniform float noiseRate;

varying vec3 vPosition;
varying vec3 vNormal;



void main(void)
{

   // Move it down a little for a better view

   vec4 vFinalPosition = vec4( gl_Vertex.x, gl_Vertex.y, gl_Vertex.z , gl_Vertex.w);
	vFinalPosition.z=vFinalPosition.z+sin(vFinalPosition.x*320.0)*0.1;
   gl_Position = gl_ModelViewProjectionMatrix * vFinalPosition;

   // Pass position to the fragment shader
   vPosition   = vec3(vFinalPosition);
 
   // Eye-space lighting
   vNormal = gl_NormalMatrix * gl_Normal;
  
}

shadertest.bmx
Import "glsl.bmx"

SetGraphicsDriver GLGraphicsDriver()
GLGraphics 800,600,0,0,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER 

glewInit()

glClearColor(0.5, 0.5, 0.5, 0.0)	' Color to clear the screen with
glClearDepth 1.0										' The depth to clear the Zbuffer to (0.0=near clip plane, 1.0=far clip plane)
glDepthFunc(GL_LESS)								' Only draw pixels if the fragment/pixel Z depth, is LESS than the Zbuffer value
glEnable(GL_DEPTH_TEST)							' Enable depth testing (Z sorting of pixels)
glFrontFace(GL_CW)									' Draw polys facing viewer Clockwise
glShadeModel(GL_SMOOTH)	
glViewport(0,0,800,600)

glMatrixMode(GL_PROJECTION)				' The Matrix to which subsequent Matrix operations work on
glLoadIdentity()
Local aspect# = Float(800)/Float(600)
gluPerspective(45.0,aspect#,1.0,100.0) ' y-FoV#, Aspect#, Near#, Far#


Local po:tProgramObject=New tProgramObject 
po=tProgramObject.create("test")

Local vs:tShaderObject=New tShaderObject
vs=CreateVertShader("test.vert")

Local fs:tShaderObject=New tShaderObject
fs=CreateFragShader("test.frag")

po.AttachVertShader(vs)
po.AttachFragShader(fs)


Rem
Global length:Int,size:Int,tp:Int,name:Byte[21]
For y=0 To 5
glGetActiveUniformARB(po.program,y,20,Varptr length,Varptr size,Varptr Tp,Varptr name[0])
n$=""
For Local x:Int =0 To length-1
	n$=n$+Chr(name[x])
Next 
Print n$
Next
EndRem
po.Activate()
po.setUF4("color",1.0,0.5,0.25,1.0)
po.DeActivate()



Global rtri:Float
Global rquad:Float 

While Not KeyDown(KEY_ESCAPE) And Not AppTerminate()	
	Local UseShader:Byte=MouseDown(1)
	glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
	GLDrawText("hold left mouse to activate shader",20,20)
	glMatrixMode(GL_MODELVIEW)
	glLoadIdentity
	glTranslatef -1.5,0.0,-6.0
	glRotatef rtri,0.0,1.0,0.0           ' Rotate The Triangle On The Y axis ( NEW )
	   	glBegin GL_POLYGON
		glColor3f 1.0,0.0,0.0              ' Set The Color To Red
		glVertex3f  0.0, 1.0, 0.0          ' Top
		glColor3f 0.0,1.0,0.0              ' Set The Color To Green
		glVertex3f  1.0,-1.0, 0.0          ' Bottom Right
		glColor3f 0.0,0.0,1.0              ' Set The Color To Blue
		glVertex3f -1.0,-1.0, 0.0          ' Bottom Left
	glEnd
	
	glLoadIdentity
	glTranslatef 0.1,0.0,-6.0               ' Move Right 1.5 Units
	glRotatef rquad,1.0,0.0,0.0             ' Rotate The Quad On The X axis ( New )
	glColor3f 0.5,0.5,1.0                   ' Set The Color To Blue One Time Only
	
	If UseShader
		po.Activate()
	End If
	

	' draw many quads so vert shader has somthing to play with!
		For Local vx:Float=-1 To 1 Step 0.1
			For Local vy:Float=-1 To 1 Step 0.1
	glBegin GL_QUADS
				glVertex3f vx-.05, vy+.05, 0.0          ' Top Left
				glVertex3f vx+.05, vy+.05, 0.0          ' Top Right
				glVertex3f vx+.05, vy-.05, 0.0          ' Bottom Right
				glVertex3f vx-.05, vy-.05, 0.0          ' Bottom Left
	glEnd
			Next
		Next
	
	If UseShader
		po.DeActivate()
	End If
	
	rtri = rtri + 1.2                   '; Increase The Rotation Variable For The Triangle ( New )
	rquad = rquad + 1                  '; Decrease The Rotation Variable For The Quad ( New )
	Flip
Wend

tom speeds modifield glsl.bmx
'Strict
Rem
Module pub.glsl

ModuleInfo "Version: 1.00"
ModuleInfo "Author: Tom Speed set uniforms bodged by ChrisC"
ModuleInfo "License: Blitz Shared Source Code"
ModuleInfo "Copyrights: Unknown"
ModuleInfo "Modserver: PUB"

Import brl.linkedlist
Import brl.standardio
Import brl.filesystem
Import brl.system
Import pub.glew
EndRem

Global ProgramObjectList:TList = CreateList()
Global ShaderObjectList:TList = CreateList()

Global clog:Byte[1024]' = MemAlloc(linked)
'Shader Object Type
Type tShaderObject
	Field ShaderObject:Int
	Field ShaderType:Int			' 1 = Vert, 2 = Frag
	Field Attached:TList			' Shaders can be attached, or 'referenced by', more than 1 ProgramObject
	Field shaderName:String
End Type

'Program Object Type
Type tProgramObject
	Field Program:Int		' The ProgramObject
	Field vList:TList		' Vertex shader list. A List of what Vert shaders are attached to this ProgramObject
	Field fList:TList		' Frag shader list. A List of what Frag shaders are attached to this ProgramObject
	Field progName:String
	
	Field vertShaderCount:Int
	Field fragShaderCount:Int



	'----------------------------------------------------
	'tProgramObject.Create(name:String)
	'
	'Creates a new Shader Program Object to which
	'multiple Vert and/or Frag Shaders can be attached to
	'
	'Returns: The newly created Program Objects ID if
	'         successful, or Null if it failed.
	'----------------------------------------------------
	Function Create:tProgramObject(name:String = "null")
		Local p:tProgramObject = New tProgramObject
		
		'Create a new GL ProgramObject
		p.Program = glCreateProgramObjectARB()
		If p.Program<1
			p = Null
			?Debug
				Print "Error: glCreateProgramObjectARB() failed"
			?
			Return Null
		End If
		
		'---------------------------------
		'The amount of Vert & Frag Shaders
		'attached to this Program Object
		'---------------------------------
		p.vertShaderCount = 0
		p.fragShaderCount = 0
	
		'---------------------------------------
		'These lists contain any Vert or Frag
		'Shader Objects Attached to this Program
		'---------------------------------------
		p.vList:TList = CreateList()
		p.fList:TList = CreateList()
		
		'This Program Objects Name
		p.progName = name
		
		'------------------------------
		'Add this Program Object to the
		'Global list of ProgramObjects
		'------------------------------
		ListAddLast ProgramObjectList, p
		Return p
	End Function

	
	'---------------------------------
	'tProgramObject.Activate()
	'
	'Activates (uses!) a ProgramObject
	'---------------------------------
	Method Activate()
		glUseProgramObjectARB(Program)
	End Method


	'----------------------------
	'tProgramObject.DeActivate()
	'
	'Turns off this ProgramObject
	'----------------------------
	Method DeActivate()
		glUseProgramObjectARB(0)
	End Method



	' Get the Uniform Variable Location from a ProgramObject
	Method GetUniLoc:Int(name:String)
		Return glGetUniformLocationARB(Program, Varptr name)
	End Method

	' Get the Attribute Variable Location from a ProgramObject
	Method GetAttribLoc:Int(name:String)
		Return glGetAttribLocationARB(Program, Varptr name)
	End Method
	

	' Set Uniform Variable Integer(s)
	Method setUI1(name:String,val:Int)
		Local loc:Int = glGetUniformLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Uniform Var Location '"+name+"' in Method setUI1"
				Return
			End If
		?
		glUniform1iARB(loc,val)
	End Method

	Method setUI2(name:String,val1:Int,val2:Int)
		Local loc:Int = glGetUniformLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Uniform Var Location '"+name+"' in Method setUI2"
				Return
			End If
		?
		glUniform2iARB(loc,val1,val2)
	End Method

	Method setUI3(name:String,val1:Int,val2:Int,val3:Int)
		Local loc:Int = glGetUniformLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Uniform Var Location '"+name+"' in Method setUI3"
				Return
			End If
		?
		glUniform3iARB(loc,val1,val2,val3)
	End Method

	Method setUI4(name:String,val1:Int,val2:Int,val3:Int,val4:Int)
		Local loc:Int = glGetUniformLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Uniform Var Location '"+name+"' in Method setUI4"
				Return
			End If
		?
		glUniform4iARB(loc,val1,val2,val3,val4)
	End Method

	Method getUI1:Int(name:String)
		Local loc:Int = glGetUniformLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Uniform Var Location '"+name+"' in Method getUI1"
				Return
			End If
		?
		Local val:Int = 10
		glGetUniformivARB(Program, loc, Varptr(val))
		Return val
	End Method
	
	
	' Set Uniform Variable Float(s)
	Method setUF1(name:String,val:Float)
		Local loc:Int = glGetUniformLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Uniform Var Location '"+name+"' in Method setUF1"
				Return
			End If
		?
		glUniform1fARB(loc,val)
	End Method

	Method setUF2(name:String,val1:Float,val2:Float)
		Local loc:Int = glGetUniformLocationARB(Program, name.ToCString() )
		?Debug
			If loc<0
				Print ">Error getting Uniform Var Location '"+name+"' in Method setUF2"
				Return
			End If
		?
		glUniform2fARB(loc,val1,val2)
	End Method

	Method setUF3(name:String,val1:Float,val2:Float,val3:Float)
		Local loc:Int = glGetUniformLocationARB(Program, name.ToCString())

		?Debug
			If loc<0
				Print "Error getting Uniform Var Location '"+name+"' in Method setUF3"
				Return
			End If
		?
		glUniform3fARB(loc, val1, val2, val3)
	End Method

	Method setUF4(name:String,val1:Float,val2:Float,val3:Float,val4:Float)
		Local loc:Int = glGetUniformLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Uniform Var Location '"+name+"' in Method setUF4"
				Return
			End If
		?
		glUniform4fARB(loc,val1,val2,val3,val4)
	End Method

	' Set Attribute Variable Short(s)
	Method setAS1(name:String, val1:Short)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAS1"
				Return
			End If
		?
		glVertexAttrib1sARB(loc, val1)
	End Method

	Method setAS2(name:String, val1:Short, val2:Short)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAS2"
				Return
			End If
		?
		glVertexAttrib2sARB(loc, val1, val2)
	End Method

	Method setAS3(name:String, val1:Short, val2:Short, val3:Short)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAS3"
				Return
			End If
		?
		glVertexAttrib3sARB(loc, val1, val2, val3)
	End Method

	Method setAS4(name:String, val1:Short, val2:Short, val3:Short, val4:Short)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAS4"
				Return
			End If
		?
		glVertexAttrib4sARB(loc, val1, val2, val3, val4)
	End Method
	
	' Set Attribute Variable Float(s)
	Method setAF1(name:String, val1:Float)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAF1"
				Return
			End If
		?
		glVertexAttrib1fARB(loc, val1)
	End Method

	Method setAF2(name:String, val1:Float, val2:Float)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAF2"
				Return
			End If
		?
		glVertexAttrib2fARB(loc, val1, val2)
	End Method

	Method setAF3(name:String, val1:Float, val2:Float, val3:Float)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAS3"
				Return
			End If
		?
		glVertexAttrib3fARB(loc, val1, val2, val3)
	End Method

	Method setAF4(name:String, val1:Float, val2:Float, val3:Float, val4:Float)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAF4"
				Return
			End If
		?
		glVertexAttrib4fARB(loc, val1, val2, val3, val4)
	End Method

	' Set Attribute Variable Double(s)
	Method setAD1(name:String, val1:Double)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAD1"
				Return
			End If
		?
		glVertexAttrib1fARB(loc, val1)
	End Method

	Method setAD2(name:String, val1:Double, val2:Double)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAD2"
				Return
			End If
		?
		glVertexAttrib2fARB(loc, val1, val2)
	End Method

	Method setAD3(name:String, val1:Double, val2:Double, val3:Double)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAD3"
				Return
			End If
		?
		glVertexAttrib3fARB(loc, val1, val2, val3)
	End Method

	Method setAD4(name:String, val1:Double, val2:Double, val3:Double, val4:Double)
		Local loc:Int = glGetAttribLocationARB(Program, name.ToCString())
		?Debug
			If loc<0
				Print "Error getting Attribute Var Location '"+name+"' in Method setAD4"
				Return
			End If
		?
		glVertexAttrib4fARB(loc, val1, val2, val3, val4)
	End Method


	'----------------------------------------------------------
	'Attach & Link a Vertex Shader Object to this ProgramObject
	'----------------------------------------------------------
	Method AttachVertShader:Int(myShader:tShaderObject)
		?Debug
			If Program = 0
				Print "Error: Invalid tProgramObject in method AddVertShader()"
				Print "-------------------------------------------------------"
				Print
			Else If Not myShader
				Print "Error: Invalid tShaderObject passed to method AddVertShader()"
				Print "-------------------------------------------------------------"
				Print
				Return
			End If
		?


		'--------------------------
		'Attach & Link a VertShader
		'--------------------------
		glAttachObjectARB(Program, myShader.ShaderObject)
		glLinkProgramARB(Program)


		'-------------------------------
		'Check if it Linked successfully
		'-------------------------------
		Local linked:Int
		glGetObjectParameterivARB(Program,GL_OBJECT_LINK_STATUS_ARB, Varptr(linked))
		
		If Not linked
			?Debug
				'An Error occured during Linking
				'dump the error logfile to console
'				Local clog:Byte Ptr
				Local slen:Int = 0

				glGetInfoLogARB(Program,1023,Varptr slen, Varptr clog[0])
				Local err:String
				Local i:Int
				For i = 0 To slen-1
					err:+Chr(clog[i])
				Next

				Print
				Print "Failed to link VertexShader "+myShader.shaderName
				Print
				Print err+"  "+slen
			?
'			FlushMem
			Return 0
		End If
		?Debug
			Print "VertexShader "+myShader.shaderName+" attached & linked ok!"
			Print
		?
	
		'Add this VertShaderObject to this ProgramObjects list
		ListAddLast vList, myShader

		'Add this ProgramObject to this Shaders 'attached to' list
		ListAddLast myShader.Attached, Self
		Return 1
	End Method

	'------------------------------------------------------------
	'Attach & Link a Fragment Shader Object to this ProgramObject
	'------------------------------------------------------------
	Method AttachFragShader:Int(myShader:tShaderObject)
		?Debug
			If Program = 0
				Print "Error: Invalid tProgramObject in method AddFragShader()"
				Print "-------------------------------------------------------"
				Print
			Else If Not myShader
				Print "Error: Invalid tShaderObject passed to method AddFragShader()"
				Print "-------------------------------------------------------------"
				Print
				Return
			End If
		?


		'--------------------------
		'Attach & Link a FragShader
		'--------------------------
		glAttachObjectARB(Program, myShader.ShaderObject)
		glLinkProgramARB(Program)


		'-------------------------------
		'Check if it Linked successfully
		'-------------------------------
		Local linked:Int
		glGetObjectParameterivARB(Program,GL_OBJECT_LINK_STATUS_ARB, Varptr(linked))

		If Not linked
			?Debug
				'An Error occured during Linking
				'dump the error logfile to console
'				Local clog:Byte Ptr
				Local slen:Int = 0

				glGetInfoLogARB(Program,1023,Varptr slen, Varptr clog[0])
				Local err:String
				Local i:Int
				For i = 0 To slen-1
					err:+Chr(clog[i])
				Next

				Print
				Print "Failed to link FragShader '"+myShader.shaderName+"'"
				Print
				Print err
			?
			
'			FlushMem
			Return 0
		End If

		?Debug
			Print "FragShader '"+myShader.shaderName+"' attached & linked ok!"
			Print
		?
		
		'Add this FragShaderObject to this ProgramObjects list
		ListAddLast fList, myShader
		
		'Add this ProgramObject to this Shaders 'attached to' list
		ListAddLast myShader.Attached, Self
		
		'Return Ok!
		Return 1
	End Method	

	'-------------------------------------------------------
	'Detach a VertShader:tShaderObject from a tProgramObject
	'-------------------------------------------------------
	Method DetachVertShader(vShader:tShaderObject)
		If ListContains(vList,vShader)
			glDetachObjectARB(Program, vShader.ShaderObject)
			RemoveLink(ListFindLink(vList,vShader))
			RemoveLink(ListFindLink(vShader.Attached, Self))
			?Debug
				Print "Detached '"+vShader.shaderName+"' from ProgramObject '"+Self.progName+"'"
			?
		End If
	End Method

	'-------------------------------------------------------
	'Detach a FragShader:tShaderObject from a tProgramObject
	'-------------------------------------------------------
	Method DetachFragShader(fShader:tShaderObject)
		If ListContains(fList,fShader)
			glDetachObjectARB(Program, fShader.ShaderObject)
			RemoveLink(ListFindLink(fList,fShader))
			RemoveLink(ListFindLink(fShader.Attached, Self))
			?Debug
				Print "Detached '"+fShader.shaderName+"' from ProgramObject '"+Self.progName+"'"			
			?
		End If
	End Method
	
	'------------------------------------------------------
	'Dump a list of Shaders attached to this tProgramObject
	'------------------------------------------------------
	Method ListAttachedShaders()
		Print "Vertex Shader(s) attached to ProgramObject '"+Self.progName+"'"
		Print "----------------------------------------------------------------------"
		If vList.Count() = 0
			Print "No Vertex Shaders attached"
		Else
			For Local v:tShaderObject = EachIn vList
				Print v.shaderName
			Next
		End If
		
		Print
		Print "Fragment Shader(s) attached to ProgramObject '"+Self.progName+"'"
		Print "-----------------------------------------------------------------------"
		If fList.Count() = 0
			Print "No Fragment Shaders attached"
		Else
			For Local f:tShaderObject = EachIn fList
				Print f.shaderName
			Next
		End If
		Print
	End Method
End Type




'-----------------------------------------------------------
'CreateVertShader:tShaderObject(shaderFileName:String)
'
'Creates a Vertex Shader Object from a File
'
'Returns: A tShaderObject if successful, or Null if it fails
'-----------------------------------------------------------
Function CreateVertShader:tShaderObject(shaderFileName:String)
	' Load the shader and dump it into a Byte Array
	Local file:TStream = ReadFile(shaderFileName)
	If Not file
		?Debug
			Print "Error, can not load file: "+shaderFileName
		?
		Return Null
	End If
	
	Local tempShaderName:String = StripAll(shaderfileName)+"."+ExtractExt(shaderfileName)
	Local FileLength:Int = FileSize(shaderFileName)
	Local ShaderObject:Int
	Local myShader:tShaderObject = New tShaderObject
	
	myShader.ShaderObject = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)
	myShader.shaderType = 1 ' 1 = Vert, 2 = Frag/Pixel

	Local i:Int = 0
	Local shaderSrc:Byte[FileLength+1]

	While Not Eof(file)
		shaderSrc[i] = ReadByte(file)
		i:+1
		If i>FileLength Then i = FileLength
	Wend
	CloseFile(file)

	' Null terminate it
	shaderSrc[i] = 0 'Null terminate (important!)
	
	Local shaderLen:Int[1]
	shaderLen[0] = i

	Local shaderPtr:Byte Ptr[1]
	shaderPtr[0] = Varptr(shaderSrc[0])

	' Send shader to ShaderObject, then compile it
	glShaderSourceARB(myShader.ShaderObject,1, shaderPtr, Null)
	Local time:Int = MilliSecs()
	glCompileShaderARB(myShader.ShaderObject)
	time = (MilliSecs()-time)

	' Did the shader compile successfuly?
	Local compiled:Int
	glGetObjectParameterivARB(myShader.ShaderObject,GL_OBJECT_COMPILE_STATUS_ARB, Varptr(compiled))

	If Not compiled

		?Debug
		' Get the cause of the error
		Local logLength:Int
		glGetObjectParameterivARB(myShader.ShaderObject,GL_OBJECT_INFO_LOG_LENGTH_ARB, Varptr(logLength))

		Print "Failed to compile "+tempShaderName
		Print
'		Local clog:Byte Ptr
		Local slen:Int = 0

		glGetInfoLogARB(myShader.ShaderObject,1023,Varptr(slen), Varptr clog[0])
		Local err:String
		For i = 0 To logLength-1
			err:+Chr(clog[i])
		Next
		Print err
		?
		

		myShader = Null
'		FlushMem
		Return Null
	End If
	
	?Debug
		Print "Compiled: "+tempShaderName+" successfuly in "+time+"ms"
		Print
	?

	myShader.Attached = New TList
	myShader.shaderName = tempShaderName
	ListAddLast ShaderObjectList, myShader
	
'	FlushMem
	Return myShader
End Function


'-----------------------------------------------------------
'CreateFragShader:tShaderObject(shaderFileName:String)
'
'Creates a Fragment Shader Object from a File
'
'Returns: A tShaderObject if successful, or Null if it fails
'-----------------------------------------------------------
Function CreateFragShader:tShaderObject(shaderFileName:String)
	
	'Check the File exists
	Local file:TStream = ReadFile(shaderFileName)
	If Not file
		?Debug
			Print "Error: Could not Load File: "+shaderFileName
		?
		Return Null
	End If
	
	Local tempShaderName:String = StripAll(shaderfileName)+"."+ExtractExt(shaderfileName)
	Local FileLength:Int = FileSize(shaderFileName)
	Local ShaderObject:Int
	Local myShader:tShaderObject = New tShaderObject
	
	myShader.ShaderObject = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)
	myShader.shaderType = 2

	Local i:Int = 0
	
	'Create a Byte Array to which the Shader Source will be copied to
	'The extra Array Byte (FileLength+1) is so we can Null terminate the array
	Local shaderSrc:Byte[FileLength+1]

	While Not Eof(file)
		shaderSrc[i] = ReadByte(file)
		i:+1
		If i>FileLength Then i = FileLength
	Wend
	CloseFile(file)

	'Null terminate it
	shaderSrc[i] = 0 'Null terminate (important!)
	
	'The Length of the Source
	Local shaderLen:Int[1]
	shaderLen[0] = i

	'A Byte Pointer Array that points to the Shader Source
	Local shaderPtr:Byte Ptr[1]
	shaderPtr[0] = Varptr(shaderSrc[0])

	'Send the Shader to the ShaderObject, then Compile it
	glShaderSourceARB(myShader.ShaderObject,1, shaderPtr, Null)
	Local time:Int = MilliSecs()
	glCompileShaderARB(myShader.ShaderObject)
	time = (MilliSecs()-time)

	'Did the shader compile successfuly?
	Local compiled:Int
	glGetObjectParameterivARB(myShader.ShaderObject,GL_OBJECT_COMPILE_STATUS_ARB, Varptr(compiled))

	If Not compiled

		?Debug
			'Get the cause of the error
			Local logLength:Int
			glGetObjectParameterivARB(myShader.ShaderObject,GL_OBJECT_INFO_LOG_LENGTH_ARB, Varptr(logLength))

			Print "Failed to compile "+tempShaderName
			Print	

	'		Local clog:Byte Ptr
			Local slen:Int = 0
	'		clog = GCMalloc(logLength)
			glGetInfoLogARB(myShader.ShaderObject,1024,Varptr(slen), Varptr clog[0])
			Local err:String

			For i = 0 To logLength-1
				err:+Chr(clog[i])
			Next
			Print err
		?
		
		myShader = Null
'		FlushMem
		Return Null
	End If
	?Debug
	Print "Compiled: "+tempShaderName+" successfuly in "+time+"ms"
	Print
	?

	'Create a list of what ProgramObjects this Shader is Attached to
	myShader.Attached = New TList
	myShader.shaderName = tempShaderName
	ListAddLast ShaderObjectList, myShader
	
'	FlushMem
	Return myShader
End Function


Function DeleteVertShader(vShader:tShaderObject Var)
	If Not vShader Return

	RemoveLink(ListFindLink(ShaderObjectList,vShader))
	
	' Detach this ShaderObject from all ProgramObjects it was attached to
	For Local p:tProgramObject = EachIn ProgramObjectList
		If ListContains(p.vList, vShader)
			p.DetachVertShader(vShader)
		End If
	Next
	
	' Delete the shader
	glDeleteObjectARB(vShader.ShaderObject)
	?Debug
		Print "Deleted ShaderObject '"+vShader.shaderName+"'"
		Print
	?
	vShader = Null
'	FlushMem
End Function
	
Function DeleteFragShader(fShader:tShaderObject Var)
	If Not fShader Return
	
	RemoveLink(ListFindLink(ShaderObjectList,fShader))
		
	' Detach this ShaderObject from all ProgramObjects it was attached to
	For Local p:tProgramObject = EachIn ProgramObjectList
		If ListContains(p.fList, fShader)
			p.DetachFragShader(fShader)
		End If
	Next
	
	' Delete the shader
	glDeleteObjectARB(fShader.ShaderObject)
	?Debug
		Print "Deleted ShaderObject '"+fShader.shaderName+"'"
		Print
	?
	fShader = Null
'	FlushMem
End Function

'	FlushMem
'End Function


Shaders are the future! :)

lol that is *so* you!

getting the effect you want with glsl can be quite the challenge sometimes tho!

Yup, the language takes some getting used to, but is definately worth learning. It'll be interesting to see how much the max 3D module uses them, Mark's said it'll likely be 'shader centric'.

This crashes for me in OSX 10.3.9. Is the integrated gaphics card (radeon 9200) too old for this?


Edit:
This is what I find in the "Output" tab:
Building shadertest
Compiling:shadertest.bmx
Linking:shadertest.debug
Executing:shadertest.debug
Op: gl_IntermediateTemp0_35666
Op: gl_Vertex
Op: gl_IntermediateTemp0_5126
Op: vFinalPosition
deep;
Op: gl_IntermediateTemp3_35666
Op: gl_IntermediateTemp3_35666
Op: vFinalPosition
Op: gl_IntermediateTemp0_5126
Op: vFinalPosition
deep;
Op: gl_IntermediateTemp3_35666
Op: gl_IntermediateTemp3_35666
Op: gl_Vertex
deep;
Op: gl_IntermediateTemp4_35666
Op: gl_IntermediateTemp4_35666
Op: gl_Vertex
Op: vFinalPosition
Op: gl_ModelViewProjectionMatrix
Op: gl_IntermediateTemp0_35676
Op: gl_IntermediateTemp0_35676
Op: gl_Position
Op: gl_IntermediateTemp0_35665
Op: vPosition
Op: gl_Normal
Op: gl_NormalMatrix
Op: gl_IntermediateTemp0_35675
Op: gl_IntermediateTemp0_35675
Op: vNormal
Compiled: test.vert successfuly in 20ms


Process complete

I also get an OSX crash window.

hmm, not sure about radeons, try out test.frag and test.vert with some kind of mac shader editor could you?

OSX xtools comes with a simple shader editor but it looks like it doesn't support glsl. And I cannot find any other shader editor for osx. :/

will this work http://www.macinit.com/mifx/index.html

I'd like to get together a simple set of shaders that will work on craptastic (and common) cards like my fx5200 and for that matter your radeon 9200

I've added some animation to both the frag and vert shader, but theres not too much point if I cant get it to work

can you increase the size of the compilers log
Global clog:Byte[1024]
to say 4096 bytes and change
all the
glGetInfoLogARB(Program,1023,Varptr slen, Varptr clog[0])
commands to
glGetInfoLogARB(Program,4095,Varptr slen, Varptr clog[0])

just to see if we have all the output from your cards shader compiler...

cannot compile mifx, it needs xtools 2 and I can only use 1.5 since I'm using osx 10.3.9.

I did the changes to glsl.bmx but nothing new was printed in the output tab. And it still crashes.

I thought xtools 2.2 was 10.4 only, but 2.1 was fine?

well unless someone with a radeon 9200 and a *working* shader editor can give me a little more feedback, I have no clue as to whats wrong, I can send you a simpler shader if your interested...

anyone got a screen shot of the above code in action?

You all have OpenGL v1.5+ drivers? Pretty sure that's what's needed for GLSL

Wasn't the Radeon 9200 a shader version 1 card, I suspect as Tom says it could be a driver problem or perhaps the shader up there using Version 2 functions ?

Testing with a Radeon 9550. glCreateProgramObjectARB() fails.

My guess is something in glew.mod is screwed up.

I determined this happens because ATI cards actually return a long-ass negative number (an unsigned integer).

Now I have to figure out how to convert this into something OpenGL can recognize as a UINT.

I fixed it so it will work with ATI cards.

-vPosition is declared as a vec2 then as a vec3. Change them both to vec3.

-In glsl.bmx, change this:
		'Create a new GL ProgramObject
		p.Program = glCreateProgramObjectARB()
		If p.Program<1

to this:
		'Create a new GL ProgramObject
		p.Program = glCreateProgramObjectARB()
		If p.Program=0