げぇむぷろぐらみんぐ

日々の生活で得た知識、経験を書きます

OpenGLでテクスチャマッピングをする際の注意点

最近、ふと思い立ってOpenGLを使って簡単なゲーム作れるくらいの知識はつけておきたいな〜と考えて勉強しているのですが、いかんせん日本語の情報が少なく、あったとしてもかなり古いものであり、今とはだいぶ違ったりしていて大変です。

そんな感じでさぐりさぐりやっているわけですが、せっかくなので自分用のメモとしてハマったところをメモっておきます。

 間違っていたら何かしらの方法で教えてもらえるととっても喜びます…!

OpenGLテクスチャマッピングをする際には大体以下のような感じになるかと思います。

GLuint tex;
//テクスチャオブジェクトの生成
glGenTextures(1, &tex);

//テクスチャのバインド
glBindTexture(GL_TEXTURE_2D, tex);

//画像の読み込み
cv::Mat img = cv::imread("texture0.png", cv::IMREAD_UNCHANGED);
//BGRAからRGBAへ変換
cv::cvtColor(img, img, cv::COLOR_BGRA2RGBA);

//テクスチャにデータを紐付ける
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.cols, img.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE,
img.data);

//テクスチャユニットを指定
glActiveTexture(GL_TEXTURE0);

//テクスチャをバインド
glBindTexture(GL_TEXTURE_2D, tex);

//指定したユニット番号をシェーダに送る
glUniform1i(uniLocation[6], 0);

 

画像の読み込みに関しては、いまいち何を使うのが良いのかわからなかったのでとりあえずOpenCVのimreadを使用しています。

実はここでもハマりました…(OpenCVがBGRAの順なのを完全に忘れてた…)

これで描画できる!やった!!!と思って実行したらなぜか真っ黒に…

その後色々調べて

glGenerateMipmap(GL_TEXTURE_2D);

これを、テクスチャにデータを紐付けたあとに呼んでやればうまいこと描画されました。

このとき僕は、glTexImage2Dの第二引数でミップマップ使わない設定にしてあるから呼ばなくていいはずなのに…って思ってました。

でもこれ、呼ばないとだめなんですね。

理由は、テクスチャパラメータのデフォルトの指定が、ミップマップを使うものになっているから。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

どうやら縮小の際の設定のデフォルト値が上記のようになっているらしい。

これのせいで、ミップマップを生成しないと、生成されていないミップマップを読み込みに行ってしまい、真っ黒になってしまうみたいです。

つまり、ミップマップを生成する必要が無いなら、先にテクスチャパラメータを指定してしまえば、glGenerateMipmapを呼んでやらなくてもうまく表示されるわけです。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

よって、上のような設定をテクスチャオブジェクトごとにしてやればおっけーです。

テクスチャパラメータの指定はどうやらテクスチャオブジェクトごとにするようなので、その点だけ注意が必要ですね。

多分これで、うまく描画出来ると思います。

 

正直全く自身がないので、本当に間違っていたら教えてもらえるとうれしいです…

あと、参考にする方がもしいれば、間違っていても構わないという気持ちでお願いします。