Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ glBlitFramebuffer操作无效_C++_Opengl_Render_Blit - Fatal编程技术网

C++ glBlitFramebuffer操作无效

C++ glBlitFramebuffer操作无效,c++,opengl,render,blit,C++,Opengl,Render,Blit,我一直在乱搞帧缓冲区和渲染到纹理,我发现需要blit它们。同样,在一些机器上,在调用glBlitFramebuffer之后,我会得到一个GL\u INVALID\u操作。绑定到帧缓冲区的每个纹理的设置方式完全相同,大小和参数都相同。此外,当我尝试将一个完整纹理(以前成功渲染到)blit到另一个帧缓冲区时,只有要写入的目标“矩形”比要读取的矩形小(例如,当我要将其blit到屏幕的四分之一时),它也会抛出一个GL\u INVALID\u操作 编辑:事实上,每当要读取和绘制的矩形具有不同大小时,它总是

我一直在乱搞帧缓冲区和渲染到纹理,我发现需要blit它们。同样,在一些机器上,在调用
glBlitFramebuffer
之后,我会得到一个
GL\u INVALID\u操作。绑定到帧缓冲区的每个纹理的设置方式完全相同,大小和参数都相同。此外,当我尝试将一个完整纹理(以前成功渲染到)blit到另一个帧缓冲区时,只有要写入的目标“矩形”比要读取的矩形小(例如,当我要将其blit到屏幕的四分之一时),它也会抛出一个
GL\u INVALID\u操作

编辑:事实上,每当要读取和绘制的矩形具有不同大小时,它总是抛出错误,因此我无法将其切换到不同大小的纹理,或相同大小但不同大小的“渲染到”区域

每次我切换到手动生成的帧缓冲区时,都会通过
glCheckFramebufferStatus
检查状态,并始终返回
GL\u framebuffer\u COMPLETE

最大的剪辑——见下面的“源代码”,显然是两个C++错误,不完全,但它只适用于GL调用< /P> 当我以屏幕帧缓冲区为目标(通过传递NULL)调用视口的最后一个方法(viewport::blit)时,会发生OpenGL错误。它首先设置自己的帧缓冲区的读取缓冲区(已经设置了绘制缓冲区),然后调用RenderTarget::blit,后者调用

glBlitFramebuffer
。在blit方法中,它绑定了两个缓冲区,您可以看到它在那里调用了
glCheckFramebufferStatus
,而不会返回错误

我读了一遍又一遍,但似乎找不到导致它的错误。当我blit颜色缓冲区时,我使用
GL\u LINEAR
,否则我使用
GL\u NEAREST
所有颜色缓冲区使用
GL\u RGB32F
作为内部格式,深度缓冲区(我从不blit)使用
GL\u depth\u组件32f

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
glGenFramebuffer(1,&u GL\u Framebuffer);
glGenTextures(1和Glzbuffer);
glBindTexture(GL_TEXTURE_2D,_GL_ZBuffer);
glTexParameteri(GL_纹理_2D,GL_纹理_基础_级别,0);
glTexParameteri(GL_纹理_2D,GL_纹理_最大水平,0);
glTexImage2D(GL_纹理_2D,0,GL_深度_组件32F,屏幕宽度,屏幕高度,0,GL_深度_组件,GL_浮动,0);
glTexParameteri(GL_纹理\u 2D、GL_纹理\u包裹\u R、GL_夹紧\u至\u边缘);
glTexParameteri(GL_纹理_2D、GL_纹理_包裹、GL_夹紧_至_边缘);
glTexParameteri(GL_纹理\u 2D、GL_纹理\u包裹\u T、GL_夹紧\u至\u边缘);
glTexParameteri(GL\u纹理\u 2D,GL\u纹理\u最小\u过滤器,GL\u最近);
glTexParameteri(GL_纹理2D,GL_纹理MAG_过滤器,GL_最近);
glBindTexture(GL_TEXTURE_2D,0);
glBindFramebuffer(GL\u FRAMEBUFFER,\u GL\u FRAMEBUFFER);
glFramebufferTexture(GL_帧缓冲区,GL_深度,GL_附件+0,_GL_ZBuffer,0);
glBindFramebuffer(GL_帧缓冲区,0);
int writeIndices[BUFFER_COUNT];
for(无符号整数i=0;i=maxAttachments)
{
删除[]个枚举;
返回false;
}
//集合索引
enums[i]=GL_COLOR_ATTACHMENT0+索引;
}
//设置索引
glBindFramebuffer(GL\u DRAW\u FRAMEBUFFER,\u GL\u FRAMEBUFFER);
glDrawBuffers(缓冲区计数,枚举);
glBindFramebuffer(GL\u DRAW\u FRAMEBUFFER,0);
删除[]个枚举;
//OpenGL错误检查,无错误

仔细阅读之后,我发现问题出在多重采样中。“主”FBO是由SFML设置的,因此只要将启动时的抗锯齿级别设置为0,问题就得到了部分解决


现在,如果绘制/读取矩形大小不相等,它会闪烁,但在一些本应工作的机器上,它会不断崩溃

你的FBO有多采样的吗?哦,关于这一点,我从来没有设置任何关于多采样的参数,我不知道FBO自己是如何处理的,但我假设他们目前遵循默认行为。我很想得到一个关于如何设置FBO的多重采样行为的正确方向的提示xD还注意到,如果绘制/读取矩形相等,它会成功地执行blit,只有当它们不相等时才会抛出错误,或者在某些笔记本电脑上(笔记本电脑至少应支持OpenGL 3.2)。您可以查看和。它还包含其他可能的原因,因为这里很难猜测。你的例子太长了,难道你不能试着用一行或20行来重现它吗?好的,我已经完成了每个调用并取出了所有OpenGL调用,请参阅问题的底部,了解实际的blitting代码和帧缓冲区/纹理创建。这些机器上的驱动程序有多大年龄?有一些老司机的FBO往往行为不端(所有