2011-11-12 5 views
1

GLSLシェーダが正しくコンパイルされており、正しくリンクされたプログラムに正常にアタッチされています。自分のプログラムで他のシェーダが正しく動作することを確認しました。奇妙なことは、私が見る結果が、デフォルトのシェーダ(色、照明なし)から出てくるのと同じ振る舞いであるようです。GLSL/C++:カスタムシェーダのデフォルトの動作

頂点シェーダとフラグメントシェーダの両方のソースコードと、シェーダに関するC++ソースコードの抜粋を貼り付けます。コメントには、自分のプログラムに固有の機能やクラスについて説明します。初期化から主にC++で

void main() 
{ 
    gl_FragColor = gl_Color; 
} 

抜粋( "dirlight.fs" に含まれる)( "dirlight.vs" に含まれる)

マイ頂点シェーダ

uniform int lightcount; 
uniform vec4 lightdirs[]; 
uniform vec4 lightdifs[]; 
uniform vec4 lightambs[]; 
uniform vec4 lightposs[]; 

void main() 
{ 
    vec3 normal = normalize(gl_NormalMatrix * gl_Normal); 
    vec4 diffuse = vec4(0.0, 0.0, 0.0, 0.0); 
    for(int i = 0; i < lightcount; i++) 
    { 
     //Adding the diffuse term multiplied by gl_Color for each light. 
     //There should be no color (0,0,0,0) if the lights are null 
     diffuse += lightdifs[i] * max(dot(normal, normalize(lightdirs[i])), 0.0) * gl_Color; 
    } 

    gl_FrontColor = diffuse; 
    gl_Position = ftransform(); 
} 

マイフラグメントシェーダ.. C++メインで、メインループから。

//class program manages shaders 
Program shaders = Program(); 
//attach a vertex shader, compiled from source in dirlight.vs 
shaders.addShaderFile(GL_VERTEX_SHADER, "dirlight.vs"); 
//attach a fragment shader compiled from source in dirlight.fs 
shaders.addShaderFile(GL_FRAGMENT_SHADER, "dirlight.fs"); 
//link program 
shaders.link(); 
//use program 
shaders.use(); 

//Program::getUniformLoc(const char* name) grabs the location 
//of the uniform specified 
GLint sTime = shaders.getUniformLoc("time"); 
GLint lightcount = shaders.getUniformLoc("lightcount"); 
GLint lightdir = shaders.getUniformLoc("lightdirs"); 
GLint lightdif = shaders.getUniformLoc("lightdifs"); 
GLint lightamb = shaders.getUniformLoc("lightambs"); 

glUniform1i(lightcount, 2); 
GLfloat lightdirs[] = {-1.f, 1.f, 1.f, 1.f, 
         1.f, 1.f, -1.f, 1.f}; 
glUniform4fv(lightdir, 2, lightdirs); 
GLfloat lightdifs[] = {1.f, 1.f, 1.f, 1.f, 
         1.f, 1.f, 1.f, 1.f}; 
glUniform4fv(lightdif, 2, lightdifs); 
glUniform4f(lightamb, 0.4f, 0.4f, 0.4f, 1.f); 

抜粋...

glUniform1f(sTime, newTime); 
//This should cause the light directions to rotate around the origin 
GLfloat lightdirs[] = {sinf(newTime * 2.f), 1.f, cosf(newTime * 2.0f), 1.f, 
         cosf(newTime * 2.f), 1.f, sinf(newTime * 2.0f), 1.f}; 
glUniform4fv(lightdir, 2, lightdirs); 
+0

私はそれを取って、作成したプログラムオブジェクト_after_を作成して、現在のOpenGLレンダリングコンテキストを作成してから、その拡張も初期化しましたか?これまでのところ、Programm :: addShaderFileは不透明で、そのソースコードを持ち、Program :: getUniformLocが役に立ちます。 – datenwolf

+1

次回GLSLの質問をするには、OpenGLのバージョンとGLSLのバージョンを指定してください。シェイダーのコンパイル/ロードルーチンのソースコードを提供していないので、Murphyの法則では、エラーチェックは一切ないと仮定します。対応するAPI関数glGetProgramivとglGetShaderivを使用して、シェーダのコンパイルステータスとプログラムのリンクステータスをチェックする必要があります。また、リンク/コンパイル後のシェーダーとプログラムの情報ログを抽出して読み込みます。デバッグの目的で、OpenGLのコールシェーダが関連するかどうかにかかわらず、glGetErrorを追加することができます。 – SigTerm

+0

私の質問で述べたように、私はシェイダーをロードする方法に他のカスタムシェーダーをロードすることでゼロの問題があることを既に確認しています。問題は、シェイダー自体か、ユニフォーム/アトリビュートの処理方法です。 – Miles

答えて

2
uniform vec4 lightdirs[]; 

これは合法的なGLSLではありません。私はあなたのコンパイラがコンパイルを許可する理由を説明することはできません(私はそれがNVIDIAコンパイラであると推測しています、もちろん、コンパイル/リンクの状態をチェックしていることを前提としていますが)。は、シェイダー。可変長配列を使用する場合は、最大長を選択してシェーダーに書き込む必要があります。シェーダは、より少ない値(渡す制服に基づいた長さ)を読み取ることができますが、それはそれです。

+0

ありがとう!最大長を設定しました!うーん。しかし、それは私にコンパイルエラーを与えることはありませんでした。私はそれがNVIDIAのコンパイラかどうか分かりませんが、NVIDIAのグラフィックスカードを持っていればコンパイルできます。 – Miles

+0

@ MilesRufat-Latreはい、GLSLコンパイラはグラフィックスドライバの一部です。 –

+0

あなたはNVidiaを使っているので、[NVEmulate](http://developer.nvidia.com/nvemulate)を見てください。とりわけ、GLSLコンパイラを "strict"に設定して、CUDAコンストラクトの受け入れを停止することができます。他にも興味深い機能があります。 – bernie

関連する問題