![]() |
are you ready for a mindfuck? |
|
....::::Menu::::.... ---------------------------...::About::... ...::Articles::... ...::Contact::... ...::Home & News::... ...::Links & Credits::... --------------------------- --------------------------- |
More vertex programs using CGby Elie De BrauwerGoal of this fileThe goal of this file is to extend the introduction on how to use vertex programs writting in Cg (C for graphics see: http://developer.nvidia.com/Cg) under the Linux operation system. This files extends the introduction with: freeing resources, handling errors and using parameters. History of this file
Handling Cg errors
Nothing is more confusing than putting your time in something and after a while find out that things aren't
working like you expected them to work out. At such a moment in a conventional programming language you'd use
for example the errno variable or use a debugger. With OpenGL and Cg things are a little different.
Either it works or it doesn't work and locating the error is sometimes difficult. For a discussion on how to
handle OpenGL errors you should look at a previous article.
void cgErrorCb(){
printf("%s\n", cgGetErrorString(cgGetError()));
}
A result is returned stating that the compilation has failed. helios@qntal:~/workdir/cg$ ./shadertest CG ERROR : The compile returned an error. Setting parametersPresented the following vertex program:
struct output{
float4 position : POSITION;
float4 color : COLOR;
};
// Uniform says the cg compiler that the constantColor variable is
// defined elsewhere.
output main(float2 position: POSITION, uniform float4 constantColor){
output OUT;
OUT.position = float4(position, 0, 1);
OUT.color = constantColor;
return OUT;
}
You can see some differences with the shader (which is in the archive that
can be downloaded). Mainly there are two big differences the first one is that the main function takes
a second float4 constantColor parameter and that the output color isn't hard coded to green anymore
but that it uses the constantColor as the output color. This means that when we have the power to
change the constantColor from our program we can let the vertex program output that color (basicly doing
the same as the glColor4f() call).
void cgGLSetParameter1{fd}(CGparameter param,
type x);
void cgGLSetParameter2{fd}(CGparameter param,
type x,
type y);
void cgGLSetParameter3{fd}(CGparameter param,
type x,
type y,
type z);
void cgGLSetParameter4{fd}(CGparameter param,
type x,
type y,
type z,
type w);
void cgGLSetParameter{1234}{fd}v(CGparameter param,
const type *v);
Cleaning upWhat do you do after you did a malloc ? What do you do after you did a new ? Indeed you have to free the resources and give them back to the system. Within the Gc api you should also give the resources back. If you want to give the resources for a single program back you should use void cgDestroyProgram( CGprogram prog ); or if you want to give the resources used by an entire CGcontext you should use: void cgDestroyContext( CGcontext ctx ); Putting it all togetherTo illustrate the three subjects discussed above the example program from the introduction to shader programs article was used. The modified shader program is already printed above. #include <Cg/cg.h> // Including Cg runtime API #include <Cg/cgGL.h> // Including OpenGL-specific Cg runtime API #include <GL/glut.h> // Glut and OpenGL api #include <stdlib.h> #include <unistd.h> // sleep void disp(); void keyb(unsigned char k, int x, int y); void cgErrorCb(); CGcontext context; CGprogram program; CGparameter param; float redvalue; float delta; The prototype for the error callback function were added and some global variables were added so that we are able to access some variables from the callback functions. redvalue is the amount of red the triangle will have and delta is the difference between the current and the next redvalue.
int main(int argc, char **argv){
glutInit(&argc, argv);
glutInitWindowPosition(0,0);
glutInitWindowSize(640,480);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("Cg test");
glutDisplayFunc(disp);
glutKeyboardFunc(keyb);
redvalue=0;
delta=0.01;
// Register the cg error Callback
cgSetErrorCallback(cgErrorCb);
// Create the context, this is a container for Cg programs
context = cgCreateContext();
if(context == NULL){
printf("Failed to create CGcontext\n");
exit(-1);
}else{
program = cgCreateProgramFromFile(context, // The context where we want it added
CG_SOURCE, // The following parameter is an array
// of bytes containing Cg source
"./shader.cg", // The sourcefile
CG_PROFILE_ARBVP1,// The profile
"main", // The entry function
NULL // Compiler options
);
if(program==NULL){
printf("Failed to compile the program\n");
exit(-1);
}else{
// Now load the program
cgGLLoadProgram(program);
// Enable the profile
cgGLEnableProfile(CG_PROFILE_ARBVP1);
// Get the parameter
param = cgGetNamedParameter(program,"constantColor");
if(param == NULL){
printf("Could not get the parameter\n");
exit(0);
}
// Bind the program
cgGLBindProgram(program);
}
}
glClearColor(0.0,0.0,0.0,0.0);
glutMainLoop();
}
void disp(){
// Set the vertex program parameter
cgGLSetParameter4f(param,redvalue,0,0,1);
redvalue+=delta;
if(redvalue>=1){
delta*=-1;
redvalue=1.0;
}else if(redvalue<=0){
delta*=-1;
redvalue=0.0;
}
redvalue+=delta;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex2f(-0.8, 0.8);
glVertex2f( 0.8, 0.8);
glVertex2f( 0.0,-0.8);
glEnd();
glutSwapBuffers();
sleep(1);
glutPostRedisplay();
}
In the main function we created a reference to the parameter and this parameter is changed in the disp() function.
We also assure the redvalue is between in the interval [0,1] and that delta is changed so that we first go from black to
red and then from red to black and so on...
void keyb(unsigned char k, int x, int y){
if(k=='q'){
// Free resources
cgDestroyProgram(program);
exit(0);
}
}
void cgErrorCb(){
printf("%s\n", cgGetErrorString(cgGetError()));
}
Last but not least we free the resources when the user pressed 'q' and the content of the error callback. Last wordsThe sources for this article are available here. No screenshots for this article but I thing your imagination can came up with a red triangle.
|