随笔-38  评论-23  文章-0  trackbacks-0

所有的lesson 都将基于lesson_1中的头文件而写.

lesson_4的内容在lesson_3的基础上添加了部分内容而写成的.这课当中,将会使用到模型变换的旋转变换.
前几次,曾使用了glTranslatef(d)来移动模型.这次将使用glRotatef 来旋转模型.而为了看到一个动画的效果,将注册一个空闲回调函数,使得角度不断自增.

#include "openglglut.h"

/*
** opengl 教程第四课内容
** 在窗口的左边部分绘制一个多彩的三角形,它将使用平滑着色
** 在窗口的右边部分绘制一个蓝色的正方形,它将使用单调着色
** 使得左边的三角形绕Y轴不停旋转
** 使得右边的正方形绕x轴不停旋转
*/

double yRot=0.0;    //三角形绕y轴旋转的角度
double xRot=0.0;    //三角形绕x轴旋转的角度
int main(int argc, char** argv)
{
    
/** 初始化窗口 并创建窗口*/
    createWindow(
"opengl lesson_4",&argc,argv);

    
/** 注册glut的一些函数 */
    glutReshapeFunc(glutResize);     
//窗口调整函数 使得调整后图形显示不发生改变
    glutIdleFunc(glutIdle);          //空闲回调函数 使得在空闲时间内进行一些操作
    glutDisplayFunc(glutDisplay);    //重绘函数     使得可以在窗口中绘制图形
    glutSpecialFunc(glutSpecial);    //特殊按键函数 使得实现全屏/窗口切换
    /** 初始化opengl的一些操作*/
    InitOpenGL();

    
/** 进入仿真循环*/
    glutMainLoop();
}

/** 实现头文件当中定义的绘制函数 绘制三角形和正方形 **/
void glutDisplay(void)
{
    glClear(GL_COLOR_BUFFER_BIT 
| GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();                   
//将先初始化单位矩阵
    glPushMatrix();                     //将当前矩阵复制一个压入栈顶,并保持当前矩阵不变
    
    glTranslatef(
-1.5,0.0,-6.0);
    glRotatef(yRot,
0.0,1.0,0.0);        //使得三角形绕y轴旋转yRot角度

    
//决定三角形三个顶点的颜色值,三角形内部各个点的颜色将会是线性插值的
    glBegin(GL_TRIANGLES);             // 绘制三角形
        glColor3f(1.0f,0.0f,0.0f);     //使用红色绘制上顶点
        glVertex3f( 0.0f1.0f0.0f); //上顶点
        glColor3f(0.0f,1.0f,0.0f);     //使用绿色绘制左下顶点
        glVertex3f(-1.0f,-1.0f0.0f); //左下
        glColor3f(0.0f,0.0f,1.0f);     //使用蓝色绘制右下顶点
        glVertex3f( 1.0f,-1.0f0.0f); //右下
    glEnd();
    glPopMatrix();                     
//恢复当前矩阵为上一次push时的矩阵

    glTranslatef(
1.5f,0.0f,-6.0f);
    glRotatef(xRot,
1.0,0.0,0.0);       //使得正方形绕x轴旋转xRot角度
    glColor3f(0.0f,0.0f,1.0f);         //将当前颜色值设置为蓝色 绘制整个正方形
    glBegin(GL_QUADS);                 // 绘制正方形
        glVertex3f(-1.0f1.0f0.0f); // 左上
        glVertex3f( 1.0f1.0f0.0f); // 右上
        glVertex3f( 1.0f,-1.0f0.0f); // 左下
        glVertex3f(-1.0f,-1.0f0.0f); // 右下
    glEnd();

    glutSwapBuffers();                 
//强制绘图命令执行绘制在缓冲区交换出来
}

/** 实现头文件当中声明的空闲回调函数*/
void glutIdle(void)
{
    yRot
+=0.2f;              //增加三角形旋转角度
    xRot-=0.15f;              //减少正方形减少角度
    glutPostRedisplay();    //使得执行完该函数后调用重绘函数
}

最终的结果是:


末尾总结:
glRotatef(angle,x,y,z) 将为使得模型绕任意轴旋转angle角度.它将会产生一个旋转矩阵右乘当前矩阵.所以改变了当前矩阵.而为了使得绘制的时候左边的三角形不影响到右边正方形的变换矩阵故在绘制三角形之前使用glPushMatrix()保存当前矩阵,绘制完成之后使用glPopMatrix() 恢复之前的矩阵.当然也可以使用glLoadIdentity()设置当前矩阵为单位矩阵的方法来实现它..

其次,这次多了以个glIdleFunc() 注册空闲回调函数.即在系统没有其他事件处理的时候将处理这个函数,使得旋转的角度不断改变.

glPostRedisplay() 使得当前窗口将会进行重绘..根据角度的改变,从而使得我们看到的是一个旋转当中的动画效果

最后将说明一点的是:我曾在红宝书看到一段内容:有时候为了实现连续的旋转,我们可能会想到重复应用一个值很小的旋转矩阵,这个会存在一个问题.就是误差,使得变换累积结果.我们应该摒弃这种做法.即使用一个新的角度来变换.就将使用如下的方法:
glLoadIdentity();
glRotatef(new_angle,x,y,z);

只要new_angle=old_angle+offset
posted on 2009-07-17 16:33 米游 阅读(571) 评论(0)  编辑 收藏 引用 所属分类: OpenGL/OSG

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