openGL读取bvh

整理下最近的看的,查的,并且自己动手实践后的一些思路吧,也方便以后整理。

程序是win32控制台程序,软件VS2010.。

一开始读取bvh文件:用的是fscanf()这个函数,可以每隔一个空格或换行读出数据来,非常方便赋值。

对于Node节点的结构,有几个要说一下:

offset:就是设置的offset[3];

channel部分:太懒了,直接设置的char channel[6][20];其实也没怎么用到,因为我在用的时候,直接固定顺序进行计算了。channel[6/3]根据文件读取的channel_cnt来迭代添加 Xposition Yposition Zposition Zrotation Xrotation Yrotation 或者 Zrotation Xrotation Yrotation。为以后判断旋转做铺垫吧.....;

节点的父亲:在读取文件之前,设个保存parent的vector,Node中对于父亲节点保存的是他在总体vNodes(vector类型)中的位置,这样可以在读取新节点时候读取父节点vector最后一个为parent赋值,同时注意每遇到‘}’就要pop出一个parent;

节点的孩子:std::vector childNodes;用的是vector,因为方便push_back(),也方便后面计算个数size();并且便于利用。直接保存的是他在总体vNodes(vector类型)中的位置,同parent一样。每保存一个父亲就保存一个孩子。这里我用的方法比较笨,因为保存parent的NodeVector1和当前所有结点的NodeVector2无关,所以每次要在NodeVector2找一遍才能添加,而且为此我还设置了一个int self来保存当前在NodeVector2的位置;

motion数据部分:对于每个Node我用float *frame动态添加。在读取文件时候动态 malloc( frame_size * sizeof(float));每个Node的frame的frame_size= frame_cnt * Node.channel_num。这里我读取的时候犯了个大错,在迭代为每个节点的frame赋值时候,忘记了读取下一帧时候要计算下写入frame[]的位置:cur_position = 此帧数*每帧读取的个数(=channel个数),否则就会导致后面的帧叠加到第0帧,其他帧会显示错误。

draw阶段:就是从root开始,由父到子迭代着translate和rotate,endsite是递归的返回点。我是边计算边画的,所以画的时候,为了不破坏当前的矩阵,就先push,glloadIdentity()//复位到世界坐标下的中心,画线,再pop回刚才的矩阵。

动态显示每一帧这里:用到了glutTimerFunc(250,timer,0);相当于定时器。开始读出第一帧显示。为mouse添加动作,如果右键则glutTimerFunc(200,timer,0); 

在time()函数中:递增要显示的帧数 frame_num = (frame_num+1)%(mym->frame_cnt);,并且,glutPostRedisplay();//刷新当前窗口,再继续glutTimerFunc(250,timer,0);。这样就可以点击右键后,看动态效果了。

还有两个问题没解决:

1.视口、投影变换那里,初始化没设置好。动着动着就没了--;

2.我节点和节点之间用椭圆画的,不知道是不是因为没调光照什么的原因,画出来的人物模型就像是扁片。。囧。。没有3d的感觉,等会要试着调整下。。

ps:

对于1的解决:

gluPerspective(125, aspect, 0.1, 100);修改为gluPerspective(125, aspect, 0.1, 100);

即: 主要修改了gluPerspective的最后一个参数,zfar是指定观察者到视景体的最远的裁剪面的距离(必须为正数)的,所以把它调大就可以显示完全每一帧的动作了。   

  这里参考百度gluPerspective():http://baike.baidu.com/view/1284926.htm 看来就明白了;

另外,对于程序中另一个显示问题:每次draw当前帧时候,总要先glTranslatef(0,-20,-50); 。我觉得肯定可以通过init()初始化时候,调整gluLookAt()代替的。并且应该是相反的。可是每次调整都没有反应。后来修改了gluLookAt()在程序的位置,马上见效了。修改如下:

原来的顺序:glViewport()、gluLookAt()、gluPerspective()、glMatrixMode(GL_MODELVIEW);  改正后的顺序:glViewport()、gluPerspective()、gluLookAt()、glMatrixMode(GL_MODELVIEW);     视图变换放在了模型变换前面,投影变换后面,就可以了。这个顺序排列我还得再查查,知识还是掌握的太少了,可能这个错误也比较低级了。。。对此,查了下gluLookAt()百度百科,解释的很到位了:“gluLookAt可以在投影变换之后或模型变换后调用。因为投影变换是设置视景体的大小和形状,gluLookAt即设置视景体在世界坐标的位置和方向来观察物体,所以只要gluLookAt在视景体设置完成后调用即可,与变换模式无关。”但是我试着放在模型变化后面不行。那应该就只能上面那个顺序了吧。。。

你可能感兴趣的:(OpenGL)