程序员爱装B

写装A程序 做装C的事情

[搬家文] 第九课 动画-part 4

主程序

    md2文件操作完成。现在看main.cpp.

const float FLOOR_TEXTURE_SIZE = 15.0f//The size of each floor "tile"

    这是每个地板上方格的大小,也就是你在截图上看到的每层图像的copy.

float _angle = 30.0f;
MD2Model* _model;
int _textureId;
//The forward position of the guy relative to an arbitrary floor "tile"
float _guyPos = 0;

    这是一些存储摄像机角度的变量,MD2Model的物体,层纹理的id,和人物走的距离模上地板的大小。

void initRendering() {
    //...
    
    //Load the model
    _model = MD2Model::load("tallguy.md2");
    if (_model != NULL) {
        _model->setAnimation("run");
    }
    
    //Load the floor texture
    Image* image = loadBMP("vtr.bmp");
    _textureId = loadTexture(image);
    delete image;
}

    在我们initRendering函数中,我们加载模型和地板纹理。

void drawScene() {
    //...
    
    //Draw the guy
    if (_model != NULL) {
        glPushMatrix();
        glTranslatef(0.0f4.5f0.0f);
        glRotatef(-90.0f0.0f0.0f1.0f);
        glScalef(0.5f0.5f0.5f);
        _model->draw();
        glPopMatrix();
    }

    这里我们绘制人物。我们需要变换,旋转,伸缩以使得人物大小合适,在合适的位置并朝着正确的方向。我找出了令人头疼的合适的变换和伸缩系数。合适的数值决定于我在Blender中创建的模型时设置的真实顶点位置。

    //Draw the floor
    glTranslatef(0.0f, -5.4f0.0f);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, _textureId);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    glBegin(GL_QUADS);
    
    glNormal3f(0.0f1.0f0.0f);
    glTexCoord2f(2000 / FLOOR_TEXTURE_SIZE, _guyPos / FLOOR_TEXTURE_SIZE);
    glVertex3f(-1000.0f0.0f, -1000.0f);
    glTexCoord2f(2000 / FLOOR_TEXTURE_SIZE,
                 (2000 + _guyPos) / FLOOR_TEXTURE_SIZE);
    glVertex3f(-1000.0f0.0f1000.0f);
    glTexCoord2f(0.0f, (2000 + _guyPos) / FLOOR_TEXTURE_SIZE);
    glVertex3f(1000.0f0.0f1000.0f);
    glTexCoord2f(0.0f, _guyPos / FLOOR_TEXTURE_SIZE);
    glVertex3f(1000.0f0.0f, -1000.0f);
    
    glEnd();
    
    //...
}

    现在绘制地板。地板只是一个四处延伸到很远的四边形。为了使人物向前走,我们设置纹理坐标使得地板砖向合适的方向移动。

void update(int value) {
    _angle += 0.7f;
    if (_angle > 360) {
        _angle -= 360;
    }
    
    //Advance the animation
    if (_model != NULL) {
        _model->advance(0.025f);
    }
    
    //Update _guyPos
    _guyPos += 0.08f;
    while (_guyPos > FLOOR_TEXTURE_SIZE) {
        _guyPos -= FLOOR_TEXTURE_SIZE;
    }
    
    glutPostRedisplay();
    glutTimerFunc(25, update, 0);
}

    这是update函数。我们只增加镜头的角度和人物的位置,并调用MD2Model对象中的advance函数。我计算出_guyPos变量的增量。

    所有这些,可以让一个3D人物行走啦!

练习:

  • 改变MD2Model类中的advance函数,使得dt允许为负。然后通过动画后退和地板图片向前而不是向后滚动让人物向走行走。
  • 让draw只画出单独的帧,而不进行插值。人物的动作应该不连贯了。即使只有很少的帧,通过插值也会使动作看起来流畅和连贯。
  • 实现当用户按下空格键(key == ' '),人物禁止不动(不是镜头),然后用户再次按下空格,人物由开始移动。

posted on 2010-07-19 20:30 camel 阅读(114) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2024年9月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

统计

常用链接

留言簿

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