【问题标题】:OpenGL - PBuffer render to TextureOpenGL - PBuffer 渲染到纹理
【发布时间】:2012-06-03 11:07:16
【问题描述】:

在我上一篇文章之后,当有人推荐我使用 pBuffers 时,我在 Google 上挖掘了一下,发现了一些很酷的示例来使用 pbuffers 进行离屏渲染。 nVidia 网站上提供的一些示例进行了简单的离屏渲染,它只是在 pbuffer 上下文中渲染,将像素读入一个数组,然后调用 opengl 函数到 DrawPixels。

我更改了此示例,以便从读取的像素创建纹理 - 将其渲染到屏幕外,将像素读取到数组,然后使用此颜色位数组初始化纹理。但这对我来说看起来非常多余 - 我们渲染图像,我们将它从图形卡内存复制到我们的内存(数组)中,然后将其复制回图形卡以便在屏幕上显示它,但只是在不同的渲染上下文。我为显示渲染纹理而制作的副本看起来有点愚蠢,所以我尝试了使用 glCopyTexImage2D() 的不同方法,不幸的是它不起作用。我将显示代码和解释:

mypbuffer.Initialize(256, 256, false, false);

- false 值用于共享上下文和共享对象。它们是错误的,因为这个出色的图形卡不支持它。

然后我执行通常的初始化,以启用混合和 GL_TEXTURE_2D。

    CreateTexture();
    mypbuffer.Activate();

        int viewport[4];
        glGetIntegerv(GL_VIEWPORT,(int*)viewport);
        glViewport(0,0,xSize,ySize);


        DrawScene(hDC);

        //save data to texture using glCopyTexImage2D
        glBindTexture(GL_TEXTURE_2D,texture);

        glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                         0,0, xSize, ySize, 0);
        glClearColor(.0f, 0.5f, 0.5f, 1.0f);                // Set The Clear Color To Medium Blue
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
        // glBindTexture(GL_TEXTURE_2D,texture);
        first = false;
        mypbuffer.Deactivate();

- DrawScene 函数很简单,它只是渲染一个三角形和一个矩形,应该是离屏渲染的(我希望)。 CreateTexture() 创建一个空纹理。该功能应该可以工作,因为它已按照我之前描述的方式进行了测试并且可以工作。

在此之后,在主循环中,我只需执行以下操作:

            glClear(GL_COLOR_BUFFER_BIT);
            glBindTexture(GL_TEXTURE_2D,texture);

            glRotatef(theta, 0.0f, 0.0f, 0.01f);
            glBegin(GL_QUADS);
            //Front Face
            glTexCoord2f(0.0f, 0.0f);
            glVertex3f(-0.5, -0.5f,  0.5f);
            glTexCoord2f(1.0f, 0.0f);
            glVertex3f( 0.5f, -0.5f,  0.5f);
            glTexCoord2f(1.0f, 1.0f);
            glVertex3f( 0.5f,  0.5f,  0.5f);
            glTexCoord2f(0.0f, 1.0f);
            glVertex3f(-0.5f,  0.5f,  0.5f);
            glEnd();
            SwapBuffers(hDC);

            theta = 0.10f;
            Sleep (1);

最终结果只是一个蓝色背景的窗口,实际上没有渲染任何内容。知道为什么会这样吗?我的显卡不支持扩展wgl_ARB_render_texture,但是调用glCopyTexImage2D()应该不会有问题吧?

我的卡也不支持 FBO

【问题讨论】:

  • 我也试过 glCopyTexSubImage2D() 也没有任何反应。谢谢。
  • 为什么四边形的 Z 坐标是 0.5f,而不是 Ortho2D 投影中通常使用的 0?
  • Luca,我尝试了不同的值:0、1、-1,但它根本没有任何区别。这只是应该在其中渲染纹理的最后一个四边形

标签: c++ opengl buffer textures


【解决方案1】:

您应该检查您的 OpenGL 实现是否支持帧缓冲区对象:这些对象能够成为渲染目标,并且它们可以附加纹理作为颜色缓冲区,实际上是直接渲染到纹理中。

这应该是要走的路,否则你的方法是另一种选择。

【讨论】:

  • 我已经检查过了。它不支持 FBO,这就是我选择 pBuffers 的原因。我的方法是另一种选择,但不幸的是我无法让它发挥作用。你知道如何解决它吗?
【解决方案2】:

您必须做的是,“连接”您的两个 OpenGL 上下文,以便 PBuffer 上下文的纹理也显示在主渲染上下文中。您需要查找的术语是“显示列表共享”。在 Windows 中,您使用 wglShareLists 追溯连接上下文,在 X11 和 MacOS X 上,您必须提供要在创建上下文时共享的上下文句柄。

另一种完全不同的可能性并且同样有效的是重用 PBuffer 上的相同上下文。这是一个鲜为人知的事实,您不仅可以在首先创建它的可绘制对象上使用 OpenGL 渲染上下文,还可以在具有兼容设置的任何可绘制对象上使用 OpenGL 渲染上下文。因此,如果您的 PBuffer 与主窗口的像素格式匹配,您可以从主窗口中分离渲染上下文并将其附加到 PBuffer。当然,您随后需要对主窗口的设备上下文/drawable 进行低级别访问,这通常隐藏在框架后面。

【讨论】:

  • 你好。我将使用 wglShareLists 尝试您的第一个建议。一旦我让它工作,我会在这里发布结果。不幸的是,我仍然没有声望支持您的解决方案。
  • 太棒了。它确实适用于 wglShareLists!请有人支持他的回答。
猜你喜欢
  • 2023-03-30
  • 2014-07-22
  • 2013-10-05
  • 1970-01-01
  • 2013-12-27
  • 1970-01-01
  • 2012-01-16
  • 2012-05-16
  • 1970-01-01
相关资源
最近更新 更多