基于Win32项目的OSG程序开发框架(VS2013)

开发OSG桌面程序,有很多种框架,最常用的有OSG自身的窗口系统,以及MFC、Win32,还有基于Qt图形视图等。严格意义上讲,MFC与Win32属于同一类,都是基于Windows的SDK程序,但是由于MFC框架的繁琐机制,并且结构复杂,因此本文以win32程序为例,建立最简单的OSG程序开发框架,进行说明。

第一步:建立一个Win32的空工程,然后添加一个源文件;
第二步:win32程序主要有两部分,一个是WinMain()函数,另一个是消息循环函数WndProc();

第三步:OSG图形渲染部分在WndProc()消息循环中完成。
第四步:设置包含路径,和库文件路径;

第五步:编译运行。

完整代码如下:
#include <Windows.h>
#include <process.h>
#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>
#include <osgViewer/api/Win32/GraphicsWindowWin32>
#include <osgDB/ReadFile>

#ifdef _DEBUG
#pragma comment(lib,"OpenThreadsd.lib")
#pragma comment(lib,"osgd.lib")
#pragma comment(lib,"osgDBd.lib")
#pragma comment(lib,"osgFXd.lib")
#pragma comment(lib,"osgGAd.lib")
#pragma comment(lib,"osgManipulatord.lib")
#pragma comment(lib,"osgParticled.lib")
#pragma comment(lib,"osgShadowd.lib")
#pragma comment(lib,"osgSimd.lib")
#pragma comment(lib,"osgTerraind.lib")
#pragma comment(lib,"osgTextd.lib")
#pragma comment(lib,"osgUtild.lib")
#pragma comment(lib,"osgViewerd.lib")
#else
#pragma comment(lib,"OpenThreads.lib")
#pragma comment(lib,"osg.lib")
#pragma comment(lib,"osgDB.lib")
#pragma comment(lib,"osgFX.lib")
#pragma comment(lib,"osgGA.lib")
#pragma comment(lib,"osgManipulator.lib")
#pragma comment(lib,"osgParticle.lib")
#pragma comment(lib,"osgShadow.lib")
#pragma comment(lib,"osgSim.lib")
#pragma comment(lib,"osgTerrain.lib")
#pragma comment(lib,"osgText.lib")
#pragma comment(lib,"osgUtil.lib")
#pragma comment(lib,"osgViewer.lib")
#endif
//全局变量
osg::ref_ptr<osgViewer::Viewer> g_viewer;
bool g_finished;
//渲染函数,有进程调用
void render(void*)
{
	while (!g_viewer->done())
	{
		g_viewer->frame();
	}
	g_finished = true;
}
//消息循环函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_CREATE:	
	{
		osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(hwnd);
		//设置窗口属性
		osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
		traits->x = 0;
		traits->y = 0;
		traits->width = 800;
		traits->height = 600;
		traits->windowDecoration = false;
		traits->doubleBuffer = true;
		traits->inheritedWindowData = windata;
		//或许上下文
		osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
		osg::ref_ptr<osg::Camera> camera = new osg::Camera;
		camera->setGraphicsContext(gc);
		camera->setViewport(new osg::Viewport(0, 0, 800, 600));
		//定义场景并加载数据
		g_viewer = new osgViewer::Viewer;
		g_viewer->addSlave(camera.get());
		//g_viewer->setSceneData(osgDB::readNodeFile("cessna.osg"));
		g_viewer->setSceneData(osgDB::readNodeFile("mymap.earth"));
		g_viewer->setCameraManipulator(new osgGA::TrackballManipulator);
		g_viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
		g_finished = false;
		_beginthread(render, 0, NULL);
		return 0;
	}
		break;
	case WM_DESTROY:
	{
		g_viewer->setDone(true);
		while (!g_finished)
		{
			Sleep(10);
		}
		PostQuitMessage(0);
		return 0;
	}
		break;
	default:
		break;
	}
	//返回Windows的默认消息处理函数
	return DefWindowProc(hwnd, message, wParam, lParam);
}
//Windows程序的入口函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[] = TEXT("gui");
	//定义窗口类
	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))
	{
		return 0;
	}
	//创建窗口
	HWND hwnd = CreateWindow(
		szAppName,
		TEXT("OSG WIN32"),
		WS_OVERLAPPEDWINDOW,
		100, 100,
		800, 600,
		NULL,
		NULL,
		hInstance,
		NULL);
	//显示窗口
	ShowWindow(hwnd, iCmdShow);
	//更新窗口
	UpdateWindow(hwnd);
	//消息循环
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);

	}
	return (int)msg.wParam;
}

运行结果如下:

本程序设计到osgEarth的知识,其中mymap.earth文件内容如下:
<map name="MyMap" type="geocentric" version="2">
<image name="bluemarble" driver="gdal">
<url>world.tif</url>
</image>
</map>

其中世界地图影像地图“world.tif”可以在NASA官网上下载。
参考文献:王锐,钱学雷.OpenSceneGraph三位渲染引擎设计与实现.清华大学出版社,2009.

猜你喜欢

转载自blog.csdn.net/u013232740/article/details/80343903
今日推荐