GL shader extensions on windows [solved]

Started by
5 comments, last by biggoron 16 years, 3 months ago
Hello. I've managed to write some basic lighting shaders and work them into a Windows GL program using the ARB extensions. I know everything works, because I can write a pair of trivial shaders and get what I expect. However, my current shaders, which rely on application-set lighting variables (set by GL's normal lighting functions) won't work. The shaders are written correctly, as far as I know, and they are read, compiled, linked, and used without problem, as far as I can tell. I think the problem lies in the way I am communicating from my application to the shaders, but I can't see any problems. All help is appreciated. Thanks. P.S. The code is very ugly, I know, but I'm just trying to get it to work, ATM.

[vert.gl]
varying vec4 diffuse, ambient;
varying vec3 normal, lightDir, halfVector;

void main(void) {
	normal = normalize(gl_NormalMatrix * gl_Normal);
	
	lightDir = normalize(vec3(gl_LightSource[0].position));
	halfVector = normalize(gl_LightSource[0].halfVector.xyz);
	
	diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
	ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
	ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient;
	
	gl_Position = ftransform();
}


[frag.gl]
varying vec4 diffuse, ambient;
varying vec3 normal, lightDir, halfVector;

void main(void) {
	vec3 n, halfV;
	float NdotL, NdotHV;
	
	vec4 color = ambient;
	
	n = normalize(normal);
	
	NdotL = max(dot(n, lightDir), 0.0);
	
	if(NdotL > 0.0) {
		color += diffuse * NdotL;
		halfV = normalize(halfVector);
		NdotHV = max(dot(n, halfV), 0.0);
		color += gl_FrontMaterial.specular *
					gl_LightSource[0].specular *
					pow(NdotHV, gl_FrontMaterial.shininess);
	}
	
	gl_FragColor = color;
}


[main.cpp]
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>

void init(void);
void display(void);
void reshape(int, int);
void idle(void);

int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
	
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(640, 480);
	glutCreateWindow(argv[0]);
	
	init();
	
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutIdleFunc(idle);
	
	glutMainLoop();
	
	return 0;
}

char *textFileRead(char *fn)
{
	FILE *fp;
	char *content = NULL;

	int count=0;

	if (fn != NULL) {
		fp = fopen(fn,"rt");

		if (fp != NULL) {
      
      fseek(fp, 0, SEEK_END);
      count = ftell(fp);
      rewind(fp);

			if (count > 0) {
				content = (char *)malloc(sizeof(char) * (count+1));
				count = fread(content,sizeof(char),count,fp);
				content[count] = '\0';
			}
			fclose(fp);
		}
	}
	return content;
}

