Using cyCg Code Release

The classes in the cyCg code release can be used in many different ways. The aim of this tutorial is to make you familiar with the classes in cyCg, and demonstrate a few ways that you can make use of these classes.

1. Initialization

The first thing you will need to do is to include Cg headers along with the cyCg header. These headers come with nVidia Cg Toolkit.

#include <cg.h>
#include <cgGL.h>
#include "cyCg.h"

Then, in one of your code files (.cpp file) insert the following line somewhere near the top of the file.

cyCgContext CG;

Finally, you need to initialize Cg. This initialization can only be done after the OpenGL context is ready. Therefore, you should first create the OpenGL context, and then call cyCgCreate function. If you are using glut library, you should call cyCgCreate after creating the OpenGL window.

cyCgCreate();

This function will complete Cg initialization.

2. Compiling Simple Cg Shaders

For simple Cg shaders you can use the class cyCgBaseProgram directly. We first create an object of this class. You would probably like to create this object as global or in a global class that you can access from your drawing functions.

cyCgBaseProgram myShader;

To create the program, we need to call the CreateFromFile method of cyCgBaseProgram. Note that, you should call this method after Cg initialization is completed.

myShader.CreateFromFile( CG_GL_VERTEX, "shaderfile.cg", "VertexProg" );

The above line will compile the shader "VertexProg" in the file "shaderfile.cg" and any compilation errors will be printed to the stdout. The program will terminate an error occurs. If you would like to use some compiler options, you can write the following:

myShader.CreateFromFile( CG_GL_VERTEX, "shaderfile.cg", "VertexProg", "-DLEVEL=2" );

This call will define a macro called LEVEL and set it equal to 2. Multiple compiler options can be used by separating then with "|" character as the following:

myShader.CreateFromFile( CG_GL_VERTEX, "shaderfile.cg", "VertexProg", "-DLEVEL=2|-v" );

3. Using Cg Shaders

To use a Cg shader, we need to bind it and enable Cg. Note that, you need to compile the shader first to be able to bind it. The following code uses a vertex shader and a fragment shader.

cyCgEnable();
myVertexShader.Bind();
myFragmentShader.Bind();
//... draw something here
cyCgDisable();

If you would only use a vertex shader call cyCgEnableVP and if you would only use a fragment shader call cyCgEnableFP.


3. Accessing Uniform Parameters

Sometimes you may want to change the values of uniform parameters in your Cg shaders. If you are not changing them frequently, you can use SetNamedParameter methods. The following call sets the value of lightDir uniform parameter of the shader:

myShader.SetNamedParameter3f( "lightDir", 1, 2, 3 );

However, these SetNamedParameter methods can be slow, if you are calling them frequently (while drawing each and every frame). To make it faster you can fist register a parameter during initialization (right after compiling the shader), and then use SetRegisteredParameter methods for altering the value of the parameter. The following code registers 3 parameters:

myShader.RegisterParameters( 3, "lightDir|intensity|distance" );

Once the parameters are registered, you can use the following call to set the value of intensity parameter to 0.97.

myShader.SetRegisteredParameter1f( 1, 0.97 );

4. Custom Shader Classes

If you are using complex shaders, you may find it useful to define your own class using cyCgBaseProgram, and use OnCreate and OnBind events to initialize and set parameters. The following class is an example of this:

class MyCustomShader : public cyCgBaseProgram
{
private:
	CGparameter mvp;
	void OnCreate()
	{
		mvp = cgGetNamedParameter( program, "mvp" );
	}
	void OnBind()
	{
		cgGLSetStateMatrixParameter( mvp,
	                                 CG_GL_MODELVIEW_PROJECTION_MATRIX,
	                                 CG_GL_MATRIX_IDENTITY );
	}
};

Here, when the program is created, OnCreate event of this custom class is called automatically and the parameter mvp is registered within this event. Similarly, whenever the program is binded using the Bind method, OnBind event is called and the parameter is set within this event.

5. Multiple Shader Versions

Sometimes you may want to have different versions of the same shader compiled with different compiler options. The class cyCgProgramContainer serves this purpose. Simply create a shader as the following:

cyCgProgramContainer< MyCustomShader > myShaderList;

If you would like to use cyCgBaseProgram instead, you can use the following:

cyCgBaseProgramContainer myShaderList;

We use the following call to compile all four shaders at once:

myShaderList.CreateFromFile( 4, CG_GL_FRAGMENT, "filename.cg", "FragmentShader",
                             "-DLEVEL=1", "-DLEVEL=2", NULL, "-DLEVEL=3|-DBOUNCE");