GLSLでのテクスチャの取り扱いについて.



シェーダへのテクスチャ受け渡し

OpenGLではglBindTextureでテクスチャをバインドし,glTexCoordでテクスチャ座標を指定して貼り付ける.このときテクスチャを表すのがglGenTexture関数に生成されたテクスチャオブジェクトである. GLSLにもテクスチャオブジェクトを渡してテクスチャ参照したいが, 現在のAPIではテクスチャユニットという別の整数インデックスを用いてアクセスする (将来的には直接テクスチャオブジェクトを渡せるようになるかもしれない).

カレントのテクスチャユニットはマルチテクスチャ使用時に用いる

void glActiveTexture(GLenum texture);

により指定する.例えばテクスチャユニット0の場合,以下となる.

glActiveTexture(GL_TEXTURE0);

使用するテクスチャユニットを上記命令でONにした後,glBindTextureにより対応するテクスチャをバインドする.

複数用いる場合の例は以下.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
    GLuint texa = 0, texb = 0, texc = 0;
    glActiveTexture(GL_TEXTURE0);
    LoadGLTexture("texture/image0.png", texa, false, false);
    glBindTexture(GL_TEXTURE_2D, texa);
 
    glActiveTexture(GL_TEXTURE1);
    LoadGLTexture("texture/image1.png", texb, false, false);
    glBindTexture(GL_TEXTURE_2D, texb);
 
    glActiveTexture(GL_TEXTURE2);
    LoadGLTexture("texture/image2.png", texc, false, false);
    glBindTexture(GL_TEXTURE_2D, texc);

ここで,LoadGLTextureは画像を読み込んでテクスチャオブジェクトを生成,テクスチャメモリに画像を転送する関数である.

GLSLに渡すときはglUniform1iを用いる.

glUniform1i(glGetUniformLocation(g_glslTexture.Prog, "texa"), 0);
glUniform1i(glGetUniformLocation(g_glslTexture.Prog, "texb"), 1);
glUniform1i(glGetUniformLocation(g_glslTexture.Prog, "texc"), 2);

テクスチャユニットの最大数

テクスチャユニットの最大数はglGetIntegerにGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS(頂点シェーダ), GL_MAX_TEXTURE_IMAGE_UNITS(フラグメントシェーダ)を指定することで取得できる.

コード例

  1
  2
  3
  4
        GLint num_tex_units;
    glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &num_tex_units);
    cout << "Max texture units = " << num_tex_units << endl;

3つのテクスチャを用いる例

以下の3つのテクスチャを読み込んで重ねて描画するコードの例を示す.

objects.jpgcheckboard.jpgmask.jpg
テクスチャ0テクスチャ1テクスチャ2

頂点シェーダは単に頂点位置を処理して,テクスチャ座標を渡すだけである.

  1
  2
  3
  4
  5
void main(void)
{
    gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;        gl_TexCoord[0] = gl_MultiTexCoord0;        }

フラグメントシェーダではテクスチャを参照して,テクスチャ0の白い部分を透明にして一番上のレイヤーに置き, テクスチャ1と2をブレンドして背景とする処理を行う.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
uniform sampler2D tex0;
uniform sampler2D tex1;
uniform sampler2D tex2;
 
void main(void)
{
        vec3 color_tex0 = texture2D(tex0, gl_TexCoord[0].st).xyz;
    vec3 color_tex1 = texture2D(tex1, gl_TexCoord[0].st).xyz;
    vec3 color_tex2 = texture2D(tex2, gl_TexCoord[0].st).xyz;
 
    float gray = (color_tex0.r+color_tex0.g+color_tex0.b)/3.0;
 
    if(gray > 0.999){
        gl_FragColor.rgb = color_tex1+color_tex2;
    }
    else{
        gl_FragColor.rgb = color_tex0;
    }
    gl_FragColor.a = 1.0;
}

実行結果

実行結果のスクリーンショットを以下に示す(クリックで拡大).

texture3.jpg

ソースコード

Visual Studio 2010用のソースコードを以下に置く(要GLUT,GLEW,libjpeg,libpng).


添付ファイル: filecheckboard.jpg 2204件 [詳細] fileobjects.jpg 2178件 [詳細] filetexture3.jpg 2444件 [詳細] filemask.jpg 2177件 [詳細] fileglsl_texture.zip 2103件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2022-11-30 (水) 13:48:07