void init(void)
{
	glColor3f(1, 1, 1);
	
	glClearColor(0, 0, 0, 0);
	glClearDepth(1);
	
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	GLfloat matSpec[] = {1.0, 1.0, 1.0, 1.0};
	GLfloat matShininess[] = {50.0};
	GLfloat lightPosition[] = {0.0, 0.0, 0.0, 0.0};
	GLfloat whiteLight[] = {1.0, 1.0, 1.0, 1.0};
	GLfloat lmodelAmbient[] = {0.1, 0.1, 0.1, 1.0};
	glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);
	glMaterialfv(GL_FRONT, GL_SHININESS, matShininess);
	glMaterialfv(GL_FRONT, GL_AMBIENT, lmodelAmbient);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, whiteLight);
	glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteLight);
	glLightfv(GL_LIGHT0, GL_SPECULAR, whiteLight);
	glLightfv(GL_LIGHT0, GL_AMBIENT, lmodelAmbient);
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodelAmbient);
	
	PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)wglGetProcAddress("glCreateShaderObjectARB");
	PFNGLSHADERSOURCEARBPROC glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)wglGetProcAddress("glShaderSourceARB");
	PFNGLCOMPILESHADERARBPROC glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)wglGetProcAddress("glCompileShaderARB");
	PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)wglGetProcAddress("glCreateProgramObjectARB");
	PFNGLATTACHOBJECTARBPROC glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)wglGetProcAddress("glAttachObjectARB");
	PFNGLLINKPROGRAMARBPROC glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)wglGetProcAddress("glLinkProgramARB");
	PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)wglGetProcAddress("glUseProgramObjectARB");
	PFNGLGETINFOLOGARBPROC glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)wglGetProcAddress("glGetInfoLogARB");
	
	char* vs;
	char* fs;
	
	GLhandleARB v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
	GLhandleARB f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
	
	vs = textFileRead("vert.gl");
	fs = textFileRead("frag.gl");
	
	const char* vv = vs;
	const char* ff = fs;
	
	glShaderSourceARB(v, 1, (const GLcharARB**)&vv, NULL);
	glShaderSourceARB(f, 1, (const GLcharARB**)&ff, NULL);
	
	free(vs);
	free(fs);
	
	glCompileShaderARB(v);
	glCompileShaderARB(f);
	
	GLcharARB log[1024] = {0};
	glGetInfoLogARB(v, 1024, NULL, log);
	printf(log);
	glGetInfoLogARB(f, 1024, NULL, log);
	printf(log);
	
	GLhandleARB p = glCreateProgramObjectARB();
	
	glAttachObjectARB(p, v);
	glAttachObjectARB(p, f);
	
	glLinkProgramARB(p);
	glUseProgramObjectARB(p);
}

void display(void)
{
	static float r = 0;
	r = (r > 360) ? (0) : (r += 0.1);
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glPushMatrix();
	glRotatef(r, 0, 1, 0);
	
	glutSolidTeapot(1);
	
	glPopMatrix();
	
	glutSwapBuffers();
}

void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45, (float)w/(float)h, 1, 256);
	gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void idle(void)
{
	glutPostRedisplay();
}

[Edited by - biggoron on December 31, 2007 1:02:50 PM]
Advertisement
I know this isn't very helpful, but usually people won't even look at your code unless you wrap it in

[_source_][\_source_] tags (only without the underscores) Please have one set of tags for each of your shaders and then your program, you'll be much more likely to get help that way.
When General Patton died after World War 2 he went to the gates of Heaven to talk to St. Peter. The first thing he asked is if there were any Marines in heaven. St. Peter told him no, Marines are too rowdy for heaven. He then asked why Patton wanted to know. Patton told him he was sick of the Marines overshadowing the Army because they did more with less and were all hard-core sons of bitches. St. Peter reassured him there were no Marines so Patton went into Heaven. As he was checking out his new home he rounded a corner and saw someone in Marine Dress Blues. He ran back to St. Peter and yelled "You lied to me! There are Marines in heaven!" St. Peter said "Who him? That's just God. He wishes he were a Marine."
Thanks, I was unaware of those tags, though they seem to change a lot of the symbols into HTML symbols.
Did you try using the OpenGL 2.0 API and Entry Points?
It's a Windows program. My Ubuntu machine only supports Mesa 1.3, unfortunately. I am planning on putting Ubuntu on this machine some time soon, though last time I checked there was no driver available for my hardware (Radeon HD 2600 XT).
You should check to see if it has successfuly linked.
After the call to glLinkProgramARB(p);

Assuming it has linked successfully, do some debugging to see if
gl_FrontMaterial.diffuse, gl_LightSource[0].diffuse

and the other stuff you are using contain the values you expect.

Not sure if it would help if you use GL 2.0 entry points, but go ahead.

"[_source_][\_source_] tags (only without the underscores)"

That should be a / instead of a
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Looks like I managed to get it to work. I made a separate program with equivalent shaders, but this time I used my own code, whereas before I was using an example code, and now it works. I'm not sure why, though. The main difference is that many of the lighting terms are calculated per-vertex and passed to the fragments via varying variables in the example shaders, but my shaders simply get the lighting data (colors, shininess, etc.) in the fragment shader.

Thanks all.

This topic is closed to new replies.

Advertisement