# CG/CGFX to GLSL

So, I'm making the painful move from my beloved XNA to OpenTK, and I'm stuck:

Since I've got a LOT of existing shaders written in HLSL, NVidia's CG compiler seems like a natural way to minimize the impact on my existing code.

I'm confused, however, about how to compile shaders that use techniques and passes rather than separate vertex and fragment shader programs. The cgc compiler seems to require that one specify an entry point for a shader. However, it's unclear what this means in terms of a shader that has multiple potential entry points without a main() function. For instance, the simple CG effect (an off-the-shelf CG effect created in the ever-flakey FX Composer):

/*

% Second line of description for my shader.

keywords: material classic

date: YYMMDD

*/

float4x4 WorldViewProj : WorldViewProjection;

float4 mainVS(float3 pos : POSITION) : POSITION{
return mul(WorldViewProj, float4(pos.xyz, 1.0));
}

float4 mainPS() : COLOR {
return float4(1.0, 0.0, 1.0, 1.0);
}

technique technique0 {
pass p0 {
CullFaceEnable = true;
VertexProgram = compile vp30 mainVS();
FragmentProgram = compile f340 mainPS();
}
}


The only way I can get this to compile with the cgc command line compiler is:

cgc -noentry test.cgfx


And,of course, I get no output other than a statement that the program was compiled without errors.

The NVidia docs say that the CG compiler can output GLSL if the appropriate profile is passed to the compiler. However, all of the profiles I've seen are either vertex- or pixel/fragment-specific, which seems to contradict the idea of having both in a single file, linked by the technique and pass definitions.

What am I missing here?

Note that I've been able to build this effect using the Cg runtime via the Tao.Cg stuff, but using that appears to require including the Cg runtime in my app distribution, and I can't see a way to make that work on OSX and Linux.

Update I've noticed that by specifying the vertex shader or pixel shader directly as an entry point, and including a -profile glslf' or-profile glslv, that I can get GLSL output for either shader, but this obviously doesn't include setting the state or take into account multiple passes or multiple techniques. Do I really have to run the compiler once for each function defined in the shader source?

• "So, I'm making the painful move from my beloved XNA to OpenTK" Is there any particular reason for that? – Nicol Bolas May 5 '12 at 16:42
• @NicolBolas Mostly Microsoft's lack of clarification on what's going to happen with XNA with Win8 and the next XBOX. Sure, it'll run in legacy mode and on the 360, but it's not exactly encouraging. And cross-platform development is kinda neat. – 3Dave May 5 '12 at 17:19
• @NicolBolas to put this in perspective: I once (circa 1998) loved an amazing tool called Delphi. Native code, REAL visual form designer,... Not really thrilled about getting stuck in the same boat with projects I do for fun. – 3Dave May 6 '12 at 3:09

You cannot process CgFX's FX data into GLSL because GLSL has no equivalent constructs (just as Cg itself doesn't). You can process the files themselves with cgc, but you have to select whether you're getting the vertex shader, fragment shader, or whatever out of the CgFX file. That's why you need to specify an entrypoint.
• Okay; if CG doesn't have equivalent constructs, why does it support technique and pass? Are those just there for HLSL compatibility? – 3Dave May 5 '12 at 17:19
• @DavidLively: Cg and CgFX are not the same thing. They're related, but they aren't the same. Cg does not support technique and pass`; CgFX does. And quite frankly, HLSL doesn't support those either; it's the FX format that does. You're conflating two ideas that, while related, are indeed separate. – Nicol Bolas May 5 '12 at 17:21