フレームバッファをいじり、テクスチャにレンダリングして、それらをブリットする必要があることに気づきました。繰り返しになりますが、一部のマシンでは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