web-dev-qa-db-ja.com

複数のテクスチャを1つのシェーダーに渡すにはどうすればよいですか?

私はfreeglutを使用しています。GLEW およびDevIL から テクスチャティーポットをレンダリング 頂点およびフラグメントシェーダーを使用しています。これは、Ubuntu 14.04上のOpenGL 2.0およびGLSL 1.2ですべて正常に動作しています。

ここで、ティーポットにバンプマップを適用します。私の講師は明らかに彼自身のお茶を醸造していないので、彼らが smooth であることになっていることを知りません。とにかく、 古いバンプマッピングに関する見栄えのよいチュートリアル が見つかりました。

uniform sampler2D DecalTex; //The texture
uniform sampler2D BumpTex; //The bump-map 

彼らが触れていないのはhow最初に2つのテクスチャをシェーダーに渡すことです。

以前は

//OpenGL cpp file
glBindTexture(GL_TEXTURE_2D, textureHandle);

//Vertex shader
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;

//Fragment shader
gl_FragColor = color * texture2D(DecalTex,gl_TexCoord[0].xy);

だから今私

//OpenGL cpp file
glBindTexture(GL_TEXTURE_2D, textureHandle);
glBindTexture(GL_TEXTURE_2D, bumpHandle);

//Vertex shader
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;

//Fragment shader
gl_FragColor = color * texture2D(BumpTex,gl_TexCoord[0].xy);
//no bump logic yet, just testing I can use texture 1 instead of texture 0

しかし、これは機能しません。テクスチャは完全に消えます(事実上ティーポットは白です)。私はGL_TEXTURE_2D_ARRAY、glActiveTexture、および他のいくつかの見かけは良いが実りのないオプションを試しました。

OpenGLとGLSLの新旧の参照の通常の混合バッグをふるいにかけた後、私はおそらくglGetUniformLocationが必要であるという結論に達しました。これを正確に使用するにはOpenGL cppファイルでを使用して、すでに入力されているテクスチャハンドルをフラグメントシェーダーに渡しますか?

(これは宿題なので、最小限のコードフラグメントで答えてください(もしあれば)。ありがとう!)

これに失敗すると、茶の心地よいメッシュを持っている人はいますか?

24
david.libremone

とてもシンプルです。必要なのは、サンプラーを glUniform1i 。したがって、コードサンプルでは、​​2つの均一なサンプラーを想定しています。

uniform sampler2D DecalTex;  // The texture  (we'll bind to texture unit 0)
uniform sampler2D BumpTex;   // The bump-map (we'll bind to texture unit 1)

初期化コードで:

// Get the uniform variables location. You've probably already done that before...
decalTexLocation = glGetUniformLocation(shader_program, "DecalTex");
bumpTexLocation  = glGetUniformLocation(shader_program, "BumpTex");

// Then bind the uniform samplers to texture units:
glUseProgram(shader_program);
glUniform1i(decalTexLocation, 0);
glUniform1i(bumpTexLocation,  1);

シェーダーのユニフォームが設​​定されました。レンダリングします。そのためには、通常の glBindTexture プラス glActiveTexture が必要です。

glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
glBindTexture(GL_TEXTURE_2D, decalTexHandle);

glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
glBindTexture(GL_TEXTURE_2D, bumpHandle);

// Done! Now you render normally.

そして、シェーダーでは、すでに行っているように、テクスチャサンプラーを使用します。

vec4 a = texture2D(DecalTex, tc);
vec4 b = texture2D(BumpTex,  tc);

注:バンプマッピングなどの手法の場合、テクスチャは同じで、異なるデータしか含まれていないため、必要なのは1セットのテクスチャ座標だけです。したがって、おそらくテクスチャ座標を vertex属性 として渡す必要があります。

42
glampert