glsl 'problem'

BlitzMax Forums/OpenGL Module/glsl 'problem'

AntonyWells(Posted 2005) [#1]
I'm just starting glsl(From cg, so not madly different, but different enough)
and basically I'm not sure why but i can't access anything other than the first binded texture.

this code below generates a vertex/pixel shader based on spec,

'ShaderGEN V0.1
'
'A system designed to generate shaders to replicate
'gl's fixed function functionality.

Type ShaderGen

	Method NewShader(name:String)
	
		Local vertFile:String = name+"Vert.glsl"
		Local pixFile:String = name+"Pix.glsl"
		vfile=WriteFile(vertfile)
		pfile=WriteFile(pixfile)
		useLights=0
			
	End Method
	
	Method GenLights()
		useLights=True
	End Method
	
	Method addTexture( blendMode )
		
		texblend[texnum]=blendmode
		texnum:+1	
		useTextures=1
		
	End Method
	
	Method genPPLights()
		useppLights=True
	End Method
	
	Method Generate()
		
		If useTextures
		
			For Local j=1 To TexNum
				WriteLine vfile,"varying vec2 texCoord"+j+";"
			Next
		EndIf
			writeHeader(vfile)
			writeVertexTForm()
			If useTextures
				
				For Local j=1 To texNum 
					WriteLine vfile,"texCoord"+j+"= vec2(gl_MultiTexCoord"+(j-1)+");"
				Next
								
			EndIf
			
			writeEnd(vfile)
			
			Local pixOut:String = "gl_FragColor = "
			
			If useTextures
			
				
			
				For Local j=1 To TexNum
					WriteLine pfile,"varying vec2 texCoord"+j+";"
					WriteLine pfile,"uniform sampler2D cTexture"+j+";"
					If j>1
						Select texblend[j-1]
							
							Case T_Normal
								pixOut="gl_FragColor = "
							Case T_ADD
								pixOut=pixOut+"+"
							Case T_Modulated
								pixOut=pixOut+"*"
							Case T_Subtract
								pixOut=pixOut+"-"
							Default
								Throw "Undefined texture blending mode."
						End Select
						
					EndIf
					
					pixOut=pixOut+"texture2D(cTexture"+j+",texCoord"+J+")"
				
				Next
				
				pixOut=pixOut+";"
			
			EndIf
			
			writeHeader(pfile)
			WriteLine pfile,pixout
			writeend(pfile)
							
		
		CloseFile vfile
		CloseFile pfile
				
	End Method
	
	Method writeVertexTForm()
	
		WriteLine vfile,"gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
	
	End Method
	
	
	Method writeHeader(file)
		WriteLine file,"void main()"
		WriteLine file,"{"
	End Method
	Method writeEnd(file)
		WriteLine file,"}"
	End Method
		
	Field useLights,useTextures
	Field usePPLights,texNum
	Field vfile,pfile	
	Field texBlend:Int[32]
	Field dred!,dgreen!,dblue!
	Field sred!,sgreen!,sblue!
		
End Type



vert shader it outputed
void main()
{
gl_position = gl_ModelViewProjectionMatrix * gl_Vertex;
}




varying vec2 texCoord1;
uniform sampler2D cTexture1;
varying vec2 texCoord2;
uniform sampler2D cTexture2;
void main()
{
gl_FragColor = texture2D(cTexture1,texCoord1)+texture2D(cTexture2,texCoord2);
}



only texture 2 appears to be texture 1 still..
is there a way to access texture handles through glstate in glsl?


ImaginaryHuman(Posted 2005) [#2]
Good luck, you're probably doing more cutting edge stuff than most people here.


visionastral(Posted 2005) [#3]
you should go to gamedev.com because this forum is for pure opengl coding in blitzmax and glsl is another kind of language very direfent from plain opengl or blitz.
I'm introducing myself into glsl but i've found huge diferences in runtime from a graphic card to another (even with full opengl2.0 support), i've found diferent behaviours in diferent aplications too, wich makes me wonder if I will someday be able to compile something who will run somewhere else than in my computer...
I've found diferences from RenderDonkey to ShaderDesigner (in RD it simply don't do parallax mapping, since the same code in SD works well). It's quite strange.
Another thing I noticed is that Shader Designer's example shows a compile error in a GeForceFX (i don't remember the FX number sorry) since in my ATI radeon 9800 pro a large number of examples work but fractal kind don't.
In RenderDonkey the same code compile well in my ATI but the effect don't work at all (parallax mapping).

I haven't coded shaders inside BMX right now, and i'm finding my way into doing it but i have noticed one important thing: it seems it's not the same using ARB extensions than using actual OpengGL2.0 commands instead.
It shouldn't be this way because the modif between the ARB and the final commands are very litle, however, it seems that the drivers of the graphic cards do have great diferences from ARB to final ones...
This kind of things makes one turning mad because you actually don't know if it doesn't compile because of a coding error or because of an implementation deficience...
(just this line makes my fragment shader turn absolutly mad: float A=gl_FragCoord.x)
However, ATI drivers seems to be more tolerant than geforce ones.

Good luck


AdrianT(Posted 2005) [#4]
thats why D3D and .FX is so popular. GL just hasn't kept up and tried to standardise across different hardware the same way D3D has. Supporting high end feature sin GL can be like coding your own video drivers specificly for certain cards, like you had to on older PC games pre DirectX. Bit of a nightmare. Particularly for artists who's shader tools favour D3D. Still, if you want cross platform I guess you havent much choise at the moment.


marksibly(Posted 2005) [#5]
Hi,

Haven't played with glsl for a while, but I think the idea is to find the 'index' of the shader sampler by name, and then use SetShaderConstInt or whatever it is with the texture unit the texture is bound to.


AntonyWells(Posted 2005) [#6]
Yeah, Mark it's glUniformIArb(blah) with the sampler object.
Discovered it the old fashioned way.(Looked at someone elses code :) )
-

Joah, I know what you mean about not knowing why shaders fail to compile(I hate the generate lack of debug info too) but glsl does have shader and program logs(English) that can be 'got'. No idea the kind of information they return though.

Here's a new version of shaderGen, for anyone interested. It now generates lights as well as blend modes/color scale.


Type ShaderGen

	Method NewShader(name:String)
	
		Local vertFile:String = name+"Vert.glsl"
		Local pixFile:String = name+"Pix.glsl"
		vfile=WriteFile(vertfile)
		pfile=WriteFile(pixfile)
		useLights=0
			
	End Method
	
	Method GenLights()
		useLights=True
	End Method
	
	Method addTexture( blendMode,coordset,colorscale)
		
		texblend[texnum]=blendmode
		texset[texnum]=coordset
		texcscale[texnum]=colorscale
		texnum:+1	
		useTextures=1
		
	End Method
	
	Method genPPLights()
		useppLights=True
	End Method
	
	Method Generate()
		
		If useTextures
		
			For Local j=1 To TexNum
				WriteLine vfile,"varying vec2 texCoord"+j+";"
			Next
		EndIf
		
			writeHeader(vfile)
			
			If uselights
			'	Rem
				WriteLine vfile,"vec3 normal,viewVector,halfVector;"
			 	WriteLine vfile,"vec3 lightDir;"
			 	WriteLine vfile,"vec4 diffuse, ambient, globalAmbient, specular = vec4(0.0);"
			 	WriteLine vfile,"float ndotl,ndothv;"
			 	WriteLine vfile,""
			 	WriteLine vfile,"normal = normalize( gl_NormalMatrix * gl_Normal );"
			 	WriteLine vfile,""
			'	Rem
			 	For  Local j=1 To lcount
			 		WriteLine vfile,"lightDir = normalize( vec3( gl_LightSource["+(j-1)+"].position));"
			  		WriteLine vfile,"ndotl = max( dot(normal,lightDir),0.0);"
			 		WriteLine vfile,"diffuse=diffuse+gl_FrontMaterial.diffuse * gl_LightSource["+(j-1)+"].diffuse;"
			 		WriteLine vfile,"ambient=ambient+gl_FrontMaterial.ambient * gl_LightSource["+(j-1)+"].ambient;"
			 		WriteLine vfile,"globalAmbient=globalAmbient+gl_LightModel.ambient * gl_FrontMaterial.ambient;"  
			 		WriteLine vfile,""
			 		WriteLine vfile,"if(ndotl>0.0){"
			 		WriteLine vfile,"ndothv = max(dot(normal,normalize(gl_LightSource["+(j-1)+"].halfVector.xyz)),0.0);"
			 		WriteLine vfile,"specular=specular+ gl_FrontMaterial.specular * gl_LightSource["+(j-1)+"].specular * pow(ndothv,gl_FrontMaterial.shininess);"
			 		WriteLine vfile,"}"
			 		WriteLine vfile,""
			 	Next
				'End Rem
			
				WriteLine vfile,"gl_FrontColor = globalAmbient + ndotl * diffuse + ambient + specular;"
			EndIf
			
			WriteLine vfile,"gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
			'writeVertexTForm()
			If useTextures
				
				For Local j=1 To texNum 
					WriteLine vfile,"texCoord"+j+"= vec2(gl_MultiTexCoord"+(j-1)+");"
				Next
								
			EndIf
			
			writeEnd(vfile)
			
			Local pixOut:String = ""
			
			If useTextures
			
				Local prePad:String
				Local postPad:String
				
							
				For Local j=1 To TexNum
					WriteLine pfile,"varying vec2 texCoord"+j+";"
					WriteLine pfile,"uniform sampler2D cTexture"+j+";"
					prePad=""
					postPad=""
					
					If j>1
						
						Select texblend[j-1]
							
							Case T_Normal
								pixOut=""
							Case T_ADD
								pixOut=pixOut+"+"
							Case T_Modulated
								pixOut=pixOut+"*"
							Case T_Subtract
								pixOut=pixOut+"-"
							Default
								Throw "Undefined texture blending mode."
						End Select
						
					EndIf
					
					Select texcScale[j-1]
						Case 1 'optimized. leaner. the real mcdaddy baddy.
					
						Default
							prePad="("
							postPad="*"+texcScale[j-1]+")"
					End Select
					
					pixOut=pixOut+prePad+"texture2D(cTexture"+j+",texCoord"+texset[J-1]+")"+postPad
				
				Next
				
				
				pixOut=pixOut+";"
			
			EndIf
			
			writeHeader(pfile)
			
			If useLights
			
				For Local j=1 To lcount
							
				Next
				
			End If
			
			WriteLine pfile,"gl_FragColor = gl_Color +"+pixout+";"
			writeend(pfile)
							
		
		CloseFile vfile
		CloseFile pfile
				
	End Method
	
	Method writeVertexTForm()
	
		WriteLine vfile,"gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
	
	End Method
	
	
	Method writeHeader(file)
		WriteLine file,"void main()"
		WriteLine file,"{"
	End Method
	Method writeEnd(file)
		WriteLine file,"}"
	End Method
	
	Method addlight()
		lcount:+1
		uselights=True
	End Method
	
	Method reset()
		uselights=0
		usetextures=0
		usepplights=0
		texnum=0
		lcount=0
	End Method

		
	Field lcount
	Field useLights,useTextures
	Field usePPLights,texNum
	Field vfile,pfile,texcscale:Int[32]	
	Field texBlend:Int[32],texSet:Int[32]
	Field dred!,dgreen!,dblue!
	Field sred!,sgreen!,sblue!
		
End Type



example vert shader,

varying vec2 texCoord1;
void main()
{
vec3 normal,viewVector,halfVector;
vec3 lightDir;
vec4 diffuse, ambient, globalAmbient, specular = vec4(0.0);
float ndotl,ndothv;

normal = normalize( gl_NormalMatrix * gl_Normal );

lightDir = normalize( vec3( gl_LightSource[0].position));
ndotl = max( dot(normal,lightDir),0.0);
diffuse=diffuse+gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
ambient=ambient+gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
globalAmbient=globalAmbient+gl_LightModel.ambient * gl_FrontMaterial.ambient;

if(ndotl>0.0){
ndothv = max(dot(normal,normalize(gl_LightSource[0].halfVector.xyz)),0.0);
specular=specular+ gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(ndothv,gl_FrontMaterial.shininess);
}

lightDir = normalize( vec3( gl_LightSource[1].position));
ndotl = max( dot(normal,lightDir),0.0);
diffuse=diffuse+gl_FrontMaterial.diffuse * gl_LightSource[1].diffuse;
ambient=ambient+gl_FrontMaterial.ambient * gl_LightSource[1].ambient;
globalAmbient=globalAmbient+gl_LightModel.ambient * gl_FrontMaterial.ambient;

if(ndotl>0.0){
ndothv = max(dot(normal,normalize(gl_LightSource[1].halfVector.xyz)),0.0);
specular=specular+ gl_FrontMaterial.specular * gl_LightSource[1].specular * pow(ndothv,gl_FrontMaterial.shininess);
}

gl_FrontColor = globalAmbient + ndotl * diffuse + ambient + specular;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
texCoord1= vec2(gl_MultiTexCoord0);
}




Tom(Posted 2005) [#7]
Ant, check this out if you aint seen it already:

http://www.tomspeed.com/glsl/

I give up on this stuff til Mark brings out the real deal :)


AntonyWells(Posted 2005) [#8]
Thanks, but ditto. :)