平民程序 - linghuye's blog

天下风云出我辈,一入江湖岁月催。皇图霸业谈笑中,不胜人生一场醉。提剑跨骑挥鬼雨,白骨如山鸟惊飞。尘事如潮人如水,只笑江湖几人回。

随笔 - 221, 文章 - 0, 评论 - 680, 引用 - 0
数据加载中……

GL_NV_register_combiners及GL_NV_XXX 扩展

设显卡硬件拥有最大4层纹理,求如何不用PixelShader语言,实现(tex0 * tex1) * (1-src_alpha) + (tex2 * tex3)*src_alpha
结论:Impossible, Use Shader  is a wise solution                           2005.12.13

使用Nvidia对OpenGL的Texture Shader机制,Register Combiners,更灵活的纹理计算机制且不使用PixelShader,从 Geforce256 开始支持,属于早期的对Pixel Shader的支持,概念很复杂.

1.Register Combiners纹理混合机制并行于原有OpenGL纹理混合机制,使用glEnable(GL_REGISTER_COMBINERS_NV)激活该扩展机制,激活后原有纹理混合机制不再起作用(如为glTexEnv所设之参数),可使用glDisable(GL_REGISTER_COMBINERS_NV)再切换回常规的机制.

2.General Combiner和Final Combiner:显卡支持1-N个General Combiner,仅1个的Final Combiner,Geforce2支持2个General Combiner,Geforce2以上显卡支持8个.
一个General Combiner可用来作如下公式运算: (A op1 B) op3 (C op2 D),并输出A op1 B, C op2 D, (A op1 B) op3 (C op2 D)三个结果值到指定的Register上.
一个Final Combiner用来作如下运算 A*B+(1-A)*C+D.
每个General Combiner按序计算,并将计算结果值作为Input Register传入下一个General Combiner继续计算,最后传入Final Combiner完成最后的计算,生成的RGBA值继续传入Pixel处理管道,Depth Testing,blending...

3.API的作用就是定义这些A,B,C,D...变量,op1,op2,op3这些计算操作符,还有那些复杂的状态.

4.使用glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 1)设置要使用的Combiner数量.
 
5.使用glCombinerParameterfvNV,传送常数颜色值到Texture Shader环境,以备随后使用GL_CONSTANT_COLOR0_NV引用之.

6.使用glCombinerInputNV将某输入参数绑定到某变量上,如
  glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
  取出纹理单元GL_TEXTURE0_ARB(input)的GL_RGB(componentUsage)值,作一下GL_UNSIGNED_IDENTITY_NV值域变换(mapping),并绑定到GL_COMBINER0_NV(stage)的GL_VARIABLE_A_NV(variable)的GL_RGB(portion)上,即前3个参数指定了目标变量,后3个参数指定了要赋予的状态值.
 
7.使用glCombinerOutputNV将某个Combiner的3个结果值绑定到下一轮的Combiner的Input Register上
  glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
  将A op1 B结果绑定到GL_SPARE0_NV的GL_RGB(portion),丢弃(GL_DISCARD_NV)没用到的2个计算值.
 
8.使用glFinalCombinerInputNV定义Final Combiner的输入变量 
  glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
  将GL_SPARE0_NV(input)的GL_RGB(componentUsage)作一下GL_UNSIGNED_IDENTITY_NV值域变换(mapping),并绑定到FinalCombiner的A变量上.
 
9.最终输出的Fragment的Alpha值等于为Final Combiner定义的GL_VARIABLE_G_NV取值.

glEnable(GL_REGISTER_COMBINERS_NV);

glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 
1);

float vClr[4= 1.0f1.0f1.0f1.0f };
glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, vClr);

// 实现ADD_MODULATE    tex0 + tex1
glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);

glCombinerInputNV(GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
glCombinerInputNV(GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_B_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
glCombinerInputNV(GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_C_NV, GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
glCombinerInputNV(GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_D_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
glCombinerOutputNV(GL_COMBINER0_NV, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
    
glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_G_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);

    // 实现BLEND_MODULATE    tex0 * tex1
glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);

glCombinerInputNV(GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
glCombinerInputNV(GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_B_NV, GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
glCombinerOutputNV(GL_COMBINER0_NV, GL_ALPHA, GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
    
glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_G_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);

References:(无基本使用方法和简单示例文档)
http://developer.nvidia.com/object/programmable_texture_blending.html
http://oss.sgi.com/projects/ogl-sample/registry/NV/register_combiners.txt
http://developer.nvidia.com/object/registercombiners.html

posted on 2005-10-01 11:48 linghuye 阅读(761) 评论(1)  编辑 收藏 引用 所属分类: 3D图形学研究

只有注册用户登录后才能发表评论。