//---------------------------------------------------------------------------------------------------- // Resize And Initialize The GL Window GLvoid ResizeGLScreen(GLsizei width, GLsizei height) { // Prevent A Divide By Zero By if (height==0) { height=1; } glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Reset the renderer's screen size to the new size _CrtRender.SetScreenWidth( width); _CrtRender.SetScreenHeight( height); }
//---------------------------------------------------------------------------------------------------- // 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); }