【问题标题】:Ogre 3d: RenderTexture bigger than RenderWindowOgre 3d:RenderTexture 比 RenderWindow 大
【发布时间】:2011-10-28 14:05:43
【问题描述】:

我有两个食人魔应用程序:

1) 子应用程序,渲染到窗口和纹理(使用相同的相机)。纹理“导出”到共享内存(linux 中的 shm)

2) 主应用程序,其中平面显示 (1) “子应用程序”中发生的事情,从共享内存加载纹理。

(1) 渲染的纹理与 (2) 中平面使用的纹理大小相同。例如:512x512

如果 RenderWindow 大于或等于 RenderTexture,则一切正常。 您在 (1) 中看到的内容反映在 (2) 具有不错 fps 的平面中。共享内存很强大!

但是如果渲染窗口小于纹理,只有一部分纹理被更新

这就是发生在我身上的事情:

一些示例显示 1x1 窗口和大渲染纹理,所以我想渲染纹理可能比窗口大。

这是创建窗口的方式:

window_ = root_->createRenderWindow("blablah"), 256, 256, false);

这是创建渲染纹理的方式:

TextureManager* tm = TextureManager::getSingletonPtr();
TexturePtr rttTexture = tm->createManual(
/**/"MainRTT"
/**/, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
/**/, TEX_TYPE_2D
/**/, 512
/**/, 512
/**/, 0
/**/, PF_R8G8B8A8
/**/, TU_RENDERTARGET);
RenderTexture* renderTarget = rttTexture->getBuffer()->getRenderTarget();
renderTarget->addViewport(camera_);
renderTarget->setAutoUpdated(false);
Viewport* vp = renderTarget->getViewport(0);
vp->setClearEveryFrame(true);
vp->setOverlaysEnabled(true);
vp->setBackgroundColour(ColourValue::Black);

这就是我更新渲染纹理的方式:

class ShmTexUpdater: public Ogre::FrameListener {
public:
    ShmTexUpdater(const int& width, const int& height, void* data,
            const TexturePtr& tex) :
        /**/width_(width)
        /**/, height_(height)
        /**/, data_(data)
        /**/, tex_(tex)
        /**/, buf_(tex->getBuffer())
        /**/, renderTarget_(tex->getBuffer()->getRenderTarget()){

    }
    virtual ~ShmTexUpdater() {

    }
private:
    virtual bool frameStarted(const FrameEvent& evt) {
        FrameWork::instance()->window()->update();
        buf_->lock(Ogre::HardwareBuffer::HBL_NORMAL);
        renderTarget_->update();
        tex_->getBuffer()->blitToMemory(
        /**/PixelBox(width_, height_, 1, ShmTexture4k::FORMAT, data_));
        buf_->unlock();
        return true;
    }
    int const width_;
    int const height_;
    void* const data_;
    TexturePtr const tex_;
    HardwarePixelBufferSharedPtr buf_;
    RenderTexture* renderTarget_;
};

阅读 RenderWindow 和 RenderTexture 的描述,这不是我所期望的。那么......这是食人魔的错误,还是opengl?还是我做错了?

  • 操作系统:Linux
  • 食人魔:版本 1.7.3 (Cthugha)
  • GL_VERSION = 4.0.0 NVIDIA 256.53

【问题讨论】:

  • 你的camera_变量是否与windows渲染目标共享?
  • @crazyjul 尝试使用新相机,使用 newCamera->synchroniseBaseSettingsWith(camera_);但结果是一样的

标签: c++ linux opengl ogre3d


【解决方案1】:

我不确定它是否有很大帮助(可能为时已晚),但前段时间我读到 OpenGL 无法渲染到大于它正在使用的窗口的纹理。 DX 可以做到这一点,但 OGL 不行。

顺便说一句,对不起,这是答案而不是评论,但我还不能写 cmets ;]

【讨论】:

    【解决方案2】:

    如果目标尺寸发生变化,您的相机需要更新:http://www.ogre3d.org/docs/api/html/classOgre_1_1Viewport.html#a23c2b69bbc3d76fd52a4729a71caed08

    调用_updateDimensions() 应该可以解决它

    【讨论】:

    • 如文档所述,_updateDimensions() 是“仅供 Ogre 内部使用。”。我尝试在vp->setBackgroundColour(ColourValue::Black);renderTarget_->update(); 之前调用它,但没有任何变化。
    • 目标没有改变他的大小。有两个不同的目标:RenderWindow 和 RenderTexture,它们都不会改变它们的大小。我的示例显示了如果 RenderWindow 大于 RenderTexture 会发生什么,反之亦然。
    【解决方案3】:

    但如果渲染窗口小于纹理,只有部分纹理被更新。

    这确实是意料之中的,而且确实是正确的行为。只有通过所谓的像素所有权测试,才会处理常规屏幕窗口的像素。这意味着,只有那些对用户可见的像素才会被渲染。因此,例如,如果您将一个窗口拖到您的 OpenGL 窗口前面,这些像素将不会被渲染到任何一个; 在现代系统上使用所谓的合成窗口管理,其中窗口的阻碍不会通过像素所有权测试。

    长话短说:如果您要渲染内容以供以后处理,则必须在完全由您控制的帧缓冲区上进行:PBuffer帧缓冲区对象 em>。

    【讨论】:

    • 我在你的回答之后做了一些测试......启用或禁用复合后,即使渲染窗口不可见(被其他窗口阻挡,缩小为图标或另一个虚拟桌面),它仍然会继续更新)。如果我用renderTarget_->update(); 强制更新,就会发生这种情况。所以我想这不是问题。对吗?
    • @AlessandroPezzato:您使用哪种操作系统和合成器?无论如何,您不应该将窗口用作渲染到纹理内容的渲染目标。使用 FBO 或 PBuffer,这就是它们的用途。
    • 这是 kde 4.6 和他的合成器。我的 Ogre 应用程序渲染到窗口和纹理 (ogre3d.org/tikiwiki/Intermediate+Tutorial+7)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    相关资源
    最近更新 更多