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 に答える
2

glAttachObjectARB 呼び出しの後に glGetError を使用して、これらが失敗しているかどうかを確認してください。

于 2009-12-21T06:29:26.553 に答える