/* custom_state_assignments - Over-riding pre-defined state assignments and creating new state assignments. */ #include <assert.h> #include <stdlib.h> #include <stdio.h> #include <math.h> #ifdef _WIN32 #include <windows.h> #endif #include <Cg/cg.h> #include <Cg/cgGL.h> static CGcontext myCgContext; static CGeffect myCgEffect; static CGtechnique myCgTechnique; static const char *myProgramName = "custom_state_assignments", *myEffectFileName = "custom_sa.cgfx"; static void checkForCgError(const char *situation) { CGerror error; const char *string = cgGetLastErrorString(&error); if (error != CG_NO_ERROR) { printf("%s: %s: %s\n", myProgramName, situation, string); if (error == CG_COMPILER_ERROR) { printf("%s\n", cgGetLastListing(myCgContext)); } exit(1); } } CGbool program_set( CGstateassignment sa ) { printf( "VertexProgram set called.\n" ); return CG_TRUE; } CGbool program_reset( CGstateassignment sa ) { printf( "VertexProgram reset called.\n" ); return CG_TRUE; } CGbool program_validate( CGstateassignment sa ) { CGprogram prog = cgGetProgramStateAssignmentValue( sa ); printf( "VertexProgram validate called. - %s\n\n", cgGetProfileString( cgGetProgramProfile( prog ) ) ); switch( cgGetProgramProfile( prog ) ) { case CG_PROFILE_VS_2_0: return CG_TRUE; case CG_PROFILE_ARBVP1: return CG_TRUE; case CG_PROFILE_GLSLV: return CG_TRUE; default: return CG_FALSE; } } CGbool foo_set( CGstateassignment sa ) { int nVals = 0; const CGbool *val = cgGetBoolStateAssignmentValues( sa, &nVals ); printf( "\nFooState set called with value %d.\n", *val ); return CG_TRUE; } CGbool foo_reset( CGstateassignment sa ) { printf( "\nFooState reset called.\n" ); return CG_TRUE; } CGbool foo_validate( CGstateassignment sa ) { printf( "FooState validate called.\n" ); return CG_TRUE; } int main(int argc, char **argv) { CGstate programState, fooState; CGpass pass; myCgContext = cgCreateContext(); checkForCgError("creating context"); cgGLRegisterStates(myCgContext); checkForCgError("registering standard CgFX states"); // Over-ride VertexProgram state assignment that was registered in cgGLRegisterStates(ctx) programState = cgGetNamedState( myCgContext, "VertexProgram" ); cgSetStateCallbacks( programState, program_set, program_reset, program_validate ); // Create and register new state FooState fooState = cgCreateState( myCgContext, "FooState", CG_BOOL ); cgSetStateCallbacks( fooState, foo_set, foo_reset, foo_validate ); myCgEffect = cgCreateEffectFromFile( myCgContext, myEffectFileName, NULL ); checkForCgError("creating custom_sa.cgfx effect"); assert(myCgEffect); myCgTechnique = cgGetFirstTechnique(myCgEffect); while (myCgTechnique && cgValidateTechnique(myCgTechnique) == CG_FALSE) { fprintf(stderr, "%s: Technique %s did not validate. Skipping.\n", myProgramName, cgGetTechniqueName(myCgTechnique)); myCgTechnique = cgGetNextTechnique(myCgTechnique); } if (myCgTechnique) { fprintf(stderr, "%s: Initially using technique %s.\n", myProgramName, cgGetTechniqueName(myCgTechnique)); } else { fprintf(stderr, "%s: No valid technique\n", myProgramName); cgDestroyEffect(myCgEffect); cgDestroyContext(myCgContext); exit(1); } // Normally this would be in your render function pass = cgGetFirstPass( myCgTechnique ); while( pass ) { cgSetPassState( pass ); // draw... cgResetPassState( pass ); pass = cgGetNextPass( pass ); } cgDestroyEffect(myCgEffect); cgDestroyContext(myCgContext); return 0; }