blog

OpenGLテクスチャ関連API

テクスチャは、シーン内の三角形に適用できる画像データの一種であり、フィルタリングされたテクスチャユニットによってソリッド領域に塗りつぶされます。テクスチャを単純に画像として理解するのが一般的ですが、テ...

Mar 8, 2020 · 9 min. read
シェア

テクスチャとは

テクスチャは、シーン内の三角形に適用できるイメージデータの一種で、フィルタリングされたテクスチャセルによってベタ領域に塗りつぶされます。通常、テクスチャは単純にイメージとして理解されますが、テクスチャは単なるイメージデータ以上のものであり、ほとんどの最新の3Dレンダリングアルゴリズムの重要な要素です。

テクスチャー関連機能のまとめ

生のイメージデータ

初期のコンピュータ・グラフィックスは非常にシンプルで、イメージデータはビットマップ(ピクセルの値のオンとオフを示す0と1の羅列)で表現されていました。ビットマップでは、メモリの各ブロックの各ビットが、画面上の特定のピクセルの状態に対応していました。

ピクセルラッピング

イメージの表示は、一般的にメモリ内のビットマップに変換され、.tga形式で保存され、保存されたイメージデータサイズの計算式は次のとおりです:

イメージ保存領域のサイズ = イメージの高さのピクセル点 * イメージ幅のピクセル点 * ピクセルあたりのバイト数を記述する

iOSの開発では、.tga形式のイメージを使用する代わりに、OpenGL ESは.pngや.jpgの圧縮イメージをテクスチャデータとして直接使用することができ、最終的にボトムレイヤーでビットマップにデコードされ、テクスチャとして表示されます。

テクスチャ関連のよく使われるAPI

関数を知る

画素蓄積方式

//ピクセルストレージを変更する
void glPixelStorei(GLenum pname,GLint param);
//ピクセル記憶法の復元
void glPixelStoref(GLenum pname,GLfloat param);
// :
// :GL_UNPACK_ALIGNMENT OpenGLがデータ・バッファからイメージをどのように展開するかを指定する データ
// :パラメータGLを示す_UNPACK_ALIGNMENT 設定値
//GL_UNPACK_ALIGNMENT メモリ上の各ピクセルの開始点をランク付けするリクエストは、1、2、4、または8に設定することが許される。
glPixelStorei(GL_UNPACK_ALIGNMENT,1);


カラーバッファの内容をピクセルマップとして直接読み込みます。

// :x,矩形の左下がウィンドウ座標となる。
// :y,矩形の左下隅のポート座標(PORT COORDINATES
// :width,矩形の幅(ピクセル単位 
// :height,ピクセル単位の高い矩形。
// :format,OpenGL のピクセル・フォーマット
// :type,pixelsパラメータが指すデータを解釈し、OpenGLに、色成分を格納するために使用するバッファのデータ型、ピクセルデータのデータ型、およびその使用方法を指示する。
// :pixels,グラフィックス・データへのポインタ
void glReadPixels(GLint x,GLint y,GLSizei width,GLSizei
height, GLenum format, GLenum type,const void * pixels);
glReadBuffer(mode); > 読み込むキャッシュを指定する 
glWriteBuffer(mode); > 書き込むキャッシュを指定する


テクスチャの読み込み

//target:テクスチャ・アプリケーション(通常はGL)のテクスチャ・モードを指定する。_TEXTURE_2D
 //GL_TEXTURE_1D
 //GL_TEXTURE_2D
 //GL_TEXTURE_3D
//Level:ロードするmipテクスチャレベルを指定する。このパラメータは0に設定するのが一般的である。
//internalformat:各テクスチャ・セルにいくつの色成分が格納されているか。
//width次のパラメータが使用される:高さ、深さ:ロードされたテクスチャの幅、高さ、深さを指す。== !==これらの値は2の整数でなければならない。
//border :テクスチャ・マップの境界幅を指定できるようにする。指定しない場合は0を書き込む。
//format :OpenGL のピクセル・フォーマット
//type :pixelsパラメータが指すデータを解釈し、OpenGLに、色成分を格納するために使用するバッファのデータ型、ピクセルデータのデータ型、およびその使用方法を指示する。
//pixels :グラフィックス・データへのポインタ
void glTexImage1D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLint border,GLenum format,GLenum type,void *data);
 
void glTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,void * data);
 
void glTexImage3D(GLenum target,GLint level,GLint internalformat,GLSizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,void *data);



テクスチャの更新。パラメータはテクスチャの読み込みと同じです。

void glTexSubImage1D(GLenum target, GLint level, GLint xOffset, GLsizei width, GLenum format, GLenum type, const GLvoid *data);
void glTexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data);
void glTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width, GLsizei height, GLsizei depth, Glenum type, const GLvoid * data);


ロードされたテクスチャと同じパラメータを持つ代替テクスチャを挿入します。

void glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsize width);
void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yOffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yOffset, GLint zOffset, GLint x, GLint y, GLsizei width, GLsizei height);



カラーバッファを使用してデータをロードし、新しいテクスチャを作成します。

void glCopyTexImage1D(GLenum target, GLint level, GLenum internalformt, GLint x, GLint y, GLsizei width, GLint border);
void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformt, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);

x,y はテクスチャデータの読み込みを開始するカラーバッファ内の位置を指定します。

バッファ内のデータは、glReadBufferを介してソースバッファによって設定されます。

注:2Dカラーバッファからボリュームを取得できないため、glCopyTextImage3Dは存在しません!



テクスチャオブジェクト

テクスチャオブジェクトの生成

//テクスチャ・オブジェクトを
//テクスチャ・オブジェクトとポインタの数を指定する  
void glGenTextures(GLsizei n, GLuint * textTures);
//テクスチャの状態をバインドする // パラメータターゲット:GL_TEXTURE_1DGL_TEXTURE_2DGL_TEXTURE_3D
//引数 texture:バインドされるテクスチャオブジェクト
void glBindTexture(GLenum target, GLunit texture);
//バインドされているテクスチャーオブジェクトを削除する
//テクスチャ・オブジェクトとテクスチャ・オブジェクト・ポインタ。
void glDeleteTextures(GLsizei n, GLuint *textures); //テクスチャオブジェクトの有効性をテストする
//textureが既に領域が確保されたテクスチャーオブジェクトである場合、この関数はGLを返す。_TRUE,そうでない場合はGLを返す。_FALSE。 
GLboolean glIsTexture(GLuint texture);


テクスチャパラメータの設定

glTexParameterf(GLenum target, GLenum pname, GLFloat param);
glTexParameteri(GLenum target, GLenum pname, GLint param);
glTexParameterfv(GLenum target, GLenum pname, GLFloat *param);
glTexParameteriv(GLenum target, GLenum pname, GLint *param);
// :target,これらのパラメータが使用されるテクスチャモードを指定する _TEXTURE_1DGL_TEXTURE_2DGL_TEXTURE_3D。 
// :pname,設定するテクスチャー・パラメーターを指定する。
// :param,特定のテクスチャ・パラメータの値を設定する


フィルタリング方法の設定

濾過には一般的に近隣濾過と直線濾過の2種類があります。

  • ネイバーフッドフィルタリング:現在の位置に最も近い色を選択するもので、テクスチャを異常に大きく引き伸ばしたときに現れる大きなパッチ状のピクセルが最も特徴的です。最もシンプルで高速なフィルタリング方法です。
  • リニアフィルタ:カラーブレンドに似た、すべての色の合成色は、テクスチャが引き伸ばされたときに現れる「歪んだ」イメージで最も注目されますが、この「歪み」は、最も近いフィルタリングモードで現れるピクセルのパッチ状のブロックよりも真実に近いものです。しかしこの「歪み」は最近傍フィルターモードで見られるパッチ状の画素塊よりは真実に近いものです。



2つの濾過方法の効果の比較を以下に示します:



フィルタリングの選択:テクスチャの縮小には近傍フィルタリングを、テクスチャの拡大には線形フィルタリングを推奨します。
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); //テクスチャを拡大するときは、リニア・フィルタリングを使う。
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); //テクスチャを縮小するときは近傍フィルタリングを使う。
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); //テクスチャを拡大するときは、リニア・フィルタリングを使う。
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //テクスチャを縮小するときは近傍フィルタリングを使う。

テクスチャーフィルタリング法:



サラウンドメソッドの設定

通常、テクスチャマップのテクスチャ単位にマッピングされるように、0.0から1.0の範囲で指定されるのはテクスチャ座標です。テクスチャ座標がデフォルトの範囲から外れている場合、OpenGLは現在のテクスチャラップモードに従ってこれを処理します。各ラップモードは異なる効果を持ち、オプションのラップモードは次のとおりです:



4種類のサラウンドの効果を図に示します:

サラウンド方式の設定:

// : テクスチャ・アプリケーションの次元、通常はGLに設定される。_TEXTURE_2D
 // GL_TEXTURE_1D 
 // GL_TEXTURE_2D: 2D
 // GL_TEXTURE_3D: 3D 
// : テクスチャー座標、通常はs、tを設定する。
 // GL_TEXTURE_WRAP_S: 座標系のX軸に相当する。
 // GL_TEXTURE_T: 座標系のY軸に相当する。
 // GL_TEXTURE_R: 座標系のZ軸に相当する。
// :テクスチャサラウンドメソッド
 // GL_REPEAT:OpenGL テクスチャー座標が1を超えた後.0の方向にテクスチャーを繰り返す。; 
 // GL_CLAMP:必要なテクスチャ単位は、自然テクスチャ境界またはTEXTUREから取得される。_BORDER_COLOR. 
 // GL_CLAMP_TO_EDGEサラウンドモードでは、範囲外のテクスチャ座標は、合法的なテクスチャセルの最後の行または列に沿ってサンプリングされる。
 // GL_CLAMP_TO_BORDER:テクスチャ座標0.0 .0範囲外の境界テクスチャセルのみが使用される。境界テクスチャセルは、ベースイメージの周りの追加の行と列として使用され、ベース・テクスチャイメージと一緒にロードされる。
 
glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_S,GL_CLAMP_TO_EDGE); glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_T,GL_CLAMP_TO_EDGE);
ラップアラウンドモードの設定は主にx軸とy軸ですが、テクスチャの説明ではx, yではなくs, tです。

注:テクスチャの s, t, r, q は座標系の x, y, z, w に対応します。







第1成分3、第2成分3、第3成分2の3成分が占める8ビットの数を示します。

8ビットの3成分が占めるビット数を示しますが、成分は逆で、第1成分が2、第2成分が3、第3成分が3です。



テクスチャ座標

テクスチャ座標は、頂点座標とのマッピング関係を記述します。



テクスチャ関連APIの一般的な使用フロー

bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode)
{
 //1.テクスチャ・オブジェクトの割り当て パラメータ1:テクスチャオブジェクトの数、パラメータ2:テクスチャ・オブジェクト・ポインタ
 glGenTextures(1, &textureID);
 //2.テクスチャ・ステートをバインドする パラメータ1:テクスチャ・ステート 2D パラメータ2:テクスチャ・オブジェクト
 glBindTexture(GL_TEXTURE_2D, textureID);
 
 //テクスチャ・ビットを読む、ピクセルを読む
 GLbyte *pBits;
 int nWidth, nHeight, nComponents;
 GLenum eFormat;
 //パラメータ1:テクスチャファイル名
 //パラメータ2:ファイル幅アドレス
 //パラメータ3:ファイルの高さアドレス
 //パラメータ4:ファイルコンポーネントアドレス
 //パラメータ5:ファイルフォーマットのアドレス
 //戻り値:pBits、イメージデータへのポインタ。
 pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat);
 if(pBits == NULL)
 return false;
 
 //テクスチャ・パラメータを設定する
 //パラメータ1:テクスチャ寸法
 //パラメータ2:S/T座標のモードを設定する
 //パラメータ3:wrapMode,wrapMode
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
 
 //パラメータ1:テクスチャ寸法
 //パラメータ2:線形フィルタリング
 //パラメータ3:wrapMode,wrapMode
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
 //5.テクスチャをロードする
 //パラメータ1:テクスチャ寸法
 //パラメータ2:ミップマッピング階層
 //パラメータ3:テクスチャユニットに格納されている色成分
 //パラメータ4:テクスチャ幅をロードする
 //パラメータ5:テクスチャを高くロードする
 //パラメータ6:ロードされたテクスチャの深さ
 //パラメータ7:ピクセルデータのデータ型(GL)_UNSIGNED_BYTE,(各色成分は8ビットの符号なし整数)。
 //パラメータ8:テクスチャイメージデータへのポインタ
 glTexImage2D(GL_TEXTURE_2D, 0, nComponents, nWidth, nHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBits);
 
 //使用後にpBitsを解放する
 free(pBits);
 
 //Mipマップは、minFilterが以下の4つのモードに等しい場合にのみ生成できる。
 //GL_NEAREST_MIPMAP_NEAREST非常に優れたパフォーマンスと非常に弱いちらつき
 //GL_LINEAR_MIPMAP_NEARESTゲームの高速化によく使われ、高品質のリニアフィルターを使用する
 //GL_LINEAR_MIPMAP_LINEAR  _NEAREST_MIPMAP_LINEAR フィルターは、Mipレイヤー間のフィルターの痕跡を取り除くために、Mipレイヤー間で追加の補間を行う。
 //GL_LINEAR_MIPMAP_LINEAR トリリニアMipマッピング。最高精度のテクスチャー・フィルタリングの黄金律。
 if(minFilter == GL_LINEAR_MIPMAP_LINEAR ||
 minFilter == GL_LINEAR_MIPMAP_NEAREST ||
 minFilter == GL_NEAREST_MIPMAP_LINEAR ||
 minFilter == GL_NEAREST_MIPMAP_NEAREST)
 //6.テクスチャはすべてのMipレイヤーを生成する
 //パラメータ:GL_TEXTURE_1DGL_TEXTURE_2DGL_TEXTURE_3D
 glGenerateMipmap(GL_TEXTURE_2D);
 
 return true;
}



Read next

バランス2進木のデータ構造の基礎を説明する

この記事への序文デフォルトの読者は、バイナリツリーに関連する概念を理解している、あなたが理解していない場合は、バイナリツリーの詳細を表示するには、バイナリツリーをクリックすることができます。バイナリ探索木BST()は、検索のパフォーマンスを向上させるために設計されているので、平均と最悪のケースでその検索が低いです。

Mar 7, 2020 · 4 min read