|
|
对于GeForce FX 和 GeForce 6 系列GPU,GL_MAX_TEXTURE_UNITS的值是4。为什么?这些GPU不是有16个纹理单元么?
GL_MAX_TEXTURE_UNITS 指得是由GL_ARB_multitexture扩展定义的传统的纹理单元数,以前它是和纹理坐标数相同的。现在,特别是在GeForce FX 和 GeForce 6800 系列,并不需要这个限制,纹理坐标和纹理单元数可以不同,并且它们都大于4。你可以使用任意多组纹理坐标去采样任意多组纹理,而不想以前一样,这两个值必须保持一致。所以,在我们的加强版中并没有改变这个传统,而是使用GL_ARB_fragment_program 和 GL_NV_fragment_program 扩展去支持那些大于4的情况。片断编程会变得更普遍,灵活,高效和可扩展性。
GL_MAX_TEXTURE_UNITS 的最大值被限制在4,而GL_ARB_fragment_program 和 GL_NV_fragment_program 扩展定义了两个新的限制:
GL_MAX_TEXTURE_IMAGE_UNITS_ARB/GL_MAX_TEXTURE_IMAGE_UNITS_NV 定义了最大的图像纹理单元数,对于GeForce FX 和 GeForce 6800 系列,它们是16。
GL_MAX_TEXTURE_COORDS_ARB/ GL_MAX_TEXTURE_COORDS_NV 定义了最大的纹理坐标数,对于GeForce FX 和 GeForce 6800 系列,它们是8。
对于不支持GL_ARB_fragment_program 和 GL_NV_fragment_program扩展的程序, 这些限制被设为GL_MAX_TEXTURE_UNITS。
了解一下这些限制在渲染线的那些阶段被使用也是非常重要的:
GL_MAX_TEXTURE_UNITS 应用于:
glEnable/glDisable(GL_TEXTURE_xxx)
glTexEnv/glGetTexEnv(GL_TEXTURE_ENV_MODE, ...)
glTexEnv/glGetTexEnviv(GL_TEXTURE_SHADER_NV, ...)
glFinalCombinerInput()
glCombinerInput()
glCombinerOutput()
GL_MAX_TEXTURE_IMAGE_UNITS_ARB/GL_MAX_TEXTURE_IMAGE_UNITS_NV 应用于:
glTexImageXXX(...)
glGetTexImage(...)
glTexSubImageXXX(...)
glCopyTexImageXXX(...)
glCopySubTexImageXXX(...)
glTexParameter/glGetTexParameter(...)
glColorTable/glGetColorTable(GL_TEXTURE_xxx/GL_PROXY_TEXTURE_xxx, ...)
glCopyColorTable/glCopyColorSubTable(GL_TEXTURE_xxx/GL_PROXY_TEXTURE_xxx, ...)
glGetColorTableParameter(GL_TEXTURE_xxx/GL_PROXY_TEXTURE_xxx, ...)
glTexEnv/glGetTexEnv(GL_TEXTURE_FILTER_CONTROL_EXT, ...)
glGetTextureLevelParameter(...)
glBindTexture(...)
GL_MAX_TEXTURE_COORDS_ARB/ GL_MAX_TEXTURE_COORDS_NV 应用于:
glEnable/glDisable(GL_TEXTURE_GEN_xxx)
glTexGen(...)
glMatrixMode(GL_TEXTURE)/glLoadIdentity/glLoadMatrix/glRotate/...
glPointParameter(GL_POINT_SPRITE_R_MODE_NV, ...)
glTexEnv/glGetTexEnv(GL_POINT_SPRITE_NV, ...)
glClientActiveTexture(...)
glMultTexCoord(...)
随便说一下,当你使用片断编程时,那些与GL_MAX_TEXTURE_UNITS相关的调用都不会起作用。例如:当你使用片断编程,并把纹理对象作为参数传入TEX/TXP/等函数后,就用不着调用glEnable/glDisable(GL_TEXTURE_xxx)函数了。 如果调用这些函数,它将限制你激活的纹理数为GL_MAX_TEXTURE_UNITS。glBindProgramARB函数用来在渲染线的不同阶段配置纹理,这个函数可以代替很多 glActiveTexture, glEnable/glDisable, 和 glTexEnv 这样的函数。
/*****************************/
The value of GL_MAX_TEXTURE_UNITS is 4 for GeForce FX and GeForce 6 Series GPUs. Why is that, since those GPUs have 16 texture units?
GL_MAX_TEXTURE_UNITS refers to the number of conventional texture units as designed by the old GL_ARB_multitexture extension for which texture coordinate sets and texture image units have to correspond. Now, it doesn’t make sense to carry on with this design choice when, as it is the case with the GeForce FX and GeForce 6800 families, the number of texture coordinate sets and the number of texture image units differs, both of them are more than 4, and you can arbitrarily use any texture coordinate to sample any texture image. So, we have intentionally chosen not to further aggrandize conventional texturing with more texture units and have programmers use the GL_ARB_fragment_program and GL_NV_fragment_program extensions when they need to work with more than 4 texture units. Fragment programs are far more general, flexible, efficient, and forward-looking.
The GL_MAX_TEXTURE_UNITS limit has thus been kept at 4 and the GL_ARB_fragment_program and GL_NV_fragment_program extensions define two new limits:
GL_MAX_TEXTURE_IMAGE_UNITS_ARB/GL_MAX_TEXTURE_IMAGE_UNITS_NV for the number of texture image units, which is 16 for the GeForce FX and GeForce 6800 families,
GL_MAX_TEXTURE_COORDS_ARB/ GL_MAX_TEXTURE_COORDS_NV for the number of texture coordinate sets, which is 8 for the GeForce FX and GeForce 6800 families.
For GPUs that do not support GL_ARB_fragment_program and GL_NV_fragment_program, those two limits are set equal to GL_MAX_TEXTURE_UNITS.
It’s also important to understand which of those three limits apply to which texture-related states:
GL_MAX_TEXTURE_UNITS applies to:
glEnable/glDisable(GL_TEXTURE_xxx)
glTexEnv/glGetTexEnv(GL_TEXTURE_ENV_MODE, ...)
glTexEnv/glGetTexEnviv(GL_TEXTURE_SHADER_NV, ...)
glFinalCombinerInput()
glCombinerInput()
glCombinerOutput()
GL_MAX_TEXTURE_IMAGE_UNITS_ARB/GL_MAX_TEXTURE_IMAGE_UNITS_NV applies to:
glTexImageXXX(...)
glGetTexImage(...)
glTexSubImageXXX(...)
glCopyTexImageXXX(...)
glCopySubTexImageXXX(...)
glTexParameter/glGetTexParameter(...)
glColorTable/glGetColorTable(GL_TEXTURE_xxx/GL_PROXY_TEXTURE_xxx, ...)
glCopyColorTable/glCopyColorSubTable(GL_TEXTURE_xxx/GL_PROXY_TEXTURE_xxx, ...)
glGetColorTableParameter(GL_TEXTURE_xxx/GL_PROXY_TEXTURE_xxx, ...)
glTexEnv/glGetTexEnv(GL_TEXTURE_FILTER_CONTROL_EXT, ...)
glGetTextureLevelParameter(...)
glBindTexture(...)
GL_MAX_TEXTURE_COORDS_ARB/ GL_MAX_TEXTURE_COORDS_NV applies to:
glEnable/glDisable(GL_TEXTURE_GEN_xxx)
glTexGen(...)
glMatrixMode(GL_TEXTURE)/glLoadIdentity/glLoadMatrix/glRotate/...
glPointParameter(GL_POINT_SPRITE_R_MODE_NV, ...)
glTexEnv/glGetTexEnv(GL_POINT_SPRITE_NV, ...)
glClientActiveTexture(...)
glMultTexCoord(...)
Incidentally, the classification above also tells you that all the calls corresponding to GL_MAX_TEXTURE_UNITS are useless when using fragment programs and actually ignored by the driver (so, making those calls has no adverse performance impact). For example, you don't need to call glEnable/glDisable(GL_TEXTURE_xxx) since the texture target is passed as a parameter to the TEX/TXP/etc instructions called inside the fragment program. Making those calls will actually generate errors if the active texture index is above GL_MAX_TEXTURE_UNITS. glBindProgramARB is the one doing all the work of state configuration and texture enabling/disabling. One glBindProgramARB basically replaces a dozen or more of glActiveTexture, glEnable/glDisable, and glTexEnv calls.
|
|