OSG-Win32窗口显示osg

深藏阁楼爱情的钟 2022-08-23 03:57 598阅读 0赞

上一节是入门:
OSG+VS2015+Win10配置

win32控制台程序下使用osg
为了方便,在上一节中,我们使用VS创建了一个win32控制台程序,然后添加代码:

写法一

  1. #include<osgViewer/Viewer>
  2. #include<osgDB/ReadFile>
  3. int main(int argc, char **argv)
  4. {
  5. osgViewer::Viewer viewer;
  6. viewer.setSceneData(osgDB::readNodeFile("cessna.osg"));
  7. return viewer.run();
  8. }

写法二
更加优雅一点,使用了智能指针。

  1. #include<osgViewer/Viewer>
  2. #include<osg/Node>
  3. #include<osg/Geode>
  4. #include<osg/Group>
  5. #include<osgDB/ReadFile>
  6. #include<osgDB/WriteFile>
  7. #include<osgUtil/Optimizer>
  8. int main(int argc, char **argv)
  9. {
  10. osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
  11. osg::ref_ptr<osg::Group> root = new osg::Group();
  12. osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cessna.osg");
  13. root->addChild(node.get());
  14. osgUtil::Optimizer optimizer;
  15. optimizer.optimize(root.get());
  16. viewer->setSceneData(root.get());
  17. viewer->realize();
  18. viewer->run();
  19. return 0;
  20. }

Win32 Project下使用osg
首先回顾一下,一个win32窗口是如何创建的:
1.1 入口函数WinMain

1.2 窗口处理函数
当窗口处理消息事件时,系统调用该函数
  LRESULT CALLBACK WindowProc(
HWND hwnd, // 窗口的句柄
UINT uMsg, // 消息的ID号
WPARAM wParam, // 消息所对应的参数
LPARAM lParam // 消息所对应的参数
);

1.3 注册窗口类型
  typedef struct _WNDCLASS {
UINT style; //窗口类的风格:不是窗口类型的风格
WNDPROC lpfnWndProc; //窗口处理函数
int cbClsExtra; //窗口类附加数据大小
int cbWndExtra; //窗口附加数据大小
HANDLE hInstance; //当前应用程序的实例句柄
HICON hIcon; //窗口图标
HCURSOR hCursor; //窗口的鼠标
HBRUSH hbrBackground; //窗口的背景画刷
LPCTSTR lpszMenuName; //菜单
LPCTSTR lpszClassName; //类型名称:不是窗口标题的名称,只是注册的名称
} WNDCLASS;

  1. 注册函数 RegisterClass

1.4 创建窗口
  HWND CreateWindow(
LPCTSTR lpClassName, //窗口类型名称
LPCTSTR lpWindowName, //窗口名称
DWORD dwStyle, //窗口类型
int x, //窗口的左上角X坐边
int y, //窗口的左上角X坐边
int nWidth, //窗口的宽度
int nHeight, //窗口的高度
HWND hWndParent, //父窗口句柄
HMENU hMenu, //窗口菜单句柄
HANDLE hInstance, //应用程序的实例句柄
LPVOID lpParam //创建的参数,一般为NULL
);

1.5 显示窗口
ShowWindow 显示窗口
  BOOL ShowWindow(
HWND hWnd, //显示的窗口句柄
int nCmdShow //显示的方式
);
UpdateWindow 刷新窗口

1.6 消息处理
GetMessage 获取消息
DispatchMessage 派发消息

1.7 程序退出
窗口销毁时,退出程序。在WndProc中实现。
WM_DESTROY: 当窗口销毁时,会调用WndProc
传递给使用者。

直接在窗口过程函数中使用,显示osg

定义一些变量:

  1. sg::ref_ptr<osgViewer::Viewer> viewer;
  2. osg::observer_ptr<osgViewer::GraphicsWindow> window;
  3. osg::ref_ptr<osg::Group> root;
  4. osg::ref_ptr<osg::Node> loadedModel;
  5. osgUtil::Optimizer optimizer;
  6. osg::ref_ptr<osg::GraphicsContext::Traits> traits;
  7. osg::ref_ptr<osg::Referenced> windata;
  8. osg::GraphicsContext* gc;
  9. osg::ref_ptr<osg::Camera> camera;
  10. bool renderok;

在WM_CREATE消息中添加代码:

  1. root = new osg::Group;
  2. loadedModel = osgDB::readNodeFile("cessna.osg");
  3. if (!loadedModel)
  4. return 1;
  5. optimizer.optimize(loadedModel.get());
  6. optimizer.reset();
  7. root->addChild(loadedModel.get());
  8. traits = new osg::GraphicsContext::Traits;
  9. windata = new osgViewer::GraphicsWindowWin32::WindowData(hwnd);
  10. traits->x = 0;
  11. traits->y = 0;
  12. traits->width = 800;
  13. traits->height = 600;
  14. traits->windowDecoration = false;
  15. traits->doubleBuffer = true;
  16. traits->sharedContext = 0;
  17. traits->inheritedWindowData = windata;
  18. traits->setInheritedWindowPixelFormat = true;
  19. gc = osg::GraphicsContext::createGraphicsContext(traits.get());
  20. camera = new osg::Camera;
  21. camera->setGraphicsContext(gc);
  22. camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height));
  23. viewer = new osgViewer::Viewer;
  24. viewer->addSlave(camera.get());
  25. viewer->setSceneData(root.get());
  26. viewer->setCameraManipulator(new osgGA::TrackballManipulator);
  27. viewer->addEventHandler(new osgViewer::StatsHandler);
  28. viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
  29. viewer->realize();
  30. renderok = false;
  31. _beginthread(render, 0, NULL);

