opengl绘制桌子(平移、旋转、缩放)

来源:互联网 发布:数据可视化工具 编辑:程序博客网 时间:2024/05/05 10:44

主要仪器设备

VisualStudio C++2015

Windows10环境

Glut压缩包

Ex2工程

操作方法和实验步骤

1.绘制立方体

桌子由立方体组成,我们可以通过绘制六个面来构造一个立方体。六个面的绘制需要八个顶点的参数,而每个顶点均有x,y,z三个参数,如果全部传入的话参数的个数会达到8*3=24个。而我们只需要知道2个x,2个y以及2个z即可构造八个顶点。如图所示,它们的坐标分别是(x1,y1,z2), (x2,y1,z2), (x1,y2,z2), (x2,y2,z2), (x1,y1,z1),(x2,y1,z1), (x1,y2,z1), (x2,y2,z1)。每个面使用QL_QUADS方式绘制所使用的顶点是(v1,v2,v4,v3),(v5,v6,v8,v7), (v3,v4,v8,v7), (v1,v2,v6,v5), (v1,v3,v7,v5), (v2,v4,v8,,v6)。

2.绘制桌子

之前已经完成了绘制立方体的函数,现在只需要把桌子拆分成5个立方体进行绘制就可以了。计算需要传入的参数,使用Draw_Cube函数进行绘制。

3.模型变换——平移、旋转、缩放

这部分功能的实现通过重绘时调用函数redraw实现。根据要求使用glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);来确定显示模式为使用线段显示物体所有面。在模型进行平移、旋转、缩放时用到的函数分别是glTranslatef,glRotatef以及glScalef函数。这三个函数中分别利用了三个因子fTranslate,fRotate以及fScale。他们控制了平移的方向,旋转轴以及缩放尺寸等等。

代码如下:

// main.cpp : 定义控制台应用程序的入口点。#include "glut.h"float fTranslate;//平移因子float fRotate;//旋转因子float fScale=1.0f;//缩放因子void Draw_Cube(GLfloat x1, GLfloat x2, GLfloat y1,GLfloat y2,GLfloat z1,GLfloat z2){//桌子由立方体组成,已知六个参数即可构造八个顶点int i, j;GLfloat vertex[8][3] = {//八个顶点,从v1-v8x1,y1,z2,x2,y1,z2,x1,y2,z2,x2,y2,z2,x1,y1,z1,x2,y1,z1,x1,y2,z1,x2,y2,z1};GLint surface[6][4] = {//v1对应0,以此类推0,1,3,2,4,5,7,6,2,3,7,6,0,1,5,4,0,2,6,4,1,3,7,5};glBegin(GL_QUADS);//指定绘制方式//将每个立方体分成六个面绘制for (i = 0; i < 6; i++)for (j = 0; j < 4; j++)glVertex3fv(vertex[surface[i][j]]);glEnd();}void Draw_Table(){//将桌子拆分成5个立方体绘制Draw_Cube(0.0, 1.0, 0.0, 0.8, 0.6, 0.8);//桌面Draw_Cube(0.1, 0.3, 0.1, 0.3, 0.0, 0.6);//四条腿Draw_Cube(0.7, 0.9, 0.1, 0.3, 0.0, 0.6);Draw_Cube(0.1, 0.3, 0.5, 0.7, 0.0, 0.6);Draw_Cube(0.7, 0.9, 0.5, 0.7, 0.0, 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 ViewportglMatrixMode(GL_PROJECTION);// Select The Projection MatrixglLoadIdentity();// Reset The Projection Matrix// Calculate The Aspect Ratio Of The WindowgluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);glMatrixMode(GL_MODELVIEW);// Select The Modelview MatrixglLoadIdentity();// Reset The Modelview Matrix}void idle(){glutPostRedisplay();}void redraw(){//display in wireframe modeglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);glClear(GL_COLOR_BUFFER_BIT);//清除窗口glLoadIdentity();// Reset The Current Modelview Matrix//模型变换——移动glPushMatrix();//glpushmatrix与glpopmatrix配合使用可以消除上一次变换对本次变换的影响glTranslatef(-2.5f, 0.0f,-6.0f);//放在左边glTranslatef(0.0f, fTranslate, 0.0f);Draw_Table();glPopMatrix();//模型变换——旋转glPushMatrix();glTranslatef(0.0f, 0.0f,-6.0f);//放在中间glRotatef(fRotate, 0, 1.0f, 0);// Rotate around Y axisDraw_Table();// Draw triangleglPopMatrix();//模型变换——缩放glPushMatrix();glTranslatef(2.0f, 0.0f, -6.0f);glScalef(fScale, fScale,fScale);Draw_Table();glPopMatrix();//更新因子fTranslate += 0.005f;fRotate += 0.5f;fScale -= 0.005f;if(fTranslate > 0.5f)fTranslate = 0.0f;if (fScale < 0.5f)//缩小到一定程度之后变回原来大小fScale = 1.0f;glutSwapBuffers();}int main (int argc,  char *argv[]){glutInit(&argc, argv);//对glut函数库进行初始化glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);//指定glutCreateWindow函数将要创建的窗口显示模式 RGB 双缓冲glutInitWindowSize(640,480);//窗口大小                                         glutCreateWindow("Exercise2");//打开设置好的窗口,进入glutMainLoop之前这个窗口不会显示glutDisplayFunc(redraw);//指定当前窗口需要重绘时调用的函数glutReshapeFunc(reshape);//注册窗口大小改变时回调函数glutIdleFunc(idle);//可以执行连续动画glutMainLoop();//进入glut事件处理循环,永远不会返回return 0;}


实验结果

其中左边的桌子向上平移到一定的位置回到原位置继续重复动作,中间的桌子绕y轴旋转,右边的桌子逐渐缩小到一定程度回到原大小继续重复动作。



如有错误,请批评指正(*/ω╲*)

0 0