Register Combiners, greater than 4 Texuture Units in NV30

I am currently using nvparse and register combiners with four texture
units in my openGL code running on a GeForce3 card (in Windows XP
MSVC++ 6.0 environment). I want to use more than four texture units
and know that I must upgrade to a GeForce FX card and that is fine.
However, it is not clear to me if I can keep the same code structure or
if I have to learn how to use Cg (I would rather not at the start, I
just want to get my current program working with some minor
modifications). Here is the code structure I am using now:

nvparse("!!RC1.0
"
"{
"
" rgb
"
" {
"
" discard = tex0;
"
" discard = tex1;
"
" spare0 = sum();
"
" }
"
"}
"
"{
"
" rgb
"
" {
"
" discard = tex2;
"
" discard = tex3;
"
" spare1 = sum();
"
" }
"
"}
"
"{
"
" rgb
"
" {
"
" discard = spare0;
"
" discard = spare1;
"
" spare0 = sum();
"
" }
"
"}
"
"out.rgb = spare0.rgb;
"
"out.a = unsigned_invert(zero);
");

for (errors = nvparse_get_errors(); *errors; errors++)
{ fprintf(stderr, *errors);
cout<<endl;
}

glEnable(GL_REGISTER_COMBINERS_NV);

nvparse("!!TS1.0
"
"texture_2d();
"
"texture_2d();
"
"texture_2d();
"
"texture_2d();
");
glEnable(GL_TEXTURE_SHADER_NV);

glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, iOutputTextureID_0);

glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, iOutputTextureID_1);

glActiveTextureARB(GL_TEXTURE2_ARB);
glBindTexture(GL_TEXTURE_2D, iOutputTextureID_2);

glActiveTextureARB(GL_TEXTURE3_ARB);
glBindTexture(GL_TEXTURE_2D, iOutputTextureID_3);

RenderQuad(PASS_DISPLAY); // calls the function that does glBegin()
etc.

I fully realize my register combiner code isn’t doing anything
interesting. Can I do the same thing but with 12 textures on my
GeForce FX5900 without getting into Cg? My application is a scientific
simulation so I am not really a graphics guy - sorry. I am
experimenting to see if my GPU runs the simulation faster than the CPU
(just very boring number crunching).

One final point: In addition to using more than one texture, I want to use what I think is called swizzling. I have used this with position coordinates in a vertex program (ADD R6.xyzw, R2.yzxw, -R3.yzxw;)
and I would like to do the analogous thing with colors in a register combiner. For example,

"{
"
" rgb
"
" {
"
" spare0.rgb = tex2.gbr;
"
" spare1.rgb = tex3.rgg;
"
" spare0 = sum();
"
" }
"
"}
"

Any guidance (or outright hand holding) would be greatly appreciated!

Sean.

I think you need to use the ARB_fragment_program extension instead of register combiners to use more texture units.

As I stated in my reply to this message on comp.graphics.api.opengl, you need to use fragment programs (either ARB_fragment_program or NV_fragment_program) to access more than four textures on a GeForceFX.

as far as i remember, the register combiners haven’t changed at all on the gfFX, meaning they behave just as if it would be a gf3/gf4… so 4 units only, too…

actually, except the ARB_fragment_program, i think there are no differences between a gfFX in capabilities over the gf4, except for the additional NV_extensions.

is it true that there are only 4 available textures in gl if you use standard multitexturing or rc’s on a gfFX? i remember i’ve read that somewhere, but i’m unsure now…

Originally posted by davepermen:
is it true that there are only 4 available textures in gl if you use standard multitexturing or rc’s on a gfFX? i remember i’ve read that somewhere, but i’m unsure now…

http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/009119.html

Thanks for the link which helps on some points, but I am still confused…

For the NV20 architecture it took me forever to figure out the relationship between !!VP1.0, !!TS1.0, and !!RC1.0, how many texture units I had in my texture shader, how many general combiners I had in the register combiners and how I needed to use nvparse, glLoadProgramNV, and/or a whole bunch of ugly gl calls to make it all work. The writing of the script or assembly code was trivial; it was seeing the forest from the trees that almost killed me.

  • Has the overall situation changed for me with the NV30 card?

  • OK so it seems that I’ll get 16 texture units by using ARB_fragment_program. What about the number of general combiners? Or is this no longer a relevant question since I must us a fragment program?

  • I guess since I’ll be writing assemly code for the fragement program, I’ll just bind and glLoadProgramNV like I have done with vertex programs right?

  • Will I be able to swizzle color components?

  • Can anyone point me to a nice fragment program doc that provides analogous information to the old nvidia vertex program and register combiner presentations?

Thanks again very much for your help and patience!

OK so it seems that I’ll get 16 texture units by using ARB_fragment_program. What about the number of general combiners? Or is this no longer a relevant question since I must us a fragment program?

There is no such thing as a combiner when using ARB_fragment_program or NV_fragment_program. The amount of stuff you can do is only limited by the number of instructions allowed by a given piece of hardware. You can query the number of instructions for an ARB_fragment_program implementation by calling glGetProgramivARB with the pname parameter set to MAX_PROGRAM_INSTRUCTIONS_ARB.

I guess since I’ll be writing assemly code for the fragement program, I’ll just bind and glLoadProgramNV like I have done with vertex programs right?

Yes, you would use glLoadProgramNV with the GL_FRAGMENT_PROGRAM_NV target if you were using the NV_fragment_program extension. If you use the ARB_fragment_program extension, you should use glLoadProgramARB and GL_FRAGMENT_PROGRAM_ARB.

Will I be able to swizzle color components?

Yes, you can do whatever swizzling you want with fragment programs.

There is no such thing as a combiner when using ARB_fragment_program or NV_fragment_program.

That’s not quite the case.

GeForceFX hardware still retains the RC hardware, post-*_fragment_program (or, put conceptually, fragment_program replaces NV_texture_shader, but not RC’s). You can still use RC’s after the fragment program. However, they retain their limitations in terms of precision, #texture units, and so forth. The NV_fragment_program spec explains how to use RC’s with fp’s.