CG: cgGLSetParameter refuses to work PLUS 2 other general questions [SOLVED]

Started by
16 comments, last by d h k 16 years, 3 months ago
Thanks for the commandline-syntax, I was looking for that, but didn't find the correct parameters.

I checked with one of the examples, as far as I can tell I do everything identical, but the problem is still the same (that example works though).

So, I guess the problem doesn't lie in the shader then. Here are the parts of my main.cpp that are relevant:

CGcontext	context;CGprogram	program;CGprofile	profile;CGparameter	ambientColorParameter;void cgErrorCallback(){	CGerror error = cgGetError ( );	if ( error != CG_NO_ERROR )	{		printf ( "%s\n", cgGetErrorString ( error ) );		done = true;	}}void init_shader ( CGprogram program, const char* filename ){	cgSetErrorCallback(cgErrorCallback);	context = cgCreateContext ( );	profile = cgGLGetLatestProfile ( CG_GL_FRAGMENT );	cgGLSetOptimalOptions ( profile );	program = cgCreateProgramFromFile ( context, CG_SOURCE, filename, profile, NULL, NULL );	cgGLLoadProgram ( program );	cgGLBindProgram ( program );	cgGLEnableProfile ( profile );}void init ( void )// initializes the game{	// initialize window	window.create ( WINDOW_TITLE, "settings.cfg" );	// initialize textures	texture[0].init ( "texture1.bmp", FILTER_LINEAR );	texture[1].init ( "texture2.bmp", FILTER_LINEAR );	// do other unrelated stuff...	// init shader	init_shader ( program, "lighting.cg" );	// get parameter (tried to do every frame in draw() as well, didn't check nothing	ambientColorParameter = cgGetNamedParameter ( program, "test" );}void draw ( void )// draws everything{	cgGLBindProgram ( program );	cgGLEnableProfile ( profile );		// OpenGL lighting must be disabled since the pixel shader	// program will compute the lighting value	glDisable ( GL_LIGHTING );	// Set the (fixed) ambient color value	cgGLSetParameter3f ( ambientColorParameter, 0.4f, 0.4f, 0.4f );	// The first texture unit contains the detail texture	glActiveTextureARB ( GL_TEXTURE0_ARB );	glEnable ( GL_TEXTURE_2D );	glBindTexture ( GL_TEXTURE_2D, texture[0].id );	glRotatef ( rotate, 0.0f, 1.0f, 0.0f );	glBegin ( GL_TRIANGLES );	for ( int i = 0; i < 2; i++ ) 	{		for ( int j = 0; j < 3; j++ )		{			cvector normalized_lvector;			light_vector.set ( triangle.vertex[j], light_position );						normalized_lvector = light_vector;			normalize ( normalized_lvector );						// Bind the light vector to COLOR0 and interpolate			// it across the edge			glColor4f ( normalized_lvector.x, normalized_lvector.y, normalized_lvector.z, length ( light_vector ) );			// Bind the texture coordinates to TEXTURE0 and			// interpolate them across the edge			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,				triangle.vertex[j].u, triangle.vertex[j].v);			// Specify the vertex coordinates			glVertex3f(triangle.vertex[j].x, triangle.vertex[j].y, triangle.vertex[j].z);		}	}	glEnd ( );	cgGLDisableProfile ( profile );}


That's all identical to the example-code, if I didn't miss anything (the example code is really somewhat unreadable).
Advertisement
Your original shader doesn't have any variables named "test", but I think the shader in your original post is not what you're currently using for testing. I changed a few parts of the source. Let's see if it makes a difference.

