2012-05-29 212 views
0

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

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

mypbuffer.Initialize(256, 256, 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函数功能很简单,它只是使三角形和矩形,其suposed待屏幕外呈现(希望)。 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要么

+0

我也试过glCopyTexSubImage2D(),也没有任何反应。谢谢。 – filipehd

+0

为什么四边形的Z坐标是0.5f,而不是通常用于Ortho2D投影的0? – Luca

+0

卢卡,我试过不同的值:0,1,-1,它根本没有任何区别。这只是纹理在最后的四边形应该在 – filipehd

回答

2

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

一个完全不同的可能性,并且工作也是在PBuffer上重复使用相同的上下文。这是一个鲜为人知的事实,您可以使用OpenGL渲染上下文不仅在第一个创建的drawable上,而且在任何可绘制的兼容设置上。因此,如果您的PBuffer与主窗口的像素格式相匹配,您可以从主窗口分离渲染上下文并将其附加到PBuffer。当然,你需要低级访问主窗口的设备上下文/可绘制,通常隐藏在框架后面。

+0

你好。我会用wglShareLists尝试你的第一个建议。一旦我做到了,我会在这里发布结果。不幸的是,我仍然没有声望来升级您的解决方案。 – filipehd

+0

太棒了。它真的与wglShareLists合作!有人请提出他的答案。 – filipehd

0

您应该检查你的OpenGL实现是否支持帧缓冲区对象:这些对象能够被渲染目标,他们可以附加纹理颜色缓冲区,确实呈现直接转换成纹理。

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

+0

我已经检查过。它不支持FBO,这就是为什么我用pBuffers替代方法。我的方法是替代方法,但不幸的是我无法使其工作。你有什么想法如何解决它? – filipehd