2010-12-07 14 views
4

実行中のシェーダプログラムに頂点属性を渡すときに問題があります。私は2つの属性、位置とRGBAカラーを渡したいと思います。属性の場所をバインドすると、その位置で機能します。しかし、それは色のために動作しません。したがって、すべてのジオメトリは最終的に黒くレンダリングされます。GLSL 1.5とOpenGL 3.3:色を頂点シェーダに渡すのが失敗するようです

これは私が何をすべきかです:

GLuint programHandler; 

// create program 
// compile & attach vertex shader 
// compile & attach fragment shader 

glBindAttribLocation(programHandler, 0, "InPosition"); 
glBindAttribLocation(programHandler, 1, "InColor"); 
glBindFragDataLocation(programHandler, 1, "FragColor"); 

glLinkProgram(programHandler); 
glUseProgram(programHandler); 

// initialize uniform variables 

// I'm trying to get the attribute locations now. 
// I expect location "0" for InPosition and location "1" for InColor. 
// In fact, it gets me a "-1" for InColor. I simply cannot see the reason for that behaviour 

GLint positionLocation = glGetAttribLocation(programHandler, "InPosition"); // returns 0 
GLint colorLocation = glGetAttribLocation(programHandler, "InColor"); // returns -1 

glEnableVertexAttribArray(positionLocation); 
glEnableVertexAttribArray(colorLocation); // fails! 

マイ頂点シェーダは非常に基本的なものです。

#version 150 core 
precision highp float; 

// input 
in vec4 PassColor; 

// output 
out vec4 FragColor; 

void main(void) { 
    FragColor = PassColor; 
} 

なぜ結合「InPosition」仕事と「InColor」:

#version 150 core 

// input 
uniform mat4 ModelviewMatrix; 
uniform mat4 ProjectionMatrix; 
in vec3 InPosition; 
in vec4 InColor; 

// output 
out vec4 PassColor; 

void main(void) { 
    // passing color through to fragment shader 
    PassColor = InColor; 

    // transformation 
    gl_Position = ProjectionMatrix * ModelviewMatrix * vec4(InPosition, 1.0); 
} 

マイフラグメントシェーダは、単にその色を返す必要があります:私は本当にすべてが頂点を変換し、フラグメントシェーダに色を渡すことですではない?私は、GLSLコンパイラがシェーダコードを最適化するので、未使用の変数をバインドできないことに気付いています。しかし、私はここで色を最適化すべき理由を理解していません。結局のところ、私はそれをフラグメントシェーダに渡すことによってそれを使用します。

+0

「glGetError()」はありますか?また、あなたのGPUとドライバのバージョンは何ですか? – Kos

答えて

1

ブラインドショット、私は、これは間違っていると信じて:

glBindFragDataLocation(programHandler, 1, "FragColor"); 

それは次のようになります。

glBindFragDataLocation(programHandler, 0, "FragColor"); 
+0

私は参照してください。しかし、複数のレンダリングターゲットにレンダリングしたい場合はどうすればいいですか?私は現在、フレームバッファオブジェクトに添付されているテクスチャにレンダリングします。もともと、色バッファーとして1つのテクスチャー以上のものを取り付けることを意図していました。これが第2引数としての "1"の理由です。 gl_FragData []配列は推奨されていません。私はそれを正しくバインドし、フラグメントシェーダでそれを宣言しますか? – Walter

+0

これは正しいですが、2番目のレンダーターゲットがある場合はレンダーしています。 2つのレンダリングターゲットがない場合、エラーになります。 –

+0

したがって、GLSLフラグメントシェーダのFragColor [1]を使用してCOLOR_ATTACHMENT1を処理すると仮定します。私はそれを行うために、FragColorをそのように宣言する必要があると思います: "out vec4 FragColor [8];" (8つのカラーバッファが取り付けられていると仮定します)。あれは正しいですか? "glBindFragDataLocation(programHandler、i、" FragColor [i] ");"のような各フラグメントデータの場所をバインドする必要がありますか? – Walter

0

フラグメントシェーダは、複数のカラープレーンに書き込む必要がある場合には、フレームバッファがなければなりません作成され、複数のカラープレーンが添付されています。

カラープレーンは、いずれかのバッファをレンダリングすることができ、

GLuint renderbuffer[2]; 
glGenRenderbuffers(2, &renderbuffer[0]); 
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer[0]); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height); 
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer[1]); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height); 

または、それらはテクスチャすることができます。

GLuint colorTexture[2]; 
glGenTextures(2, &colorTexture[0]); 
glBindTexture(GL_TEXTURE_2D, colorTexture[0]); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
glBindTexture(GL_TEXTURE_2D, colorTexture[1]); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 

テクスチャまたはレンダリングバッファをフレームバッファに接続する必要があります。

はもちろんのバッファ

GLuint frameBuffer; 
glGenFramebuffers(1, &frameBuffer); 
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer[0]); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer[1]); 

テクスチャ

GLuint frameBuffer; 
glGenFramebuffers(1, &frameBuffer); 
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture[0], 0); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, colorTexture[1], 0); 

注意、バッファやテクスチャを混合することができ、一方の異なるカラープレーンと同じフレームに取り付けることができるレンダリングレンダリングバッファ。
デプスバッファまたはステンシルバッファが必要な場合は、GL_DEPTH_ATTACHMENT,GL_STENCIL_ATTACHMENTまたはGL_DEPTH_STENCIL_ATTACHMENTをフレームバッファに添付する必要があります。

farmeバッファが正常に終了した場合は、glCheckFramebufferStatusで評価することができる。

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
{ 
    // error 
} 

単一のフレームバッファに取り付けることができるカラーバッファの最大数によって、OGL機能glGetIntegervによって決定することができますパラメータGL_MAX_COLOR_ATTACHMENTSを使用して:

GLint maxColAttchemnts = 0; 
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColAttchemnts); 

は、すべての色の添付ファイルを同時に起動する必要があるわけではありません。フラグメントシェーダデータからの出力が書き込まれるバッファの配列は、glDrawBuffersで定義できます。フラグメントシェーダで

GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT1 }; 
glDrawBuffers(1, &drawBuffers[0]); 

各アクティブ色の付着のために宣言される1つのout変数を有します。

out fragColor0; 
out fragColor1; 

void main() 
{ 
    .... 
    fragColor0 = ....; 
    .... 
    fragColor1 = ....; 
} 

明示glBindFragDataLocationで指定することができるフレームバッファのカラーアタッチメントのインデックスにout変数の結合。これは、シェーダプログラムをリンクする前に行う必要があります。

GLuint prog = ....; 
glBindFragDataLocation(prog, 0, "fragColor0"); 
glBindFragDataLocation(prog, 1, "fragColor1"); 
glLinkProgram(prog); 

特定の出力が書き込む現代のOpenGLバッファインデックスでは、レイアウトの場所によって明示的に指定できます。これにより、glBindFragDataLocationの使用を控えることができます。

layout(location = 0) out fragColor0; 
layout(location = 1) out fragColor1; 
関連する問題