tangent space via cG / ARB_vertex_program

Hi @ll,

Perhaps a question for the beginners forum, but I´ll post it in here .

Last time I did some intensive OGL coding, is quite some weeks ago, as that said let´s come to my question(s).

If I download NVs cG compiler and read the docs on using the language.
And then try to write some code for generating tangent space matrices, compute light vector and half-angle vector and all that stuff one needs for DOT-3 bumpmapping via cG (I did all that stuff for myself before, but I guess it would be cool to offload that task from CPU to GPU), will cG generate the VP code for me, that I can use in my program or how does this work?
And will it be “easy” to understand how I can write that stuff via cG, if I did it before for myself?

And another question, should I read through the whole ARB_vertex_program spec or will it be sufficient to know how to write the cG code and how to load / use finished VP programs in my code?

And very good example for ARB_vertex_program available?

Regards,
Diapolo

will cG generate the VP code for me, that I
can use in my program

Yes, the Cg compiler will generate the vertex program code for you.

And will it be “easy” to understand how I can write that stuff via cG, if I did it before for myself?

Should be fairly straightforward. Also I think there are examples in the Cg Toolkit that do exactly what you want to do. So it’s just a matter of copy & paste :wink:

And another question, should I read through the whole ARB_vertex_program spec or will it be sufficient to know how to write the cG code and how to load / use finished VP programs in my code?

The latter. You don’t have to read the ARB_v_p spec at all to use Cg. But it’s not bad to know a bit of the spec, so that you can understand the compiler output better.

And very good example for ARB_vertex_program available?

Not any I know of, but it’s very straightforward to convert any DirectX or NV_vertex_program vertex programs to ARB_v_p. In fact, I just wrote a couple of translators that do that automatically :slight_smile:

Cheers.

[This message has been edited by Asgard (edited 09-18-2002).]

Thanks for your reply, sounds like I have to DL and take a look at cG .

By the way, if I write cG code in the cG-Compiler, can I preview it and how does that work (silly question perhaps g).

And what you think, how much faster should GPU processed tangent space be, in contrast to “unoptimized” CPU calculated TS?
Is it worth the effort?

And could one give me a link to the latest OpenGL Extension file with ARB_v_p support or is there none available?

Thanks,
Diapolo

@NV: When will there be an updated version of the OGL Extension Specs online (last Updated: July 8, 2002)?

By the way, if I write cG code in the cG-Compiler, can I preview it and how does that work (silly question perhaps g).

I don’t understand what you mean by “write Cg code in the Cg compiler”…you write code in a text editor and the compiler is a command-line tool that compiles it to vertex program assembly code.

And what you think, how much faster should GPU processed tangent space be, in contrast to “unoptimized” CPU calculated TS?
Is it worth the effort?

Probably. How much faster (or if faster at all) depends on your application. If your application just draws a bump mapped quad all the time and does nothing else (no physics, AI or whatever), then you won’t see any difference, because, while the GPU is executing the vertex program, the CPU will have to wait for it to finish rendering.

And could one give me a link to the latest OpenGL Extension file with ARB_v_p support or is there none available?

As always, the best place for OpenGL extension specs is the SGI extension registry which can be found here: http://oss.sgi.com/projects/ogl-sample/registry/
Note that the ARB_v_p spec is not the newest revision, though (there’s a newer revision that fixes a couple of mistakes and typos).

@NV: When will there be an updated version of the OGL Extension Specs online (last Updated: July 8, 2002)?

I guess they’ll release a new version once all the new NV_xxx extensions for the NV30 architecture are finalized.

Cheers.

[This message has been edited by Asgard (edited 09-18-2002).]

I don’t understand what you mean by “write Cg code in the Cg compiler”…you write code in a text editor and the compiler is a command-line tool that compiles it to vertex program assembly code.

OK I dled the whole Cg and NVSDK (70 MB) via ISDN and did a short look.
My guess was, that I could write cG code in a GUI Tool and press a button to compile it into the corresponding assembler code.
But I guess that was an illusion .
There is cgc.exe which seems to be the “Compiler”. How can I control this compiler, where can I lookup the options / parameters for it?
How can I choose via which profile it should compile and all that stuff?
I guess if I had Visual Studio this thing would integrate into it and do what I want, right?
But I´m on Borland C++ Builder 5 .

Any help / hints on this?

Diapolo

How can I control this compiler, where can I lookup the options / parameters for it?

Try cgc --help. Choosing a profile is done with the -profile switch. You can also use the Cg runtime and not worry about the compiler at all. For more info, consult the Cg documentation.

I guess if I had Visual Studio this thing would integrate into it and do what I want, right?

