__fastcall TActiveFormX::TActiveFormX(TComponent* AOwner) : TActiveForm(AOwner) { // create a new world world = new cWorld(); // set background color world->setBackgroundColor(0.0f,0.0f,0.0f); // Create a camera camera = new cCamera(world); world->addChild(camera); // Create a light source and attach it to camera light = new cLight(world); light->setEnabled(true); light->setPos(cVector3d(2,1,1)); // define camera position cameraAngleH = 10; cameraAngleV = 20; cameraDistance = 2.0; flagCameraInMotion = false; updateCameraPosition(); camera->setClippingPlanes(0.01, 10.0); // create a display for graphic rendering viewport = new cViewport(Panel1->Handle, camera, true); viewport->setStereoOn(false); // create a mesh - we will build a simple cube, and later let the // user load 3d models object = new cMesh(world); world->addChild(object); // create a nice little cube createCube(object, 0.2); // define a material property for this object cMaterial material; material.m_ambient.set( 0.4, 0.2, 0.2, 1.0 ); material.m_diffuse.set( 0.8, 0.6, 0.6, 1.0 ); material.m_specular.set( 0.9, 0.9, 0.9, 1.0 ); material.setShininess(100); material.setStiffness(20 ); object->m_material = material; // update camera position updateCameraPosition(); // don't start the haptics loop yet flagSimulationOn = false; flagHasExitedSimulation = true; }
void ofxSplineEditor::update(){ updateSpline(); updateSplineFileSystem(); updateSplinePoint(); updateCameraPosition(); editPointIndex.setMax(spline.GetPointNum()); }
void ofxFPSCamera::update(ofEventArgs&) { if (controlsEnabled) { if(b_back||b_fwd||b_strafe_left||b_strafe_right||b_strafe_up||b_strafe_down) { updateCameraPosition(); } if(b_roll_ccw||b_roll_cw||b_roll_reset||b_yaw_left||b_yaw_right||b_pitch_up||b_pitch_down) { updateCameraRoll(); } } }
void __fastcall TActiveFormX::Timer1Timer(TObject *Sender) { // update camera position updateCameraPosition(); // render world in display if (viewport != NULL) { viewport->render(); } }
void updatePlayState(PlayState *playState, GameContext *gameContext, UserInput *userInput, GameMemory *gameMemory) { updateScrollingBackground(playState->scrollingBackground, gameContext); updateCameraPosition(playState, gameContext); updateEntities(playState, &playState->entityList, gameContext, userInput, gameMemory); }
void frameRender() { // Déplacement de la caméra updateCameraPosition(); // Dessin g_pTechnique->GetPassByIndex(0)->Apply(0); g_pD3DDevice->Draw(4, 0); // Swapbuffer g_pSwapChain->Present(0, 0); }
void mouseMove(int x, int y) { if (flagCameraInMotion) { if (mouseButton == GLUT_RIGHT_BUTTON) { cameraDistance = cameraDistance - 0.01 * (y - mouseY); } else if (mouseButton == GLUT_LEFT_BUTTON) { cameraAngleH = cameraAngleH - (x - mouseX); cameraAngleV = cameraAngleV + (y - mouseY); } } updateCameraPosition(); mouseX = x; mouseY = y; }
// Updates the tileMap with the information in the baseGrid and the gameObjectGrid void GameMap::step() { // Calculate the first visible tile from the map cocos2d::Vec2 origin = cocos2d::Director::getInstance()->getVisibleOrigin(); // Update camera position updateCameraPosition(); int offset_x = firstVisibleTile_x * tileWidth; int offset_y = firstVisibleTile_y * tileHeight; // Run through the tileMap and color the sprites according to the baseGrid and gameObjectGrid data // Initialize x index of current tile int currentTile_x = firstVisibleTile_x; for (int x = 0; x < tileMap.size(); ++x) { // Initialize y index of current tile int currentTile_y = firstVisibleTile_y; for (int y = 0; y < tileMap[x].size(); ++y) { if (currentTile_x >= baseGrid.size() || currentTile_y >= baseGrid[currentTile_x].size()) { tileMap[x][y]->setVisible(false); } else if (baseGrid[currentTile_x][currentTile_y] == TileType::stone) { tileMap[x][y]->setVisible(true); tileMap[x][y]->setColor(stoneColour); } else if (baseGrid[currentTile_x][currentTile_y] == TileType::dirt) { tileMap[x][y]->setVisible(true); tileMap[x][y]->setColor(dirtColour); } else if (gameObjectGrid[currentTile_x][currentTile_y] == nullptr) { // empty tileMap[x][y]->setVisible(true); tileMap[x][y]->setColor(emptyColour); } else { // Game Object present tileMap[x][y]->setVisible(true); tileMap[x][y]->setColor(gameObjectGrid[currentTile_x][currentTile_y]->getColour()); } ++currentTile_y; } ++currentTile_x; } }
void __fastcall TActiveFormX::Panel1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if (flagCameraInMotion) { if (Shift.Contains(ssLeft)) { cameraAngleH = cameraAngleH - (X - mouseX); cameraAngleV = cameraAngleV + (Y - mouseY); } else if (Shift.Contains(ssRight)) { cameraDistance = cameraDistance - 0.01 * (Y - mouseY); } updateCameraPosition(); } mouseX = X; mouseY = Y; }
void initShader() { // Récupération des variables du shader g_pMaterialAmbientColorVariable = g_pEffect->GetVariableByName("g_MaterialAmbientColor")->AsVector(); g_pMaterialDiffuseColorVariable = g_pEffect->GetVariableByName("g_MaterialDiffuseColor")->AsVector(); g_pMaterialSpecularColorVariable = g_pEffect->GetVariableByName("g_MaterialSpecularColor")->AsVector(); g_pMaterialShininessVariable = g_pEffect->GetVariableByName("g_MaterialShininess")->AsScalar(); g_pMaterialReflectivityVariable = g_pEffect->GetVariableByName("g_MaterialReflectivity")->AsScalar(); g_pMaterialTransmittivityVariable = g_pEffect->GetVariableByName("g_MaterialTransmittivity")->AsScalar(); g_pMaterialRefractionIndiceVariable = g_pEffect->GetVariableByName("g_MaterialRefractionIndice")->AsScalar(); g_pSpherePositionVariable = g_pEffect->GetVariableByName("g_SpherePosition")->AsVector(); g_pSphereRadiusVariable = g_pEffect->GetVariableByName("g_SphereRadius")->AsScalar(); g_pPlaneNormalVariable = g_pEffect->GetVariableByName("g_PlaneNormal")->AsVector(); g_pPlaneHeightVariable = g_pEffect->GetVariableByName("g_PlaneHeight")->AsScalar(); g_pLightPositionVariable = g_pEffect->GetVariableByName("g_LightPosition")->AsVector(); g_pLightDirectionVariable = g_pEffect->GetVariableByName("g_LightDirection")->AsVector(); g_pLightColorVariable = g_pEffect->GetVariableByName("g_LightColor")->AsVector(); g_pLightCosInnerConeVariable = g_pEffect->GetVariableByName("g_LightCosInnerCone")->AsScalar(); g_pLightCosOuterConeVariable = g_pEffect->GetVariableByName("g_LightCosOuterCone")->AsScalar(); g_pEyePositionVariable = g_pEffect->GetVariableByName("g_EyePosition")->AsVector(); g_pLookAtVariable = g_pEffect->GetVariableByName("g_LookAt")->AsVector(); g_pUpVariable = g_pEffect->GetVariableByName("g_Up")->AsVector(); g_pRatioVariable = g_pEffect->GetVariableByName("g_Ratio")->AsScalar(); g_pFovVariable = g_pEffect->GetVariableByName("g_Fov")->AsScalar(); // Initialisation des variables du shader D3DXVECTOR3 materialAmbientColorArray[OBJECT_NUM]; D3DXVECTOR3 materialDiffuseColorArray[OBJECT_NUM]; D3DXVECTOR3 materialSpecularColorArray[OBJECT_NUM]; float materialShininessArray[OBJECT_NUM]; float materialReflectivityArray[OBJECT_NUM]; float materialTransmittivityArray[OBJECT_NUM]; float materialRefractionIndiceArray[OBJECT_NUM]; D3DXVECTOR3 spherePositionArray[SPHERE_NUM]; float sphereRadiusArray[SPHERE_NUM]; D3DXVECTOR3 planeNormalArray[PLANE_NUM]; float planeHeightArray[PLANE_NUM]; D3DXVECTOR3 lightPositionArray[LIGHT_NUM]; D3DXVECTOR3 lightDirectionArray[LIGHT_NUM]; D3DXVECTOR3 lightColorArray[LIGHT_NUM]; float lightCosInnerConeArray[LIGHT_NUM]; float lightCosOuterConeArray[LIGHT_NUM]; for(int i = 0; i < OBJECT_NUM; i++) { materialAmbientColorArray[i] = D3DXVECTOR3(0.0f, 0.01f, 0.02f); materialDiffuseColorArray[i] = D3DXVECTOR3(0.0f, 0.4f, 0.8f); materialSpecularColorArray[i] = D3DXVECTOR3(1.0f, 1.0f, 1.0f); materialShininessArray[i] = 25.0f; materialReflectivityArray[i] = 0.3f; materialTransmittivityArray[i] = 0.2f; materialRefractionIndiceArray[i] = 1.1f; } for(int i = 0; i < SPHERE_NUM; i++) { spherePositionArray[i] = D3DXVECTOR3(3.0f*cos(i*2.0f*PI/SPHERE_NUM), 1.0f, 3.0f*sin(i*2.0f*PI/SPHERE_NUM)); sphereRadiusArray[i] = 1.0f; } for(int i = 0; i < PLANE_NUM; i++) { planeNormalArray[i] = D3DXVECTOR3(0.0f, 1.0f, 0.0f); planeHeightArray[i] = 0.0f; } for(int i = 0; i < LIGHT_NUM; i++) { lightPositionArray[i] = D3DXVECTOR3(-15.0f, 30.0f, 0.0f); lightDirectionArray[i] = D3DXVECTOR3(0.4f, -0.6f, 0.0f); lightColorArray[i] = D3DXVECTOR3(1.0f, 1.0f, 1.0f); lightCosInnerConeArray[i] = 0.7f; lightCosOuterConeArray[i] = 0.6f; } g_pMaterialAmbientColorVariable->SetFloatVectorArray((float *) materialAmbientColorArray, 0, OBJECT_NUM); g_pMaterialDiffuseColorVariable->SetFloatVectorArray((float *) materialDiffuseColorArray, 0, OBJECT_NUM); g_pMaterialSpecularColorVariable->SetFloatVectorArray((float *) materialSpecularColorArray, 0, OBJECT_NUM); g_pMaterialShininessVariable->SetFloatArray(materialShininessArray, 0, OBJECT_NUM); g_pMaterialReflectivityVariable->SetFloatArray(materialReflectivityArray, 0, OBJECT_NUM); g_pMaterialTransmittivityVariable->SetFloatArray(materialTransmittivityArray, 0, OBJECT_NUM); g_pMaterialRefractionIndiceVariable->SetFloatArray(materialRefractionIndiceArray, 0, OBJECT_NUM); g_pSpherePositionVariable->SetFloatVectorArray((float *) spherePositionArray, 0, SPHERE_NUM); g_pSphereRadiusVariable->SetFloatArray(sphereRadiusArray, 0, SPHERE_NUM); g_pPlaneNormalVariable->SetFloatVectorArray((float *) planeNormalArray, 0, PLANE_NUM); g_pPlaneHeightVariable->SetFloatArray(planeHeightArray, 0, PLANE_NUM); g_pLightPositionVariable->SetFloatVectorArray((float *) lightPositionArray, 0, LIGHT_NUM); g_pLightDirectionVariable->SetFloatVectorArray((float *) lightDirectionArray, 0, LIGHT_NUM); g_pLightColorVariable->SetFloatVectorArray((float *) lightColorArray, 0, LIGHT_NUM); g_pLightCosInnerConeVariable->SetFloatArray(lightCosInnerConeArray, 0, LIGHT_NUM); g_pLightCosOuterConeVariable->SetFloatArray(lightCosOuterConeArray, 0, LIGHT_NUM); updateCameraPosition(); g_pRatioVariable->SetFloat((float)SCREEN_WIDTH/(float)SCREEN_HEIGHT); g_pFovVariable->SetFloat(FOV); }
/* Updates the viewpoint according to the object being tracked */ static bool camTrackCamera() { PROPULSION_STATS *psPropStats; DROID *psDroid; bool bFlying = false; /* Most importantly - see if the target we're tracking is dead! */ if(trackingCamera.target->died) { return(false); } /* Update the acceleration,velocity and position of the camera for movement */ updateCameraAcceleration(CAM_ALL); updateCameraVelocity(CAM_ALL); updateCameraPosition(CAM_ALL); /* Update the acceleration,velocity and rotation of the camera for rotation */ /* You can track roll as well (z axis) but it makes you ill and looks like a flight sim, so for now just pitch and orientation */ if(trackingCamera.target->type == OBJ_DROID) { psDroid = (DROID*)trackingCamera.target; psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat; if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT) { bFlying = true; } } if(bRadarAllign || trackingCamera.target->type == OBJ_DROID) { if(bFlying) { updateCameraRotationAcceleration(CAM_ALL); } else { updateCameraRotationAcceleration(CAM_X_AND_Y); } } if(bFlying) { updateCameraRotationVelocity(CAM_ALL); updateCameraRotationPosition(CAM_ALL); } else { updateCameraRotationVelocity(CAM_X_AND_Y); updateCameraRotationPosition(CAM_X_AND_Y); } /* Update the position that's now stored in trackingCamera.position */ player.p.x = trackingCamera.position.x; player.p.y = trackingCamera.position.y; player.p.z = trackingCamera.position.z; /* Update the rotations that're now stored in trackingCamera.rotation */ player.r.x = trackingCamera.rotation.x; player.r.y = trackingCamera.rotation.y; player.r.z = trackingCamera.rotation.z; /* There's a minimum for this - especially when John's VTOL code lets them land vertically on cliffs */ if(player.r.x>DEG(360+MAX_PLAYER_X_ANGLE)) { player.r.x = DEG(360+MAX_PLAYER_X_ANGLE); } /* Clip the position to the edge of the map */ CheckScrollLimits(); /* Store away our last update as acceleration and velocity are all fn()/dt */ trackingCamera.lastUpdate = realTime; if(bFullInfo) { flushConsoleMessages(); if(trackingCamera.target->type == OBJ_DROID) { printDroidInfo((DROID*)trackingCamera.target); } } /* Switch off if we're jumping to a new location and we've got there */ if(getRadarTrackingStatus()) { /* This will ensure we come to a rest and terminate the tracking routine once we're close enough */ if (trackingCamera.velocity*trackingCamera.velocity + trackingCamera.acceleration*trackingCamera.acceleration < 1.f && trackingCamera.rotVel*trackingCamera.rotVel + trackingCamera.rotAccel*trackingCamera.rotAccel < 1.f) { setWarCamActive(false); } } return(true); }
int main(int argc, char* argv[]) { //----------------------------------------------------------------------- // INITIALIZATION //----------------------------------------------------------------------- printf ("\n"); printf ("-----------------------------------\n"); printf ("CHAI 3D\n"); printf ("Demo: 52-GEL-duck\n"); printf ("Copyright 2003-2010\n"); printf ("-----------------------------------\n"); printf ("\n\n"); printf ("Keyboard Options:\n\n"); printf ("[1] - Show GEL Skeleton\n"); printf ("[2] - Hide GEL Skeleton\n"); printf ("[x] - Exit application\n"); printf ("\n\n"); // parse first arg to try and locate resources resourceRoot = string(argv[0]).substr(0,string(argv[0]).find_last_of("/\\")+1); //----------------------------------------------------------------------- // 3D - SCENEGRAPH //----------------------------------------------------------------------- // create a new world. world = new cWorld(); // set the background color of the environment // the color is defined by its (R,G,B) components. world->setBackgroundColor(0.0, 0.0, 0.0); world->setBackgroundColor(1.0, 1.0, 1.0); // create a camera and insert it into the virtual world camera = new cCamera(world); world->addChild(camera); // position and oriente the camera // define a default position of the camera (described in spherical coordinates) cameraAngleH = 0; cameraAngleV = 45; cameraDistance = 2.5; updateCameraPosition(); // set the near and far clipping planes of the camera // anything in front/behind these clipping planes will not be rendered camera->setClippingPlanes(0.01, 10.0); // enable higher rendering quality because we are displaying transparent objects camera->enableMultipassTransparency(true); // create a light source and attach it to the camera light = new cLight(world); camera->addChild(light); // attach light to camera light->setEnabled(true); // enable light source light->setPos(cVector3d( 2.0, 0.5, 1.0)); // position the light source light->setDir(cVector3d(-2.0, 0.5, 1.0)); // define the direction of the light beam light->setDirectionalLight(false); light->m_ambient.set(0.5, 0.5, 0.5); light->m_diffuse.set(0.7, 0.7, 0.7); light->m_specular.set(0.9, 0.9, 0.9); //----------------------------------------------------------------------- // 2D - WIDGETS //----------------------------------------------------------------------- // create a 2D bitmap logo logo = new cBitmap(); // add logo to the front plane camera->m_front_2Dscene.addChild(logo); // load a "chai3d" bitmap image file bool fileload; fileload = logo->m_image.loadFromFile(RESOURCE_PATH("resources/images/chai3d.bmp")); if (!fileload) { #if defined(_MSVC) fileload = logo->m_image.loadFromFile("../../../bin/resources/images/chai3d.bmp"); #endif } // position the logo at the bottom left of the screen (pixel coordinates) logo->setPos(10, 10, 0); // scale the logo along its horizontal and vertical axis logo->setZoomHV(0.4, 0.4); // here we replace all black pixels (0,0,0) of the logo bitmap // with transparent black pixels (0, 0, 0, 0). This allows us to make // the background of the logo look transparent. logo->m_image.replace( cColorb(0, 0, 0), // original RGB color cColorb(0, 0, 0, 0) // new RGBA color ); // enable transparency logo->enableTransparency(true); //----------------------------------------------------------------------- // HAPTIC DEVICES / TOOLS //----------------------------------------------------------------------- // create a haptic device handler handler = new cHapticDeviceHandler(); // get access to the first available haptic device handler->getDevice(hapticDevice, 0); // retrieve information about the current haptic device cHapticDeviceInfo info; if (hapticDevice) { hapticDevice->open(); info = hapticDevice->getSpecifications(); } // desired workspace radius of the cursor cursorWorkspaceRadius = 0.8; // read the scale factor between the physical workspace of the haptic // device and the virtual workspace defined for the tool workspaceScaleFactor = cursorWorkspaceRadius / info.m_workspaceRadius; // define a scale factor between the force perceived at the cursor and the // forces actually sent to the haptic device deviceForceScale = 0.005 * (info.m_maxForceStiffness / workspaceScaleFactor); // define a force scale factor for the current haptic device. const double FORCE_REFERENCE = 10.0; deviceForceScale = info.m_maxForce / FORCE_REFERENCE; // create a large sphere that represents the haptic device deviceRadius = 0.12; device = new cShapeSphere(deviceRadius); world->addChild(device); device->m_material.m_ambient.set(0.4, 0.4, 0.4, 0.7); device->m_material.m_diffuse.set(0.7, 0.7, 0.7, 0.7); device->m_material.m_specular.set(1.0, 1.0, 1.0, 0.7); device->m_material.setShininess(100); stiffness = 40; //----------------------------------------------------------------------- // COMPOSE THE VIRTUAL SCENE //----------------------------------------------------------------------- // create a world which supports deformable object defWorld = new cGELWorld(); world->addChild(defWorld); world->setPos(-1.5, 0.0, -0.1); world->rotate(cVector3d(0,1,0), cDegToRad(30)); //----------------------------------------------------------------------- // COMPOSE THE WATER //----------------------------------------------------------------------- ground = new cGELMesh(world); ground->m_useMassParticleModel = true; defWorld->m_gelMeshes.push_back(ground); cGELMassParticle::default_mass = 0.010; cGELMassParticle::default_kDampingPos = 0.4; cGELMassParticle::default_gravity.set(0,0,0); int u,v; int RESOLUTION = 15; double SIZE = 3.5; for (v=0; v<RESOLUTION; v++) { for (u=0; u<RESOLUTION; u++) { double px, py, tu, tv; // compute the position of the vertex px = SIZE / (double)RESOLUTION * (double)u - (SIZE/2.0); py = SIZE / (double)RESOLUTION * (double)v - (SIZE/2.0); // create new vertex unsigned int index = ground->newVertex(px, py, level); cVertex* vertex = ground->getVertex(index); // compute texture coordinate tu = (double)u / (double)RESOLUTION; tv = (double)v / (double)RESOLUTION; vertex->setTexCoord(tu, tv); vertex->setColor(cColorf(1.0, 0.0, 0.1)); } } ground->buildVertices(); for (v=0; v<RESOLUTION; v++) { for (u=0; u<RESOLUTION; u++) { if ((u == 0) || (v == 0) || (u == (RESOLUTION-1)) || (v == (RESOLUTION-1))) { // create new vertex unsigned int index = ((v + 0) * RESOLUTION) + (u + 0); ground->m_gelVertices[index].m_massParticle->m_fixed = true; } } } cGELLinearSpring::default_kSpringElongation = 10.0; // [N/m] // Create a triangle based map using the above pixels for (v=0; v<(RESOLUTION-1); v++) { for (u=0; u<(RESOLUTION-1); u++) { // get the indexing numbers of the next four vertices unsigned int index00 = ((v + 0) * RESOLUTION) + (u + 0); unsigned int index01 = ((v + 0) * RESOLUTION) + (u + 1); unsigned int index10 = ((v + 1) * RESOLUTION) + (u + 0); unsigned int index11 = ((v + 1) * RESOLUTION) + (u + 1); // create two new triangles ground->newTriangle(index00, index01, index10); ground->newTriangle(index10, index01, index11); cGELMassParticle* m0 = ground->m_gelVertices[index00].m_massParticle; cGELMassParticle* m1 = ground->m_gelVertices[index01].m_massParticle; cGELMassParticle* m2 = ground->m_gelVertices[index10].m_massParticle; cGELLinearSpring* spring0 = new cGELLinearSpring(m0, m1); cGELLinearSpring* spring1 = new cGELLinearSpring(m0, m2); ground->m_linearSprings.push_back(spring0); ground->m_linearSprings.push_back(spring1); } } double transparencyLevel = 0.7; ground->setUseMaterial(true); ground->m_material.m_ambient.set(0.6, 0.6, 0.6, transparencyLevel); ground->m_material.m_diffuse.set(0.8, 0.8, 0.8, transparencyLevel); ground->m_material.m_specular.set(0.9, 0.9, 0.9, transparencyLevel); ground->setTransparencyLevel(transparencyLevel); ground->setUseTransparency(true); cTexture2D* textureGround = new cTexture2D(); ground->setTexture(textureGround); ground->setUseTexture(true, true); fileload = textureGround->loadFromFile(RESOURCE_PATH("resources/images/aqua.bmp")); if (!fileload) { #if defined(_MSVC) fileload = textureGround->loadFromFile("../../../bin/resources/images/aqua.bmp" ); #endif if (!fileload) { printf("Error - 3D Texture failed to load correctly.\n"); close(); return (-1); } } //----------------------------------------------------------------------- // COMPOSE SOME REFLEXION //----------------------------------------------------------------------- cGenericObject* reflexion = new cGenericObject(); world->addChild(reflexion); cMatrix3d rot; rot.set(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0); reflexion->setRot(rot); reflexion->addChild(defWorld); reflexion->setPos(0.0, 0.0, 2.0 * level); cGenericObject* reflexionTool = new cGenericObject(); reflexion->addChild(reflexionTool); reflexionTool->addChild(device); reflexionTool->setPos(0.0, 0.0, -0.5 * level); // Play with thse numbers carefully! defWorld->m_integrationTime = 0.001; // create a deformable mesh defObject = new cGELMesh(world); defWorld->m_gelMeshes.push_front(defObject); //----------------------------------------------------------------------- // BUILD THE DUCK! //----------------------------------------------------------------------- if (USE_SKELETON_MODEL) { fileload = createSkeletonMesh(defObject, RESOURCE_PATH("resources/models/ducky/duck-200.off"), RESOURCE_PATH("resources/models/ducky/duck-full.obj")); if (!fileload) { #if defined(_MSVC) fileload = createSkeletonMesh(defObject, "../../../bin/resources/models/ducky/duck-200.off", "../../../bin/resources/models/ducky/duck-full.obj"); #endif if (!fileload) { printf("Error - 3D Model failed to load correctly.\n"); close(); return (-1); } } } else { fileload = createTetGenMesh(defObject, RESOURCE_PATH("resources/models/ducky/duck-1200.off"), RESOURCE_PATH("resources/models/ducky/duck-green.obj")); if (!fileload) { #if defined(_MSVC) fileload = createTetGenMesh(defObject, "../../../bin/resources/models/ducky/duck-1200.off", "../../../bin/resources/models/ducky/duck-green.obj"); #endif if (!fileload) { printf("Error - 3D Model failed to load correctly.\n"); close(); return (-1); } } } //----------------------------------------------------------------------- // OPEN GL - WINDOW DISPLAY //----------------------------------------------------------------------- // initialize GLUT glutInit(&argc, argv); // retrieve the resolution of the computer display and estimate the position // of the GLUT window so that it is located at the center of the screen int screenW = glutGet(GLUT_SCREEN_WIDTH); int screenH = glutGet(GLUT_SCREEN_HEIGHT); int windowPosX = (screenW - WINDOW_SIZE_W) / 2; int windowPosY = (screenH - WINDOW_SIZE_H) / 2; // initialize the OpenGL GLUT window glutInitWindowPosition(windowPosX, windowPosY); glutInitWindowSize(WINDOW_SIZE_W, WINDOW_SIZE_H); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutCreateWindow(argv[0]); glutMouseFunc(mouseClick); glutMotionFunc(mouseMove); glutDisplayFunc(updateGraphics); glutKeyboardFunc(keySelect); glutReshapeFunc(resizeWindow); glutSetWindowTitle("CS 268 - Sonny Chan & Francois Conti - March 2009"); // create a mouse menu (right button) glutCreateMenu(menuSelect); glutAddMenuEntry("full screen", OPTION_FULLSCREEN); glutAddMenuEntry("window display", OPTION_WINDOWDISPLAY); glutAddMenuEntry("show skeleton", OPTION_SHOWSKELETON); glutAddMenuEntry("hide skeleton", OPTION_HIDESKELETON); glutAttachMenu(GLUT_RIGHT_BUTTON); //----------------------------------------------------------------------- // START SIMULATION //----------------------------------------------------------------------- // simulation in now running simulationRunning = true; // create a thread which starts the main haptics rendering loop cThread* hapticsThread = new cThread(); hapticsThread->set(updateHaptics, CHAI_THREAD_PRIORITY_HAPTICS); // start the main graphics rendering loop glutMainLoop(); // close everything close(); // exit return (0); }
void updateHaptics(void) { // state machine const int STATE_IDLE = 1; const int STATE_MODIFY_MAP = 2; const int STATE_MOVE_CAMERA = 3; int state = STATE_IDLE; // current tool position cVector3d toolGlobalPos; // global world coordinates cVector3d toolLocalPos; // local coordinates // previous tool position cVector3d prevToolGlobalPos; // global world coordinates cVector3d prevToolLocalPos; // local coordinates // main haptic simulation loop while(simulationRunning) { // compute global reference frames for each object world->computeGlobalPositions(true); // update position and orientation of tool tool->updatePose(); // compute interaction forces tool->computeInteractionForces(); // read user switch bool userSwitch = tool->getUserSwitch(0); // update tool position toolGlobalPos = tool->getDeviceGlobalPos(); toolLocalPos = tool->getDeviceLocalPos(); if ((state == STATE_MOVE_CAMERA) && (!userSwitch)) { state = STATE_IDLE; // enable haptic interaction with map object->setHapticEnabled(true, true); } else if (((state == STATE_MODIFY_MAP) && (!userSwitch)) || ((state == STATE_MODIFY_MAP) && (!tool->isInContact(magneticLine)))) { state = STATE_IDLE; // disable magnetic line magneticLine->setHapticEnabled(false); magneticLine->setShowEnabled(false); // disable spheres sphereA->setShowEnabled(false); sphereB->setShowEnabled(false); // enable haptic interaction with map object->setHapticEnabled(true, true); // disable forces tool->setForcesOFF(); // update bounding box (can take a little time) object->createAABBCollisionDetector(1.01 * proxyRadius, true, false); // enable forces again tool->setForcesON(); } // user clicks with the mouse else if ((state == STATE_IDLE) && (userSwitch)) { // start deforming object if (tool->isInContact(object)) { state = STATE_MODIFY_MAP; // update position of line cVector3d posA = toolGlobalPos; posA.z =-0.7; cVector3d posB = toolGlobalPos; posB.z = 0.7; magneticLine->m_pointA = posA; magneticLine->m_pointB = posB; // update position of spheres sphereA->setPos(posA); sphereB->setPos(posB); // enable spheres sphereA->setShowEnabled(true); sphereB->setShowEnabled(true); // enable magnetic line magneticLine->setHapticEnabled(true); magneticLine->setShowEnabled(true); // disable haptic interaction with map object->setHapticEnabled(false, true); } // start moving camera else { state = STATE_MOVE_CAMERA; // disable haptic interaction with map object->setHapticEnabled(false, true); } } // modify map else if (state == STATE_MODIFY_MAP) { // compute tool offset cVector3d offset = toolGlobalPos - prevToolGlobalPos; // map offset on z axis double offsetHeight = offset.z; // apply offset to all vertices through a weighted function int numVertices = object->getNumVertices(true); for (int i=0; i<numVertices; i++) { // get next vertex cVertex* vertex = object->getVertex(i, true); // compute distance between vertex and tool cVector3d posTool = tool->getProxyGlobalPos(); cVector3d posVertex = vertex->getPos(); double distance = cDistance(posTool, posVertex); // compute factor double RADIUS = 0.4; double relativeDistance = distance / RADIUS; double clampedRelativeDistance = cClamp01(relativeDistance); double w = 0.5 + 0.5 * cos(clampedRelativeDistance * CHAI_PI); // apply offset double offsetVertexHeight = w * offsetHeight; posVertex.z = posVertex.z + offsetVertexHeight; vertex->setPos(posVertex); } } // move camera else if (state == STATE_MOVE_CAMERA) { // compute tool offset cVector3d offset = toolLocalPos - prevToolLocalPos; // apply camera motion cameraDistance = cameraDistance - 2 * offset.x; cameraAngleH = cameraAngleH - 40 * offset.y; cameraAngleV = cameraAngleV - 40 * offset.z; updateCameraPosition(); } // store tool position prevToolLocalPos = toolLocalPos; prevToolGlobalPos = toolGlobalPos; // send forces to device tool->applyForces(); } // exit haptics thread simulationFinished = true; }
int main(int argc, char* argv[]) { //----------------------------------------------------------------------- // INITIALIZATION //----------------------------------------------------------------------- printf ("\n"); printf ("-----------------------------------\n"); printf ("CHAI 3D\n"); printf ("Demo: 20-map\n"); printf ("Copyright 2003-2010\n"); printf ("-----------------------------------\n"); printf ("\n\n"); printf ("Instructions:\n\n"); printf ("- Use left mouse button to rotate camera view. \n"); printf ("- Use right mouse button to control camera zoom. \n"); printf ("- Use haptic device and user switch to rotate \n"); printf (" camera or deform terrain. \n"); printf ("\n\n"); printf ("Keyboard Options:\n\n"); printf ("[1] - Texture (ON/OFF)\n"); printf ("[2] - Wireframe (ON/OFF)\n"); printf ("[x] - Exit application\n"); printf ("\n\n"); // parse first arg to try and locate resources resourceRoot = string(argv[0]).substr(0,string(argv[0]).find_last_of("/\\")+1); //----------------------------------------------------------------------- // 3D - SCENEGRAPH //----------------------------------------------------------------------- // create a new world. world = new cWorld(); // set the background color of the environment // the color is defined by its (R,G,B) components. world->setBackgroundColor(0.1, 0.1, 0.1); // create a camera and insert it into the virtual world camera = new cCamera(world); world->addChild(camera); // define a default position of the camera (described in spherical coordinates) cameraAngleH = 0; cameraAngleV = 45; cameraDistance = 1.8 * MESH_SCALE_SIZE; updateCameraPosition(); // set the near and far clipping planes of the camera // anything in front/behind these clipping planes will not be rendered camera->setClippingPlanes(0.01, 10.0); // create a light source and attach it to the camera light = new cLight(world); camera->addChild(light); // attach light to camera light->setEnabled(true); // enable light source light->setPos(cVector3d( 0.0, 0.3, 0.3)); // position the light source light->setDir(cVector3d(-1.0,-0.1, -0.1)); // define the direction of the light beam light->m_ambient.set(0.5, 0.5, 0.5); light->m_diffuse.set(0.8, 0.8, 0.8); light->m_specular.set(1.0, 1.0, 1.0); //----------------------------------------------------------------------- // 2D - WIDGETS //----------------------------------------------------------------------- // create a 2D bitmap logo logo = new cBitmap(); // add logo to the front plane camera->m_front_2Dscene.addChild(logo); // load a "chai3d" bitmap image file bool fileload; fileload = logo->m_image.loadFromFile(RESOURCE_PATH("resources/images/chai3d.bmp")); if (!fileload) { #if defined(_MSVC) fileload = logo->m_image.loadFromFile("../../../bin/resources/images/chai3d.bmp"); #endif } // position the logo at the bottom left of the screen (pixel coordinates) logo->setPos(10, 10, 0); // scale the logo along its horizontal and vertical axis logo->setZoomHV(0.4, 0.4); // here we replace all black pixels (0,0,0) of the logo bitmap // with transparent black pixels (0, 0, 0, 0). This allows us to make // the background of the logo look transparent. logo->m_image.replace( cColorb(0, 0, 0), // original RGB color cColorb(0, 0, 0, 0) // new RGBA color ); // enable transparency logo->enableTransparency(true); //----------------------------------------------------------------------- // HAPTIC DEVICES / TOOLS //----------------------------------------------------------------------- // create a haptic device handler handler = new cHapticDeviceHandler(); // get access to the first available haptic device cGenericHapticDevice* hapticDevice; handler->getDevice(hapticDevice, 0); // retrieve information about the current haptic device cHapticDeviceInfo info; if (hapticDevice) { info = hapticDevice->getSpecifications(); } // create a 3D tool and add it to the world tool = new cGeneric3dofPointer(world); // attach tool to camera camera->addChild(tool); // position tool workspace in front of camera (x-axis of camera reference pointing towards the viewer) tool->setPos(-cameraDistance, 0.0, 0.0); // connect the haptic device to the tool tool->setHapticDevice(hapticDevice); // initialize tool by connecting to haptic device tool->start(); // map the physical workspace of the haptic device to a larger virtual workspace. tool->setWorkspaceRadius(1.0); // define a radius for the tool (graphical display) tool->setRadius(0.03); // hide the device sphere. only show proxy. tool->m_deviceSphere->setShowEnabled(false); // set the physical readius of the proxy. proxyRadius = 0.0; tool->m_proxyPointForceModel->setProxyRadius(proxyRadius); tool->m_proxyPointForceModel->m_collisionSettings.m_checkBothSidesOfTriangles = false; //----------------------------------------------------------------------- // COMPOSE THE VIRTUAL SCENE //----------------------------------------------------------------------- // create a new mesh to display a height map object = new cMesh(world); world->addChild(object); // load default map loadHeightMap(); // read the scale factor between the physical workspace of the haptic // device and the virtual workspace defined for the tool double workspaceScaleFactor = tool->getWorkspaceScaleFactor(); // define a maximum stiffness that can be handled by the current // haptic device. The value is scaled to take into account the // workspace scale factor double stiffnessMax = info.m_maxForceStiffness / workspaceScaleFactor; object->setStiffness(0.5 * stiffnessMax, true); // create a small vertical white magnetic line that will be activated when the // user deforms the mesh. magneticLine = new cShapeLine(cVector3d(0,0,0), cVector3d(0,0,0)); world->addChild(magneticLine); magneticLine->m_ColorPointA.set(0.6, 0.6, 0.6); magneticLine->m_ColorPointB.set(0.6, 0.6, 0.6); magneticLine->setShowEnabled(false); // set haptic properties magneticLine->m_material.setStiffness(0.05 * stiffnessMax); magneticLine->m_material.setMagnetMaxForce(0.2 * info.m_maxForce); magneticLine->m_material.setMagnetMaxDistance(0.25); magneticLine->m_material.setViscosity(0.05 * info.m_maxLinearDamping); // create a haptic magnetic effect cEffectMagnet* newEffect = new cEffectMagnet(magneticLine); magneticLine->addEffect(newEffect); // disable haptic feedback for now magneticLine->setHapticEnabled(false); // create two sphere that will be added at both ends of the line sphereA = new cShapeSphere(0.02); sphereB = new cShapeSphere(0.02); world->addChild(sphereA); world->addChild(sphereB); sphereA->setShowEnabled(false); sphereB->setShowEnabled(false); // define some material properties for spheres cMaterial matSphere; matSphere.m_ambient.set(0.5, 0.2, 0.2); matSphere.m_diffuse.set(0.8, 0.4, 0.4); matSphere.m_specular.set(1.0, 1.0, 1.0); sphereA->setMaterial(matSphere); sphereB->setMaterial(matSphere); //----------------------------------------------------------------------- // OPEN GL - WINDOW DISPLAY //----------------------------------------------------------------------- // initialize GLUT glutInit(&argc, argv); // retrieve the resolution of the computer display and estimate the position // of the GLUT window so that it is located at the center of the screen int screenW = glutGet(GLUT_SCREEN_WIDTH); int screenH = glutGet(GLUT_SCREEN_HEIGHT); int windowPosX = (screenW - WINDOW_SIZE_W) / 2; int windowPosY = (screenH - WINDOW_SIZE_H) / 2; // initialize the OpenGL GLUT window glutInitWindowPosition(windowPosX, windowPosY); glutInitWindowSize(WINDOW_SIZE_W, WINDOW_SIZE_H); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutCreateWindow(argv[0]); glutDisplayFunc(updateGraphics); glutMouseFunc(mouseClick); glutMotionFunc(mouseMove); glutKeyboardFunc(keySelect); glutReshapeFunc(resizeWindow); glutSetWindowTitle("CHAI 3D"); //----------------------------------------------------------------------- // START SIMULATION //----------------------------------------------------------------------- // simulation in now running simulationRunning = true; // create a thread which starts the main haptics rendering loop cThread* hapticsThread = new cThread(); hapticsThread->set(updateHaptics, CHAI_THREAD_PRIORITY_HAPTICS); // start the main graphics rendering loop glutMainLoop(); // close everything close(); // exit return (0); }
/* Updates the viewpoint according to the object being tracked */ BOOL camTrackCamera( void ) { PROPULSION_STATS *psPropStats; DROID *psDroid; BOOL bFlying; bFlying = false; /* Most importantly - see if the target we're tracking is dead! */ if(trackingCamera.target->died) { setFindNewTarget(); return(false); } /* Cancel tracking if it's no longer selected. This may not be desirable? */ if(trackingCamera.target->type == OBJ_DROID) { // if(!trackingCamera.target->selected) // { // return(false); // } } /* Update the acceleration,velocity and position of the camera for movement */ updateCameraAcceleration(CAM_ALL); updateCameraVelocity(CAM_ALL); updateCameraPosition(CAM_ALL); /* Update the acceleration,velocity and rotation of the camera for rotation */ /* You can track roll as well (z axis) but it makes you ill and looks like a flight sim, so for now just pitch and orientation */ if(trackingCamera.target->type == OBJ_DROID) { psDroid = (DROID*)trackingCamera.target; psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat; if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT) { bFlying = true; } } /* bIsBuilding = false; if(trackingCamera.target->type == OBJ_DROID) { psDroid= (DROID*)trackingCamera.target; if(DroidIsBuilding(psDroid)) { bIsBuilding = true; } } */ if(bRadarAllign || trackingCamera.target->type == OBJ_DROID) { if(bFlying) { updateCameraRotationAcceleration(CAM_ALL); } else { updateCameraRotationAcceleration(CAM_X_AND_Y); } } if(bFlying) { updateCameraRotationVelocity(CAM_ALL); updateCameraRotationPosition(CAM_ALL); } /* else if(bIsBuilding) { updateCameraRotationVelocity(CAM_X_ONLY); } */ else { updateCameraRotationVelocity(CAM_X_AND_Y); updateCameraRotationPosition(CAM_X_AND_Y); } /* Record the old positions for comparison */ oldPosition.x = player.p.x; oldPosition.y = player.p.y; oldPosition.z = player.p.z; /* Update the position that's now stored in trackingCamera.position */ player.p.x = trackingCamera.position.x; player.p.y = trackingCamera.position.y; player.p.z = trackingCamera.position.z; /* Record the old positions for comparison */ oldRotation.x = player.r.x; oldRotation.y = player.r.y; oldRotation.z = player.r.z; /* Update the rotations that're now stored in trackingCamera.rotation */ player.r.x = trackingCamera.rotation.x; /*if(!bIsBuilding)*/ player.r.y = trackingCamera.rotation.y; player.r.z = trackingCamera.rotation.z; /* There's a minimum for this - especially when John's VTOL code lets them land vertically on cliffs */ if(player.r.x>DEG(360+MAX_PLAYER_X_ANGLE)) { player.r.x = DEG(360+MAX_PLAYER_X_ANGLE); } /* if(bIsBuilding) { player.r.y+=DEG(1); } */ /* Clip the position to the edge of the map */ CheckScrollLimits(); /* Store away our last update as acceleration and velocity are all fn()/dt */ trackingCamera.lastUpdate = gameTime2; if(bFullInfo) { flushConsoleMessages(); if(trackingCamera.target->type == OBJ_DROID) { printDroidInfo((DROID*)trackingCamera.target); } } /* Switch off if we're jumping to a new location and we've got there */ if(getRadarTrackingStatus()) { /* This will ensure we come to a rest and terminate the tracking routine once we're close enough */ if(getRotationMagnitude()<10000) { if(getPositionMagnitude() < 60) { setWarCamActive(false); } } } return(true); }
bool Visualization::update() { if (!m_initialized) { printf("Visualization has not been yet initialized."); return false; } // Compute the time since last update (in seconds). Uint32 time = SDL_GetTicks(); float dt = (time - m_lastTickCount) / 1000.0f; m_lastTickCount = time; bool singleSimulationStep = false; bool scrollForward = false; bool scrollBackward = false; int mscroll = 0; SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: // Handle any key presses here. if (event.key.keysym.sym == SDLK_ESCAPE) //Escape. { m_stopRequested = true; } else if (event.key.keysym.sym == SDLK_SPACE) { m_paused = !m_paused; } else if (event.key.keysym.sym == SDLK_TAB) { singleSimulationStep = true; } else if (event.key.keysym.sym == SDLK_r) { float pos[3] = {-15, 0, 15}; m_crowd->pushAgentPosition(0, pos); } else if (event.key.keysym.sym == SDLK_KP7) { float pos[3] = {-19, 0, -19}; dtVnormalize(pos); dtVscale(pos, pos, 2.f); dtCrowdAgent ag; m_crowd->fetchAgent(ag, 0); dtVcopy(ag.velocity, pos); m_crowd->pushAgent(ag); } else if (event.key.keysym.sym == SDLK_KP9) { float pos[] = {19, 0, -19}; dtVnormalize(pos); dtVscale(pos, pos, 2.f); dtCrowdAgent ag; m_crowd->fetchAgent(ag, 0); dtVcopy(ag.velocity, pos); m_crowd->pushAgent(ag); } else if (event.key.keysym.sym == SDLK_KP3) { float pos[3] = {19, 0, 19}; dtVnormalize(pos); dtVscale(pos, pos, 2.f); dtCrowdAgent ag; m_crowd->fetchAgent(ag, 0); dtVcopy(ag.velocity, pos); m_crowd->pushAgent(ag); } else if (event.key.keysym.sym == SDLK_KP1) { float pos[3] = {-19, 0, 19}; dtVnormalize(pos); dtVscale(pos, pos, 2.f); dtCrowdAgent ag; m_crowd->fetchAgent(ag, 0); dtVcopy(ag.velocity, pos); m_crowd->pushAgent(ag); } else if (event.key.keysym.sym == SDLK_KP5) { float pos[3] = {0, 0, 0}; dtVnormalize(pos); dtVscale(pos, pos, 2.f); dtCrowdAgent ag; m_crowd->fetchAgent(ag, 0); dtVcopy(ag.velocity, pos); m_crowd->pushAgent(ag); } break; case SDL_MOUSEBUTTONDOWN: if (event.button.button == SDL_BUTTON_RIGHT) { // Rotate view m_rotating = true; m_initialMousePosition[0] = m_mousePosition[0]; m_initialMousePosition[1] = m_mousePosition[1]; m_intialCameraOrientation[0] = m_cameraOrientation[0]; m_intialCameraOrientation[1] = m_cameraOrientation[1]; m_intialCameraOrientation[2] = m_cameraOrientation[2]; } else if (event.button.button == SDL_BUTTON_WHEELUP) { scrollForward = true; } else if (event.button.button == SDL_BUTTON_WHEELDOWN) { scrollBackward = true; } break; case SDL_MOUSEBUTTONUP: if (event.button.button == SDL_BUTTON_RIGHT) { m_rotating = false; } else if (event.button.button == SDL_BUTTON_LEFT) { float pickedPosition[3]; int index = 0; pick(pickedPosition, &index); } break; case SDL_MOUSEMOTION: m_mousePosition[0] = event.motion.x; m_mousePosition[1] = m_winHeight-1 - event.motion.y; if (m_rotating) { int dx = m_mousePosition[0] - m_initialMousePosition[0]; int dy = m_mousePosition[1] - m_initialMousePosition[1]; m_cameraOrientation[0] = m_intialCameraOrientation[0] - dy*0.25f; m_cameraOrientation[1] = m_intialCameraOrientation[1] + dx*0.25f; } break; case SDL_QUIT: m_stopRequested = true; break; default: break; } } unsigned char mbut = 0; if (SDL_GetMouseState(0,0) & SDL_BUTTON_LMASK) mbut |= IMGUI_MBUT_LEFT; if (SDL_GetMouseState(0,0) & SDL_BUTTON_RMASK) mbut |= IMGUI_MBUT_RIGHT; // Update the camera velocity from keyboard state. Uint8* keystate = SDL_GetKeyState(NULL); #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4800) #endif updateCameraVelocity( dt, keystate[SDLK_w] || keystate[SDLK_UP] || scrollForward, keystate[SDLK_s] || keystate[SDLK_DOWN] || scrollBackward, keystate[SDLK_a] || keystate[SDLK_LEFT], keystate[SDLK_d] || keystate[SDLK_RIGHT], SDL_GetModState() & KMOD_SHIFT); #ifdef _MSC_VER #pragma warning(pop) #endif //Update the camera position updateCameraPosition(dt); //Update the crowd if (m_crowd) { if (singleSimulationStep) { m_paused = true; m_debugInfo->startUpdate(); m_crowd->update(m_crowdDt); m_debugInfo->endUpdate(m_crowdDt); m_crowdAvailableDt = 0.f; } else if (!m_paused) { m_crowdAvailableDt += dt; while(m_crowdAvailableDt > m_crowdDt) { m_debugInfo->startUpdate(); m_crowd->update(m_crowdDt); m_debugInfo->endUpdate(m_crowdDt); m_crowdAvailableDt -= m_crowdDt; } } else { m_crowdAvailableDt = 0.f; } } // Set rendering context glViewport(0, 0, m_winWidth, m_winHeight); glClearColor(0.3f, 0.3f, 0.32f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_2D); // Render 3D glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(50.0f, (float)m_winWidth/(float)m_winHeight, m_zNear, m_zFar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(m_cameraOrientation[0],1,0,0); glRotatef(m_cameraOrientation[1],0,1,0); glRotatef(m_cameraOrientation[2],0,0,1); glTranslatef(-m_cameraPosition[0], -m_cameraPosition[1], -m_cameraPosition[2]); // Extract OpenGL view properties glGetDoublev(GL_PROJECTION_MATRIX, m_projection); glGetDoublev(GL_MODELVIEW_MATRIX, m_modelView); glGetIntegerv(GL_VIEWPORT, m_viewport); renderScene(); renderCrowd(); // Render 2D Overlay glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, m_winWidth, 0, m_winHeight); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); imguiBeginFrame(m_mousePosition[0], m_mousePosition[1], mbut,mscroll); renderDebugInfoOverlay(); imguiEndFrame(); imguiRenderGLDraw(); glEnable(GL_DEPTH_TEST); SDL_GL_SwapBuffers(); return true; }