• OpenGL的矩阵使用——绘制桌子


    其中最左边的桌子循环上移(即匀速上移到一定位置后回到原点继续匀速上移),中间的桌子不断旋转(即绕自身中间轴旋转),最右边的桌子循环缩小(即不断缩小到一定大小后回归原来大小继续缩小)。

    img

    桌子的模型尺寸如下:

    img


    操作方法和实验步骤

    绘制桌子

    根据题目要求,主要实现的是桌子的移动、旋转和缩放,因此首先需要绘制出桌子的形状。

    由于题目要求的桌子主要由五个立法体组成,分别是一个桌面和四个桌脚,而立方体又是由6个面组成的,因此通过绘制模式GL_QUAD绘制所有的面即可;如图:

    img

    一个立方体的大小和位置有中心点位置和长宽高决定(假设中点位置坐标为x、y、z),因此我们可以得到四个面、二十四个点的位置为:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    { x + width,y + depth,z },{ x + width,y - depth,z },{ x - width,y - depth,z },{ x - width,y + depth,z },

    { x - width,y + depth,z },{ x - width,y - depth,z },{ x - width,y - depth,z - height },{ x - width,y + depth,z - height },

    { x - width,y + depth,z - height },{ x - width,y - depth,z - height },{ x + width,y - depth,z - height },{ x + width,y + depth,z - height },

    { x + width,y + depth,z - height },{ x + width,y - depth,z - height },{ x + width,y - depth,z },{ x + width,y + depth,z },

    { x + width,y + depth,z },{ x - width,y + depth,z },{ x - width,y + depth,z - height },{ x + width,y + depth,z - height },

    { x + width,y - depth,z },{ x - width,y - depth,z },{ x - width,y - depth,z - height },{ x + width,y - depth,z - height }

    设置多边形的绘制模式为glPolygonMode(GL_FRONT_AND_BACK,GL_LINE),绘制出立方体来:

    1
    2
    3
    4
    glBegin(GL_QUADS);
    for (int i = 0; i < 24; i++)
    glVertex3f(point[i][0], point[i][1],point[i][2]);
    glEnd();

    最后把绘制立方体的过程封装成函数,传入中心点位置和长宽高即可绘制出桌子;


    桌子循环上移、旋转、缩小放大

    循环上移通过函数glTranslatefglRotateglScale完成桌子移动、旋转和缩放的操作;这几个函数的操作原理是将当前的栈顶矩阵乘以一个操作矩阵(移动、旋转、缩放),因此每次绘制前我们都需要通过glLoadIdentity()将当前的操作矩阵矩阵重置为单位矩阵;然在具体的移动或旋转或缩放操作时,将操作矩阵压进栈中,避免这三个操作相互影响;


    移动

    void glTranslatef(GLfloatx,GLfloat y,GLfloat z);

    函数功能: 沿X轴正方向平移x个单位

    ​ 沿Y轴正方向平移y个单位

    ​ 沿Z轴正方向平移z个单位

    img

    旋转

    void glRotatef(GLfloatangle,GLfloat x,GLfloat y,GLfloat z);

    函数功能:以点(0,0,0)到点(x,y,z)为轴,旋转angle角度;

    img

    根据题目要求,绕着y轴旋转,即用右手握住这条y轴向量,大拇指指向向量的正方向,四指环绕的方向就是旋转的方向;

    缩放

    void glScalef(GLfloat Sx, GLfloat Sy, GLfloat Sz);

    函数功能:Sx,Sy,Sz分别为模型在x,y,z轴方向的缩放比;

    img


    源代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119


    float fTranslate;
    float fRotate;
    float fScale = 1.0f;

    void (GLfloat x, GLfloat y , GLfloat z,GLfloat width_, GLfloat depth_, GLfloat height_) {
    GLfloat width = width_ * 0.5;
    GLfloat depth = depth_ * 大专栏  OpenGL的矩阵使用——绘制桌子pan class="number">0.5;
    GLfloat height = height_;

    GLfloat point[24][3] = {
    { x + width,y + depth,z },{ x + width,y - depth,z },{ x - width,y - depth,z },{ x - width,y + depth,z },
    { x - width,y + depth,z },{ x - width,y - depth,z },{ x - width,y - depth,z - height },{ x - width,y + depth,z - height },
    { x - width,y + depth,z - height },{ x - width,y - depth,z - height },{ x + width,y - depth,z - height },{ x + width,y + depth,z - height },
    { x + width,y + depth,z - height },{ x + width,y - depth,z - height },{ x + width,y - depth,z },{ x + width,y + depth,z },
    { x + width,y + depth,z },{ x - width,y + depth,z },{ x - width,y + depth,z - height },{ x + width,y + depth,z - height },
    { x + width,y - depth,z },{ x - width,y - depth,z },{ x - width,y - depth,z - height },{ x + width,y - depth,z - height }
    };

    glBegin(GL_QUADS);
    for (int i = 0; i < 24; i++)
    glVertex3f(point[i][0], point[i][1],point[i][2]);
    glEnd();
    }

    void Draw_Dest() // This function draws a triangle with RGB colors
    {
    Draw_Cube(0, 0, 0, 1, 0.8, 0.2); //桌面
    Draw_Cube(0.3, 0.2, -0.2, 0.2, 0.2, 0.6);//桌脚
    Draw_Cube(-0.3, 0.2, -0.2, 0.2, 0.2, 0.6);
    Draw_Cube(0.3, -0.2, -0.2, 0.2, 0.2, 0.6);
    Draw_Cube(-0.3, -0.2, -0.2, 0.2, 0.2, 0.6);
    }

    void reshape(int width, int height)
    {
    if (height==0) // Prevent A Divide By Zero By
    {
    height=1; // Making Height Equal One
    }

    glViewport(0,0,width,height); // Reset The Current Viewport

    glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
    glLoadIdentity(); // Reset The Projection Matrix

    // Calculate The Aspect Ratio Of The Window
    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

    glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
    glLoadIdentity(); // Reset The Modelview Matrix
    }

    void idle()
    {
    glutPostRedisplay();
    }

    void redraw()
    {

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity(); // Reset The Current Modelview Matrix

    glPushMatrix();
    glTranslatef(-2.0f, 0.0f,-6.0f); // Place the triangle Left
    glTranslatef(0.0f, fTranslate, 0.0f); // Translate in Y direction
    Draw_Dest(); // Draw desk
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.0f, 0.0f,-6.0f); // Place the dest at Center
    glRotatef(fRotate, 0, 3.0f, 0); // Rotate around Y axis
    Draw_Dest(); // Draw desk
    glPopMatrix();

    glPushMatrix();
    glTranslatef(2.0f, 0.0f, -6.0f); // Place the dest right
    glScalef(fScale, fScale, fScale); // Scale
    Draw_Dest(); // Draw Draw desk
    glPopMatrix();

    fScale -= 0.005f;
    fTranslate += 0.005f;
    fRotate += 0.3f;

    if (fTranslate > 0.5f) fTranslate = 0.0f;
    if (fScale < 0.5f) fScale = 1.0f;

    glutSwapBuffers();
    }

    void processNormalKeys(unsigned char key, int x, int y)
    {

    if (key == 27) //按ESC退出
    exit(0);
    }

    int main (int argc, char *argv[])
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutInitWindowSize(640,480);
    glutCreateWindow("Exercise2");

    glutDisplayFunc(redraw);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);

    glutKeyboardFunc(processNormalKeys);

    glutMainLoop();

    return 0;
    }


    效果

    img

  • 相关阅读:
    子类构造函数是否会默认调用父类的无参构造函数
    使用多线程
    进程和多线程的概念及线程的优点
    Java API文档
    InputStream
    【颗粒归仓】--Zookeeper基本概念
    【颗粒归仓】--Struts2
    【颗粒归仓】--spring IoC容器
    【颗粒归仓】--Java泛型
    【多线程】--线程同步
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12255935.html
Copyright © 2020-2023  润新知