No, not really. You can just use it in a custom build step. I’m sure Borland has something similar. But I’m always calling the Cg compiler from within my engine which implements its own runtime.

Thanks again for your answers !

OK, so I´ll take a look into the whole Specs of Cg and the compiler options.

You mentioned the Runtime, that I can use directly in my own code.
I hope it doesn´t use a pre-compiled lib, because then I will have to use the compiler generated ASM Code (Borland doesn´t work with MS VS Libs and I dunno how to convert them).

Diapolo

You mentioned the Runtime, that I can use directly in my own code.
I hope it doesn´t use a pre-compiled lib, because then I will have to use the compiler generated ASM Code.

Unfortunately, the runtime is a pre-compiled lib…I also had huge problems getting it to work with some debug DLLs in my engine. Seeing that it has some other design flaws IMHO, I decided to write my own runtime
It’s quite easy to parse the semantic information out of the assembler output, but it would still be nice if NVIDIA could release the runtime with source code.

Ok, I read the first 30 Pages of the Cg_Toolkit-1.5.pdf file and guess I understood most of the things mentioned there.
I´ll have to read on during the next days, but before I´ve got a question.

If I compile a Cg programm into a vertex program and have got the resulting example.vp file.

Is there a NVIDIA PDF, that describes how to load finished VPs (NV or ARB V_P)?

And what I don´t really got is how the vertex data of my app is passed to the vertex program?

Is this only a matter of what I define as input struct / parameters (binding semantics) and when I call the VP in my main OGL app?

Diapolo

Is there a NVIDIA PDF, that describes how to load finished VPs (NV or ARB V_P)?

They are regular vertex programs and can be loaded with the regular APIs. So when you use the vp20 profile, you get an NV_v_p program that you can load and use as described in the NV_v_p extension spec. Similarly, for the arbvp1 profile and ARB_v_p.

However, you will have to manually parse the semantic information in the resulting vertex program (the stuff that’s written at the beginning of the resulting file by the Cg compiler in form of comments).
Or you use the Cg runtime. In that case you don’t have to worry about NV_v_p or ARB_v_p details and about parsing semantic information.

And what I don´t really got is how the vertex data of my app is passed to the vertex program?

Just as in NV_vertex_program. Or if you use the runtime, with the new runtime functions. Read the chapter about the Cg runtime in the Cg docs and look at the samples.

Is this only a matter of what I define as input struct / parameters (binding semantics) and when I call the VP in my main OGL app?

The input struct defines your per-vertex input data (the vertex attributes). The parameters are the constant registers of NV_v_p or parameter registers of ARB_v_p.

OK, since I can´t use the Runtime Libs (@NV: could you please generate one for Borland C++ Builder 5.0), I have to stick with the VP API itself.

manually parse the semantic information in the resulting vertex program (the stuff that’s written at the beginning of the resulting file by the Cg compiler in form of comments).

I didn´t read deep enough into the specs of ARB_V_B / NV_V_P, but I guess you are talking about inserting matrices and all that stuff or could you explain it a bit more detailed?
“Semantic information” is such a strange word for me, because I´m german and didn´t get it´s real meaning .

In my last post I asked on how I insert vertices and all that stuff into the VP.
I think the VP “catches” all stuff like glVertex, glNormal and so on, is this correct?
For other stuff like matrices or constant colors I have to call an VP API function, right?

Really hope I´m on the right way g.

Thanks again,
Diapolo

PS.: I would like to see a Borland Lib !

PPS.: @NV: When will there be a stable 40.XX driver, that I can use? The current one doesn´t allow me to use more than 75 Hz (Windows, OGL, D3D) .

[This message has been edited by Diapolo (edited 09-20-2002).]

I didn´t read deep enough into the specs of ARB_V_B / NV_V_P

Well, I’m afraid you will have to get very familiar with at least one of them to be able to live without the Cg runtime.

but I guess you are talking about inserting matrices and all that stuff or could you explain it a bit more detailed?

Yes, kind of. What I was talking about is the fact that, if you’re not using the runtime, your application has to find out the mapping of Cg variables used in your Cg program to hardware registers. The compiler writes these mappings at the beginning of the resulting vertex program in form of comments.

Here’s a very basic example. Say we have the following simplistic Cg program:

struct appdata
{
float4 position : POSITION;
};

struct vfconn
{
float4 HPOS : POSITION;
float4 COL0 : COLOR0;
};

vfconn main(appdata input, uniform float4x4 ModelViewProj)
{
vfconn OUT;
OUT.HPOS = mul(ModelViewProj, input.position);
OUT.COL0 = float4(1, 1, 1, 1);
return OUT;
}

Compiling this with the arbvp1 profile gives us:

!!ARBvp1.0