=============================================================
全部代码:

  1. #include <windows.h>
  2. #include <osgViewer/Viewer>
  3. #include <osgViewer/ViewerEventHandlers>
  4. #include <osgViewer/api/win32/GraphicsWindowWin32>
  5. #include <osgUtil/Optimizer>
  6. #include <osgGA/TrackballManipulator>
  7. #include <osgDB/ReadFile>
  8. #include <process.h>
  9. osg::ref_ptr<osgViewer::Viewer> viewer;
  10. osg::observer_ptr<osgViewer::GraphicsWindow> window;
  11. osg::ref_ptr<osg::Group> root;
  12. osg::ref_ptr<osg::Node> loadedModel;
  13. osgUtil::Optimizer optimizer;
  14. osg::ref_ptr<osg::GraphicsContext::Traits> traits;
  15. osg::ref_ptr<osg::Referenced> windata;
  16. osg::GraphicsContext* gc;
  17. osg::ref_ptr<osg::Camera> camera;
  18. bool renderok;
  19. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  20. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
  21. {
  22. static TCHAR szAppName[] = TEXT("HelloOSG Win32 Project");
  23. HWND hwnd;
  24. MSG msg;
  25. WNDCLASS wndclass;
  26. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  27. wndclass.lpfnWndProc = WndProc;
  28. wndclass.cbClsExtra = 0;
  29. wndclass.cbWndExtra = 0;
  30. wndclass.hInstance = hInstance;
  31. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  32. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  33. wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  34. wndclass.lpszMenuName = NULL;
  35. wndclass.lpszClassName = szAppName;
  36. if (!RegisterClass(&wndclass))
  37. {
  38. MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
  39. return 0;
  40. }
  41. hwnd = CreateWindow(szAppName, // window class name
  42. TEXT("The Hello Program"), // window caption
  43. WS_OVERLAPPEDWINDOW, // window style
  44. 100, // initial x position
  45. 100, // initial y position
  46. 800, // initial x size
  47. 600, // initial y size
  48. NULL, // parent window handle
  49. NULL, // window menu handle
  50. hInstance, // program instance handle
  51. NULL); // creation parameters
  52. ShowWindow(hwnd, iCmdShow);
  53. UpdateWindow(hwnd);
  54. while (GetMessage(&msg, NULL, 0, 0))
  55. {
  56. TranslateMessage(&msg);
  57. DispatchMessage(&msg);
  58. }
  59. return (int)msg.wParam;
  60. }
  61. void render(void* ptr)
  62. {
  63. while (!viewer->done())
  64. {
  65. viewer->frame();
  66. }
  67. renderok = true;
  68. }
  69. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  70. {
  71. switch (message)
  72. {
  73. case WM_CREATE:
  74. root = new osg::Group;
  75. loadedModel = osgDB::readNodeFile("cessna.osg");
  76. if (!loadedModel)
  77. return 1;
  78. optimizer.optimize(loadedModel.get());
  79. optimizer.reset();
  80. root->addChild(loadedModel.get());
  81. traits = new osg::GraphicsContext::Traits;
  82. windata = new osgViewer::GraphicsWindowWin32::WindowData(hwnd);
  83. traits->x = 0;
  84. traits->y = 0;
  85. traits->width = 800;
  86. traits->height = 600;
  87. traits->windowDecoration = false;
  88. traits->doubleBuffer = true;
  89. traits->sharedContext = 0;
  90. traits->inheritedWindowData = windata;
  91. traits->setInheritedWindowPixelFormat = true;
  92. gc = osg::GraphicsContext::createGraphicsContext(traits.get());
  93. camera = new osg::Camera;
  94. camera->setGraphicsContext(gc);
  95. camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height));
  96. viewer = new osgViewer::Viewer;
  97. viewer->addSlave(camera.get());
  98. viewer->setSceneData(root.get());
  99. viewer->setCameraManipulator(new osgGA::TrackballManipulator);
  100. viewer->addEventHandler(new osgViewer::StatsHandler);
  101. viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
  102. viewer->realize();
  103. renderok = false;
  104. _beginthread(render, 0, NULL);
  105. return 0;
  106. case WM_PAINT:
  107. return 0;
  108. case WM_DESTROY:
  109. viewer->setDone(true);
  110. while (!renderok)
  111. {
  112. Sleep(10);
  113. }
  114. PostQuitMessage(0);
  115. return 0;
  116. }
  117. return DefWindowProc(hwnd, message, wParam, lParam);
  118. }

运行:
这里写图片描述

发表评论

表情:
评论列表 (有 0 条评论,598人围观)

还没有评论,来说两句吧...

相关阅读

    相关 stm32 窗口看门狗 WWDG

    窗口看门狗WWDG其实和独立看门狗类似,它是一个7位递减计数器不断的往下递减计数,当减到一个固定值0x40时还不喂狗的话,产生一个MCU复位,这个值叫窗口的下限,是固定的值,不