[OpenGL] 桌子的平移、旋转和缩放
来源:互联网 发布:南京电大试卷数据库 编辑:程序博客网 时间:2024/04/27 19:53
1)绘制立方体
考虑分别绘制六个面,先把每个正方形的坐标点存储在数组中,然后再利用循环完成绘制。(这样的绘制模式使一条边被绘制了两次,有一些优化的方法,为了逻辑更清晰没有进行优化)
在三维笛卡尔坐标系中,一个立方体可由三个顶点坐标唯一确定,一共是9个值。考虑到这里的立方体每条边都是与坐标轴平行的,简化后只需传入6个值。
由此,很容易计算出六个面的四点坐标值:
{ { x1,y1,z1 },{ x2,y1,z1 },{ x2,y2,z1 },{ x1,y2,z1 } },
{ { x1,y1,z1 },{ x2,y1,z1 },{ x2,y1,z2 },{ x1,y1,z2 } },
{ { x2,y1,z1 },{ x2,y2,z1 },{ x2,y2,z2 },{ x2,y1,z2 } },
{ { x1,y1,z1 },{ x1,y2,z1 },{ x1,y2,z2 },{ x1,y1,z2 } },
{ { x1,y2,z1 },{ x2,y2,z1 },{ x2,y2,z2 },{ x1,y2,z2 } },
{ { x1,y1,z2 },{ x2,y1,z2 },{ x2,y2,z2 },{ x1,y2,z2 } };
绘制时,先设置多边形模式为正反面、线型,调用如下函数绘制多个四边形:
2)绘制桌子
调用已有立方体函数,通过传入具体位置来绘制桌子,由于会多次调用,将其封装成一个函数。
3)平移,旋转,缩放
完成基本的平移旋转缩放操作需要调glTranslatef,glRotatef,glScalef三个函数,更准确的来说,它们完成的不是平移旋转缩放操作,而是在当前操作矩阵上乘以一个平移,旋转或缩放矩阵。所以在绘制时,我们需要先设置当前矩阵的模式为模型矩阵,并且将矩阵初始化为单位矩阵。
并且,在完成特定操作(如平移)时,我们将所有的操作矩阵放到堆栈时,完成后再抛出,这样可以保证不同操作之间相互不影响。
同时需要注意到相乘顺序与实际情况是相反的:
为了完成屏幕的时刻刷新,需要注册空闲时调用的回调函数,在这个回调函数中调用自己的绘图函数,每执行完一次绘图函数刷新一下平移/旋转/缩放因子,达到动画效果。
平移矩阵:
glTranslatef(GLfloat z, GLfloaty, GLfloat z);传入的参数是在x,y,z方向上平移的长度。
1 0 0 0
[ x y z1 ] [ 0 1 0 0 ]
0 0 1 0
dx dy dz 1
旋转矩阵:
glRotatef(GLfloat theta, GLfloatx, GLfloat y, GLfloat z);传入参数是旋转角度,坐标轴。需要注意的是,旋转轴是过原点的,需要先把物体移到原点,旋转,再挪回来。
cosa 0 -sina 0
[ x y z 1 ] [ 0 1 0 0 ]
sina 0 cosa 0
0 0 0 1
(绕y轴旋转)
缩放矩阵:
glScalef(GLfloat x, GLfloat y, GLfloatz);传入参数是不同坐标轴方向缩放程度,同理,要先把物体移到原点,再缩放,最后移到原位。
Sx 0 0 0
[ x y z 1 ] [ 0 Sy 0 0 ]
0 0 Sz 0
0 0 0 1
/*author:fish1996date:2016/03/24*/#define GLUT_DISABLE_ATEXIT_HACK #include "gl/glut.h"float fTranslate; //平移因子float fRotate; //旋转因子float fScale = 1.0f; //缩放因子//绘制正方体,它是由直线x = x1, x = x2, y = y1, y = y2, z = z1, z = z2 划分出的空间void drawCube(GLfloat x1, GLfloat x2, GLfloat y1, GLfloat y2, GLfloat z1, GLfloat z2){int i, j;//指定六个面的四个顶点,每个顶点用3个坐标值表示GLfloat point[6][4][3] = {{ { x1,y1,z1 },{ x2,y1,z1 },{ x2,y2,z1 },{ x1,y2,z1 } },{ { x1,y1,z1 },{ x2,y1,z1 },{ x2,y1,z2 },{ x1,y1,z2 } },{ { x2,y1,z1 },{ x2,y2,z1 },{ x2,y2,z2 },{ x2,y1,z2 } },{ { x1,y1,z1 },{ x1,y2,z1 },{ x1,y2,z2 },{ x1,y1,z2 } },{ { x1,y2,z1 },{ x2,y2,z1 },{ x2,y2,z2 },{ x1,y2,z2 } },{ { x1,y1,z2 },{ x2,y1,z2 },{ x2,y2,z2 },{ x1,y2,z2 } }};//设置正方形绘制模式glBegin(GL_QUADS);for (i = 0; i < 6; i++) {for (j = 0; j < 4; j++) {glVertex3fv(point[i][j]);}}glEnd();}//绘制桌子void drawTable(){drawCube(0.0, 1.0, 0.0, 0.8, 0.6, 0.8);//桌面drawCube(0.1, 0.3, 0.1, 0.3, 0.0, 0.6); //四条腿drawCube(0.7, 0.9, 0.1, 0.3, 0.0, 0.6);drawCube(0.1, 0.3, 0.5, 0.7, 0.0, 0.6);drawCube(0.7, 0.9, 0.5, 0.7, 0.0, 0.6);}void reshape(int width, int height){if (height == 0){height = 1; //高度为0时,让高度为1}glViewport(0, 0, width, height);//设置视窗大小glMatrixMode(GL_PROJECTION);//设置矩阵模式为投影glLoadIdentity();//初始化矩阵为单位矩阵gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);//设置投影方位glMatrixMode(GL_MODELVIEW); //设置矩阵模式为模型glLoadIdentity();//初始化矩阵为单位矩阵}void idle(){glutPostRedisplay();//调用当前绘制函数}void redraw(){glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//设置多边形绘制模式:正反面,线型glClear(GL_COLOR_BUFFER_BIT);//清除颜色缓冲glLoadIdentity();//初始化矩阵为单位矩阵glPushMatrix(); //压入矩阵堆栈glTranslatef(-2.0f, 0.0f, -6.0f); //图形向左平移,同时向里平移glTranslatef(0.0f, fTranslate, 0.0f);//y轴方向上平移drawTable();//画桌子glPopMatrix();//抛出矩阵堆栈glPushMatrix();//压入矩阵堆栈glTranslatef(0.5f, 0.0f, -6.0f); //旋转前向右平移,改变坐标轴,同时向里平移glRotatef(fRotate, 0, 1.0f, 0); //以y轴为坐标轴旋转glTranslatef(-0.5f, 0.0f, 0.0f); //旋转后向左平移,恢复位置drawTable();//画桌子glPopMatrix();//抛出矩阵堆栈glPushMatrix();//压入矩阵堆栈glTranslatef(2.0f, 0.4f, -6.0f); //图形向右,向里平移 + 缩放前向右,向上平移,改变缩放点 glScalef(fScale, fScale, fScale); //等比例缩放glTranslatef(-0.5f, -0.4f, 0.0f); //缩放后向左,向下平移,恢复位置drawTable();//画桌子glPopMatrix();//抛出矩阵堆栈fTranslate += 0.002f; //更新平移因子fRotate += 0.4f; //更新旋转因子fScale -= 0.002f; //更新缩放因子if (fTranslate > 0.5f) fTranslate = 0.0f; //移到一定位置从头开始移if (fScale < 0.6f)fScale = 1.0f; //缩放到一定程度恢复原状glutSwapBuffers(); //交换缓冲区}int main(int argc, char *argv[]){glutInit(&argc, argv);//对glut的初始化glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);//初始化显示模式:RGB颜色模型,双缓冲 glutInitWindowSize(640, 480);//设置窗口大小 glutCreateWindow("Exercise2");//设置窗口标题 glutDisplayFunc(redraw);//注册绘制回调函数 glutReshapeFunc(reshape);//注册重绘回调函数 glutIdleFunc(idle);//注册全局回调函数:空闲时调用glutMainLoop();// glut事件处理循环 return 0;}
- [OpenGL] 桌子的平移、旋转和缩放
- opengl绘制桌子(平移、旋转、缩放)
- openGL 矩阵的旋转-平移-缩放
- OpenGL中的平移旋转缩放
- OpenGL之旋转、平移、缩放
- opengl中平移、旋转、缩放
- OpenGL-旋转平移与缩放
- Bitmap和Canvas的平移、缩放、旋转
- 矩阵的平移,缩放和旋转
- OpenGL绘制简单场景,实现旋转缩放平移和灯光效果
- VC++调用OpenGL实现3维图形的旋转,平移和缩放
- 二维图形学的变换-平移、旋转、缩放 OpenGL
- opengl 教程(11) 平移/旋转/缩放
- openGL ES JNI贴图 平移 旋转 缩放
- OpenGL坐标变换 平移,缩放与旋转
- Android OpenGL ES 绘图 -- 缩放、平移、旋转
- Matrix控制平移、旋转和缩放的方法
- iOS控件的缩放,平移,旋转和回到原点
- 高并发优化
- java通过代码获取音频的时长
- 面试准备
- Java编程基础_安装配置编程环境
- Wrong02-Could not find a storyboard named‘Main’in bundle NSBundle
- [OpenGL] 桌子的平移、旋转和缩放
- 网易2015年Java开发笔试第三题 选择题
- Android技术积累:开发规范
- hdu 5592 ZYB's Premutation 线段树
- Coursera_机器学习_week1_介绍&Octave
- 代码块(block)
- Dark Frame Subtraction
- Redis基本命令
- socket编程之自定义TCP帧数据包