Open Inventor练习-SoWinExaminerViewer的继承演示

Open Inventor遵循C++的语言机制,具有面向对象编程的性质,下面演示了SoWinExaminerViewer得继承,代码如下。

// TestCoin.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#define COIN_DLL    
#define SOWIN_DLL    
// 加载COIN库文件    
#ifdef _DEBUG    
#pragma comment(lib, "SoWin1d.lib")    
#pragma comment(lib, "Coin3d.lib")    
#else    
#pragma comment(lib, "SoWin1.lib")    
#pragma comment(lib, "Coin3.lib")    
#endif
#pragma comment(lib, "OpenGL32.lib")
// 添加COIN头文件-Window操作显示库和节点库
// This example shows how to put a permanent background image on your
// viewer canvas, below the 3D graphics, plus overlay foreground
// geometry.  Written by mortene.  Copyright Systems in Motion 2002.

// *************************************************************************

#include <Inventor/Win/SoWin.h>
#include <Inventor/Win/viewers/SoWinExaminerViewer.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoImage.h>
#include <Inventor/nodes/SoLightModel.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoRotationXYZ.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoTranslation.h>

#include <GL/gl.h>

// *************************************************************************

class MyExaminerViewer : public SoWinExaminerViewer
{
public:
	MyExaminerViewer(HWND parent, const char * filename);
	~MyExaminerViewer();

protected:
	virtual void actualRedraw(void);

private:
	SoSeparator * bckgroundroot;
	SoSeparator * foregroundroot;
	SoRotationXYZ * arrowrotation;
};

MyExaminerViewer::MyExaminerViewer(HWND parent, const char * filename)
: SoWinExaminerViewer(parent)
{
	// Coin should not clear the pixel-buffer, so the background image
	// is not removed.
	this->setClearBeforeRender(FALSE, TRUE);

	// Set up background scenegraph with image in it.

	this->bckgroundroot = new SoSeparator;
	this->bckgroundroot->ref();

	SoOrthographicCamera * cam = new SoOrthographicCamera;
	cam->position = SbVec3f(0, 0, 1);
	cam->height = 1;
	// SoImage will be at z==0.0.
	cam->nearDistance = 0.5;
	cam->farDistance = 1.5;

	SoImage * img = new SoImage;
	img->vertAlignment = SoImage::HALF;
	img->horAlignment = SoImage::CENTER;
	img->filename = filename;

	this->bckgroundroot->addChild(cam);
	this->bckgroundroot->addChild(img);

	// Set up foreground, overlayed scenegraph.

	this->foregroundroot = new SoSeparator;
	this->foregroundroot->ref();

	SoLightModel * lm = new SoLightModel;
	lm->model = SoLightModel::BASE_COLOR;

	SoBaseColor * bc = new SoBaseColor;
	bc->rgb = SbColor(1, 1, 0);

	cam = new SoOrthographicCamera;
	cam->position = SbVec3f(0, 0, 5);
	cam->height = 10;
	cam->nearDistance = 0;
	cam->farDistance = 10;

	const double ARROWSIZE = 2.0;

	SoTranslation * posit = new SoTranslation;
	posit->translation = SbVec3f(-2.5 * ARROWSIZE, 1.5 * ARROWSIZE, 0);

	arrowrotation = new SoRotationXYZ;
	arrowrotation->axis = SoRotationXYZ::Z;

	SoTranslation * offset = new SoTranslation;
	offset->translation = SbVec3f(ARROWSIZE/2.0, 0, 0);

	SoCube * cube = new SoCube;
	cube->width = ARROWSIZE;
	cube->height = ARROWSIZE/15.0;

	this->foregroundroot->addChild(cam);
	this->foregroundroot->addChild(lm);
	this->foregroundroot->addChild(bc);
	this->foregroundroot->addChild(posit);
	this->foregroundroot->addChild(arrowrotation);
	this->foregroundroot->addChild(offset);
	this->foregroundroot->addChild(cube);
}

MyExaminerViewer::~MyExaminerViewer()
{
	this->bckgroundroot->unref();
	this->foregroundroot->unref();
}

void MyExaminerViewer::actualRedraw(void)
{
	// Must set up the OpenGL viewport manually, as upon resize
	// operations, Coin won't set it up until the SoGLRenderAction is
	// applied again. And since we need to do glClear() before applying
	// the action..
	const SbViewportRegion vp = this->getViewportRegion();
	SbVec2s origin = vp.getViewportOriginPixels();
	SbVec2s size = vp.getViewportSizePixels();
	glViewport(origin[0], origin[1], size[0], size[1]);

	const SbColor col = this->getBackgroundColor();
	glClearColor(col[0], col[1], col[2], 0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Render our scenegraph with the image.
	SoGLRenderAction * glra = this->getGLRenderAction();
	glra->apply(this->bckgroundroot);

	// Render normal scenegraph.
	SoWinExaminerViewer::actualRedraw();

	// Increase arrow angle with 1/1000 ° every frame.
	arrowrotation->angle = arrowrotation->angle.getValue() + (0.001 / M_PI * 180);
	// Render overlay front scenegraph.
	glClear(GL_DEPTH_BUFFER_BIT);
	glra->apply(this->foregroundroot);
}

// *************************************************************************

int main(int argc, char ** argv)
{
	if (argc != 2) 
	{
		(void)fprintf(stderr, "\n\n\tUsage: %s <image-filename>\n\n", argv[0]);
		exit(1);
	}

	HWND window = SoWin::init(argv[0]);

	MyExaminerViewer * viewer = new MyExaminerViewer(window, argv[1]);

	viewer->setSceneGraph(new SoCone);
	viewer->show();

	SoWin::show(window);
	SoWin::mainLoop();

	delete viewer;
	return 0;
}

// *************************************************************************
MyExaminerViewer从SoWinExaminerViewer派生,添加了前视图和后视图独立控制的两个节点,构造函数传递进来背景绘制的文件名称,SoImage用来读取如片文件内容,作为背景显示节点,SoOrthographicCamera用来正交观察显示背景,达到背景大小不变的效果;前视图显示中有SoLightModel来控制灯光,是物体例外显示灯光效果较好,SoOrthographicCamera以更远的距离来观察实景物体,并添加一个变换后的立方体显示。

运行效果如下。

Open Inventor练习-SoWinExaminerViewer的继承演示_第1张图片Open Inventor练习-SoWinExaminerViewer的继承演示_第2张图片

你可能感兴趣的:(Open Inventor练习-SoWinExaminerViewer的继承演示)