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

桌子的模型尺寸如下:

操作方法和实验步骤

绘制桌子

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

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

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

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  1. { x + width,y + depth,z },{ x + width,y - depth,z },{ x - width,y - depth,z },{ x - width,y + depth,z },
  2.  
  3. { x - width,y + depth,z },{ x - width,y - depth,z },{ x - width,y - depth,z - height },{ x - width,y + depth,z - height },
  4.  
  5. { x - width,y + depth,z - height },{ x - width,y - depth,z - height },{ x + width,y - depth,z - height },{ x + width,y + depth,z - height },
  6.  
  7. { x + width,y + depth,z - height },{ x + width,y - depth,z - height },{ x + width,y - depth,z },{ x + width,y + depth,z },
  8.  
  9. { x + width,y + depth,z },{ x - width,y + depth,z },{ x - width,y + depth,z - height },{ x + width,y + depth,z - height },
  10.  
  11. { 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. 1
    2
    3
    4
  1. 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个单位

旋转

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

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

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

缩放

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

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

源代码

  1. 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
  1.  
  2. float fTranslate;
    float fRotate;
    float fScale = 1.0f;
  3.  
  4. 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_;
  5.  
  6. 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 }
    };
  7.  
  8. glBegin(GL_QUADS);
    for (int i = 0; i < 24; i++)
    glVertex3f(point[i][0], point[i][1],point[i][2]);
    glEnd();
    }
  9.  
  10. 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);
    }
  11.  
  12. void reshape(int width, int height)
    {
    if (height==0) // Prevent A Divide By Zero By
    {
    height=1; // Making Height Equal One
    }
  13.  
  14. glViewport(0,0,width,height); // Reset The Current Viewport
  15.  
  16. glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
    glLoadIdentity(); // Reset The Projection Matrix
  17.  
  18. // Calculate The Aspect Ratio Of The Window
    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
  19.  
  20. glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
    glLoadIdentity(); // Reset The Modelview Matrix
    }
  21.  
  22. void idle()
    {
    glutPostRedisplay();
    }
  23.  
  24. void redraw()
    {
  25.  
  26. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  27.  
  28. glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity(); // Reset The Current Modelview Matrix
  29.  
  30. 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();
  31.  
  32. 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();
  33.  
  34. glPushMatrix();
    glTranslatef(2.0f, 0.0f, -6.0f); // Place the dest right
    glScalef(fScale, fScale, fScale); // Scale
    Draw_Dest(); // Draw Draw desk
    glPopMatrix();
  35.  
  36. fScale -= 0.005f;
    fTranslate += 0.005f;
    fRotate += 0.3f;
  37.  
  38. if (fTranslate > 0.5f) fTranslate = 0.0f;
    if (fScale < 0.5f) fScale = 1.0f;
  39.  
  40. glutSwapBuffers();
    }
  41.  
  42. void processNormalKeys(unsigned char key, int x, int y)
    {
  43.  
  44. if (key == 27) //按ESC退出
    exit(0);
    }
  45.  
  46. int main (int argc, char *argv[])
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutInitWindowSize(640,480);
    glutCreateWindow("Exercise2");
  47.  
  48. glutDisplayFunc(redraw);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
  49.  
  50. glutKeyboardFunc(processNormalKeys);
  51.  
  52. glutMainLoop();
  53.  
  54. return 0;
    }

效果

