将场景渲染到一个同屏幕大小一致的浮点纹理,在通过一些操作处理,能实现一些非常好的效果.
1、使用OpenGL中的一些简单的纹理操作函数也可以达到渲染到纹理的功能
首先建立一个长宽为x,y的空纹理,设置的纹理参数可以按需求改变
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, ....
......
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, x, y, 0, GL_RGB, GL_FLOAT, NULL);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, x, y);
执行要渲染到纹理的场景......
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, x, y, 0);
glPopAttrib();
这样就建立好了,使用的时候就可以直接调用纹理texture绑定使用。
2、使用PBO
建立PBuffer
int pfAttribFList[] = { WGL_RED_BITS_ARB, 32, WGL_GREEN_BITS_ARB, 32, WGL_BLUE_BITS_ARB, 32,
WGL_ALPHA_BITS_ARB, 32, WGL_STENCIL_BITS_ARB, 8, WGL_DEPTH_BITS_ARB, 24, WGL_FLOAT_COMPONENTS_NV, true, WGL_DRAW_TO_PBUFFER_ARB, true, 0, };
int piFormats = 0;
unsigned int nNumFormats = 0;
wglChoosePixelFormatARB(m_hWinDC, pfAttribFList, NULL, 1, &piFormats, &nNumFormats);
g_hPBuffer = wglCreatePbufferARB(m_hWinDC, piFormats, 512, 512, NULL);
g_hDC = wglGetPbufferDCARB(g_hPBuffer);
g_hGLRC = wglCreateContext(g_hDC);
wglShareLists(m_hWinGLRC, g_hGLRC);
wglMakeCurrent(g_hDC, g_hGLRC); // 设置PBuffer环境
PBuffer可以看作重新建立的一个隐形窗口,设置像素和投影矩阵,和OpenGL等一些属性
注:设置OpenGL的一些属性,如光照,纹理等,还有透视矩阵等
渲染过程中:
wglMakeCurrent(g_hDC, g_hGLRC); // 设置PBuffer环境
渲染场景....
调用纹理函数跟新纹理
glBindTexture(GL_TEXTURE_2D, m_uiTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 512, 512);
wglMakeCurrent(m_hWinDC, m_hWinGLRC); // 还原窗口显示环境
调用纹理进行渲染。
3、使用FBO
首先建立空纹理,创建帧缓冲区和深度缓冲区......
glGenFramebuffersEXT(1, &fbo); // 创建帧缓冲区
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_uiTexture, 0); // 绑定纹理
glGenRenderbuffersEXT(1, &depth); // 创建深度缓冲区
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, 512, 512);
// 建立深度缓冲区
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth); // 绑定深度缓冲区到帧缓冲区
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
// 绑定帧缓冲区
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
// 渲染场景...
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
// 完成渲染后,便可以直接调用纹理进行渲染