6

フレームバッファをいじり、テクスチャにレンダリングして、それらをブリットする必要があることに気づきました。繰り返しになりますが、一部のマシンではGL_INVALID_OPERATION、呼び出しの後に権利が得られglBlitFramebufferます。フレームバッファにバインドされた各テクスチャは、すべて同じサイズとパラメータで、まったく同じ方法でセットアップされます。また、1 つのテクスチャ全体 (以前は正常にレンダリングされたもの) を別のフレーム バッファにブリットしようとすると、書き込み先の「四角形」だけが読み取り元の四角形よりも小さくなります (たとえば、テクスチャの 4 分の 1 にブリットしたい場合)。画面)、それもスローしGL_INVALID_OPERATIONます。

編集: 実際には、読み取りおよび描画する四角形が異なるサイズになると常にエラーがスローされるため、異なるサイズのテクスチャ、または同じサイズで異なるサイズの「レンダリング先」領域にブリットすることはできません。 ..?

手動で生成されたフレームバッファにブリットするたびに、ステータスがチェックされglCheckFramebufferStatus、常に が返されますGL_FRAMEBUFFER_COMPLETE

-史上最大のスニップ-、短い「ソースコード」については以下を参照してください。明らかにいくつかのC++エラーがあり、完全ではありませんが、GL呼び出しのみです

スクリーン フレームバッファをターゲットとして (NULL を渡すことにより) ビューポートの最後のメソッド (Viewport::blit) を呼び出すと、OpenGL エラーが発生します。最初に独自のフレーム バッファの読み取りバッファを設定し (描画バッファは既に設定されています)、次に RenderTarget::blit を呼び出しますglBlitFramebuffer。blit メソッドでは、両方のバッファーをバインドしglCheckFramebufferStatus、エラーを返さない呼び出しを確認できます。

これを何度も読んでいますが、原因となるエラーを見つけることができないようです。私が使用するカラーバッファをブリットするときGL_LINEAR、それ以外の場合はGL_NEARESTすべてのカラーバッファGL_RGB32Fを内部フォーマットとして使用し、深度バッファ(ブリットしない)を使用しますGL_DEPTH_COMPONENT32F

短い例である EDIT は、すべての GL 呼び出しを取得し、使用したパラメーターを埋めただけです。

glBindFramebuffer(GL_READ_FRAMEBUFFER, _GL_Framebuffer);
glReadBuffer(GL_COLOR_ATTACHMENT0 + index);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);

// OpenGL error check, does not return an error

glBindFramebuffer(GL_READ_FRAMEBUFFER, _GL_Framebuffer);
GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE)
{
    // Some error checking, fortunately status always turns out to be complete
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

glBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, target, (target == GL_COLOR_BUFFER_BIT) ? GL_LINEAR : GL_NEAREST);

// If the source/destination read/draw rectangles are different in size, GL_INVALID_OPERATION is cought here

フレームバッファ/テクスチャの作成:

glGenFramebuffer(1, &_GL_Framebuffer);

glGenTextures(1, &_GL_ZBuffer);
glBindTexture(GL_TEXTURE_2D, _GL_ZBuffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, screenWidth, screenHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);

glBindFramebuffer(GL_FRAMEBUFFER, _GL_Framebuffer);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT + 0, _GL_ZBuffer, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

int writeIndices[BUFFER_COUNT];
for(unsigned int i = 0; i < BUFFER_COUNT; ++i)
{
    writeIndices[i] = i;

    glGenTextures(1, &_GL_Texture);
    glBindTexture(GL_TEXTURE_2D, _GL_Texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, screenWidth, screenHeight, 0, GL_RGB, GL_FLOAT, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);

    glBindFramebuffer(GL_FRAMEBUFFER, _GL_Framebuffer);
    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, _GL_Texture, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // In the actual code each texture is obviously saved in an object
}

GLenum *enums = new GLenum[BUFFER_COUNT];
for(unsigned int i = 0; i < BUFFER_COUNT; ++i)
{
    // Get index and validate
    int index = *(indices + i); // indices = writeIndices
    if(index < 0 || index >= maxAttachments)
    {
        delete[] enums;
        return false;
    }

    // Set index
    enums[i] = GL_COLOR_ATTACHMENT0 + index;
}

// Set indices
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _GL_Framebuffer);
glDrawBuffers(BUFFER_COUNT, enums);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

delete[] enums;

// OpenGL error check, no errors
4

1 に答える 1

6

注意深く読んだ後、マルチサンプリングの違いが問題であることがわかりました。「メイン」の FBO は SFML によってセットアップされたので、起動時にアンチ エイリアシング レベルを 0 に設定するだけで、問題は部分的に解決されました。

描画/読み取りの四角形のサイズが等しくない場合にブリットするようになりましたが、動作することが想定されている一部のマシンでクラッシュし続けます。

于 2012-08-11T19:02:12.000 に答える