使用OSG获取模板缓冲区时的FBO错误

194 篇文章 40 订阅

我正在尝试使用OSG中的离线渲染来获取节点的模板索引 . 我的主要程序如下:

  • 深度复制我想离线渲染的节点并获取模板索引;

  • 创建一个离线渲染摄像头,并将之前复制的节点作为摄像头的子节点,然后将此摄像头作为子节点添加到我想要离线渲染的原始节点;

  • 创建一个DrawCallback,它获取模板缓冲区并检查每个像素的模板索引,并获得最大的模板索引 .

好的,程序看起来有点长 . 现在我可以获得正确的最大模板索引,但是,我得到警告和错误:

“RenderStage :: runCameraSetUp(),FBO设置失败,FBO状态= 0x8cdd”“警告:在SceneView :: draw()结束时检测到OpenGL错误'无效操作'...”

整个代码有点冗长乏味 . 下面列出了一些主要代码段:

void OfflineCallback::operator()(osg::RenderInfo &renderInfo)const
{
    osg::Image *image = new osg::Image;
    image->readPixels(0, 0, 512, 512, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE);
    unsigned char *dtBuf = (unsigned char *)(image->getDataPointer());
    int maxStencil = 0;
    for (int i = 0; i != image->s(); ++i){
        for (int j = 0; j != image->t(); ++j){
            unsigned char dt = dtBuf[image->s() * i + j];
            if(dt > maxStencil)
                maxStencil = dt;
        }
    }
}

然后我创建离线渲染摄像头,并附加模板缓冲区:

osg::Camera *camera = new osg::Camera;
camera->setClearMasks(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
camera->attach(osg::Camera::STENCIL_BUFFER, GL_UNSIGNED_BYTE);

osg::Stencil *stencil = new osg::Stencil;
stencil->setFunction(osg::Stencil::GREATER, 1, 0xff);
stencil->setOperation(osg::Stencil::INCR, osg::Stencil::INCR, osg::Stencil::INCR);
osg::Depth *depth = new osg::Depth;
depth->setFunction(osg::Depth::ALWAYS);

osg::StateSet *ss = camera->getOrCreateStateSet();
ss->setAttributeAndModes(stencil, osg::StateAttribute::ON);
ss->setAttributeAndModes(depth, osg::StateAttribute::ON);
camera->setPostDrawCallback(new OfflineCallback);

为了测试代码,我创建一个球体作为主节点,然后我得到最大的模板索引为2,这是正确的,但开头提到的错误和警告 .

我错过了什么?哪一步错了?任何建议将不胜感激 . 谢谢!

真诚的,吉米

opengl  openscenegraph 

2 回答

1

这个电话看起来很可疑:

camera->attach(osg::Camera::STENCIL_BUFFER, GL_UNSIGNED_BYTE);

我没有使用过OSG,但根据文档,这个方法的第二个参数是internalFormat,它直接对应于模板附件内部格式的OpenGL GLenum 值 . GL_UNSIGNED_BYTE 不是模板缓冲区的有效值内部格式 . 这需要 GL_STENCIL_INDEX ,或其大小的变体之一 . 例如:

camera->attach(osg::Camera::STENCIL_BUFFER, GL_STENCIL_INDEX8);

除此之外, 0x8cddGL_FRAMEBUFFER_UNSUPPORTED 的值 . 这意味着(稍微从规范中解释),"the combination of internal formats of the attached images violates an implementation-dependent set of restrictions."

OpenGL实现可以为未按要求指定的任何附件组合提供此错误,如OpenGL 4.5规范中“9.4.3必需的帧缓冲区格式”一节中所述 .

如果在修复模板格式后仍然出现此错误,我强烈怀疑您的尝试失败,因为您使用单独的缓冲区进行深度和模板 . 第9.4.3节特别提到了这种情况:

但是,当存在深度和模板附件时,仅需要实现支持帧缓冲对象,其中两个附件都引用相同的图像 .

当需要深度和模板时,供应商通常仅支持组合深度/模板 . 在内部,通常存在单个32位/像素缓冲器,其具有24位深度和8位模板数据 .

所以如果你现在有这样的东西:

camera->attach(osg::Camera::DEPTH_BUFFER, GL_DEPTH_COMPONENT24);
...
camera->attach(osg::Camera::STENCIL_BUFFER, GL_STENCIL_INDEX8);

如果希望代码在大多数平台上运行,则应使用组合深度/模板缓冲区:

camera->attach(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER, GL_DEPTH24_STENCIL8);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值