void GutReadKeyboard(void) { static char keyboard[256]; GutReadKeyboard(keyboard); for ( int i=0; i<256; i++ ) { // key down if ( keyboard[i] && !g_keyboard_state[i] ) { if ( g_pKeyDownFuncs[i] ) g_pKeyDownFuncs[i](); } // key up if ( !keyboard[i] && g_keyboard_state[i] ) { if ( g_pKeyUpFuncs[i] ) g_pKeyUpFuncs[i](); } // key pressed if ( keyboard[i] ) { if ( g_pKeyPressedFuncs[i] ) g_pKeyPressedFuncs[i](); } } memcpy(g_keyboard_state, keyboard, sizeof(keyboard)); }
void GetUserInput(void) { g_fFrame_Time = g_Timer.Stop(); g_Timer.Restart(); GutReadKeyboard(); g_Control.Update(g_fFrame_Time, CGutUserControl::CONTROLLER_ROTATEOBJECT); }
void GetUserInput(void) { // `讀取滑鼠` GutMouseInfo mouse; GutReadMouse(&mouse); // `讀取鍵盤` char keyboard_state[256]; GutReadKeyboard(keyboard_state); // `取得畫完前一個畫面到現在所經歷的時間` float time_diff = g_Timer.Stop(); g_Timer.Restart(); float moving_speed = 2.0f * time_diff; float rotation_speed = 1.0 * time_diff; // `極座標系統` static float theta = -MATH_PI * 0.5f; static float phi = 0.0f; // `如果按下滑鼠左鍵, 就旋轉鏡頭.` if ( mouse.button[0] ) { theta += mouse.x * rotation_speed; phi -= mouse.y * rotation_speed; } float sin_phi, cos_phi; float sin_theta, cos_theta; FastMath::SinCos(phi, sin_phi, cos_phi); FastMath::SinCos(theta, sin_theta, cos_theta); // `計算鏡頭的面向` Vector4 camera_facing; camera_facing[0] = cos_phi * cos_theta; camera_facing[1] = sin_phi; camera_facing[2] = cos_phi * sin_theta; // `計算鏡頭正上方的軸向` Vector4 camera_up; FastMath::SinCos(phi + MATH_PI*0.5f, sin_phi, cos_phi); camera_up[0] = cos_phi * cos_theta; camera_up[1] = sin_phi; camera_up[2] = cos_phi * sin_theta; // `取得鏡面右方的方向` Vector4 camera_right = Vector3CrossProduct(camera_facing, camera_up); // `按下W或方向鍵向上` if ( keyboard_state[GUTKEY_W] || keyboard_state[GUTKEY_UP] ) { g_eye += camera_facing * moving_speed; } // `按下S或方向鍵向下` if ( keyboard_state[GUTKEY_S] || keyboard_state[GUTKEY_DOWN] ) { g_eye -= camera_facing * moving_speed; } // `按下A或方向鍵向左` if ( keyboard_state[GUTKEY_A] || keyboard_state[GUTKEY_LEFT] ) { g_eye -= camera_right * moving_speed; } // `按下D或方向鍵向右` if ( keyboard_state[GUTKEY_D] || keyboard_state[GUTKEY_RIGHT] ) { g_eye += camera_right * moving_speed; } // `計算出鏡頭對準的點, 產生鏡頭轉換矩陣時會用到.` g_lookat = g_eye + camera_facing; // `因為是對2個軸轉動, 需要更新鏡頭朝上的軸.` g_up = camera_up; }
void CGutUserControl::FPSCamera(float time_advance) { char keyboard_state[256]; float moving_speed = m_fMoveSpeed * time_advance; float rotation_speed = m_fRotateSpeed * time_advance; if ( time_advance ) { // 讀取滑鼠 GutMouseInfo mouse; GutReadMouse(&mouse); // 讀取鍵盤 GutReadKeyboard(keyboard_state); // 速度 // 如果按下滑鼠左鍵,就旋轉鏡頭 if ( mouse.button[0] ) { m_fCameraHeading -= mouse.x * rotation_speed; m_fCameraPitch -= mouse.y * rotation_speed; } } /* // 極座標系統 float heading_sin, heading_cos; float pitch_sin, pitch_cos; float up_sin, up_cos; FastMath::SinCos(m_fCameraHeading, heading_sin, heading_cos); FastMath::SinCos(m_fCameraPitch, pitch_sin, pitch_cos); FastMath::SinCos(m_fCameraPitch + MATH_PI*0.5f, up_sin, up_cos); Vector4 camera_facing, camera_up; switch(m_eUP) { case UP_X: break; case UP_Y: // 計算鏡頭的面向 camera_facing[0] = pitch_cos * heading_cos; camera_facing[1] = pitch_sin; camera_facing[2] = pitch_cos * heading_sin; // 計算鏡頭正上方的軸向 camera_up[0] = up_cos * heading_cos; camera_up[1] = up_sin; camera_up[2] = up_cos * heading_sin; break; case UP_Z: // 計算鏡頭的面向 camera_facing[0] = pitch_cos * heading_cos; camera_facing[2] = pitch_sin; camera_facing[1] = -pitch_cos * heading_sin; // 計算鏡頭正上方的軸向 camera_up[0] = up_cos * heading_cos; camera_up[2] = up_sin; camera_up[1] = -up_cos * heading_sin; break; } // 取得鏡面右方的方向 Vector4 camera_right = Vector3CrossProduct(camera_up, camera_facing); */ Matrix4x4 rot_matrix; rot_matrix.Identity(); rot_matrix.RotateY_Replace(m_fCameraHeading); rot_matrix.RotateX(m_fCameraPitch); Matrix4x4 CameraOrient = rot_matrix * m_RefCameraMatrix; Vector4 camera_right = CameraOrient[0]; Vector4 camera_up = CameraOrient[1]; Vector4 camera_facing = -CameraOrient[2]; if ( time_advance ) { // 按下W或方向鍵向上 if ( keyboard_state[GUTKEY_W] || keyboard_state[GUTKEY_UP] ) { m_vEye += camera_facing * moving_speed; } // 按下S或方向鍵向下 if ( keyboard_state[GUTKEY_S] || keyboard_state[GUTKEY_DOWN] ) { m_vEye -= camera_facing * moving_speed; } // 按下A或方向鍵向左 if ( keyboard_state[GUTKEY_A] || keyboard_state[GUTKEY_LEFT] ) { m_vEye -= camera_right * moving_speed; } // 按下D或方向鍵向右 if ( keyboard_state[GUTKEY_D] || keyboard_state[GUTKEY_RIGHT] ) { m_vEye += camera_right * moving_speed; } } // 計算出鏡頭對準的點, 產生鏡頭轉換矩陣時會用到. m_vLookAt = m_vEye + camera_facing; // 因為是對2個軸轉動, 需要更新鏡頭朝上的軸 m_vUp = camera_up; // 確認w = 1 m_vEye[3] = m_vUp[3] = m_vLookAt[3] = 1.0f; UpdateViewMatrix(); }
void main(void) { // 內定使用DirectX 9來繪圖 char *device = "dx9"; void (*render)(void) = RenderFrameDX9; bool (*init_resource)(void) = InitResourceDX9; bool (*release_resource)(void) = ReleaseResourceDX9; void (*resize_func)(int width, int height) = ResizeWindowDX9; #ifdef _ENABLE_DX10_ printf("Press\n(1) for Direct3D9\n(2) for OpenGL\n(3) for Direct3D10\n"); #else printf("Press\n(1) for Direct3D9\n(2) for OpenGL\n"); #endif int c = getche(); switch(c) { default: case '1': render = RenderFrameDX9; init_resource = InitResourceDX9; release_resource = ReleaseResourceDX9; resize_func = ResizeWindowDX9; break; case '2': device = "opengl"; init_resource = InitResourceOpenGL; release_resource = ReleaseResourceOpenGL; render = RenderFrameOpenGL; resize_func = ResizeWindowOpenGL; break; #ifdef _ENABLE_DX10_ case '3': device = "dx10"; init_resource = InitResourceDX10; release_resource = ReleaseResourceDX10; render = RenderFrameDX10; resize_func = ResizeWindowDX10; break; #endif } printf("\nSelected %s device for rendering.\n", device); GutInputInit(); GutRegisterKeyDown(GUTKEY_ESCAPE, KeyDown_ESCAPE); GutResizeFunc( resize_func ); // 切換成全螢幕模式 if ( !GutFullScreen(800, 600) ) { GutFullScreen(600, 800); } // 做OpenGL或DirectX初始化 if ( !GutInitGraphicsDevice(device) ) { printf("Failed to initialize %s device\n", device); exit(0); } GutInputInit(); // 載入shader if ( !init_resource() ) { release_resource(); printf("Failed to load resources\n"); exit(0); } // 主回圈 while( GutProcessMessage() ) { render(); GutReadKeyboard(); } // 卸載shader release_resource(); // 關閉OpenGL/DirectX繪圖裝置 GutReleaseGraphicsDevice(); }
void GetUserControl_FPSCamera(Vector4 &vEye, Vector4 &vUp, Vector4 &vLookAt, float time_advance) { // 讀取滑鼠 GutMouseInfo mouse; GutReadMouse(&mouse); // 讀取鍵盤 char keyboard_state[256]; GutReadKeyboard(keyboard_state); float moving_speed = 2.0f * time_advance; float rotation_speed = 1.0f * time_advance; // 極座標系統 static float theta = -MATH_PI * 0.5f; static float phi = 0.0f; // 如果按下滑鼠左鍵,就旋轉鏡頭 if ( mouse.button[0] ) { theta += mouse.x * rotation_speed; phi -= mouse.y * rotation_speed; } float sin_phi, cos_phi; float sin_theta, cos_theta; FastMath::SinCos(phi, sin_phi, cos_phi); FastMath::SinCos(theta, sin_theta, cos_theta); // 計算鏡頭的面向 Vector4 camera_facing; camera_facing[0] = cos_phi * cos_theta; camera_facing[1] = sin_phi; camera_facing[2] = cos_phi * sin_theta; // 計算鏡頭正上方的軸向 Vector4 camera_up; FastMath::SinCos(phi + MATH_PI*0.5f, sin_phi, cos_phi); camera_up[0] = cos_phi * cos_theta; camera_up[1] = sin_phi; camera_up[2] = cos_phi * sin_theta; // 取得鏡面右方的方向 Vector4 camera_right = Vector3CrossProduct(camera_up, camera_facing); // 按下W或方向鍵向上 if ( keyboard_state[GUTKEY_W] || keyboard_state[GUTKEY_UP] ) { vEye += camera_facing * moving_speed; } // 按下S或方向鍵向下 if ( keyboard_state[GUTKEY_S] || keyboard_state[GUTKEY_DOWN] ) { vEye -= camera_facing * moving_speed; } // 按下A或方向鍵向左 if ( keyboard_state[GUTKEY_A] || keyboard_state[GUTKEY_LEFT] ) { vEye += camera_right * moving_speed; } // 按下D或方向鍵向右 if ( keyboard_state[GUTKEY_D] || keyboard_state[GUTKEY_RIGHT] ) { vEye -= camera_right * moving_speed; } // 計算出鏡頭對準的點, 產生鏡頭轉換矩陣時會用到. vLookAt = vEye + camera_facing; // 因為是對2個軸轉動, 需要更新鏡頭朝上的軸 vUp = camera_up; vEye[3] = vUp[3] = vLookAt[3] = 1.0f; }