渲染到纹理(转载)

来源:互联网 发布:vs2013怎么写c语言 编辑:程序博客网 时间:2024/06/05 17:24
渲染到纹理实现方式:

1. 渲染到帧缓存,然后用glReadPixels将需要的部分读入到客户内存,然后使用glTexImage()函数创建纹理

    缺点:比较慢


2.渲染到帧缓存,然后使用glCopyTexImage() 直接从帧缓存创建纹理


3.渲染到帧缓存,然后使用glCopyTexSubImage() 从帧缓存中读出需要的部分更新纹理的一部分


4.使用 pbuffer,直接渲染到纹理

   需要的扩展:
   WGL_ARB_extensions_string
   WGL_ARB_render_texture
   WGL_ARB_pbuffer
   WGL_ARB_pixel_format

   缺点:
   只可以在windows系统上使用。
   每一个pbuffer在不同的OpenGL上下文中工作,管理麻烦
   pbuffer之间切换开销很大

用pbuffer的DC 和RC作为渲染设备和渲染上下文执行渲染



5. 使用 framebuffer object (FBO)扩展: GL_EXT_framebuffer_object
 
 
 

将场景渲染到一个同屏幕大小一致的浮点纹理,在通过一些操作处理,能实现一些非常好的效果.

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);

// 完成渲染后,便可以直接调用纹理进行渲染

0 0
原创粉丝点击