⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soguigameviewer.cpp

📁 海量地形数据漫游系统,对于OPENGL开发人员具有一定的参考
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************\ * * SoGuiGameViewer.cpp * * So???RenderArea derived GUI window with advanced mouse handling  * (delta mouse mode). * * When delta mode is activated, SoLocationEvent does not contain absolute * mouse coordinates, but deltas from previous SoLocationEvent. * Such deltas can be used for easy realization of mouse-look and so on. * * * Authors: PCJohn (peciva AT fit.vutbr.cz) * Contributors: * * ---------------------------------------------------------------------------- * * THIS SOFTWARE IS NOT COPYRIGHTED * * This source code is offered for use in the public domain. * You may use, modify or distribute it freely. * * This source code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY.  ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY * DISCLAIMED.  This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * If you find the source code useful, authors will kindly welcome * if you give them credit and keep their names with their source code, * but do not feel forced to do so. *\*****************************************************************************/#include <Inventor/SbVec2s.h>#include <Inventor/SbBox2s.h>#include <Inventor/nodes/SoCamera.h>#include <Inventor/nodeKits/SoBaseKit.h>#include <Inventor/actions/SoSearchAction.h>#include <Inventor/events/SoLocation2Event.h>#include <Inventor/errors/SoDebugError.h>#include "SoGuiGameViewer.h"#if defined(__WIN32__) || defined(_WIN32)#include <Inventor/Win/devices/SoWinMouse.h>#define SoGuiMouse SoWinMouse#define SOGUI_OBJECT_SOURCE SOWIN_OBJECT_SOURCE#else#define SOGUI_OBJECT_SOURCE SOQT_OBJECT_SOURCE#endifclass SoGuiGameViewerP {public:  SoGuiGameViewer *parent;  SoGuiGameViewer::MouseMode mouseMode;  SoCamera *camera;  SbVec2f mouseSensitivity;  SbBool mouseDeltaMode;  SbBool mouseDeltaModeActive;  SbVec2s mouseSavedPos;  SbVec2s mouseCenter;  SbBox2s windowRect;  SoGuiGameViewer::ClipMode clipMode;  void setMouseDeltaMode(SbBool on);  void activateMouseDeltaMode();  void deactivateMouseDeltaMode();  void updateDeltaMouseActivation();#if defined(__WIN32__) || defined(_WIN32)  HWND topLevelWnd;  SbBool wndActive;  WNDPROC prevWndProc;  static HHOOK hookHandle;  static HHOOK shellHookHandle;  static LRESULT CALLBACK wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);  static LRESULT CALLBACK messageHook(int nCode, WPARAM wParam, LPARAM lParam);  static LRESULT CALLBACK shellHook(int nCode, WPARAM wParam, LPARAM lParam);  static SbList<SoGuiGameViewerP*> listOfGameViewers;  static SbDict handle2viewerp;  static SoGuiGameViewer* getViewerByHandle(HWND h, SbBool searchParentWidgets);  SbBool isInForeground() const;  static UINT focusMessageId;    SoLocation2Event *locationEvent;  SbBool shiftDown;  SbBool ctrlDown;  SbBool altDown;  void clipMouse(const SbBox2s &box);  void unclipMouse();#endif /* __WIN32__ || _WIN32 */  SoGuiGameViewerP(SoGuiGameViewer *parent);  ~SoGuiGameViewerP();};#if defined(__WIN32__) || defined(_WIN32)HHOOK SoGuiGameViewerP::hookHandle;HHOOK SoGuiGameViewerP::shellHookHandle;SbList<SoGuiGameViewerP*> SoGuiGameViewerP::listOfGameViewers;SbDict SoGuiGameViewerP::handle2viewerp;UINT SoGuiGameViewerP::focusMessageId = -1;static SbVec2s getMousePos();static void setMousePos(const SbVec2s &pos);static void updateMouseCenter(SbVec2s &mouseCenter, const SbBox2s &windowRect);static void updateWindowRect(HWND h, SbBox2s &rect);#endif /* __WIN32__ || _WIN32 */#ifdef THIS#undef THIS#endif#define THIS pimplSOGUI_OBJECT_SOURCE(SoGuiGameViewer);void SoGuiGameViewer::setMouseMode(MouseMode mode){  THIS->mouseMode = mode;  THIS->setMouseDeltaMode(mode==DELTA_TO_SCENE_GRAPH || mode==CAMERA ||                          mode==CAMERA_AND_SCENE_GRAPH);}SoGuiGameViewer::MouseMode SoGuiGameViewer::getMouseMode() const{  return THIS->mouseMode;}void SoGuiGameViewer::setMouseSensitivity(const SbVec2f &sensitivity){  THIS->mouseSensitivity = sensitivity;}SbVec2f SoGuiGameViewer::getMouseSensitivity() const{  return THIS->mouseSensitivity;}void SoGuiGameViewer::setCamera(SoCamera *camera){  if (THIS->camera)  THIS->camera->unref();  THIS->camera = camera;  if (THIS->camera)  THIS->camera->ref();}SoCamera* SoGuiGameViewer::getCamera() const{  return THIS->camera;}void SoGuiGameViewer::setSceneGraph(SoNode *node){  if (node == inherited::getSceneGraph())    return;  inherited::setSceneGraph(node);  if (node == NULL)     // If no scene graph then reset camera    setCamera(NULL);  else {    // Search for camera in the scene graph    SbBool oldSearchChildren = SoBaseKit::isSearchingChildren();    SoBaseKit::setSearchingChildren(TRUE);    SoSearchAction search;    search.setType(SoCamera::getClassTypeId());    search.apply(node);    SoBaseKit::setSearchingChildren(oldSearchChildren);    SoPath *path = search.getPath();    if (path)      setCamera((SoCamera*)((SoFullPath*)path)->getTail());    else {      setCamera(NULL);      SoDebugError::post("SoGuiGameViewer::setSceneGraph",                         "The scene graph does not contain any cameras.\n"                         "Consequences: (1) Nothing will be seen.\n"                         "(2) No camera movements will be made.");    }  }}SoGuiGameViewer::SoGuiGameViewer(WIDGET parent,                  const char *name,                  SbBool embed,                  MouseMode mouseMode)                  : inherited(parent, name, embed, TRUE, TRUE){  pimpl = new SoGuiGameViewerP(this);  THIS->clipMode = CLIP_RELEASE_ONLY;  THIS->mouseMode = mouseMode;  THIS->camera = NULL;  THIS->mouseSensitivity = SbVec2f(0.03f,0.03f);  THIS->mouseDeltaMode = mouseMode==DELTA_TO_SCENE_GRAPH || mouseMode==CAMERA ||                         mouseMode==CAMERA_AND_SCENE_GRAPH;  THIS->mouseDeltaModeActive = FALSE;#if defined(__WIN32__) || defined(_WIN32)  THIS->wndActive = FALSE;  THIS->shiftDown = FALSE;  THIS->ctrlDown = FALSE;  THIS->altDown = FALSE;#endif /* __WIN32__ || _WIN32 */}SoGuiGameViewer::~SoGuiGameViewer(){  THIS->setMouseDeltaMode(FALSE);  setCamera(NULL);  delete pimpl;}void SoGuiGameViewerP::setMouseDeltaMode(SbBool on){  if (mouseDeltaMode == on)    return;  mouseDeltaMode = on;  updateDeltaMouseActivation();}#if defined(__WIN32__) || defined(_WIN32)LRESULT CALLBACK SoGuiGameViewerP::wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){  // get pointer to our object  SoGuiGameViewerP *pimpl;  if (!handle2viewerp.find((unsigned long)hwnd, (*(void**)&pimpl)))    assert(FALSE && "Pointer to SoGuiGameViewerP not found.");  switch (uMsg) {        case WM_MOUSEMOVE: {#ifdef DEBUG_FOCUS      printf("mouseMove, focus is %s, my value %i\n", GetForegroundWindow() == THIS->parent->getParentWidget() ? "TRUE" : "FALSE", THIS->wndActive);#endif      if (THIS->mouseMode == SoGuiGameViewer::SCENE_GRAPH)        return CallWindowProc(THIS->prevWndProc, hwnd, uMsg, wParam, lParam);      if (!THIS->mouseDeltaModeActive)        return 0; // stop further processing      // handle mouse      SbVec2s pos = getMousePos();      SbVec2s delta = pos - THIS->mouseCenter;            if (delta != SbVec2s(0,0)) {        setMousePos(THIS->mouseCenter);                assert(THIS->mouseMode != SoGuiGameViewer::DISABLED &&               THIS->mouseMode != SoGuiGameViewer::SCENE_GRAPH &&               "Wrong mouse mode.");                if (THIS->mouseMode==SoGuiGameViewer::CAMERA ||             THIS->mouseMode==SoGuiGameViewer::CAMERA_AND_SCENE_GRAPH) {          if (THIS->camera) {            SbRotation orientation = THIS->camera->orientation.getValue();            SbRotation rotChange(SbRotation(SbVec3f(0.f,-1.f,0.f),                                             delta[0]*THIS->mouseSensitivity[0]) *                                 SbRotation(SbVec3f(-1.f,0.f,0.f),                                             delta[1]*THIS->mouseSensitivity[1]));            THIS->camera->orientation.setValue(rotChange * orientation);          }        }        if (THIS->mouseMode==SoGuiGameViewer::DELTA_TO_SCENE_GRAPH ||            THIS->mouseMode == SoGuiGameViewer::CAMERA_AND_SCENE_GRAPH) {          THIS->locationEvent->setPosition(delta);          THIS->locationEvent->setShiftDown(THIS->shiftDown);          THIS->locationEvent->setCtrlDown(THIS->ctrlDown);          THIS->locationEvent->setAltDown(THIS->altDown);          THIS->locationEvent->setTime(SbTime::getTimeOfDay());          THIS->parent->sendSoEvent(THIS->locationEvent);        }      }      return 0; // stop further processing    }    case WM_SIZE: {      // update mouse      updateWindowRect(THIS->parent->getNormalWidget(), THIS->windowRect);      updateMouseCenter(THIS->mouseCenter, THIS->windowRect);      setMousePos(THIS->mouseCenter);      break;    }    case WM_SETCURSOR: {      // hide cursor      if (THIS->mouseDeltaModeActive) {        SetCursor(NULL);        return TRUE;      }      break;    }    case WM_SETFOCUS: {      THIS->wndActive = THIS->isInForeground();#ifdef DEBUG_FOCUS      printf("setfocus, wndActive is %s\n", THIS->wndActive ? "TRUE" : "FALSE");#endif      THIS->updateDeltaMouseActivation();      break;    }    case WM_KILLFOCUS: {      THIS->wndActive = FALSE;#ifdef DEBUG_FOCUS      printf("killfocus\n");#endif      THIS->updateDeltaMouseActivation();      break;    }    case WM_KEYDOWN:    case WM_SYSKEYDOWN:      switch (wParam) {        case VK_SHIFT:   THIS->shiftDown = TRUE; break;        case VK_CONTROL: THIS->ctrlDown  = TRUE; break;        case VK_MENU:    THIS->altDown   = TRUE; break;      }      break;        case WM_KEYUP:    case WM_SYSKEYUP:      switch (wParam) {        case VK_SHIFT:   THIS->shiftDown = FALSE; break;        case VK_CONTROL: THIS->ctrlDown  = FALSE; break;        case VK_MENU:    THIS->altDown   = FALSE; break;      }      break;    default:      if (uMsg == focusMessageId) {        SetFocus(THIS->parent->getNormalWidget());        return 0;      }  }  return CallWindowProc(THIS->prevWndProc, hwnd, uMsg, wParam, lParam);}SoGuiGameViewer* SoGuiGameViewerP::getViewerByHandle(HWND h, SbBool searchParentWidgets){  if (!searchParentWidgets) {    SoGuiGameViewerP *pimpl;    if (handle2viewerp.find((unsigned long)h, (*(void**)&pimpl)))  return pimpl->parent;    else  return NULL;  } else {    const int c = listOfGameViewers.getLength();    int i;    for (i=0; i<c; i++) {      SoGuiGameViewer *gv = listOfGameViewers[i]->parent;      HWND w = gv->getNormalWidget();      do {        if (w == h)  return gv;        w = GetParent(w);      } while (w != NULL);    }    return NULL;  }}SbBool SoGuiGameViewerP::isInForeground() const{  HWND fg = GetForegroundWindow();  return (fg == parent->getParentWidget() ||          fg == parent->getNormalWidget());}LRESULT CALLBACK SoGuiGameViewerP::messageHook(int nCode, WPARAM wParam, LPARAM lParam){  CWPSTRUCT *msg = (CWPSTRUCT*)lParam;  // Windows documentation says: process messages only when nCode >= 0  if (nCode >= 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -