使用opengl核心外形管线来完成3d场景的渲染,在此文中用作的示例场景,它包括一个简单反弹的开发箱壁的动画球。此动态场景的选择能提供更多来自不同实现的“实时”效果。
使用aframebufferobject渲染场景纹理是为了更容易操作计算得到的数据,使用纹理作为渲染目的,而不是依靠主要后备缓冲区拥有的某一优势。
输出尺寸(宽与高)变得更容易控制
能避免渲染窗口与别的窗口重叠的问题。
通常来说,用这种后处理流水线能更自然地符合场景纹理的使用。
然而,它很可能使用标准后备缓冲区来渲染和简单地来回读取此缓冲区。
场景渲染通常有两个输出结果:颜色缓存和深度缓存。深度缓存是立体图产生的一部分。当渲染场景的时候,就没有必要存储颜色,只需要深度信息。所以,当创建帧缓存对象的时候,就不需要添加颜色纹理信息。下面的代码就展示了以深度纹理作为目的的,帧缓存的创建。
// Allocate a texture to which depth will be rendered.
// This texture will be used as an input for our stereogram generation algorithm.
glGenTextures( 1 , &mDepthTexture );
glBindTexture( GL_TEXTURE_2D , mDepthTexture );
glTexImage2D(
GL_TEXTURE_2D ,
0 ,
GL_DEPTH_COMPONENT32 ,
kSceneWidth ,
kSceneHeight ,
0 ,
GL_DEPTH_COMPONENT ,
GL_FLOAT ,
0
);
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE );
glBindTexture( GL_TEXTURE_2D , 0 );
// Create a framebuffer object to render directly to the depth texture.
glGenFramebuffers( 1 , &mDepthFramebufferObject );
// Attach only the depth texture: we don't even bother attaching a target
// for colors, because we don't care about it.
glBindFramebuffer( GL_FRAMEBUFFER , mDepthFramebufferObject );
glFramebufferTexture2D(
GL_FRAMEBUFFER ,
GL_DEPTH_ATTACHMENT ,
GL_TEXTURE_2D ,
mDepthTexture ,
0
);
glBindFramebuffer( GL_FRAMEBUFFER , 0 );
当场景渲染的时候,还有一些初始化的任务。尤其是:
1. 创建,加载和编译渲染着色器
2. 创建顶点缓存
在主渲染循环中,下面的任务是必须加入的:
1. 设置帧缓存对象作为渲染的目标
2. 设置着色器程序作为当前活跃程序
3. 渲染场景
为了保持文章在合理的长度内,这些内容在此都不一一解释了。这些在这个算法中都是很常用,很直接的,没有特别的地方。
下面就是用这个程序渲染的场景结果: