2

1 つのフラグメント シェーダーで 2 つのテクスチャにアクセスしようとしています。

このために、次のコードで設定した 2 つのテクスチャがあります。

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glVertexPointer(2, GL_FLOAT, 0, vbuff);
glTexCoordPointer(2, GL_FLOAT, 0, tbuff);

glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, texture0);
glEnable(GL_TEXTURE_2D);

glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, texture1); 
glEnable(GL_TEXTURE_2D);

そして、それらを次のフラグメントシェーダーと組み合わせようとします:

uniform sampler2D tex0;
uniform sampler2D tex1;
void main()
{
    vec4 texval1 = texture2D(tex0, TextureCoordOut);
    vec4 texval2 = texture2D(tex1, TextureCoordOut);
    gl_FragColor = 0.5*(texval1 + texval2)
}

どういうわけかこれは機能せず、2 番目のテクスチャしか表示されません。

PS: Windows7 でシェーダーを開発していますが、C++ コードとシェーダーを Android デバイスの Android NDK で使用したいと考えています。

編集:私はそれを機能させ、ここにコードを投稿して、他の人がそれから利益を得ることができるようにします:

頂点シェーダー

varying vec2 TextureCoordOut;
void main()
{
    gl_Position = ftransform();
    TextureCoordOut = vec2(gl_MultiTexCoord0);
}

フラグメントシェーダー

varying mediump vec2 TextureCoordOut;
uniform sampler2D tex0;
uniform sampler2D tex1;
void main()
{
    gl_FragColor = texture2D(tex0, TextureCoordOut) * texture2D(tex1, TextureCoordOut);
}

与える

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glVertexPointer(2, GL_FLOAT, 0, vbuff);  //2 dimensional vertex buffer
glTexCoordPointer(2, GL_FLOAT, 0, tbuff); // 2 dimensional textures
glColor4f(1, 1, 1, 1);

glActiveTexture(GL_TEXTURE0);       glBindTexture(GL_TEXTURE_2D, mapid1);
glActiveTexture(GL_TEXTURE1);       glBindTexture(GL_TEXTURE_2D, mapid2);

glUseProgram(shader);

glUniform1i(glGetUniformLocation(gfx.prog, "tex0"), 0);   //GL_TEXTURE0
glUniform1i(glGetUniformLocation(gfx.prog, "tex1"), 1);   //GL_TEXTURE1

render....

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4

1 に答える 1

7

これらのテクスチャをそれぞれのユニットにバインドするだけでは不十分です。sampler2Dまた、ユニフォームのテクスチャをどこから取得するかをシェーダーに伝える必要もあります。これは、使用するテクスチャ ユニットに対応する整数の均一な値を設定することによって行われます。

//get uniform locations (either init code or render code)
int locTex0 = glGetUniformLocation(program, "tex0");
int locTex1 = glGetUniformLocation(program, "tex1");

...    

//bind textures to texture units
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture0);

//bind program and specify texture units for each sampler2D uniform
glUseProgram(program);
glUniform1i(locTex0, 0);   //use texture bound to GL_TEXTURE0
glUniform1i(locTex1, 1);   //use texture bound to GL_TEXTURE1

...
draw

もちろん、これは、シェーダーの使用方法と均一な値の指定方法を知っていることを前提としています。

いくつかの追加のコメント:

  • glEnable(GL_TEXTURE_2D)フラグメント シェーダを使用する場合、テクスチャを使用するかどうかはシェーダ自身が決定するため、を呼び出す必要はありません。
  • これらのARBバージョンの関数と定数を使用しないでください。少なくとも、GL 1.2または1.3(〜15年)以降のコアであるマルチテクスチャリングのような古くて確立されたものには使用しないでください。
  • コードが OpenGL ES 2.0 に 1 対 1 で移植できるとは思わないでください。OpenGL ES 2.0 は古い組み込み属性 (glVertexPointerまたは などglTexCoordPointer) を認識していませんが、それは別の問題です。
于 2012-01-06T18:12:11.423 に答える