SoEventCallback是Open Inventor用来管理事件的,SoKeyboardEvent是键盘事件,SO_KEY_PRESS_EVENT宏可以获得是键盘上哪个键被操作了,SoSwitch是一个节点切换开关节点,这里用来管理颜色信息。
代码如下
// 预定义COIN宏
#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
// 添加COIN头文件-Window操作显示库和节点库
#include <Inventor/Win/SoWin.h>
#include <Inventor/Win/viewers/SoWinExaminerViewer.h>
#include <Inventor/events/SoKeyboardEvent.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoEventCallback.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSwitch.h>
void changeColor(const char* color)
{
SoSeparator *r;
SoNode *n;
SoSwitch *s;
if (!(r = (SoSeparator *)SoNode::getByName(color)))
{
fprintf(stderr, "Error: Couldn't find separator for %s light.\n", color);
return;
}
n = r->getChild(0);
if (n->getTypeId() == SoSwitch::getClassTypeId())
{
s = (SoSwitch*) n;
}
else
{
fprintf(stderr, "Error: SoSwitch node expected.\n");
return;
}
s->whichChild.setValue(s->whichChild.getValue() ? 0 : 1);
return;
}
void keyCB(void *userData, SoEventCallback *eventCB)
{
const SoEvent *event = eventCB->getEvent();
if (SO_KEY_PRESS_EVENT(event, R))
{
changeColor("red");
eventCB->setHandled();
}
if (SO_KEY_PRESS_EVENT(event, Y))
{
changeColor("yellow");
eventCB->setHandled();
}
if (SO_KEY_PRESS_EVENT(event, G))
{
changeColor("green");
eventCB->setHandled();
}
}
SoSeparator *readSGFromFile (const char* filename)
{
SoInput in;
if (!in.openFile(filename))
{
fprintf(stderr, "Could not open file %s\n", filename);
return NULL;
}
SoSeparator *sg = SoDB::readAll(&in);
if (!sg)
{
fprintf(stderr, "Error reading file. \n");
return NULL;
}
in.closeFile();
return sg;
}
int main (int argc, char** argv)
{
HWND win = SoWin::init(argv[0]);
if (win == NULL) exit(1);
SoSeparator* root = new SoSeparator;
root->ref();
SoEventCallback *e = new SoEventCallback;
e->addEventCallback(SoKeyboardEvent::getClassTypeId(), keyCB, root);
root->addChild(e);
root->addChild(readSGFromFile("trafficlight.iv"));
SoWinExaminerViewer* x = new SoWinExaminerViewer(win);
x->setSceneGraph(root);
x->setViewing(FALSE);
x->setTitle("traffic light example");
x->show();
SoWin::show(win);
SoWin::mainLoop();
return 0;
}
iv文件如下
#Inventor V2.1 ascii
Separator {
DEF red Separator {
Switch {
whichChild 0
Material {
diffuseColor 1 0 0
}
Material {
diffuseColor 0.3 0.3 0.3
}
}
DEF s Sphere {
radius 0.12
}
}
DEF yellow Separator {
Switch {
whichChild 1
Material {
diffuseColor 1 1 0
}
Material {
diffuseColor 0.3 0.3 0.3
}
}
Transform {
translation 0 -0.25 0
}
USE s
}
DEF green Separator {
Switch {
whichChild 1
Material {
diffuseColor 0 1 0
}
Material {
diffuseColor 0.3 0.3 0.3
}
}
Transform {
translation 0 -0.5 0
}
USE s
}
Transform {
translation 0 -0.25 -0.1
}
Material {
diffuseColor 0.2 0.2 0.2
}
Cube {
width 0.3
height 0.8
depth 0.3
}
}
运行结果如下