OSG-Win32窗口显示osg

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

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

写法一

#include

#include

int main(int argc, char **argv)

{

  osgViewer::Viewer viewer;

  viewer.setSceneData(osgDB::readNodeFile("cessna.osg"));

  return viewer.run();

}

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

#include<osgViewer/Viewer>
#include<osg/Node>
#include<osg/Geode>
#include<osg/Group>

#include<osgDB/ReadFile>
#include<osgDB/WriteFile>

#include<osgUtil/Optimizer>

int main(int argc, char **argv)
{
  osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();

  osg::ref_ptr<osg::Group> root = new osg::Group();

  osg::ref_ptr<osg::Node> node =  osgDB::readNodeFile("cessna.osg");

  root->addChild(node.get());

  osgUtil::Optimizer optimizer;
  optimizer.optimize(root.get());

  viewer->setSceneData(root.get());

  viewer->realize();

  viewer->run();

  return 0;
}

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;

注册函数 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

定义一些变量:

sg::ref_ptr::Viewer> viewer;
osg::observer_ptr::GraphicsWindow> window;
osg::ref_ptr::Group> root;
osg::ref_ptr::Node> loadedModel;
osgUtil::Optimizer optimizer;
osg::ref_ptr::GraphicsContext::Traits> traits;
osg::ref_ptr::Referenced> windata;
osg::GraphicsContext* gc;
osg::ref_ptr::Camera> camera;
bool renderok;

在WM_CREATE消息中添加代码:

    root = new osg::Group;
    loadedModel = osgDB::readNodeFile("cessna.osg");
    if (!loadedModel)
      return 1;
    optimizer.optimize(loadedModel.get());
    optimizer.reset();
    root->addChild(loadedModel.get());
    traits = new osg::GraphicsContext::Traits;
    windata = new osgViewer::GraphicsWindowWin32::WindowData(hwnd);
    traits->x = 0;
    traits->y = 0;
    traits->width = 800;
    traits->height = 600;
    traits->windowDecoration = false;
    traits->doubleBuffer = true;
    traits->sharedContext = 0;
    traits->inheritedWindowData = windata;
    traits->setInheritedWindowPixelFormat = true;
    gc = osg::GraphicsContext::createGraphicsContext(traits.get());
    camera = new osg::Camera;
    camera->setGraphicsContext(gc);
    camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height));
    viewer = new osgViewer::Viewer;
    viewer->addSlave(camera.get());
    viewer->setSceneData(root.get());
    viewer->setCameraManipulator(new osgGA::TrackballManipulator);
    viewer->addEventHandler(new osgViewer::StatsHandler);
    viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
    viewer->realize();
    renderok = false;
    _beginthread(render, 0, NULL);

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

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

osg::ref_ptr::Viewer> viewer;
osg::observer_ptr::GraphicsWindow> window;
osg::ref_ptr::Group> root;
osg::ref_ptr::Node> loadedModel;
osgUtil::Optimizer optimizer;
osg::ref_ptr::GraphicsContext::Traits> traits;
osg::ref_ptr::Referenced> windata;
osg::GraphicsContext* gc;
osg::ref_ptr::Camera> camera;
bool renderok;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
  static TCHAR szAppName[] = TEXT("HelloOSG Win32 Project");
  HWND hwnd;
  MSG msg;
  WNDCLASS wndclass;
  wndclass.style = CS_HREDRAW | CS_VREDRAW;
  wndclass.lpfnWndProc = WndProc;
  wndclass.cbClsExtra = 0;
  wndclass.cbWndExtra = 0;
  wndclass.hInstance = hInstance;
  wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  wndclass.lpszMenuName = NULL;
  wndclass.lpszClassName = szAppName;
  if (!RegisterClass(&wndclass))
  {
    MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
    return 0;
  }
  hwnd = CreateWindow(szAppName, // window class name
    TEXT("The Hello Program"), // window caption
    WS_OVERLAPPEDWINDOW, // window style
    100, // initial x position
    100, // initial y position
    800, // initial x size
    600, // initial y size
    NULL, // parent window handle
    NULL, // window menu handle
    hInstance, // program instance handle
    NULL); // creation parameters
  ShowWindow(hwnd, iCmdShow);
  UpdateWindow(hwnd);
  while (GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return (int)msg.wParam;
}
void render(void* ptr)
{
  while (!viewer->done())
  {
    viewer->frame();
  }
  renderok = true;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)
  {
  case WM_CREATE:
    root = new osg::Group;
    loadedModel = osgDB::readNodeFile("cessna.osg");
    if (!loadedModel)
      return 1;
    optimizer.optimize(loadedModel.get());
    optimizer.reset();
    root->addChild(loadedModel.get());
    traits = new osg::GraphicsContext::Traits;
    windata = new osgViewer::GraphicsWindowWin32::WindowData(hwnd);
    traits->x = 0;
    traits->y = 0;
    traits->width = 800;
    traits->height = 600;
    traits->windowDecoration = false;
    traits->doubleBuffer = true;
    traits->sharedContext = 0;
    traits->inheritedWindowData = windata;
    traits->setInheritedWindowPixelFormat = true;
    gc = osg::GraphicsContext::createGraphicsContext(traits.get());
    camera = new osg::Camera;
    camera->setGraphicsContext(gc);
    camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height));
    viewer = new osgViewer::Viewer;
    viewer->addSlave(camera.get());
    viewer->setSceneData(root.get());
    viewer->setCameraManipulator(new osgGA::TrackballManipulator);
    viewer->addEventHandler(new osgViewer::StatsHandler);
    viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
    viewer->realize();
    renderok = false;
    _beginthread(render, 0, NULL);
    return 0;
  case WM_PAINT:
    return 0;
  case WM_DESTROY:
    viewer->setDone(true);
    while (!renderok)
    {
      Sleep(10);
    }
    PostQuitMessage(0);
    return 0;
  }
  return DefWindowProc(hwnd, message, wParam, lParam);
}

运行:
OSG-Win32窗口显示osg_第1张图片

你可能感兴趣的:(C++)