ARB_vertex_program generated by NVIDIA Cg compiler

nv30vp backend compiling ‘main’ program

PARAM c4 = { 1, 1, 1, 1 };
#vendor NVIDIA Corporation
#version 1.0.1
#profile arbvp1
#program main
#semantic main.ModelViewProj
#var float4 input.position : $vin.POSITION : POSITION : 0 : 1
#var float4x4 ModelViewProj : : c[0], 4 : 1 : 1
#var float4 HPOS : $vout.POSITION : POSITION : -1 : 1
#var float4 COL0 : $vout.COLOR0 : COLOR0 : -1 : 1
TEMP R0;
ATTRIB v0 = vertex.attrib[0];
PARAM c0[4] = { program.local[0…3] };
DP4 R0.x, c0[0], v0;
DP4 R0.y, c0[1], v0;
DP4 R0.z, c0[2], v0;
DP4 R0.w, c0[3], v0;
MOV result.position, R0;
MOV result.color.front.primary, c4;
END

Your application will have to parse that to find out that, for example, the uniform variable ModelViewProj is expected in registers c0-c3 (which is program.local[0…3] for ARB_v_p).

“Semantic information” is such a strange word for me, because I´m german and didn´t get it´s real meaning .

Well, I’m Austrian…maybe my choice of words wasn’t very good :slight_smile:

In my last post I asked on how I insert vertices and all that stuff into the VP.
I think the VP “catches” all stuff like glVertex, glNormal and so on, is this correct?

Vertices, normals, colors, etc. are the per-vertex attributes that the vertex program receives as input.

For other stuff like matrices or constant colors I have to call an VP API function, right?

Yes, since they usually get stored in some kind of constant register set, that requires new API functions. For ARB_v_p, this would be e.g. glProgramEnvParameter.

Cheers.

Ok, so I have to understand how to suply the VP with parameters via the VP API.

Should I start with NV_V_P or leave it out and start with ARB_V_P?
Are there BIG differences?

So lets come to this here:

#program main
#semantic main.ModelViewProj
#var float4 input.position : $vin.POSITION : POSITION : 0 : 1
#var float4x4 ModelViewProj : : c[0], 4 : 1 : 1
#var float4 HPOS : $vout.POSITION : POSITION : -1 : 1
#var float4 COL0 : $vout.COLOR0 : COLOR0 : -1 : 1

You mentioned only the ModelView Matrix, which has to be loaded into the constant registers c[0]-c[3].
I see this line for that: “#var float4x4 ModelViewProj : : c[0], 4 : 1 : 1”.
The beginning register is there (c[0]) and I guess the 4 is the length of needed registers, OK.
Doesn´t seem to be that complicated, but what about “#var float4 input.position : $vin.POSITION : POSITION : 0 : 1” and the &vout stuff?
Do I have to “parse” that too?
I guess the POSITION is an input the VP recives via glVertex, so I don´t have to call a function of the VP API.
And for the outputs … they are passed to the next stage in the OGL pipeline automatically!

Hope you don´t get crazy, because I really appreciate your help .

Diapolo

Should I start with NV_V_P or leave it out and start with ARB_V_P?
Are there BIG differences?

Yes, there are quite big differences. I’d go for ARB_v_p, seeing that it is the new ARB-approved extension. But it’s a bit more complicated and longer than the NV_v_p spec.

Doesn´t seem to be that complicated, but what about “#var float4 input.position : $vin.POSITION : POSITION : 0 : 1” and the &vout stuff?
Do I have to “parse” that too?

Yes. The first entry in that line is the data type of the vertex attribute. The next token is the name of the variable. $vin indicates that this is an input variable to the vertex program (aka vertex attribute), and POSITION indicates the hardware register used (POSITION would map to vertex.position for ARB_v_p or v[OPOS] for NV_v_p). There’s a list of available varying variable bindings (such as POSITION, NORMAL) in the Cg documentation. The exact same names are used here in the compiler output.
Ok, the next token, which is 0, indicates the 0-based index of the variable in the formal parameter list, if it is a formal parameter to a function. So if you have main(appdata input, uniform float4x4 modelview) in your Cg program, input.position and any other members of the appdata structure would have an index of 0, modelview would have an index of 1. Global variables and output variables have -1 instead of the index. I don’t know the meaning of the last token and it seems to always be 1.

I guess the POSITION is an input the VP recives via glVertex, so I don´t have to call a function of the VP API.

Correct. But there might be other bindings, such as ATTR6, in which case you’d have to call one of the glVertexAttrib functions of ARB_v_p.

And for the outputs … they are passed to the next stage in the OGL pipeline automatically!

Correct.

Hope you don´t get crazy, because I really appreciate your help .

No worries

Best Regards.