void COLLADA_Viewer::SixAxis(float flX, float flY, float flZ, float flG) { (void) flG; if (_CrtRender.UsingPhysics()) { static float dampedX = 0.0f; static float dampedY = 0.0f; static float dampedZ = 0.0f; dampedX=(flX + 10.f*dampedX)/11.f; dampedY=(flY + 10.f*dampedY)/11.f; dampedZ=(flZ + 10.f*dampedZ)/11.f; btTransform floorTrans; floorTrans.setIdentity(); btVector3 xAxis(1,0,0); btVector3 zAxis(0,0,1); btQuaternion rotX(zAxis,dampedX*10.f); btQuaternion rotZ(xAxis,-dampedZ*10.f); btQuaternion combinedRot = rotZ*rotX; btMatrix3x3 orn; orn.setRotation(combinedRot); btVector3 up = orn.getColumn(1); CrtVec3f newG = CrtVec3f(up.getX(),up.getY(),up.getZ()); _CrtRender.SetGravity(newG); // printf("new gravity (%f, %f, %f)\n", newG.getX(), newG.getY(), newG.getZ()); } }
static void DestroyCrt(void) { _CrtRender.Destroy(); DestroyGLWindow(); }
void MouseCallback(int button, int state, int x, int y) { switch (button) { case GLUT_MIDDLE_BUTTON: if (state == GLUT_UP) { sLeftBtnDown = false; } else if (state == GLUT_DOWN) { sLeftBtnDown = true; _CrtRender.SetNextCamera(); } break; case GLUT_LEFT_BUTTON: if (state == GLUT_UP) sLeftBtnDown = false; else if (state == GLUT_DOWN) sLeftBtnDown = true; break; case GLUT_RIGHT_BUTTON: if (state == GLUT_UP) sRightBtnDown = false; else if (state == GLUT_DOWN) sRightBtnDown = true; break; default: break; } }
void COLLADA_Viewer::onShutdown() { FWGLApplication::onShutdown(); _CrtRender.Destroy(); cellDbgFontConsoleClose(mDbgFontID); cellDbgFontExit(); }
static void specialKeyboardCallback(int key, int x, int y) { (void)x; (void)y; switch (key) { case GLUT_KEY_F1: fullscreen = !fullscreen; if (fullscreen) { Xpos = glutGet((GLenum)GLUT_WINDOW_X); /* Save parameters */ Ypos = glutGet((GLenum)GLUT_WINDOW_Y); Xsize = glutGet((GLenum)GLUT_WINDOW_WIDTH); Ysize = glutGet((GLenum)GLUT_WINDOW_HEIGHT); glutFullScreen(); /* Go to full screen */ } else { glutReshapeWindow(Xsize, Ysize); /* Restore us */ glutPositionWindow(Xpos,Ypos); glutPostRedisplay(); } break; case GLUT_KEY_LEFT : _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed, 0.0f); break; case GLUT_KEY_RIGHT : _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, - _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed, 0.0f); break; case GLUT_KEY_UP : // UI code to move the camera farther up _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, 0.0f, _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed); break; case GLUT_KEY_DOWN : _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, 0.0f, - _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed); break; default: printf("unused (special) key : %i\n", key ); break; } }
//---------------------------------------------------------------------------------------------------- // 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); }
//---------------------------------------------------------------------------------------------------- // Render routine //---------------------------------------------------------------------------------------------------- void DrawGLScene(void) { // Clear The Screen And The Depth Buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); CrtMaterial mat; mat.Ambient = CrtColor3f( 1,1,1 ); mat.Diffuse = CrtColor3f( 1,1,1 ); glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, (GLfloat *)&mat.Diffuse ); glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, (GLfloat *)&mat.Ambient ); glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *)&mat.Specular ); glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, (GLfloat )mat.Shininess ); if(_CrtRender.GetScene()) _CrtRender.Render(); glutSwapBuffers(); }
void COLLADA_Viewer::onRender() { // base implementation clears screen and sets up camera FWGLApplication::onRender(); if (!load_ok) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); Browser.onRender(); cellDbgFontPuts(0.5f, 0.5f, 1.0f, 0xff00ffff, "Load Error!"); cellDbgFontDraw(); return; } if (mRunning==false) return; glPushMatrix(); glEnable(GL_DEPTH_TEST); _CrtRender.Render(); glPopMatrix(); // FPS REPORTING glDisable(GL_VSYNC_SCE); // get current timing info FWTimeVal timeNow = FWTime::getCurrentTime(); float fElapsedInFrame = (float)(timeNow - mLastTime); mLastTime = timeNow; ++frames; timeElapsed+=fElapsedInFrame; // report fps at appropriate interval if (timeElapsed>=timeReport) { //printf("FPS: %.2f\n",(frames-framesLastReport)*1.f/(float)(timeElapsed-timeLastReport)); timeReport+=REPORT_TIME; timeLastReport=timeElapsed; framesLastReport=frames; } glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); Browser.onRender(); cellDbgFontDraw(); }
bool COLLADA_Viewer::onUpdate() { float tolerrance = 0.15; static float buttonTime = 0; static float cameraTime = 0; bool result = FWGLApplication::onUpdate(); if (mRunning==false) return result; FWTimeVal curTime = FWTime::getCurrentTime(); if ((float)curTime - buttonTime > 0.15) // execute these control base on time elapse, not frame rate { buttonTime = curTime; if(mpPad->getRawBool(FWInput::Channel_Button_Select)) { _CrtRender.SetNextCamera(); return result; } else if(mpPad->getRawBool(FWInput::Channel_Button_L3)) { if (Browser.IsVisible()) Browser.SetVisible(false); else Browser.SetVisible(true); } else if(mpPad->getRawBool(FWInput::Channel_Button_R3)) { if (togglewireframe) { togglewireframe = false; } else { togglewireframe = true; } } else if(mpPad->getRawBool(FWInput::Channel_Button_Square)) { if (togglelighting) { togglelighting = false; } else { togglelighting = true; } } else if(mpPad->getRawBool(FWInput::Channel_Button_Cross)) { mCurrentFile = Browser.GetThumbnail(Browser.GetSelection())->GetDocument(); load_ok = _CrtRender.Load(mCurrentFile, NULL); return result; } else if(mpPad->getRawBool(FWInput::Channel_Button_Up)) { Browser.SelectPrev(); } else if(mpPad->getRawBool(FWInput::Channel_Button_Down)) { Browser.SelectNext(); } } if ((float)curTime - cameraTime > 0.05) // execute these control base on time elapse, not frame rate { cameraTime = curTime; // Get the values from the analog sticks float conditioned_X_0 = mpPad->getRawFloat(FWInput::Channel_XAxis_0); float conditioned_Y_0 = mpPad->getRawFloat(FWInput::Channel_YAxis_0); float conditioned_X_1 = mpPad->getRawFloat(FWInput::Channel_XAxis_1); float conditioned_Y_1 = mpPad->getRawFloat(FWInput::Channel_YAxis_1); if (-tolerrance < conditioned_X_0 && conditioned_X_0 < tolerrance) conditioned_X_0 = 0.0f; if (-tolerrance < conditioned_Y_0 && conditioned_Y_0 < tolerrance) conditioned_Y_0 = 0.0f; if (-tolerrance < conditioned_X_1 && conditioned_X_1 < tolerrance) conditioned_X_1 = 0.0f; if (-tolerrance < conditioned_Y_1 && conditioned_Y_1 < tolerrance) conditioned_Y_1 = 0.0f; conditioned_X_0 = mpInputX0 ? -mpInputX0->getFloatValue() : 0.f; conditioned_Y_0 = mpInputY0 ? -mpInputY0->getFloatValue() : 0.f; conditioned_X_1 = mpInputX1 ? -mpInputX1->getFloatValue() : 0.f; conditioned_Y_1 = mpInputY1 ? -mpInputY1->getFloatValue() : 0.f; float multiplier = 10.0f; if (conditioned_X_0 != 0.0f || conditioned_Y_0 != 0.0f) { _CrtRender.ActiveInstanceCamera->MoveOrbit(conditioned_X_0 * multiplier, conditioned_Y_0 * multiplier); } if (conditioned_X_1 != 0.0f || conditioned_Y_1 != 0.0f) { _CrtRender.ActiveInstanceCamera->SetPanAndTilt(conditioned_X_1 * multiplier, conditioned_Y_1 * multiplier); } } if(mpPad->getRawBool(FWInput::Channel_Button_L2)) { // zoom in _CrtRender.ZoomIn(-0.005f); } else if(mpPad->getRawBool(FWInput::Channel_Button_L1)) { // zoom out _CrtRender.ZoomIn(0.005f); } if (togglewireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } if (togglelighting) { glEnable(GL_LIGHTING); } else { glDisable(GL_LIGHTING); } #if defined SPU_BULLET || !defined (SN_TARGET_PS3) if (mpPad->getRawBool(FWInput::Channel_Button_Triangle)) { float fl_x, fl_y, fl_z, fl_g; fl_x = mpPad->getRawFloat(FWInput::Channel_XAxis_2); fl_y = mpPad->getRawFloat(FWInput::Channel_YAxis_2); fl_z = mpPad->getRawFloat(FWInput::Channel_ZAxis_2); fl_g = mpPad->getRawFloat(FWInput::Channel_Gyro); SixAxis(fl_x, fl_y, fl_z, fl_g); } else { _CrtRender.SetGravity(CrtVec3f(0.0f, -10.0f, 0.0f)); } #endif static const int CONS_PUTS_INTERVAL = 50; if (frames % CONS_PUTS_INTERVAL == 0){ } char title[1024]; const char * selectedfile = Browser.GetThumbnail(Browser.GetSelection())->GetDocument(); sprintf(title, "%s %s", "COLLADA Viewer", mCurrentFile); cellDbgFontPuts(0.1f, 0.1f, 1.0f, 0xffffffff, title); cellDbgFontPuts(0.1f, 0.9f, 1.0f, 0xffffffff, selectedfile); Browser.onUpdate(); return result; }
bool COLLADA_Viewer::onInit(int argc, char **ppArgv) { FWGLApplication::onInit(argc, ppArgv); glClearColor(0.3f,0.3f,0.7f, 0.0f); glClearDepthf(1.0f); glEnable(GL_DEPTH_TEST); FWDebugFont::setColor(1.f, 1.f, 1.f, 1.f); InitFS(); Browser.Init(); psglLoadShaderLibrary("/app_home/shaders.bin"); // Initialize the renderer _CrtRender.Init(); _CrtRender.SetUsingVBOs(CrtTrue); _CrtRender.SetShowHiearchy(CrtTrue); glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 1.0f, 0.5f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable( GL_CULL_FACE ); glCullFace( GL_BACK ); cgRTCgcInit(); ParseDir("/app_home/"); // Load the target file Browser.onUpdate(); if (argc > 0) { char path_name[1024]; mCurrentFile = ppArgv[0]; sprintf(path_name, "%s%s", "/app_home/", ppArgv[0]); printf(path_name); load_ok = _CrtRender.Load(path_name, NULL); if ( !load_ok ) return false; } else if (Browser.GetSize() > 0) { mCurrentFile = Browser.GetThumbnail(0)->GetDocument(); load_ok = _CrtRender.Load(mCurrentFile, NULL); if ( !load_ok ) return false; } // Get the gamepad so we can read it later mpPad = FWInput::getDevice(FWInput::DeviceType_Pad,0); if(mpPad==NULL) { printf("Error, couldn't get a pad\n"); exit(0); } mpInputX0 = mpPad->bindFilter(); mpInputX0->setChannel(FWInput::Channel_XAxis_0); mpInputX0->setGain( 1.0f ); mpInputX0->setDeadzone( 0.3f ); mpInputY0 = mpPad->bindFilter(); mpInputY0->setChannel(FWInput::Channel_YAxis_0); mpInputY0->setGain( 1.0f ); mpInputY0->setDeadzone( 0.3f ); mpInputX1 = mpPad->bindFilter(); mpInputX1->setChannel(FWInput::Channel_XAxis_1); mpInputX1->setGain( 1.0f ); mpInputX1->setDeadzone( 0.3f ); mpInputY1 = mpPad->bindFilter(); mpInputY1->setChannel(FWInput::Channel_YAxis_1); mpInputY1->setGain( 1.0f ); mpInputY1->setDeadzone( 0.3f ); // initialize debug font library, then open console. int ret; CellDbgFontConfig cfg; memset(&cfg, 0, sizeof(CellDbgFontConfig)); cfg.bufSize = 512; cfg.screenWidth = mDispInfo.mWidth; cfg.screenHeight = mDispInfo.mHeight; ret = cellDbgFontInit(&cfg); if (ret != CELL_OK) { printf("cellDbgFontInit() failed %x\n", ret); return true; } CellDbgFontConsoleConfig ccfg; memset(&ccfg, 0, sizeof(CellDbgFontConsoleConfig)); ccfg.posLeft = 0.1f; ccfg.posTop = 0.6f; ccfg.cnsWidth = 16; ccfg.cnsHeight = 4; ccfg.scale = 1.5f; ccfg.color = 0xffffffff; mDbgFontID = cellDbgFontConsoleOpen(&ccfg); if (mDbgFontID < 0) { printf("cellDbgFontConsoleOpen() failed %x\n", mDbgFontID); return true; } return true; }
//---------------------------------------------------------------------------------------------------- // 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); }
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_ACTIVATE: { if (!HIWORD(wParam)) { active=TRUE; } else { active=FALSE; } return 0; } case WM_SYSCOMMAND: { switch (wParam) { case SC_SCREENSAVE: case SC_MONITORPOWER: return 0; } break; } case WM_CLOSE: { PostQuitMessage(0); return 0; } case WM_KEYDOWN: { // We only want to know which keys are down, so if this was an auto-repeat, ignore it if(!(HIWORD(lParam) & KF_REPEAT)) { // Remember which keys are being held down keys[wParam] = TRUE; } return 0; } case WM_KEYUP: { keys[wParam] = FALSE; return 0; } case WM_SIZE: { ResizeGLScreen(LOWORD(lParam),HIWORD(lParam)); return 0; } case WM_MOUSEWHEEL: { if (_CrtRender.ActiveInstanceCamera) { float gcWheelDelta = (short) HIWORD(wParam); _CrtRender.ZoomIn((CrtFloat) (-gcWheelDelta * MouseWheelSpeed)); return 0; } } case WM_MBUTTONDOWN: { // Change camera _CrtRender.SetNextCamera(); return 0; } case WM_MOUSEMOVE: { // UI code to move camera in response to mouse movement. static float lastx = 0, lasty = 0; static int lastLeft = 0, lastRight = 0, lastMiddle = 0; // Retrieve mouse screen position and button state float x=(float) (short)LOWORD(lParam); float y=(float) (short)HIWORD(lParam); // bool controlButtonDown=((wParam & MK_CONTROL) !=0); bool leftButtonDown=((wParam & MK_LBUTTON) !=0); bool middleButtonDown=((wParam & MK_MBUTTON) !=0); bool rightButtonDown=((wParam & MK_RBUTTON) !=0); // Handle rotations if left button was pressed if(leftButtonDown) { if(lastLeft && _CrtRender.ActiveInstanceCamera) { _CrtRender.ActiveInstanceCamera->SetPanAndTilt((lastx - x) * MouseRotateSpeed, (lasty - y) * MouseRotateSpeed); lastx = x; lasty = y; } else { // Remember where the mouse was when it first went down. lastLeft = true; lastx = x; lasty = y; return 0; } } else { lastLeft = false; } if (middleButtonDown) { if(lastMiddle && _CrtRender.ActiveInstanceCamera) { _CrtRender.ActiveInstanceCamera->MoveOrbit((lastx - x) * MouseTranslateSpeed, - (lasty - y) * MouseTranslateSpeed); lastx = x; lasty = y; } else { // Remember where the mouse was when it first went down. lastMiddle = true; lastx = x; lasty = y; return 0; } } if(rightButtonDown) { // Was the mouse previously down? if(lastRight && _CrtRender.ActiveInstanceCamera) { _CrtRender.ActiveInstanceCamera->MoveOrbit((lastx - x) * MouseTranslateSpeed, - (lasty - y) * MouseTranslateSpeed); lastx = x; lasty = y; } else { // Remember that the button was down, and where it went down lastRight = true; lastx = x; lasty = y; return 0; } } else { lastRight = false; } return 0; } } // Pass All Unhandled Messages To DefWindowProc return DefWindowProc(hWnd,uMsg,wParam,lParam); }
// Call ProcessInput once per frame to process input keys void ProcessInput( bool keys[] ) { // These keys we don't want to auto-repeat, so we clear them in "keys" after handling them once if (keys['E'] && amplitudeGlobalParameter) { float value; cgGetParameterValuefc(amplitudeGlobalParameter, 1, &value); value += 0.1f; cgSetParameter1f(amplitudeGlobalParameter, value); keys['E'] = false; } if (keys['R'] && amplitudeGlobalParameter) { float value; cgGetParameterValuefc(amplitudeGlobalParameter,1, &value); value -= 0.1f; cgSetParameter1f(amplitudeGlobalParameter, value); keys['R'] = false; } if (keys[VK_TAB] ) { // When 'C' is pressed, change cameras _CrtRender.SetNextCamera(); keys[VK_TAB] = false; } if ( keys['M'] ) { // Speed up UI by 25% AdjustUISpeed(1.25f); keys['M'] = false; } if ( keys['N'] ) { // Slow down UI by 25% AdjustUISpeed(0.75f); // Go 25% slower keys['N'] = false; } if (keys['Q']) { if (togglewireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); togglewireframe = FALSE; } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); togglewireframe = TRUE; } keys['Q'] = false; } if (keys['K']) { if (togglehiearchy) { _CrtRender.SetShowHiearchy(CrtTrue); togglehiearchy = FALSE; } else { _CrtRender.SetShowHiearchy(CrtFalse); togglehiearchy = TRUE; } keys['K'] = false; } if (keys['L']) { if (togglelighting) { glDisable(GL_LIGHTING); togglelighting = FALSE; } else { glEnable(GL_LIGHTING); togglelighting = TRUE; } keys['L'] = false; } if (keys['P'] ) { if (sAnimationEnable) { _CrtRender.SetAnimationPaused( CrtTrue ); sAnimationEnable = false; } else { _CrtRender.SetAnimationPaused( CrtFalse ); sAnimationEnable = true; } keys['P'] = false; } if (keys[VK_F1]) { keys[VK_F1]=FALSE; _CrtRender.Destroy(); DestroyGLWindow(); fullscreen=!fullscreen; // Recreate Our OpenGL Window if (!CreateGLWindow("Collada Viewer for PC", _CrtRender.GetScreenWidth(), _CrtRender.GetScreenHeight(),32,fullscreen)) { exit(1); } if ( !_CrtRender.Load( cleaned_file_name )) { exit(0); } keys[VK_F1] = false; } // These keys that do a function as long as they are held down, so we don't clear "keys". // Remember to scale these functions by time! if (keys['S']) { // UI code to move the camera closer _CrtRender.ActiveInstanceCamera->MoveTransform(_CrtRender.GetAnimDelta() * KeyboardTranslateSpeed *0.5f, 0.0f, 0.0f); } if (keys['W']) { // UI code to move the camera farther away _CrtRender.ActiveInstanceCamera->MoveTransform(- _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed * 0.5f, 0.0f, 0.0f); } if (keys[VK_SPACE]) { // UI code to move the camera farther up _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, 0.0f, _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed); } if (keys['X']) { // UI code to move the camera farther down _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, 0.0f, - _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed); } if (keys['D']) { // UI code to move the camera farther right _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, - _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed, 0.0f); } if (keys['A']) { // UI code to move the camera farther left _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed, 0.0f); } if (keys['F']) { if(togglecullingface == 0) { // turn it front glEnable( GL_CULL_FACE ); glCullFace(GL_FRONT); togglecullingface = 1; } else if(togglecullingface == 1) { // turn it both glDisable( GL_CULL_FACE ); togglecullingface = 2; } else { // turn it back glEnable( GL_CULL_FACE ); glCullFace(GL_BACK); togglecullingface = 0; } keys['F'] = false; } }
//---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- 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); }
static void KeyboardCallback(const unsigned char key, const int x, const int y) { (void)x; (void)y; switch (key) { case 9 : /* TAB key */ _CrtRender.SetNextCamera(); break; case 'k' : case 'K' : sHierarchy = !sHierarchy; if (!sHierarchy) { _CrtRender.SetShowHiearchy( CrtFalse ); } else { _CrtRender.SetShowHiearchy( CrtTrue ); } break; case 'l' : case 'L' : sGlLighting = !sGlLighting; if (sGlLighting) { glEnable(GL_LIGHTING); } else { glDisable(GL_LIGHTING); } break; case 'm' : case 'M' : AdjustUISpeed(1.25f); break; case 'n' : case 'N' : AdjustUISpeed(0.75f); break; case 'p' : case 'P' : sAnimation = !sAnimation; if (!sAnimation) { _CrtRender.SetAnimationPaused( CrtTrue ); } else { _CrtRender.SetAnimationPaused( CrtFalse ); } break; case 'q' : case 'Q' : sWireframe = !sWireframe; if (sWireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } break; case 's' : //zoom in case 'S' : _CrtRender.ActiveInstanceCamera->MoveTransform(_CrtRender.GetAnimDelta() * KeyboardTranslateSpeed *0.5f, 0.0f, 0.0f); break; case 'w' : // zoom out case 'W' : _CrtRender.ActiveInstanceCamera->MoveTransform(- _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed * 0.5f, 0.0f, 0.0f); break; case 32 : // space key, UP // UI code to move the camera farther up _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, 0.0f, _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed); break; case 'x' : // down case 'X' : _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, 0.0f, - _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed); break; case 'd' : // right case 'D' : _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, - _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed, 0.0f); break; case 'a' : // left case 'A' : _CrtRender.ActiveInstanceCamera->MoveTransform(0.0f, _CrtRender.GetAnimDelta() * KeyboardTranslateSpeed, 0.0f); break; case 'f' : case 'F' : if(sCulling == 0) { // turn it front glEnable( GL_CULL_FACE ); glCullFace(GL_FRONT); sCulling = 1; } else if(sCulling == 1) { // turn it both glDisable( GL_CULL_FACE ); sCulling = 2; } else { // turn it back glEnable( GL_CULL_FACE ); glCullFace(GL_BACK); sCulling = 0; } break; default: printf("unused key : %i\n", key ); break; } }