I am experiencing problems when trying to load shaders. I will post my code before explaining my observations in more detail. All the code is not shown, instead I have made comments in those places where code has been removed for clarity.
// install function of shader class.
// Initialize handles to zero.
//
GLhandleARB vs_shader_obj = 0;
GLhandleARB fs_shader_obj = 0;
// Assert that driver supports shaders.
// (pseudo-code)
//
// assert("GL_ARB_shading_language_100")
// assert("GL_ARB_shader_objects")
// assert("GL_ARB_vertex_shader")
// assert("GL_ARB_fragment_shader")
//
// (these assertions don't fail)
// Set the function pointers in function while debugging.
//
PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)wglGetProcAddress("glCreateShaderObjectARB");
PFNGLSHADERSOURCEARBPROC glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)wglGetProcAddress("glShaderSourceARB");
PFNGLGETSHADERSOURCEPROC glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)wglGetProcAddress("glGetShaderSource");
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)wglGetProcAddress("glGetObjectParameterivARB");
PFNGLGETSHADERIVPROC glGetShaderiv = (PFNGLGETSHADERIVPROC)wglGetProcAddress("glGetShaderiv");
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)wglGetProcAddress("glGetShaderInfoLog");
// Check extension validity.
// (these assertions don't fail)
//
assert( 0 != glCreateShaderObjectARB );
assert( 0 != glShaderSourceARB );
assert( 0 != glGetShaderSource );
assert( 0 != glGetObjectParameterivARB );
assert( 0 != glGetShaderiv );
assert( 0 != glGetShaderInfoLog );
// Now do the actual work.
//
vs_shader_obj = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
// Don't fail.
//
assert( 0 != vs_shader_obj );
assert( 0 == glGetError() );
// Setup the string to pass as shader source
// to OpenGL. Hard-coded for debugging.
// The simplest possible vertex shader.
//
const GLcharARB hard_coded_src[] = "void main(){gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;}";
GLint length = static_cast<GLint>(strlen(hard_coded_src)); // Does not count trailing null-termination character?!
GLcharARB* vs_src = new GLcharARB[length+1]; // Reserve one trailing character for null-termination.
memcpy( vs_src, &hard_coded_src[0], length*sizeof(GLcharARB) );
vs_src[length] = 0; // Explicit null-termination.
glShaderSourceARB( vs_shader_obj,
1, // Pass as one string.
(const GLcharARB**)&vs_src, // Ugly C-style cast...
0 ); // Null-termination criteria used.
// Read back source.
// Compare is zero, suggesting that
// the fetched source is the same as
// the uploaded source.
// src_size == length
//
GLcharARB dummy[4096];
GLint src_size;
glGetShaderSource( vs_shader_obj, 4096, &src_size, &dummy[0] );
GLcharARB* fetch_src = new GLcharARB[src_size];
glGetShaderSource( vs_shader_obj, src_size, &src_size, fetch_src );
int compare = memcmp( vs_src, fetch_src, src_size );
delete[] fetch_src;
assert( 0 == glGetError() ); // Passes.
GLint shader_compiled; // Error flag.
glGetObjectParameterivARB( vs_shader_obj,
GL_COMPILE_STATUS, //GL_OBJECT_COMPILE_STATUS_ARB?
&shader_compiled );
assert( 0 == glGetError() ); // Passes.
// Fetch compile log.
// log_length == 1, i.e. no log message
//
GLint log_length;
glGetShaderiv( vs_shader_obj, GL_INFO_LOG_LENGTH, &log_length );
GLcharARB* log_msg = new GLcharARB[log_length];
glGetShaderInfoLog( vs_shader_obj,
log_length,
0,
log_msg );
// Print log_msg...
delete[] log_msg;
delete[] vs_src;
// Exit function here, since
// shader_compiled == 0
if( GL_FALSE == shader_compiled )
{ // Compilation failure.
return false;
}
// Rest of funtion (not reached)
// * Compile fragment shader
// * Attach to shaders to program object
// * Link program object.
// * Locate uniforms.
// * return true.
In short, all the assertions behave as expected above. I am running on a nVidia Quadro FX 350M (laptop), ForceWare 156.83, Windows XP (SP 2). There is only one thread in the program and the context is created through SDL. Other extensions, such as FBO’s have worked under this setup, and it seems like the extension functions are actually doing something (they are definitely not NULL).
Help appreciated,
- T