|
设显卡硬件拥有最大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.0f, 1.0f, 1.0f, 1.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
|