3

我有一个小类,允许我加载着色器并在我的程序中使用它们。我能够编译着色器,但是当需要链接它们时,他们就是不想这样做。使用 glGetProgramInfoLog 我得到以下错误日志。我不明白为什么它告诉我没有定义程序,因为编译工作正常......

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

下面的代码执行 GLSL 链接:

program_ = glCreateProgramObjectARB();

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

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

glLinkProgramARB(program_); 

vertex_ 和 fragment_ 是顶点和片段着色器,program_ 是 ProgramObjectARB。

我想知道为了使这个运行我需要做哪些必要的修改。

顶点着色器:

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;
}

片段着色器:

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;
}

编辑 - 解决方案 我用来读取源文件的方法似乎不正确。着色器可以编译,但在链接时,它不能正常工作。现在我使用这种方法来读取我的文件并且链接是正确的:

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;
}
4

3 回答 3

8

来自 Nvidia 驱动程序中 GLSL 编译器的特定错误代码意味着它在着色器中找不到名为“main”的函数(在这种情况下为顶点或片段)

最常见的原因是,当您认为自己是时,您实际上并没有将程序输入驱动程序——您传入的字符串尚未初始化,或者您传入的长度为 0,而你实际上并没有编译任何东西。

编辑

我最好的猜测是 glCreateShader 或 glSetShaderSource 调用有一些微妙的错误。很多时候,错误只会在您尝试链接着色器(而不是编译)时出现,因为这是驱动程序第一次知道它具有完整的着色器,而不仅仅是需要链接另一个着色器才能完成的部分、不完整的着色器.

于 2009-12-21T06:53:16.953 回答
3

你的着色器对我来说工作得很好,我做了一个小测试程序来编译它们并且没有问题:

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);

你做同样的事情吗?

于 2009-12-21T08:13:06.953 回答
2

在您的 glAttachObjectARB 调用后尝试使用 glGetError 以查看这些是否失败。

于 2009-12-21T06:29:26.553 回答