1. ホーム
  2. c++

[解決済み] OpenGL glGeneratemipmapとフレームバッファ

2022-02-07 07:46:22

質問

私はミップマップをオンザフライで生成することについて頭を抱えており、このコードでこのビットを読んでいます。 http://www.g-truc.net/post-0256.html

//Create the mipmapped texture
glGenTextures(1, &ColorbufferName);
glBindTexture(ColorbufferName);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_UNSIGNED_BYTE, NULL);
glGenerateMipmap(GL_TEXTURE_2D); // /!\ Allocate the mipmaps /!\
...
//Create the framebuffer object and attach the mipmapped texture
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColorbufferName, 0);
...
//Commands to actually draw something
render();
...
//Generate the mipmaps of ColorbufferName
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, ColorbufferName);
glGenerateMipmap(GL_TEXTURE_2D);

私の質問です。

  1. なぜ glGenerateMipmap は、テクスチャへのレンダリングの場合、2回呼び出される必要があるのですか?
  2. このように毎フレーム呼び出さなければならないのでしょうか?

例えば、拡散2Dテクスチャをインポートする場合、OpenGLにロードした後、このように一度だけ呼び出す必要があります。

    GLCALL(glGenTextures(1, &mTexture));
    GLCALL(glBindTexture(GL_TEXTURE_2D, mTexture));

    GLint format = (colorFormat == ColorFormat::COLOR_FORMAT_RGB ? GL_RGB : colorFormat == ColorFormat::COLOR_FORMAT_RGBA ? GL_RGBA : GL_RED);
    GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, format, textureWidth, textureHeight, 0, format, GL_UNSIGNED_BYTE, &textureData[0]));

    GLCALL(glGenerateMipmap(GL_TEXTURE_2D));
    GLCALL(glBindTexture(GL_TEXTURE_2D, 0));

フレームごとにテクスチャが再描画され、ミップマップ生成でその内容が使われるからだと思われますが、その確認が欲しいです。

3 - また、gbufferにレンダリングした後、すぐに glBlitFramebuffer をデフォルトのFBOにバインドする必要があるのでしょうか? glGenerateMipmap このように?

GLCALL(glBindTexture(GL_TEXTURE_2D, mGBufferTextures[GBuffer::GBUFFER_TEXTURE_DIFFUSE]));
GLCALL(glGenerateMipmap(GL_TEXTURE_2D));
GLCALL(glReadBuffer(GL_COLOR_ATTACHMENT0 + GBuffer::GBUFFER_TEXTURE_DIFFUSE));
GLCALL(glBlitFramebuffer(0, 0, mWindowWidth, mWindowHeight, 0, 0, mWindowWidth, mWindowHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR));

解決方法は?

  1. リンク先の投稿で説明されているように、"[ ]です。 glGenerateMipmap は、実際には2つのことを行っており、これがおそらく唯一の問題点です。それは、ミップマップのメモリを確保することと、ミップマップを生成することです(")。

    最初の glGenerateMipmap の呼び出しは glTexImage2D をNULLデータポインタで呼び出します。これら 2 つのコールを組み合わせると、テクスチャのすべてのレベルのメモリが単純に割り当てられます。この時点で含まれているデータはゴミです。

    テクスチャの最初のレベルに画像を読み込んだら、次に glGenerateMipmap ダウンサンプルされた画像で小さなレベルを実際に埋めるために、2回目の処理を行います。

  2. あなたの推測は正しいです。 glGenerateMipmap がフレームごとに呼び出されるのは、テクスチャの第1階層にレンダリングされる画像がフレームごとに変化するためです(レンダリング先が変わるため)。この関数を呼び出さない場合、小さいミップマップは決して変更されません(そのようなテクスチャをマッピングする場合、十分に離れていると、初期化されていない小さいミップマップレベルが見えるはずです)。

  3. ミップマップは、ミップマップを使用するテクスチャフィルタリングモードでテクスチャを三角形にマッピングする場合にのみ必要です。テクスチャの最初のレベルしか扱わないのであれば、ミップマップを生成する必要はありません。実際、テクスチャをマッピングしないのであれば、フレームバッファでテクスチャの代わりにレンダーバッファを使用することができます。