CrtInt CrtRender::LoadCgProgram( CrtChar * fileName, const CrtInt programType ) { CrtChar fullFileName[CRT_MAX_NAME_SIZE]; CrtCpy( fullFileName, ShaderFilePrefix ); CrtCat( fullFileName, fileName ); CrtPrint(" Loading %s Shader From Binary \n", fullFileName ); // get the name extention CrtChar * ext = CrtGetExtention( fullFileName ); if ( !CrtCmpIn( ext, ".cg" ) && !CrtCmpIn( ext, ".CG" ) ) { CrtPrint("CrtRender::LoadCgProgram: Invalid File Name %s \n", fullFileName ); return -1; } // Load And Compile The Vertex Shader From File if ( programType == CrtFragmentProgram ) { CrtCpy( ext, ".cg" ); cgPrograms[NumCgPrograms] = cgCreateProgramFromFile(cgContext, CG_SOURCE, fullFileName, cgFragmentProfile, NULL, NULL); } else { CrtCpy( ext, ".cg" ); cgPrograms[NumCgPrograms] = cgCreateProgramFromFile(cgContext, CG_SOURCE, fullFileName, cgVertexProfile, "main", 0); } // Validate Success if (cgPrograms[NumCgPrograms] == NULL) { // Check for a Cg Error, If So switch to FixedFunction if ( ! CrtCheckForCgError() ) return -1; // failed to load CgShader CrtChar buff[CRT_MAX_NAME_SIZE]; sprintf(buff," Shader Load Failed %s \n", fileName ); return -1; } CrtPrint(" Shader ID %d \n", cgPrograms[NumCgPrograms] ); cgGLLoadProgram(cgPrograms[NumCgPrograms]); NumCgPrograms ++; return NumCgPrograms - 1; }
CrtInt CrtRender::LoadCgProgram( CrtChar * fileName, const CrtInt programType ) { CrtChar fullFileName[CRT_MAX_NAME_SIZE]; sprintf(fullFileName, "%s%s", ShaderFilePrefix, fileName ); //CrtCpy( fullFileName, fileName ); CrtPrint("CrtRender::LoadCgProgram: Loading %s Shader From File \n", fileName ); // Load And Compile The Vertex Shader From File if ( programType == CrtFragmentProgram ) cgPrograms[NumCgPrograms] = cgCreateProgramFromFile(cgContext, CG_SOURCE, fullFileName, cgFragmentProfile, "main", 0); else cgPrograms[NumCgPrograms] = cgCreateProgramFromFile(cgContext, CG_SOURCE, fullFileName, cgVertexProfile, "main", 0); // Validate Success if (cgPrograms[NumCgPrograms] == NULL) { // Check for a Cg Error, If So switch to FixedFunction if ( ! CrtCheckForCgError() ) return -1; // failed to load CgShader CrtChar buff[100]; sprintf(buff,"CrtRender::LoadCgProgram: Failed Compile CgFile %s \n", fileName ); MessageBox(NULL, buff, "Cg Compile Error", MB_OK ); return -1; } cgGLLoadProgram(cgPrograms[NumCgPrograms]); NumCgPrograms ++; return NumCgPrograms - 1; }
CrtBool CrtExitCg() { CrtPrint("destroying CG context\n"); _CrtRender.DisableCgProfiles(); _CrtRender.DestroyCg(); return CrtFalse; }
CrtVoid CrtInitExtentions() { // get the arb extention if ( !glClientActiveTexture || !glActiveTexture ) { glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB"); glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB"); } if ( !glClientActiveTexture || !glActiveTexture ) { CrtPrint( " Needed Arb Entension was not found \n" ); MessageBox(NULL, "Failed to find Needed ARB Entension!", "Error", MB_OK); CrtPrint( " This app will not be rendered with Cg \n" ); MessageBox(NULL, "Switching to Fixed Function OpenGL \n", "Error", MB_OK ); _CrtRender.DisableCgProfiles(); _CrtRender.DisableCg(); return; } }
CrtBool CrtInitCg() { CrtPrint("creating CG context\n"); cgContext = cgCreateContext(); if(cgContext == NULL) { printf("Failed to create CG context\n"); return CrtFalse; } // Register GL states cgGLRegisterStates(cgContext); // Get the latest GL Vertex Profile cgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); // Was hardcoded to CG_PROFILE_SCE_VP_TYPEB cgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); // Was hardcoded to CG_PROFILE_SCE_FP_TYPEB // Make sure the profiles came back valid if(cgVertexProfile == CG_PROFILE_UNKNOWN || cgFragmentProfile == CG_PROFILE_UNKNOWN) { CrtPrint("Invalid profile type returned from cgGLGetLatestProfile\n"); return CrtFalse; } // Set Optimal Options for this profile cgGLSetOptimalOptions(cgVertexProfile); cgGLSetOptimalOptions(cgFragmentProfile); // Check for Cg errors if ( !CrtCheckForCgError() ) return CrtFalse; CrtPrint("CG context created\n"); return CrtTrue; }
CrtBool CrtInitCg() { // Create a context for the CG programs we are going to load and validate it was successful CrtPrint("Creating CG context\n"); cgContext = cgCreateContext(); if (cgContext == NULL) { // BLahhh exit here MessageBox(NULL, "Failed To Create Cg Context", "Error", MB_OK); return CrtFalse; } // cgSetAutoCompile(cgContext, CG_COMPILE_MANUAL); // Register GL states (ugly crashes if you don't do this) cgGLRegisterStates(cgContext); // Get The Latest GL Vertex Profile cgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); cgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); // Validate Our Profile Determination Was Successful if (cgVertexProfile == CG_PROFILE_UNKNOWN || cgFragmentProfile == CG_PROFILE_UNKNOWN) { MessageBox(NULL, "Invalid profile type", "Error", MB_OK); return CrtFalse; } // Set The Current Profile cgGLSetOptimalOptions(cgVertexProfile); cgGLSetOptimalOptions(cgFragmentProfile); // Check for errors if(!CrtCheckForCgError()) return CrtFalse; return CrtTrue; }
void handleWarning(daeString msg) { CrtPrint( "DOM Warning: %s\n", msg ); }
void handleError(daeString msg) { CrtPrint( "DOM Error: %s\n", msg ); }
//---------------------------------------------------------------------------------------------------- // Standard windows mainline, this is the program entry point // CrtInt32 WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, CrtInt32 nCmdShow) { (void)hPrevInstance; // Avoid warnings (void)nCmdShow; // Avoid warnings (void)hInstance; // Avoid warnings #ifndef NO_DEVIL ilInit(); #endif MSG msg; BOOL done=FALSE; // Avoid warnings later msg.wParam = 0; // Turns on windows heap debugging #if HEAP_DEBUG _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF /*| _CRTDBG_DELAY_FREE_MEM_DF*/); #endif // Ask The User Which Screen Mode They Prefer // if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO) { fullscreen=FALSE; } // Set the default screen size _CrtRender.SetScreenWidth( 640); _CrtRender.SetScreenHeight( 480); // Create an OpenGL Window if (!CreateGLWindow("Collada Viewer for PC", _CrtRender.GetScreenWidth(), _CrtRender.GetScreenHeight(),32,fullscreen)) { return 0; } // Turn data dumping (debug) off //CrtBool dumpData = CrtFalse; // Initialize the renderer // !!!GAC for compatibility with the new COLLADA_FX code, Init now forces UsingCg and UsingVBOs to // !!!GAC false. It also calls CrtInitCg, creating the CG context and calling cgGLRegisterStates. // !!!GAC All these things are currently required for the cfx rendering path to work, changing them // !!!GAC may cause problems. This is work in progress and will be much cleaner when the refactor is done. _CrtRender.Init(); //_CrtRender.SetRenderDebug( CrtTrue ); // !!!GAC kept for reference, changing these may cause problems with the cfx include path //_CrtRender.SetUsingCg( CrtFalse ); // Turn off VBOs (the GL skinning path doesn't work with VBOs yet) _CrtRender.SetUsingVBOs( CrtTrue ); _CrtRender.SetUsingNormalMaps( CrtTrue ); //_CrtRender.SetRenderDebug( CrtTrue ); //_CrtRender.SetUsingShadowMaps(CrtTrue); // We might get a windows-style path on the command line, this can mess up the DOM which expects // all paths to be URI's. This block of code does some conversion to try and make the input // compliant without breaking the ability to accept a properly formatted URI. Right now this only // displays the first filename char file[512], *in = lpCmdLine, *out = file; *out = NULL; // If the first character is a ", skip it (filenames with spaces in them are quoted) if(*in == '\"') { in++; } if(*(in+1) == ':') { // Second character is a :, assume we have a path with a drive letter and add a slash at the beginning *(out++) = '/'; } int i; for(i =0; i<512; i++) { // If we hit a null or a quote, stop copying. This will get just the first filename. if(*in == NULL || *in == '\"') break; // Copy while swapping backslashes for forward ones if(*in == '\\') { *out = '/'; } else { *out = *in; } in++; out++; } // Should throw an error if i>= 512, but we don't have error dialongs in the code yet so just let it try to load and fail if(i < 511) *out = NULL; time_t seconds = time (NULL); clock_t clocka = clock (); cleaned_file_name = file; // Load the file name provided on the command line if ( !_CrtRender.Load( cleaned_file_name )) { exit(0); } time_t loadtime = time (NULL) - seconds; int clockload = (int) clock () - clocka; CrtPrint("\nLOAD TIME OF %s\n", file); CrtPrint("IS %d SECONDS\n", loadtime); CrtPrint("IS %d CLOCK TICKS\n\n", clockload); // This block of code shows how to enumerate all the effects, get their parameters and then // get their UI information. #if 1 { // Get the scene and setup to iterate over all the effects stored in the cfxLoader CrtScene *scene = _CrtRender.GetScene(); std::map<std::string, cfxEffect*>::iterator effectIterator; effectIterator = scene->cfxEffects.begin(); // Iterate over all the effects while(effectIterator != scene->cfxEffects.end()) { // This is the effect name you would use in a UI CrtPrint("Effect name %s\n", effectIterator->first.c_str()); cfxEffect *thiscfxEffect = effectIterator->second; CGeffect thisCGEffect = thiscfxEffect->getEffect(); CGparameter thisCGParameter = cgGetFirstEffectParameter(thisCGEffect); while(thisCGParameter != NULL) { // This is the parameter name you would use in the UI const char *parameterName = cgGetParameterName(thisCGParameter); // This is for the example of how to tweek a parameter (doesn't work yet) if(CrtCmp(parameterName, "Amplitude")) { // Capture the parameter and save it in a global, in a GUI you would // save this handle in the widget so it would know what to tweek. amplitudeGlobalParameter = thisCGParameter; } #if 0 // This is here for debugging, it iterates over all the annotations and prints them out // so you can see what's in them. Normally this code will be turned off. CrtPrint(" Parameter name %s\n",parameterName); CGannotation dbgCGAnnotation = cgGetFirstParameterAnnotation(thisCGParameter); while(dbgCGAnnotation != NULL) { const char *annotationName = cgGetAnnotationName(dbgCGAnnotation); CrtPrint(" Annotation: %s",annotationName); if(cgGetAnnotationType(dbgCGAnnotation) == CG_STRING) { const char *annotationString = cgGetStringAnnotationValue(dbgCGAnnotation); CrtPrint(" value: %s\n",annotationString); } else if(cgGetAnnotationType(dbgCGAnnotation) == CG_FLOAT) { int nvalues; const float *value = cgGetFloatAnnotationValues(dbgCGAnnotation, &nvalues); CrtPrint(" value: %f\n",*value); // Assume there is one value } else { CrtPrint("\n"); } dbgCGAnnotation = cgGetNextAnnotation(dbgCGAnnotation); } #endif // This code looks at the parameter annotations to see if they specify some kind of UI // cgGetNamedParameterAnnotation isn't used for this because it is case sensitive and at // least some of the annotations FXcomposer uses for UI appear to NOT be case sensitive. // This method should collect the parameter values regardless of case, but it has to scan // ALL the parameters and do case-blind compares on each one, which is slower. // This code currently only collects the annotation values for defining sliders and color pickers. const char *UIName = "unknown"; const char *UIWidget = "unknown"; float UIMin = -99999.0f; float UIMax = 99999.0f; float UIStep = 0.0f; int nvalues; CGannotation thisCGAnnotation = cgGetFirstParameterAnnotation(thisCGParameter); // Iterate over all the annotations while(thisCGAnnotation != NULL) { // Get the name of this annotation const char *annotationName = cgGetAnnotationName(thisCGAnnotation); // Do case-blind compares to see if the annotation is one of the ones used to make UI // and save the value if it is. if(CrtICmp("UIWidget",annotationName)) { // This is the widget type UIWidget = cgGetStringAnnotationValue(thisCGAnnotation); } if(CrtICmp("UIName",annotationName)) { // This is the name to attach to the widget UIName = cgGetStringAnnotationValue(thisCGAnnotation); } if(CrtICmp("UIMin",annotationName)) { // This is the minimum value for a slider widget const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues); if(nvalues == 1) UIMin = *value; } if(CrtICmp("UIMax",annotationName)) { // This is the maximum value for a slider widget const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues); if(nvalues == 1) UIMax = *value; } if(CrtICmp("UIStep",annotationName)) { // This is the step (minimum change) for a slider widget const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues); if(nvalues == 1) UIStep = *value; } // Get the next annotation thisCGAnnotation = cgGetNextAnnotation(thisCGAnnotation); } // Is the UIWidget a type that we recognize? (just slider and color picker for now) // Replace the CrtPrint with the code that generates the UI, remember the UI needs to // store thisCGParameter someplace so it can use it to change the parameter later. if(CrtICmp("slider", UIWidget)) { CrtPrint("Parameter %s needs a slider named %s going from %f to %f with step %f\n",parameterName,UIName,UIMin,UIMax, UIStep ); } if(CrtICmp("color", UIWidget)) { CrtPrint("Parameter %s needs a color picker named %s\n",parameterName,UIName); } // Move on to the next parameter thisCGParameter = cgGetNextParameter(thisCGParameter); } // Move on to the next effect effectIterator++; } } #endif while(!done) { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if (msg.message==WM_QUIT) { done=TRUE; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } else { // Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene() if ((active && !DrawGLScene()) || keys[VK_ESCAPE]) // Active? Was There A Quit Received? { done=TRUE; } else { SwapBuffers(hDC); ProcessInput( keys ); } } } _CrtRender.Destroy(); // Shutdown #ifndef NO_DEVIL ilShutDown(); #endif DestroyGLWindow(); return (int)(msg.wParam); }
//---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- int main(int LArgC, char** LArgV) { atexit(DestroyCrt); // Need this, because old GLUT never returns from glutMainLoop() // Create an OpenGL Window if (!CreateGLWindow(LArgC, LArgV, (char*)"COLLADA_DOM Sample Viewer", _CrtRender.GetScreenWidth(), _CrtRender.GetScreenHeight())) { return 0; } // Initialize the renderer // !!!GAC for compatibility with the new COLLADA_FX code, Init now forces UsingCg and UsingVBOs to // !!!GAC false. It also calls CrtInitCg, creating the CG context and calling cgGLRegisterStates. // !!!GAC All these things are currently required for the cfx rendering path to work, changing them // !!!GAC may cause problems. This is work in progress and will be much cleaner when the refactor is done. _CrtRender.Init(); _CrtRender.SetUsingVBOs( CrtTrue ); _CrtRender.SetUsingNormalMaps( CrtTrue ); // Load the file name provided on the command line if(LArgC > 1 && LArgV[1]) { printf("%s(): Loading %s...\n", __FUNCTION__, LArgV[1]); fflush(stdout); if ( !_CrtRender.Load( LArgV[1] )) { exit(0); } } else { printf("%s(): Loading default document cage.dae... \n", __FUNCTION__); fflush(stdout); if ( !_CrtRender.Load( "cage.dae" )) { exit(0); } } // This block of code shows how to enumerate all the effects, get their parameters and then // get their UI information. #if 1 if(_CrtRender.GetScene()) { // Get the scene and setup to iterate over all the effects stored in the cfxLoader CrtScene *scene = _CrtRender.GetScene(); std::map<std::string, cfxEffect*>::iterator effectIterator; effectIterator = scene->cfxEffects.begin(); // Iterate over all the effects while(effectIterator != scene->cfxEffects.end()) { // This is the effect name you would use in a UI CrtPrint("Effect name %s\n", effectIterator->first.c_str()); cfxEffect *thiscfxEffect = effectIterator->second; CGeffect thisCGEffect = thiscfxEffect->getEffect(); CGparameter thisCGParameter = cgGetFirstEffectParameter(thisCGEffect); while(thisCGParameter != NULL) { // This is the parameter name you would use in the UI const char *parameterName = cgGetParameterName(thisCGParameter); // This is for the example of how to tweek a parameter (doesn't work yet) if(CrtCmp(parameterName, "Amplitude")) { // Capture the parameter and save it in a global, in a GUI you would // save this handle in the widget so it would know what to tweek. amplitudeGlobalParameter = thisCGParameter; } #if 0 // This is here for debugging, it iterates over all the annotations and prints them out // so you can see what's in them. Normally this code will be turned off. CrtPrint(" Parameter name %s\n",parameterName); CGannotation dbgCGAnnotation = cgGetFirstParameterAnnotation(thisCGParameter); while(dbgCGAnnotation != NULL) { const char *annotationName = cgGetAnnotationName(dbgCGAnnotation); CrtPrint(" Annotation: %s",annotationName); if(cgGetAnnotationType(dbgCGAnnotation) == CG_STRING) { const char *annotationString = cgGetStringAnnotationValue(dbgCGAnnotation); CrtPrint(" value: %s\n",annotationString); } else if(cgGetAnnotationType(dbgCGAnnotation) == CG_FLOAT) { int nvalues; const float *value = cgGetFloatAnnotationValues(dbgCGAnnotation, &nvalues); CrtPrint(" value: %f\n",*value); // Assume there is one value } else { CrtPrint("\n"); } dbgCGAnnotation = cgGetNextAnnotation(dbgCGAnnotation); } #endif // This code looks at the parameter annotations to see if they specify some kind of UI // cgGetNamedParameterAnnotation isn't used for this because it is case sensitive and at // least some of the annotations FXcomposer uses for UI appear to NOT be case sensitive. // This method should collect the parameter values regardless of case, but it has to scan // ALL the parameters and do case-blind compares on each one, which is slower. // This code currently only collects the annotation values for defining sliders and color pickers. const char *UIName = "unknown"; const char *UIWidget = "unknown"; float UIMin = -99999.0f; float UIMax = 99999.0f; float UIStep = 0.0f; int nvalues; CGannotation thisCGAnnotation = cgGetFirstParameterAnnotation(thisCGParameter); // Iterate over all the annotations while(thisCGAnnotation != NULL) { // Get the name of this annotation const char *annotationName = cgGetAnnotationName(thisCGAnnotation); // Do case-blind compares to see if the annotation is one of the ones used to make UI // and save the value if it is. if(CrtICmp("UIWidget",annotationName)) { // This is the widget type UIWidget = cgGetStringAnnotationValue(thisCGAnnotation); } if(CrtICmp("UIName",annotationName)) { // This is the name to attach to the widget UIName = cgGetStringAnnotationValue(thisCGAnnotation); } if(CrtICmp("UIMin",annotationName)) { // This is the minimum value for a slider widget const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues); if(nvalues == 1) UIMin = *value; } if(CrtICmp("UIMax",annotationName)) { // This is the maximum value for a slider widget const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues); if(nvalues == 1) UIMax = *value; } if(CrtICmp("UIStep",annotationName)) { // This is the step (minimum change) for a slider widget const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues); if(nvalues == 1) UIStep = *value; } // Get the next annotation thisCGAnnotation = cgGetNextAnnotation(thisCGAnnotation); } // Is the UIWidget a type that we recognize? (just slider and color picker for now) // Replace the CrtPrint with the code that generates the UI, remember the UI needs to // store thisCGParameter someplace so it can use it to change the parameter later. if(CrtICmp("slider", UIWidget)) { CrtPrint("Parameter %s needs a slider named %s going from %f to %f with step %f\n",parameterName,UIName,UIMin,UIMax, UIStep ); } if(CrtICmp("color", UIWidget)) { CrtPrint("Parameter %s needs a color picker named %s\n",parameterName,UIName); } // Move on to the next parameter thisCGParameter = cgGetNextParameter(thisCGParameter); } // Move on to the next effect effectIterator++; } } #endif glutMainLoop(); return(0); }