GLSLでテクスチャを使う手順

最終更新日10 Nov 2017 04:44

OpenGLでテクスチャを使う手順

テクスチャデータを渡すまでに書くことの流れ

  1. uniform sapler2D Texture;
  2. GLuint gTexSamplerLoc;
  3. gTexSamplerLoc=glGetUniformLocation(gProgram,"Texture");
  4. glUniform1i(gTexSamplerLoc,アクティブなテクスチャ番号);

用意するシェーダ

gl_TexCoord[0]は組み込みのvarying変数

uniform mat4 ModelView;
uniform mat4 Proj;
void main(){
    gl_Position =Proj *ModelView* gl_Vertex;
    gl_TexCoord[0]=gl_MultiTexCoord0;//gl_TexCoordだとエラー
}

init関数にて

どんなテクスチャパラメータがいいかはテクスチャについて参照。

   glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, GAUSSIZE, GAUSSIZE, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, texturedatapointer);//この後に
gTexSamplerLoc= glGetUniformLocation ( gProgram, "voltexture" );
 
glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2,GL_FLOAT,5*sizeof(float), cubeVerticesForQuads);//gl_MultiTexCoord0に渡る
    glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), &cubeVerticesForQuads[2]);
    glUseProgram(gProgram);
    glAtciveTexture(GL_TEXTURE0);
    glUniform1i(gTexSamplerLoc,0);//glBindしたときのIDではなく、アクティブなテクスチャ番号を渡すこと。
    //multitextureのうち0番目のテクスチャ、という意味で。 texIdを渡してはだめ!

glTexCoordPointer(size,type,stride,pointer);

size…1頂点につき何個のデータか。x,yだけ使うなら2だし、x,y,z使うなら3である。
type….渡す配列のデータ型がintか、floatか。など。GL_INT,GL_FLOATなどが渡される。(配列の型に合わせる)
pointer….テクスチャ座標情報を詰め込んだ配列へのポインターを渡す。

display()関数にて

   glEnable ( GL_TEXTURE_2D );
   
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texId);
glVertexAttribPointer(ATTRIB_VERTEX,3,GL_FLOAT,GL_FALSE,0,cubeVerticesForQuads);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glDrawArrays(GL_QUADS,0,24);//四角を頂点番号0~24個目まで描く

glEnable関数は不要。らしいぞ。
バインドは、テクスチャユニットの切り替えも忘れずに
【例】
… …
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, TexId);
glutSolidTeapot(1);
glBindTexture(GL_TEXTURE_2D, 0);

テクスチャをあとから書き換えるには

一度確保したテクスチャをデータの中身をあとからアップデートするには?

  • glTexureSub1D
  • glTexureSub2D
  • glTexureSub3D
glBindTexture ( GL_TEXTURE_3D, m_TexId[VOLUME_TEX] );
glTexSubImage3D ( GL_TEXTURE_3D, 0, 0,0,0, _xy, _xy, _z,GL_LUMINANCE, _type, _data );
glUseProgram(programID);
glUniform1i(gTexSamplerLoc,0);
//draw

遭遇したエラー

エラーに遭遇したらテクスチャに関する情報を調べるで色々調べてみるといいかもしれない。

texture1DでUNSIGNED_BYTEの場合

Cgみたいに、勝手に正規化してくれるのではなく、UNSIGNED_BYTEで渡したらそのまま、0~255の値で来るので要注意!

テクスチャが出ない!!

glUniform1i(loc,アクティブテクスチャ番号);

この第2引数で渡すのは、テクスチャIDでなく、GL_TEXTURE0の番号!
GL_TEXTURE0だったら0を渡す

glUniform1iはglUseProgram(番号)とglUseProgram(0)で囲むこと

glUseProgram(m_Program);
glUniform1i(m_Map[names[i]]->loc,0);
glUseProgram(0);

たぶん、
glUseProgram(m_Program);の状態なのに、glGetUniformLocationすると怒られたり、
glUseProgram(0);の状態なのにglUniform1iすると怒られるんだと思う。
  • glUniformはシェーダ初期化の段階で1回やれば良く、draw関数で何回も呼ぶ必要はない。
  • テクスチャの内容を動的に変える場合glActiveTextureglBindTextureをdraw関数で呼ぶことにより変わる。
void draw() {
    glClearColor(0.3f, 0.3f, 1.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(shaderID);
    glEnable(GL_TEXTURE_2D);
    //1オブジェクトに貼るテクスチャの枚数分以下を繰り返す↓
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureName[0]);
 
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, textureName[1]);

texture


ファイル

サポートサイト Wikidot.com texture