Shader compilation

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

I do not see call to the glCompileShaderARB function.

Additionally you are using ARB extension for shader creation and specification yet you are attempting to retrieve the shader log using the glGetShaderInfoLog from the 2.0 core.

Thanks, Komat.

You are right of course about glCompileShaderARB. I have added it but still the same errors (shader not compiled and no log output).

The retrieval is debug only, but all the same I will look into ARB versions of these functions. However, the values return by the 2.0 core versions seem to make sense.

Due to some template specialization involving function pointers there was an error in my extension loading. glCompileShaderARB was actually calling glActiveTextureARB. Results were of course undefined. What I’ve learned is: Never use function pointer types as template arguments!

Sorry for wasting your time, I was sure I had it right.

Yet more reason to use GLee/Glew and program with GLIntercept running in the background.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.