1、什么是动态纹理(What is Dynamic Texturing)
这是适用处理实时的“飞于空中”的纹理贴图。
The creation of texture maps "on the fly" for use in real time.
简化观点(Simplified view):
循环(Loop):
1)渲染图像。
Render an image.
2)创建源于图像中的纹理。
Create a texture from that image.
3)使用纹理时你应该使用静态纹理。
Use the texture as you would a static texture.
2、动态纹理的应用(Applications of Dynamic Texturing)
光源替用特效(Impostors)
反馈效果(Feedback Effects)
可产生动态立方体/环境贴图(Dynamic Cube / Environment map generation)
可产生动态法向量图(Dynamic Normal map generation)
动态体积雾化(Dynamic Volumetric Fog)
程序纹理(Procedural Texturing)
动态图像的处理(Dynamic Image Processing)
物理仿真(Physical (PDE) Simulation)
[[The No.1 Picture.]]
3、挑战动态纹理帖图(Challenge of Dynamic Texturing)
性能的瓶颈
Performance Bottlenecks
简化观点(Simplified view):
循环(Loop):
1)渲染图像。
Render an image.
2)创建源于图像中的纹理。
Create a texture from that image.
3)使用纹理时你应该用静态纹理。
Use the texture as you would a static texture.
第二步是主要瓶颈,但一、三步还可以很好的工作。
Step 2 is primary bottleneck but 1 and 3 can be relevant as well.
4、创建纹理的方法(Methods for Creating the Texture)
如何把纹理渲染到图像中?
How to get rendered image into a texture?
glReadPixels() - glTexImage*() ?
缓慢(Slow)
glCopyTexImage*()
比较好(Better)
glCopyTexSubImage*()
甚至更好(Even Better)
Render Directly to Texture
消除“纹理复制” ― 潜在地理想方法。
Eliminates "texture copy" - potentially optimal.
5、直接渲染纹理(Rendering Directly to a Texture)
其不是OpenGL 1.3的核心部分,但ARB扩展指令可让它可以在大多数的图形处理器上实现。
Not a core part of OpenGL 1.3, but ARB extensions make this possible on most GPUs.
必须的扩展指令(Required Extensions):
WGL_ARB_extensions_string
WGL_ARB_render_texture
WGL_ARG_pbuffer
WGL_ARB_pixel_format
NVIDIA公司目前GeForce以上的产品(必须28.40版以上的驱动程序)都可以使用它们。
Available on all NVIDIA products since (requires 28.40 driver)
5.1 纵览(Rendering Directly to a Texture: An Overview)
基本思路:允许P缓存作为一个纹理而进行限制。
Basic Idea: Allow a p-buffer to be bound as a texture.
创建纹理对象。
Create a texture object.
创建“渲染纹理”(即P缓存)。
Create a "Render Texture" (i.e. the pbuffer)
作必要循环:
Loop as necessary:
建立当前渲染对象的P缓存
Make the pbuffer the current rendering target
渲染图像
Render an image
建立当前渲染对象的窗口
Make the window the current rendering target
将P缓存混合到纹理对象中
Bind the pbuffer to the texture object
当你需要使用纹理对象的时候
Use the texture object as you would any other
释放纹理对象所占用的P缓存
Release the pbuffer from the texture object
清理
Clean Up
5.2 创建纹理对象(Creating the Texture Object)
是否需要创建一个常规的纹理 ― 不,没有必要指定实际的纹理数据。
Just as you would for a regular texture -- no need to specify the actual texture data.
// Create a render texture object
glGenTextures( 1, &render_texture );
glBindTexture( GL_TEXTURE_2D, render_texture );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_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 );
5.3 创建P缓存(Creating the Pbuffer)
快速预览(Quick Overview):
5.3.1 获得有效设备的上下文(Get a valid device context)
HDC hdc = wglGetCurrentDC();
5.3 2 选择象素格式(Choose a pixel format)
指定一套最低属性:
Specify a set of minimum attributes
色彩位、深度位、模板位、单精/双精度等。
Color bits, Depth bits, Stencil bits, single/double, etc.
可用WGL_DRAW_TO_PBUFFER、WGL_BIND_TO_TEXTURE_RGB_ARB或WGL_BIND_TO_TEXTURE_RGBA_ARB中任意一条。
Must also specify WGL_DRAW_TO_PBUFFER and either WGL_BIND_TO_TEXTURE_RGB_ARB or WGL_BIND_TO_TEXTURE_RGBA_ARB as TRUE.
调用wglChoosePixelFormat():
Then call wglChoosePixelFormat()
返回最低要求的格式列表。
Returns a list of formats which meet minimum requirements.
fid = 在列表里拣选任意一种格式。
fid = pick any format in the list.
5.3.3 建P缓存(Create the pbuffer)
HPBUFFER hbuf = wglCreatePbufferARB( hdc, fid, width, height, attr );
width、height为P缓存的尺度参数。
width and height are dimensions of the pbuffer
“attr”是P缓存其它属性的列表。
"attr" is a list of other properties for your pbuffer.
设置(Set)WGL_TEXTURE_FORMAT_ARB:
WGL_TEXTURE_RGB_ARB or WGL_TEXTURE_RGBA_ARB
设置(Set)WGL_TEXTURE_TARGET_ARB:
WGL_TEXTURE_1D_ARB, WGL_TEXTURE_2D_ARB, or WGL_TEXTURE_CUBE_MAP_ARB
设置WGL_MIPMAP_TEXTURE_ARB需求纹理细化的空间值,其为非零。
Set WGL_MIPMAP_TEXTURE_ARB to non-zero value to request space for mipmaps.
设置WGL_PBUFFER_LARGEST_ARB以获取更多可用的P缓存空间,其为非零。
Set WGL_PBUFFER_LARGEST_ARB to non-zero value to obtain largest possible pbuffer.
5.3.4 获取P缓存设备的上下文(Get the device context for the pbuffer)
hpbufdc = wglGetPbufferDCARB( hbuf );
5.3.5 获取渲染P缓存的上下文(Get a rendering context for the pbuffer)
创建一个新的 ― P缓存获取GL状态集:
Create a new one - pbuffer gets its own GL state:
hpbufglrc = wglCreateContext( hpbufdc );
5.3.6 决定创建的P缓存的实际尺寸(Determine the actual dimension of the created pbuffer)
wglQueryPbufferARB( hbuf, WGL_PBUFFER_WIDTH_ARB, width );
wglQueryPbufferARB( hbuf, WGL_PBUFFER_HEIGHT_ARB, height );
5.3.7 对纹理进行渲染(Rendering to the Texture)
创建P缓存一旦完成。
Can be done anytime once the creation of the pbuffer is complete
初始化函数、显示循环、每次十帧等:
Initialization function, display loop, every 10 frames, etc.
可使用wglMakeCurrent建立当前P缓存的渲染上下文:
Must make the rendering context for the pbuffer current using wglMakeCurrent:
wglMakeCurrent( hpbufdc, hpbufglrc );
发出OpenGL绘制指令。
Issue OpenGL drawing commands.
wglMakeCurrent( hwindc, hwinglrc );
向纹理渲染的机制允许我们对纹理的特定区域进行渲染操作:
The render to texture mechanism allows for rendering to specific regions of a texture:
纹理细化的细节层次
A specific level of a mipmapped texture
立方图纹理的细节面
A specific face of a cube map texture
立方图纹理的细节面的细节细化层次
A specific mip level of a specific face of a cube map texture
可使用wglSetPbufferAttribARB()选择渲染的立方图的面或纹理细化层次。
Can use wglSetPbufferAttribARB() to choose which cube map face or