// Leaf.cpp : Defines the entry point for the console application.
//
#include "stdAfx.h"
#define graphfile "t3.WRL" //读入的VRML文件名称
#define texturefile "bigLeaf1.JPG" //读入的纹理图像名称
int numOfCoord; //储存顶点坐标的个数
int numOfTexCoord; //存储纹理坐标个数
int numOfIndex; //储存索引信息个数
float (*tempCoord)[3];
int *tempIndex;
float (*tempTexCoord)[2];
//读取VRML文件中的场景数据
void readFile(const char *filename)
{
//创建读取外部文件
SoInput myGraphInput;
if (!myGraphInput.openFile(filename))
{
fprintf(stderr, "Cannot open file %s/n",filename);
exit(1);
}
SoVRMLGroup *myGraph = SoDB::readAllVRML(&myGraphInput);
if (myGraph == NULL)
{
fprintf(stderr, "Problem reading file/n");
exit(1);
}
myGraphInput.closeFile();
//读取VRML文件
//搜索并取出SoVRMLShape节点
myGraph->ref();
SoVRMLShape *Shape = new SoVRMLShape;
SoSearchAction search;
search.setType(SoVRMLShape::getClassTypeId());
search.setInterest(SoSearchAction::FIRST);
search.apply(myGraph);
if(search.getPath() == 0)
{
printf("error!/n");
exit(1);
}
else
{
printf("right/n");
Shape = (SoVRMLShape *)search.getPath()->getTail();
Shape->setOverride(TRUE);
}
//得到geometry的信息,其是指向SoVRMLIndexedFaceSet节点的指针的容器
SoVRMLIndexedFaceSet *indexedFaceSet = new SoVRMLIndexedFaceSet;
indexedFaceSet = (SoVRMLIndexedFaceSet *)Shape->geometry.getValue();
//得到其中的点的坐标信息并保存到全局变量数组
SoVRMLCoordinate *coordInate = new SoVRMLCoordinate;
coordInate = (SoVRMLCoordinate *)indexedFaceSet->coord.getValue();
numOfCoord = coordInate->point.getNum();
tempCoord=new float[numOfCoord][3];
for(int i=0; i<numOfCoord; i++)
{
for(int j=0; j<3; j++)
{
tempCoord[i][j] =coordInate->point[i][j];
// printf("%f ",);
}
}
//得到其中的点的坐标索引信息并保存到全局变量数组
numOfIndex = indexedFaceSet->coordIndex.getNum();
tempIndex = new int[numOfIndex];
for(int k=0; k<numOfIndex; k++)
{
tempIndex[k] = indexedFaceSet->coordIndex[k];
}
//得到其中的纹理的坐标信息并保存到全局变量数组
SoTextureCoordinate2 *textureCoord = new SoTextureCoordinate2;
textureCoord = (SoTextureCoordinate2 *)indexedFaceSet->texCoord.getValue();
numOfTexCoord = textureCoord->point.getNum();
tempTexCoord=new float[numOfTexCoord][2];
for(int n=0; n<numOfTexCoord; n++)
{
for(int p=0; p<2; p++)
{
tempTexCoord[n][p] = textureCoord->point[n][p];
}
}
}
//场景数据初始化
void drawFace(SoIndexedFaceSet *myIndexedFaceSet)
{
SoMFVec3f coordVec3f;
SoMFInt32 coordIndex;
SoMFVec2f textureCoordVec2f;
for(int j=0; j<numOfCoord; j++)
{
coordVec3f.set1Value(j,tempCoord[j]);
}
for(int k=0;k<numOfIndex;k++)
{
coordIndex.set1Value(k,tempIndex[k]);
}
for(int i=0; i<numOfTexCoord; i++)
{
textureCoordVec2f.set1Value(i,tempTexCoord[i]);
}
SoVertexProperty *myVertexProperty = new SoVertexProperty;
//设置顶点的坐标
myVertexProperty->vertex = coordVec3f;
//设定平面法失
myVertexProperty->normal.set1Value(0, SbVec3f(0, 1, 0));
//设置纹理坐标
myVertexProperty->texCoord = textureCoordVec2f;
//定义法失绑定方式
myVertexProperty->normalBinding = SoNormalBinding::OVERALL;
//定义面集
myIndexedFaceSet->coordIndex = coordIndex;
myIndexedFaceSet->vertexProperty.setValue(myVertexProperty);
}
//定时器传感器回调函数
static void timertra(void * data, SoSensor *)
{
static SbBool direction = FALSE;
SoIndexedFaceSet * myIndexedFaceSet = (SoIndexedFaceSet*) data;
SoMFVec3f coordVec3f;
SoMFInt32 coordIndex;
SoMFVec2f textureCoordVec2f;
//修改顶点坐标,实现波动效果
/*
if (!direction)
{
for(int i=0; i<numOfCoord; i++)
{
if((i%33)/2 == 0)
tempCoord[i][1] += 0.5;
else
tempCoord[i][1] -= 0.5;
coordVec3f.set1Value(i,tempCoord[i]);
//恢复到原来的点
if((i%33)/2 == 0)
tempCoord[i][1] -= 0.5;
else
tempCoord[i][1] += 0.5;
}
}
else
{
for(int i=0; i<numOfCoord; i++)
{
if((i%33)/2 == 0)
tempCoord[i][2] -= 5;
else
tempCoord[i][2] += 5;
coordVec3f.set1Value(i,tempCoord[i]);
//恢复到原来的点
if((i%33)/2 == 0)
tempCoord[i][2] += 5;
else
tempCoord[i][2] -= 5;
}
}
*/
for(int j=0; j<numOfCoord; j++)
coordVec3f.set1Value(j,tempCoord[j]);
for(int k=0; k<numOfIndex;k++)
{
coordIndex.set1Value(k,tempIndex[k]);
}
for(int i=0; i<numOfTexCoord; i++)
{
textureCoordVec2f.set1Value(i,tempTexCoord[i]);
}
direction = !direction;
SoVertexProperty *myVertexProperty = new SoVertexProperty;
//设置顶点的坐标
myVertexProperty->vertex = coordVec3f;
//设定平面法失
myVertexProperty->normal.set1Value(0, SbVec3f(0, 1, 0));
//设置纹理坐标
myVertexProperty->texCoord = textureCoordVec2f;
//定义法失绑定方式
myVertexProperty->normalBinding = SoNormalBinding::OVERALL;
//定义面集
myIndexedFaceSet->coordIndex = coordIndex;
myIndexedFaceSet->vertexProperty.setValue(myVertexProperty);
}
int
main(int argc, char ** argv)
{
HWND window = SoWin::init(argv[0]);
if (window==NULL) exit(1);
SoWinExaminerViewer * viewer = new SoWinExaminerViewer(window);
//旋转物体
SoRotation * myrotation = new SoRotation;
myrotation->rotation.setValue(1, 0, 0, 1.5707963f);
SoIndexedFaceSet * myIndexedFaceSet = new SoIndexedFaceSet;
readFile(graphfile);
drawFace(myIndexedFaceSet);
//设定要更新的数据
SoTimerSensor *timer = new SoTimerSensor(timertra,myIndexedFaceSet);
timer->setInterval(0.5);
timer->schedule();
SoSeparator *root = new SoSeparator;
root->ref();
root->addChild(myrotation);
//利用得到的信息构建自己的场景节点
SoTexture2 *backG = new SoTexture2;
root->addChild(backG);
backG->filename.setValue(texturefile);
root->addChild(myIndexedFaceSet);
viewer->setSceneGraph(root);
viewer->show();
viewer->setBackgroundColor(SbColor(0.92f, 0.92f, 0.92f));
SoWin::show(window);
SoWin::mainLoop();
delete viewer;
root->unref();
return 0;
}