CGcontext	context;CGprogram	program;CGprofile	profile;CGparameter	ambientColorParameter;void cgErrorCallback(){	CGerror error = cgGetError ( );	if ( error != CG_NO_ERROR )	{		printf ( "%s\n", cgGetErrorString ( error ) );		done = true;	}}void init_shader ( CGprogram program, const char* filename ){	//cgSetErrorCallback(cgErrorCallback);	context = cgCreateContext ( );		// new	cgSetErrorCallback( cgErrorCallback );	// new	cgGLSetDebugMode( CG_TRUE );	profile = cgGLGetLatestProfile ( CG_GL_FRAGMENT );	cgGLSetOptimalOptions ( profile );	program = cgCreateProgramFromFile ( context, CG_SOURCE, filename, profile, NULL, NULL );	cgGLLoadProgram ( program );		// new	ambientColorParameter = cgGetNamedParameter( program, "test" );		// new - you might as well move this call to the main loop, but there's no point in doing so	cgGLSetParameter3f ( ambientColorParameter, 0.4f, 0.4f, 0.4f );			//cgGLBindProgram ( program );	//cgGLEnableProfile ( profile );}void init ( void )// initializes the game{	// initialize window	window.create ( WINDOW_TITLE, "settings.cfg" );	// initialize textures	texture[0].init ( "texture1.bmp", FILTER_LINEAR );	texture[1].init ( "texture2.bmp", FILTER_LINEAR );	// do other unrelated stuff...	// init shader	init_shader ( program, "lighting.cg" );	// get parameter (tried to do every frame in draw() as well, didn't check nothing	//ambientColorParameter = cgGetNamedParameter ( program, "test" );}void draw ( void )// draws everything{	cgGLBindProgram ( program );	cgGLEnableProfile ( profile );		// OpenGL lighting must be disabled since the pixel shader	// program will compute the lighting value	glDisable ( GL_LIGHTING );	// Set the (fixed) ambient color value	//cgGLSetParameter3f ( ambientColorParameter, 0.4f, 0.4f, 0.4f );	// The first texture unit contains the detail texture	glActiveTextureARB ( GL_TEXTURE0_ARB );	glEnable ( GL_TEXTURE_2D );	glBindTexture ( GL_TEXTURE_2D, texture[0].id );	glRotatef ( rotate, 0.0f, 1.0f, 0.0f );	glBegin ( GL_TRIANGLES );	for ( int i = 0; i < 2; i++ ) 	{		for ( int j = 0; j < 3; j++ )		{			cvector normalized_lvector;			light_vector.set ( triangle.vertex[j], light_position );						normalized_lvector = light_vector;			normalize ( normalized_lvector );						// Bind the light vector to COLOR0 and interpolate			// it across the edge			glColor4f ( normalized_lvector.x, normalized_lvector.y, normalized_lvector.z, length ( light_vector ) );			// Bind the texture coordinates to TEXTURE0 and			// interpolate them across the edge			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,				triangle.vertex[j].u, triangle.vertex[j].v);			// Specify the vertex coordinates			glVertex3f(triangle.vertex[j].x, triangle.vertex[j].y, triangle.vertex[j].z);		}	}	glEnd ( );	cgGLDisableProfile ( profile );}
You're right, my current shader has a "uniform float test"-variable as main ()-function parameter.

I followed your changes, still doesn't work. It returns:

CG ERROR : Invalid program handle.CG ERROR : Invalid program handle.


I have no idea why it throws two errors.
Quote:
You're right, my current shader has a "uniform float test"-variable as main ()-function parameter.

uniform float? But you're trying to set the value for a float3 variable by calling cgGLSetParameter3f()?! If so, you need to redefine your variable as float3:

uniform float3 test;
Argh. Dumbest. Mistake. Ever.

Hehe, thanks a lot. I just checked though - in my previous test (see the original shader-code posted above), I actually had put "uniform float3", so my solution was actually your lines (change of order) PLUS the typo in the shader, that I introduced.

Geez, CG sure is picky when it comes to what function to call first when initializing.

Thanks a ton for your continued help! :) Rating++.
You're welcome. :) Actually I've had my own share of problems and headaches with Cg and yes, it gets annoying at times.

By the way, don't forget to remove the call to cgGLSetDebugMode in your release builds. Some conditional compilation trick will do the job:
#ifdef _DebugcgGLSetDebugMode( CG_TRUE );#endif
I suspect is related to your question number 2 but one note about your bump map shader.

You compute the normal vector as:
normal_vector = 2.0 * ( normal_vector.rgb - 0.5 );

That's fine as you are transforming linearly from [0, 1] to [-1, 1] range.

But then you compute your light vector as:
light_vector = 2.0 * ( light_vector.rgb - 0.5 );

Is not easier to pass the light vector in the [-1, 1] range from your vertex shader (opengl code) than computing it for every pixel? (Maybe opengl clamp (normalized) the color atribute to [0, 1] range so is necesary to transform?)

All in all why are you passing light vector, rarely related with a vertex attribute, as a vertex attibute? Light vector is normally constant through all vertices, so it makes more sense to pass it as a uniform.

Yep, all that doesn't make much sense there. It was just a test, parts of these lines are from the CG Bumpmapping article on gamedev.net - now that I'm able to pass data from application to shader, I'm working on real shaders... ;)

This topic is closed to new replies.

Advertisement