Question

I have a small class that allows me to load shaders and use them in my program. I am able to compile the shaders, but when it's time to link them, they just don't want to. Using glGetProgramInfoLog I got the following error log. I don't understand why it tells me that there are no program defined since the compilation worked fine...

Vertex info
-----------
(0) : error C3001: no program defined
Fragment info
-------------
(0) : error C3001: no program defined

The code below does the GLSL linking:

program_ = glCreateProgramObjectARB();

if (vertex_) {
   glAttachObjectARB(program_, vertex_);
}

if (fragment_) {
   glAttachObjectARB(program_, fragment_);
}

glLinkProgramARB(program_); 

vertex_ and fragment_ are the vertex and fragment shader, and program_ is the ProgramObjectARB.

I'd like to know what are the necessary modifications I need to do in order to make this run.

Vertex shader:

varying vec4 OCPosition;   // surface positon in world's coordinates
varying vec4 ECposition;   // surface position in eye coordinates
varying vec4 ECballCenter; // ball center in eye coordinates
uniform vec4 BallCenter;   // ball center in modelling coordinates

void main()
{
  OCPosition   = gl_Vertex;
  ECposition   = gl_ModelViewMatrix * OCPosition;
  ECballCenter = gl_ModelViewMatrix * BallCenter;

  gl_Position  = gl_ProjectionMatrix * ECposition;
}

Fragment shader:

varying vec4 OCPosition;   // surface position in world coordinates
varying vec4 ECposition;   // surface position in eye coordinates
varying vec4 ECballCenter; // ball center in eye coordinates

uniform vec4  LightDir;     // light direction, should be normalized
uniform vec4  HVector;      // reflection vector for infinite light source
uniform vec4  SpecularColor;
uniform vec4  BaseColor, StripeColor;

uniform float StripeWidth;  // = 0.3
uniform float FWidth;       // = 0.005

void main()
{
vec3  normal;              // Analytically computed normal
vec4  p;                   // Point in shader space
vec4  surfColor;           // Computed color of the surface
float intensity;           // Computed light intensity
vec4  distance;            // Computed distance values
float inorout;             // Counter for computing star pattern

p.xyz = normalize(OCPosition.xyz);    // Calculate p
p.w   = 1.0;

distance.y = StripeWidth - abs(p.z);
distance.xy = smoothstep(-FWidth, FWidth, distance.xy);

surfColor = mix(BaseColor, StripeColor, distance.y);

// normal = point on surface for sphere at (0,0,0)
normal = normalize(ECposition.xyz - ECballCenter.xyz);

// Per fragment diffuse lighting
intensity  = 0.2; // ambient
intensity += 0.8 * clamp(dot(LightDir.xyz, normal), 0.0, 1.0);
surfColor *= intensity;

// Per fragment specular lighting
intensity  = clamp(dot(HVector.xyz, normal), 0.0, 1.0);
intensity  = pow(intensity, SpecularColor.a);
surfColor += SpecularColor * intensity;

gl_FragColor = surfColor;
}

EDIT - SOLUTION It seems the method I used to read the source file was incorrect. The shader would compile, but at linking, it was not working correctly. Now I use this method to read my file and the linking is correct:

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;
}
Was it helpful?

Solution

That specific error code from the GLSL compiler in the Nvidia driver means that it couldn't find a function called 'main' in your shader (either vertex or fragment in this case)

The most common reason for this is that you're not actually getting the program in to the driver when you think you are -- either the string you are passing in has not been initialized, or you're passing in a length of 0, and you're not actually compiling anything.

Edit

My best guess is there's something subtly wrong with the glCreateShader or glSetShaderSource calls. Much of the time, errors only show up when you try to link the shaders (rather than compile), as that's the first time the driver knows it has complete shaders and not just partial, incomplete shaders that need another shader linked in to be complete.

OTHER TIPS

Your shaders work fine for me, I made a small test program to compile them and got no problems:

GLuint program = glCreateProgramObjectARB();
assert(program);

GLuint vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
assert(vertex_shader);
glShaderSourceARB(vertex_shader, 1, /*your vertex shader*/, 0);
glCompileShaderARB(vertex_shader);

GLint compile_status;
glGetObjectParameterivARB(vertex_shader, GL_OBJECT_COMPILE_STATUS_ARB, &compile_status);
assert(1 == compile_status);

GLuint fragment_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
assert(fragment_shader);
glShaderSourceARB(fragment_shader, 1, /*your fragment shader*/, 0);
glCompileShaderARB(fragment_shader);

glGetObjectParameterivARB(vertex_shader, GL_OBJECT_COMPILE_STATUS_ARB, &compile_status);
assert(1 == compile_status);

glAttachObjectARB(program, vertex_shader);
assert(GL_NO_ERROR == glGetError());

glAttachObjectARB(program, fragment_shader);
assert(GL_NO_ERROR == glGetError());

glLinkProgramARB(program);  
assert(GL_NO_ERROR == glGetError());

GLint link_status;
glGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &link_status);
assert(1 == link_status);

Do you do the same thing?

Try using glGetError after your glAttachObjectARB calls to see if these are failing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top