OpenGL的矩阵使用——绘制桌子的更多相关文章

  1. Opengl中矩阵和perspective/ortho的相互转换

    Opengl中矩阵和perspective/ortho的相互转换 定义矩阵 Opengl变换需要用四维矩阵.我们来定义这样的矩阵. +BIT祝威+悄悄在此留下版了个权的信息说: 四维向量 首先,我们定 ...

  2. OpenGL投影矩阵

    概述 透视投影 正交投影 概述 计算机显示器是一个2D平面.OpenGL渲染的3D场景必须以2D图像方式投影到计算机屏幕上.GL_PROJECTION矩阵用于该投影变换.首先,它将所有定点数据从观察坐 ...

  3. OpenGL投影矩阵【转】

    OpenGL投影矩阵 概述 透视投影 正交投影 概述 计算机显示器是一个2D平面.OpenGL渲染的3D场景必须以2D图像方式投影到计算机屏幕上.GL_PROJECTION矩阵用于该投影变换.首先,它 ...

  4. Opengl ES之四边形绘制

    四边形的绘制在Opengl ES是很重要的一项技巧,比如做视频播放器时视频的渲染就需要使用到Opengl ES绘制四边形的相关知识.然而在Opengl ES却没有直接提供 绘制四边形的相关函数,那么如 ...

  5. OPENGL之矩阵

    前面的若干重要概念中描述了OPENGL中的几个重要变换,而矩阵是线性代数中的重要数学工具,它被用来对这些变换进行数学上的实现. 矩阵主要有以下几种: 模型视图矩阵:模型视图矩阵是个4*4的矩阵,代表经 ...

  6. openGL线s的绘制

    /** * 缓冲区工具类 */ public class BufferUtil { /** * 将浮点数组转换成字节缓冲区 */ public static ByteBuffer arr2ByteBu ...

  7. 3D Computer Grapihcs Using OpenGL - 16 使用DrawElementsInstanced绘制立方体

    我们使用15节学到的知识来绘制14节的立方体. 在第14节我们使用了两次glDrawElements实现了OpenGL实例化,发现这样仍然不太方便,如果需要绘制成千上万的立方体,就需要手写成千上万次的 ...

  8. IOS 中openGL使用教程2(openGL ES 入门篇 | 绘制一个多边形)

    在上一篇我们学习了如何搭建IOS下openGL的开发环境,接下来我们来学习如何绘制一个多边形. 在2.0之前,es的渲染采用的是固定管线,何为固定管线,就是一套固定的模板流程,局部坐标变换 -> ...

  9. ogre, dx, opengl坐标矩阵

    opengl 右手坐标系 列向量 左乘 列主序存储矩阵osg   右手坐标系 行向量 右乘 行主序存储矩阵d3d       左手坐标系 行向量 右乘 行主序存储矩阵ogre    右手坐标系 列向量 ...

随机推荐

  1. Spring和MyBatis的集成

    Spring和MyBatis的整合   1. Spring和各个框架的整合 Spring目前是JavaWeb开发中最终的框架,提供一站式服务,可以其他各个框架整合集成 Spring整合方案 1.1.  ...

  2. a标签的一些特殊使用

    <a href="tel:10086">10086</a> //点击后直接拨打10086  <a href="mailto:c1586@qq ...

  3. JS中的7种设计模式

    第九章Refactoring to OOP Patterns 重构为OOP模式 7种设计模式: 1,模版方法模式(template method) 2,策略模式(strategy) 3,状态模式(st ...

  4. [ZJOI2019]浙江省选(半平面交)

    一眼看上去就应该能用半平面交去做. 首先考虑怎么求可能得第1名的人:每个人的函数为直线,就是在所有人的半平面交中的上边界者即可获得第一名,这个可以单调队列求解. 再考虑如何求可能得第2名的人:满足2个 ...

  5. android课程表控件、悬浮窗、Todo应用、MVP框架、Kotlin完整项目源码

    Android精选源码 Android游戏2048 MVP Kotlin项目(RxJava+Rerotfit+OkHttp+Glide) Android基于自定义Span的富文本编辑器 android ...

  6. 4412开发板QtE系统下MT6620-wifi的测试

    基于iTOP4412系统烧写并启动之后,使用如下命令.wpa_passphrase XXX "YYY " >> /etc/wpa_supplicant.conf其中 X ...

  7. LGOJ3327 【SDOI2015】约数个数和

    又是一道卡常好题 坑掉我的 \(define \space int \space long \space long\) 感觉出题人并没有获得什么快乐-- Description link 题意概述: ...

  8. VB6实现Excel多工作簿数据合并

    以前的同事,工作需要,让我帮忙完成多个工作簿的汇总. 我就用最熟悉的VB6写了一个Form应用程序,这是因为我不知道她目前的系统和Office情况,如果太高大上了,她不会部署安装.索性就简单粗暴地来个 ...

  9. String截取字符串的指定字节长度

    /** TODO:截取字符串的指定字节长度 * @Author wenjing * @Date 11:02 2019/5/15 * @Param [str, bengin, end] * @retur ...

  10. 102)PHP,目录操作

    基本的操作: 创建目录: mkdir(目录地址,权限,是否递归创建=false); 注意第二个参数在windows系统下没有作用, 递归创建,就是多级目录,要是设计不存在目录,就自动创建 删除目录 R ...