Shader Problems

BlitzMax Forums/OpenGL Module/Shader Problems

AndrewT(Posted 2010) [#1]
I'm having problems with GLSL shaders--namely the fact that they're simply not doing anything.

Here's my code:

SuperStrict

Type NovaShader
	'Vertex shader
	Field VS:Int
	'Fragment shader
	Field FS:Int
	
	'Shader program ID
	Field ID:Int
	
	'Begins the shader.
	Method Bind()
		glUseProgram(ID)
	EndMethod
	
	'Ends the shader.
	Method UnBind()
		glUseProgram(0)
	EndMethod
	
	'Loads a shader
	Function Load:NovaShader(VSFileName:String, FSFileName:String)
		Local S:NovaShader = New NovaShader
	
		'Create shaders
		S.VS = glCreateShader(GL_VERTEX_SHADER)
		S.FS = glCreateShader(GL_FRAGMENT_SHADER)
		
		Local VSFile:TStream = OpenFile(VSFileName)
		Local VSSource:String = LoadText(VSFile)
		VSFile.Close()
		
		Local FSFile:TStream = OpenFile(FSFileName)
		Local FSSource:String = LoadText(FSFile)
		FSFile.Close()

		Local VS_CStr:Byte Ptr = VSSource.ToCString()
		Local FS_CStr:Byte Ptr = FSSource.ToCString()
		
		glShaderSource(S.VS, 1, Varptr(VS_CStr), Null)
		glShaderSource(S.FS, 1, Varptr(FS_CStr), Null)

                MemFree(VS_CStr)
                MemFree(FS_CStr)
		
		glCompileShader(S.VS)
		glCompileShader(S.FS)
		
		S.ID = glCreateProgram()
		glAttachShader(S.ID, S.VS)
		glAttachShader(S.ID, S.FS)
		glLinkProgram(S.ID)
		
		Return S
	EndFunction
EndType

Function NovaStart(DisplayWidth:Int = 640, DisplayHeight:Int = 480, IsFullscreen:Int = 0)
	GLGraphics(DisplayWidth, DisplayHeight, IsFullscreen)
	glEnable(GL_TEXTURE_2D)
	'glEnable(GL_LIGHTING)
	glEnable(GL_DEPTH_TEST)
	glShadeModel(GL_SMOOTH)
	glDepthFunc(GL_LEQUAL)		
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
	glMatrixMode(GL_PROJECTION)
	gluPerspective(45.0, 1024.0 / 768.0, 0.1, 100.0)
	glMatrixMode(GL_MODELVIEW)
	glClearColor(0.0, 0.4, 0.6, 1.0)
	glClearDepth(1.0)	
	
	glewInit()
EndFunction

NovaStart(1024, 768, 0) 

glTranslatef(-1.5, 0.0, -6.5) 
Local Vertices:Float[] = [-1.0, -1.0, 0.0, -1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, -1.0, 0.0]

Local VB:Int
glGenBuffers(1, Varptr(VB)) 
glBindBuffer(GL_ARRAY_BUFFER, VB)
glBufferData(GL_ARRAY_BUFFER, SizeOf(Vertices), Vertices, GL_STATIC_DRAW)

Local Shader:NovaShader = NovaShader.Load("vertshader.vert", "fragshader.frag")

Repeat 

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
	
	glRotatef(1.0, 0.0, 1.0, 0.0) 
	
	Shader.Bind()

	glEnableClientState(GL_VERTEX_ARRAY)
	glBindBuffer(GL_ARRAY_BUFFER, VB)
	glVertexPointer(3, GL_FLOAT, 0, Null)
	glDrawArrays(GL_QUADS, 0, 4) 
	glDisableClientState(GL_VERTEX_ARRAY)
	
	Shader.UnBind()
	
	Flip
	
Until AppTerminate() Or KeyHit(KEY_ESCAPE)




Vertshader.vert:

void main(void)
{
 vec4 a = gl_Vertex;
 a.x = a.x * 0.5;
 a.y = a.y * 0.5;
 a.z = a.z * 0.5;

 gl_Position = gl_ModelViewProjectionMatrix * a;
}


Fragshader.frag:

void main(void)
{
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}


If all goes well the shaders should shrink the square to half-size and color it red. Unfortunately, they're not doing anything. All I get is a rotating white square, which is exactly what I get without the shaders.

Any ideas as to where I'm going wrong?

EDIT:

I've fixed it, I was passing the strings incorrectly.


Kryzon(Posted 2010) [#2]
What is that MemFree function you using?


Nate the Great(Posted 2010) [#3]
I get an error, it wont even compile for me. It says error reading from stream on one of the loadtext lines and I got the shaders and all too...


AndrewT(Posted 2010) [#4]
Nate the Great:

I'm not sure what could be going wrong. Does it say that the pointer is uninitialized (i.e. the stream didn't load), or is it just a problem with reading the data? Check that the pointer isn't null. If the stream just isn't loading then it'll be easier to find the problem, as opposed to the stream being loaded but the data not being read with LoadText().

Kryzon:

In another thread where I asked about passing the string I was told to include that to free the memory. I don't think I need it because of BlitzMax's garbage collection, but I included it anyway. I'll remove it.


Noobody(Posted 2010) [#5]
I don't think I need it because of BlitzMax's garbage collection, but I included it anyway. I'll remove it.

Don't! BMax does not apply garbage collection on pointers, because pointers are, as opposed to references, not 'locked' onto a memory block, but can easily be decremented or incremented to point wherever imagination takes them. This is why BMax leaves it to the programmer himself to free memory blocks allocated with MemAlloc() (which includes C-Strings). Therefore memory leaks will occur if you don't clean up after ToCString().


Kryzon(Posted 2010) [#6]
One thing I always wanted to know about shaders...taking AndrewT for example, will he have to include the source files of his shaders in the distribution of his game or will they be compiled and "embedded" inside the exe?


Dreamora(Posted 2010) [#7]
you must include them in some wayor they don't exist.

you can naturally also provide them in code as a massive string if you want.

But they are not compiled or anything, they are just another text file to bm


AndrewT(Posted 2010) [#8]
Noobody:

Thanks, I've added it again. I've never been very good with memory management :P


Kryzon(Posted 2010) [#9]
Hmmm, indeed Dreamora. That's probably what commercial games do anyway, write shaders in code already instead of external files.


Dreamora(Posted 2010) [#10]
Kryzon: some of them. most of them realize that shader programs run through the pipe in their shader instruction form anyway and can be read right from there and don't waste time on fictive security.


Kryzon(Posted 2010) [#11]
@Dreamora: Indeed again. makes sense too; not long ago I was playing with Dx3DRipper, an app that extracts models, textures and shaders from any app using the D3D api. Just for study, of course!

But still, it requires some amount of intent from the user. So that suggestion of writing it in code strings is very good. Makes everything feel more of a "unit" too.

Thanks for the tips.