English 中文(简体)
Unable to link compiled shaders (GLSL)
原标题:
  • 时间:2009-12-21 06:08:17
  •  标签:
  • opengl
  • glsl

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] =   ;
        }
        fclose(fp);
    }
}
return content;
}
最佳回答

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.

问题回答

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.





相关问题
OpenGL 3D Selection

I am trying to create a 3D robot that should perform certain actions when certain body parts are clicked. I have successfully (sort of) implemented picking in that if you click on any x-plane part, it ...

CVDisplayLink instead of NSTimer

I have started to implement cvDisplayLink to drive the render loop instead of nstimer, as detailed in this technical note https://developer.apple.com/library/archive/qa/qa1385/_index.html Is it ...

Can the iPhone simulator handle PVR textures?

I have a really weird problem with PVR textures on the iPhone simulator- the framerate falls through the floor on the iPhone simulator, but on the iPhone itself it works just fine. Has anyone had any ...

Calculate fps (frames per second) for iphone app

I am using an opengl es iphone application. What is the most accurate way to calculate the frames per second of my application for performance tuning?

Java - Zoom / 3D Data Visualization Libraries

What are the best libraries/frameworks for doing 3D and/or Zoom interfaces in Java? I d like to be able to do some prototyping of creating new types of interfaces for navigating within data and ...

FLTK in Cygwin using Eclipse (Linking errors)

I have this assignment due that requires the usage of FLTK. The code is given to us and it should compile straight off of the bat, but I am having linking errors and do not know which other libraries ...

热门标签