精华内容
参与话题
问答
  • OpenGL 超酷三维动画DEMO 附源代码

    热门讨论 2007-08-26 18:15:40
    OpenGL 超酷三维动画DEMO 附源代码
  • OpenGL初级入门视频教程(2018)

    千人学习 2017-12-01 17:50:56
    OpenGL入门课程主要带领完全没有OpenGL基础的同学,入门OpenGL世界,课程内容包括OpenGL萌谷手册、搭建OpenGL绘图框架、图元绘制、矩阵操作、3D模型绘制、光照的封装、键盘鼠标事件、向量等。
  • OpenGL安装(适用于VS2017)

    千次阅读 2019-03-15 09:28:59
    OpenGL安装(适用于VS2017) 这个是参考网上的博客,感谢前人的贡献,文末加上了一些我个人踩的坑 参考博客:在VS2017中安装OpenGL - 我有点帅哦 - 博客园 利用VS2017下的包管理软件Nuget下载安装OpenGL库 优点:...

    OpenGL安装(适用于VS2017)

    这个是参考网上的博客,感谢前人的贡献,文末加上了一些我个人踩的坑
    参考博客:在VS2017中安装OpenGL - 我有点帅哦 - 博客园


    利用VS2017下的包管理软件Nuget下载安装OpenGL库
    优点:安装很简单
    缺点:每次创建项目都要重新下载OpenGL库

    1. VS2017创建C++控制台程序,最好选择空项目(否则可能会有其他的错误)

    2. 创建好了项目,点击菜单栏的“项目”下的“管理Nuget程序包”

    3. “浏览”下输入NupenGL,两个都点击安装

    4. 新建一个C++文件

    5. 输入下面的Demo,运行F5

    #include <windows.h>  
    #include <GL/gl.h>  
    #include <GL/glu.h>  
    #include <GL/glut.h>  
    
    #include <cstdlib>  
    #include <cstdio>  
    #include <cmath>  
    
    void display(void) {
    	GLubyte fly[] = {
    		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    		0x03,0x80,0x01,0xC0,0x06,0xC0,0x03,0x60,
    		0x04,0x60,0x06,0x20,0x04,0x30,0x0C,0x20,
    		0x04,0x18,0x18,0x20,0x04,0x0C,0x30,0x20,
    
    		0x04,0x06,0x60,0x20,0x04,0x03,0xC0,0x22,
    		0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,
    		0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,
    		0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,
    
    		0x66,0x01,0x80,0x66,0x33,0x01,0x80,0xCC,
    		0x19,0x81,0x81,0x98,0x0C,0xC1,0x83,0x30,
    		0x07,0xe1,0x87,0xe0,0x03,0x3f,0xfc,0xc0,
    		0x03,0x31,0x8c,0xc0,0x03,0x33,0xCC,0xC0,
    
    		0x06,0x64,0x26,0x60,0x0c,0xcc,0x33,0x30,
    		0x18,0xcc,0x33,0x18,0x10,0xc4,0x23,0x08,
    		0x10,0x63,0xc6,0x08,0x10,0x30,0x0c,0x08,
    		0x10,0x18,0x18,0x08,0x10,0x00,0x00,0x08,
    	};
    
    	GLubyte halftone[] = {
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    		0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    	};
    
    	glClear(GL_COLOR_BUFFER_BIT);
    	glColor3f(1.0, 1.0, 1.0);
    	glRectf(25.0, 25.0, 125.0, 125.0);
    	glEnable(GL_POLYGON_STIPPLE);
    	glPolygonStipple(fly);
    	glRectf(125.0, 25.0, 225.0, 125.0);
    	glPolygonStipple(halftone);
    	glRectf(225.0, 25.0, 325.0, 125.0);
    	glDisable(GL_POLYGON_STIPPLE);
    	glFlush();
    }
    
    void init(void) {
    	glClearColor(0.0, 0.0, 0.0, 0.0);
    	glShadeModel(GL_FLAT);
    }
    
    void reshape(int w, int h) {
    	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
    }
    
    int main(int argc, char** argv) {
    	glutInit(&argc, argv);
    	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    	glutInitWindowSize(350, 150);
    	glutCreateWindow(argv[0]);
    	init();
    	glutDisplayFunc(display);
    	glutReshapeFunc(reshape);
    	glutMainLoop();
    	return 0;
    }
    

    效果图如下

    可能遇到的小问题

    1. 创建项目时windows控制台项目,而非空项目可能遇到如下问题
    错误	C1010	在查找预编译头时遇到意外的文件结尾。
    是否忘记了向源中添加“#include "pch.h"
    

    最简单的解决方案就是重新创建一个空项目
    2. 在C++一个项目只能存在一个.cpp文件,否则可能会报错
    解决办法:在VS2017项目管理中找到要移除C++文件,右击移除即可

    展开全文
  • 此课为三维变换的内容,比较枯燥。主要是因为很多函数在单独使用时都不好描述其效果, 在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从-1到1,还只能是X轴向右,Y轴向上,Z轴垂直屏幕...

    OpenGL入门学习(五)

    此课为三维变换的内容,比较枯燥。主要是因为很多函数在单独使用时都不好描述其效果,

    在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从-1到1,还只能是X轴向右,Y轴向上,Z轴垂直屏幕。这些限制给我们的绘图带来了很多不便。

    我们生活在一个三维的世界——如果要观察一个物体,我们可以:
    1、从不同的位置去观察它。(视图变换)
    2、移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它。(模型变换)
    3、如果把物体画下来,我们可以选择:是否需要一种“近大远小”的透视效果。另外,我们可能只希望看到物体的一部分,而不是全部(剪裁)。(投影变换)
    4、我们可能希望把整个看到的图形画下来,但它只占据纸张的一部分,而不是全部。(视口变换)
    这些,都可以在OpenGL中实现。

    OpenGL变换实际上是通过矩阵乘法来实现。无论是移动、旋转还是缩放大小,都是通过在当前矩阵的基础上乘以一个新的矩阵来达到目的。关于矩阵的知识,这里不详细介绍,有兴趣的朋友可以看看线性代数(大学生的话多半应该学过的)。
    OpenGL可以在最底层直接操作矩阵,不过作为初学,这样做的意义并不大。这里就不做介绍了。

    1、模型变换和视图变换
    相对移动的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。在OpenGL中,实现这两种功能甚至使用的是同样的函数。
    由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为模型视图矩阵。设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:
    glMatrixMode(GL_MODELVIEW);
    通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。这也只需要一行代码:
    glLoadIdentity();

    然后,就可以进行模型变换和视图变换了。进行模型和视图变换,主要涉及到三个函数:
    glTranslate*,把当前矩阵和一个表示移动物体的矩阵相乘。三个参数分别表示了在三个坐标上的位移值。
    glRotate*,把当前矩阵和一个表示旋转物体的矩阵相乘。物体将绕着(0,0,0)(x,y,z)的直线以逆时针旋转,参数angle表示旋转的角度。
    glScale*,把当前矩阵和一个表示缩放物体的矩阵相乘。x,y,z分别表示在该方向上的缩放比例。

    注意我都是说XX相乘,而不是直接说“这个函数就是旋转”或者“这个函数就是移动”,这是有原因的,马上就会讲到。
    假设当前矩阵为单位矩阵,然后先乘以一个表示旋转的矩阵R,再乘以一个表示移动的矩阵T,最后得到的矩阵再乘上每一个顶点的坐标矩阵v。所以,经过变换得到的顶点坐标就是((RT)v)。由于矩阵乘法的结合率,((RT)v) = (R(Tv)),换句话说,实际上是先进行移动,然后进行旋转。即:实际变换的顺序与代码中写的顺序是相反的。由于先移动后旋转先旋转后移动得到的结果很可能不同,初学的时候需要特别注意这一点。
    OpenGL之所以这样设计,是为了得到更高的效率。但在绘制复杂的三维图形时,如果每次都去考虑如何把变换倒过来,也是很痛苦的事情。这里介绍另一种思路,可以让代码看起来更自然(写出的代码其实完全一样,只是考虑问题时用的方法不同了)。
    让我们想象,坐标并不是固定不变的。旋转的时候,坐标系统随着物体旋转。移动的时候,坐标系统随着物体移动。如此一来,就不需要考虑代码的顺序反转的问题了。

    以上都是针对改变物体的位置和方向来介绍的。如果要改变观察点的位置,除了配合使用glRotate*和glTranslate*函数以外,还可以使用这个函数:gluLookAt。它的参数比较多,前三个参数表示了观察点的位置,中间三个参数表示了观察目标的位置,最后三个参数代表从(0,0,0)到 (x,y,z)的直线,它表示了观察者认为的“上”方向。


    2
    、投影变换
    投影变换就是定义一个可视空间,可视空间以外的物体不会被绘制到屏幕上。(注意,从现在起,坐标可以不再是-1.01.0了!)
    OpenGL支持两种类型的投影变换,即透视投影和正投影。投影也是使用矩阵来实现的。如果需要操作投影矩阵,需要以GL_PROJECTION为参数调用glMatrixMode函数。
    glMatrixMode(GL_PROJECTION);
    通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。
    glLoadIdentity();

    透视投影所产生的结果类似于照片,有近大远小的效果,比如在火车头内向前照一个铁轨的照片,两条铁轨似乎在远处相交了。
    使用glFrustum函数可以将当前的可视空间设置为透视投影空间。其参数的意义如下图:

    声明:该图片来自www.opengl.org,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。也可以使用更常用的gluPerspective函数。其参数的意义如下图:

    声明:该图片来自www.opengl.org,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

    正投影相当于在无限远处观察得到的结果,它只是一种理想状态。但对于计算机来说,使用正投影有可能获得更好的运行速度。使用glOrtho函数可以将当前的可视空间设置为正投影空间。其参数的意义如下图:

    声明:该图片来自www.opengl.org,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

    如果绘制的图形空间本身就是二维的,可以使用gluOrtho2D。他的使用类似于glOrgho。

    3、视口变换
    当一切工作已经就绪,只需要把像素绘制到屏幕上了。这时候还剩最后一个问题:应该把像素绘制到窗口的哪个区域呢?通常情况下,默认是完整的填充整个窗口,但我们完全可以只填充一半。(即:把整个图象填充到一半的窗口内)

    声明:该图片来自www.opengl.org,该图片是《OpenGL编程指南》一书的附图,由于该书的旧版(第一版,1994年)已经流传于网络,我希望没有触及到版权问题。

    使用glViewport来定义视口。其中前两个参数定义了视口的左下脚(0,0表示最左下方),后两个参数分别是宽度和高度

    4、操作矩阵堆栈
    介于是入门教程,先简单介绍一下堆栈。你可以把堆栈想象成一叠盘子。开始的时候一个盘子也没有,你可以一个一个往上放,也可以一个一个取下来。每次取下的,都是最后一次被放上去的盘子。通常,在计算机实现堆栈时,堆栈的容量是有限的,如果盘子过多,就会出错。当然,如果没有盘子了,再要求取一个盘子,也会出错。
    我们在进行矩阵操作时,有可能需要先保存某个矩阵,过一段时间再恢复它。当我们需要保存时,调用glPushMatrix函数,它相当于把矩阵(相当于盘子)放到堆栈上。当需要恢复最近一次的保存时,调用glPopMatrix函数,它相当于把矩阵从堆栈上取下。OpenGL规定堆栈的容量至少可以容纳32个矩阵,某些OpenGL实现中,堆栈的容量实际上超过了32个。因此不必过于担心矩阵的容量问题。
    通常,用这种先保存后恢复的措施,比先变换再逆变换要更方便,更快速。
    注意:模型视图矩阵和投影矩阵都有相应的堆栈。使用glMatrixMode来指定当前操作的究竟是模型视图矩阵还是投影矩阵

    5、综合举例
    好了,视图变换的入门知识差不多就讲完了。但我们不能就这样结束。因为本次课程的内容实在过于枯燥,如果分别举例,可能效果不佳。我只好综合的讲一个例子,算是给大家一个参考。至于实际的掌握,还要靠大家自己花功夫。闲话少说,现在进入正题。

    我们要制作的是一个三维场景,包括了太阳、地球和月亮。假定一年有12个月,每个月30天。每年,地球绕着太阳转一圈。每个月,月亮围着地球转一圈。即一年有360天。现在给出日期的编号(0~359),要求绘制出太阳、地球、月亮的相对位置示意图。(这是为了编程方便才这样设计的。如果需要制作更现实的情况,那也只是一些数值处理而已,与OpenGL关系不大)
    首先,让我们认定这三个天体都是球形,且他们的运动轨迹处于同一水平面,建立以下坐标系:太阳的中心为原点,天体轨迹所在的平面表示了X轴与Y轴决定的平面,且每年第一天,地球在X轴正方向上,月亮在地球的正X轴方向。
    下一步是确立可视空间。注意:太阳的半径要比太阳到地球的距离短得多。如果我们直接使用天文观测得到的长度比例,则当整个窗口表示地球轨道大小时,太阳的大小将被忽略。因此,我们只能成倍的放大几个天体的半径,以适应我们观察的需要。(百度一下,得到太阳、地球、月亮的大致半径分别是:696000km,  6378km,1738km。地球到太阳的距离约为1.5亿km=150000000km,月亮到地球的距离约为380000km。)
    让我们假想一些数据,将三个天体的半径分别“修改”为:69600000(放大100),15945000(放大2500),4345000(放大5000)。将地球到月亮的距离“修改”为38000000(放大100)。地球到太阳的距离保持不变。
    为了让地球和月亮在离我们很近时,我们仍然不需要变换观察点和观察方向就可以观察它们,我们把观察点放在这个位置:(0, -200000000, 0)  ——因为地球轨道半径为150000000,咱们就凑个整,取-200000000就可以了。观察目标设置为原点(即太阳中心),选择Z轴正方向作为 “上”方。当然我们还可以把观察点往“上”方移动一些,得到(0, -200000000, 200000000),这样可以得到45度角的俯视效果。
    为了得到透视效果,我们使用gluPerspective来设置可视空间。假定可视角为60度(如果调试时发现该角度不合适,可修改之。我在最后选择的数值是75。),高宽比为1.0。最近可视距离为1.0,最远可视距离为200000000*2=400000000。即:gluPerspective (60, 1, 1, 400000000);

    现在我们来看看如何绘制这三个天体。
    为了简单起见,我们把三个天体都想象成规则的球体。而我们所使用的glut实用工具中,正好就有一个绘制球体的现成函数glutSolidSphere,这个函数在“原点”绘制出一个球体。由于坐标是可以通过glTranslate*和glRotate*两个函数进行随意变换的,所以我们就可以在任意位置绘制球体了。函数有三个参数:第一个参数表示球体的半径,后两个参数代表了的数目简单点说就是球体的精确程度,数值越大越精确,当然代价就是速度越缓慢。这里我们只是简单的设置后两个参数为20。
    太阳在坐标原点,所以不需要经过任何变换,直接绘制就可以了。
    地球则要复杂一点,需要变换坐标。由于今年已经经过的天数已知为day,则地球转过的角度为day/一年的天数*360度。前面已经假定每年都是360天,因此地球转过的角度恰好为day。所以可以通过下面的代码来解决:
    glRotatef(day, 0, 0, -1);
    /* 注意地球公转是自西向东,因此是饶着Z轴负方向进行逆时针旋转 */
    glTranslatef(地球轨道半径, 0, 0);
    glutSolidSphere(地球半径, 20, 20);
    月亮是最复杂的。因为它不仅要绕地球转,还要随着地球绕太阳转。但如果我们选择地球作为参考,则月亮进行的运动就是一个简单的圆周运动了。如果我们先绘制地球,再绘制月亮,则只需要进行与地球类似的变换:
    glRotatef(月亮旋转的角度, 0, 0, -1);
    glTranslatef(月亮轨道半径, 0, 0);
    glutSolidSphere(月亮半径, 20, 20);
    但这个“月亮旋转的角度”,并不能简单的理解为day/一个月的天数30*360度。因为我们在绘制地球时,这个坐标已经是旋转过的。现在的旋转是在以前的基础上进行旋转,因此还需要处理这个“差值”。我们可以写成:day/30*360 - day,即减去原来已经转过的角度。这只是一种简单的处理,当然也可以在绘制地球前用glPushMatrix保存矩阵,绘制地球后用glPopMatrix恢复矩阵。再设计一个跟地球位置无关的月亮位置公式,来绘制月亮。通常后一种方法比前一种要好,因为浮点的运算是不精确的,即是说我们计算地球本身的位置就是不精确的。拿这个不精确的数去计算月亮的位置,会导致 “不精确”的成分累积,过多的“不精确”会造成错误。我们这个小程序没有去考虑这个,但并不是说这个问题不重要。
    还有一个需要注意的细节: OpenGL把三维坐标中的物体绘制到二维屏幕,绘制的顺序是按照代码的顺序来进行的。因此后绘制的物体会遮住先绘制的物体,即使后绘制的物体在先绘制的物体的“后面”也是如此。使用深度测试可以解决这一问题。使用的方法是:1、以GL_DEPTH_TEST为参数调用glEnable函数,启动深度测试。2、在必要时(通常是每次绘制画面开始时),清空深度缓冲,即:glClear(GL_DEPTH_BUFFER_BIT);其中,glClear (GL_COLOR_BUFFER_BIT)与glClear(GL_DEPTH_BUFFER_BIT)可以合并写为:
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    且后者的运行速度可能比前者快。

    到此为止,我们终于可以得到整个“太阳,地球和月亮”系统的完整代码。
    <span style="font-size:14px;">// 太阳、地球和月亮
    // 假设每个月都是30天
    // 一年12个月,共是360天
    static int day = 200; // day的变化:从0到359
    void myDisplay(void)
    {
        glEnable(GL_DEPTH_TEST);        //启动深度测试,解决后绘制的物体挡住先绘制的物体
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   //清空深度缓存和屏幕上的颜色
    
        glMatrixMode(GL_PROJECTION);   //操作的是投影矩阵
        glLoadIdentity();                                  //把当前矩阵设置为单位矩阵。
        gluPerspective(75, 1, 1, 400000000);   //将当前的可视空间设置为透视投影空间
    
        glMatrixMode(GL_MODELVIEW);   //设置当前操作的矩阵为“模型视图矩阵”。
        glLoadIdentity();
        gluLookAt(0, -200000000, 200000000, 0, 0, 0, 0, 0, 1);  //要改变观察点的位置
    
        // 绘制红色的“太阳”
        glColor3f(1.0f, 0.0f, 0.0f);
        glutSolidSphere(69600000, 20, 20);
        // 绘制蓝色的“地球”
        glColor3f(0.0f, 0.0f, 1.0f);
        glRotatef(day/360.0*360.0, 0.0f, 0.0f, -1.0f);
        glTranslatef(150000000, 0.0f, 0.0f);
        glutSolidSphere(15945000, 20, 20);
        // 绘制黄色的“月亮”
        glColor3f(1.0f, 1.0f, 0.0f);
        glRotatef(day/30.0*360.0 - day/360.0*360.0, 0.0f, 0.0f, -1.0f);
        glTranslatef(38000000, 0.0f, 0.0f);
        glutSolidSphere(4345000, 20, 20);
    
        glFlush();
    }
    </span>

    试修改day的值,看看画面有何变化。
    小结:本课开始,我们正式进入了三维的OpenGL世界。
    OpenGL通过矩阵变换来把三维物体转变为二维图象,进而在屏幕上显示出来。为了指定当前操作的是何种矩阵,我们使用了函数glMatrixMode。
    我们可以移动、旋转观察点或者移动、旋转物体,使用的函数是glTranslate*和glRotate*。
    我们可以缩放物体,使用的函数是glScale*。
    我们可以定义可视空间,这个空间可以是“正投影”的(使用glOrtho或gluOrtho2D),也可以是“透视投影”的(使用glFrustum或gluPerspective)。
    我们可以定义绘制到窗口的范围,使用的函数是glViewport。
    矩阵有自己的“堆栈”,方便进行保存和恢复。这在绘制复杂图形时很有帮助。使用的函数是glPushMatrix和glPopMatrix。

    OpenGL入门学习(六)

    动画制作——让昨天那个“太阳、地球和月亮”天体图画动起来。

    本次课程,我们将进入激动人心的计算机动画世界。

    想必大家都知道电影和动画的工作原理吧?是的,快速的把看似连续的画面一幅幅的呈现在人们面前。一旦每秒钟呈现的画面超过24幅,人们就会错以为它是连续的。
    我们通常观看的电视,每秒播放25或30幅画面。但对于计算机来说,它可以播放更多的画面,以达到更平滑的效果。如果速度过慢,画面不够平滑。如果速度过快,则人眼未必就能反应得过来。对于一个正常人来说,每秒60~120幅图画是比较合适的。具体的数值因人而异。

    假设某动画一共有n幅画面,则它的工作步骤就是:
    显示第1幅画面,然后等待一小段时间,直到下一个1/24秒
    显示第2幅画面,然后等待一小段时间,直到下一个1/24秒
    ……
    显示第n幅画面,然后等待一小段时间,直到下一个1/24秒
    结束
    如果用C语言伪代码来描述这一过程,就是:
    for(i=0; i<n; ++i)
    {
        DrawScene(i);
        Wait();
    }
    1、双缓冲技术
    在计算机上的动画与实际的动画有些不同:实际的动画都是先画好了,播放的时候直接拿出来显示就行。计算机动画则是画一张,就拿出来一张,再画下一张,再拿出来。如果所需要绘制的图形很简单,那么这样也没什么问题。但一旦图形比较复杂,绘制需要的时间较长,问题就会变得突出。
    让我们把计算机想象成一个画图比较快的人,假如他直接在屏幕上画图,而图形比较复杂,则有可能在他只画了某幅图的一半的时候就被观众看到。而后面虽然他把画补全了,但观众的眼睛却又没有反应过来,还停留在原来那个残缺的画面上。也就是说,有时候观众看到完整的图象,有时却又只看到残缺的图象,这样就造成了屏幕的闪烁
    如何解决这一问题呢?我们设想有两块画板,画图的人在旁边画,画好以后把他手里的画板与挂在屏幕上的画板相交换。这样以来,观众就不会看到残缺的画了。这一技术被应用到计算机图形中,称为双缓冲技术即:在存储器(很有可能是显存)中开辟两块区域,一块作为发送到显示器的数据,一块作为绘画的区域,在适当的时候交换它们由于交换两块内存区域实际上只需要交换两个指针,这一方法效率非常高,所以被广泛的采用。
    注意:虽然绝大多数平台都支持双缓冲技术,但这一技术并不是OpenGL标准中的内容。OpenGL为了保证更好的可移植性,允许在实现时不使用双缓冲技术。当然,我们常用的PC都是支持双缓冲技术的。
    要启动双缓冲功能,最简单的办法就是使用GLUT工具包。我们以前在main函数里面写:
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    其中GLUT_SINGLE表示单缓冲,如果改成GLUT_DOUBLE就是双缓冲了。
    当然还有需要更改的地方——每次绘制完成时,我们需要交换两个缓冲区,把绘制好的信息用于屏幕显示(否则无论怎么绘制,还是什么都看不到)。如果使用GLUT工具包,也可以很轻松的完成这一工作,只要在绘制完成时简单的调用glutSwapBuffers函数就可以了。


    2、实现连续动画
    似乎没有任何疑问,我们应该把绘制动画的代码写成下面这个样子:
    for(i=0; i<n; ++i)
    {
        DrawScene(i);
        glutSwapBuffers();
        Wait();
    }
    但事实上,这样做不太符合窗口系统的程序设计思路。还记得我们的第一个OpenGL程序吗?我们在main函数里写:glutDisplayFunc(&myDisplay);
    意思是对系统说:如果你需要绘制窗口了,请调用myDisplay这个函数。为什么我们不直接调用myDisplay,而要采用这种看似“舍近求远”的做法呢?原因在于——我们自己的程序无法掌握究竟什么时候该绘制窗口。因为一般的窗口系统——拿我们熟悉一点的来说——Windows和X窗口系统,都是支持同时显示多个窗口的。假如你的程序窗口碰巧被别的窗口遮住了,后来用户又把原来遮住的窗口移开,这时你的窗口需要重新绘制。很不幸的,你无法知道这一事件发生的具体时间。因此这一切只好委托操作系统来办了。
    现在我们再看上面那个循环。既然DrawScene都可以交给操作系统来代办了,那让整个循环运行起来的工作是否也可以交给操作系统呢?答案是肯定的。我们先前的思路是:绘制,然后等待一段时间;再绘制,再等待一段时间。但如果去掉等待的时间,就变成了绘制,绘制,……,不停的绘制。——当然了,资源是公用的嘛,杀毒软件总要工作吧?我的下载不能停下来吧?我的mp3播放还不能给耽搁了。总不能因为我们的动画,让其他的工作都停下来。因此,我们需要在CPU空闲的时间绘制。
    这里的“在CPU空闲的时间绘制”和我们在第一课讲的“在需要绘制的时候绘制”有些共通,都是“在XX时间做XX事”,GLUT工具包也提供了一个比较类似的函数:glutIdleFunc,表示在CPU空闲的时间调用某一函数。其实GLUT还提供了一些别的函数,例如“在键盘按下时做某事”等。

    到现在,我们已经可以初步开始制作动画了。好的,就拿上次那个“太阳、地球和月亮”的程序开刀,让地球和月亮自己动起来。
    <span style="font-size:14px;">#include <GL/glut.h>
    // 太阳、地球和月亮
    // 假设每个月都是30天
    // 一年12个月,共是360天
    static int day = 200; // day的变化:从0到359
    void myDisplay(void)
    {
        /****************************************************
         这里的内容照搬上一课的,只因为使用了双缓冲,补上最后这句
        *****************************************************/
        glutSwapBuffers();
    }
    
    void myIdle(void)
    {
        /* 新的函数,在空闲时调用,作用是把日期往后移动一天并重新绘制,达到动画效果 */
        ++day;
        if( day >= 360 )
            day = 0;
        myDisplay();
    }
    
    int main(int argc, char *argv[])
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); // 修改了参数为GLUT_DOUBLE
        glutInitWindowPosition(100, 100);
        glutInitWindowSize(400, 400);
        glutCreateWindow("太阳,地球和月亮");   // 改了窗口标题
        glutDisplayFunc(&myDisplay);
        glutIdleFunc(&myIdle);               // 新加入了这句
        glutMainLoop();
        return 0;
    }
    </span>

    3、关于垂直同步
    代码是写好了,但相信大家还有疑问。某些朋友可能在运行时发现,虽然CPU几乎都用上了,但运动速度很快,根本看不清楚,另一些朋友在运行时发现CPU使用率很低,根本就没有把空闲时间完全利用起来。但对于上面那段代码来说,这些现象都是合理的。这里就牵涉到关于垂直同步的问题。

    大家知道显示器的刷新率是比较有限的,一般为60~120Hz,也就是一秒钟刷新60~120次。但如果叫计算机绘制一个简单的画面,例如只有一个三角形,则一秒钟可以绘制成千上万次。因此,如果最大限度的利用计算机的处理能力,绘制很多幅画面,但显示器的刷新速度却跟不上,这不仅造成性能的浪费,还可能带来一些负面影响(例如,显示器只刷新到一半时,需要绘制的内容却变化了,由于显示器是逐行刷新的,于是显示器上半部分和下半部分实际上是来自两幅画面)。采用垂直同步技术可以解决这一问。即,只有在显示器刷新时,才把绘制好的图象传输出去供显示。这样一来,计算机就不必去绘制大量的根本就用不到的图象了。如果显示器的刷新率为85Hz,则计算机一秒钟只需要绘制85幅图象就足够,如果场景足够简单,就会造成比较多的CPU空闲。
    几乎所有的显卡都支持“垂直同步”这一功能。
    垂直同步也有它的问题。如果刷新频率为60Hz,则在绘制比较简单的场景时,绘制一幅图画需要的时间很短,帧速可以恒定在60FPS(即60帧/秒)。如果场景变得复杂,绘制一幅图画的时间超过了1/60秒,则帧速将急剧下降。
    如果绘制一幅图画的时间为1/50,则在第一个1/60秒时,显示器需要刷新了,但由于新的图画没有画好,所以只能显示原来的图画,等到下一个1/60秒时才显示新的图画。于是显示一幅图画实际上用了1/30秒,帧速为30FPS。(如果不采用垂直同步,则帧速应该是50FPS)
    如果绘制一幅图画的时间更长,则下降的趋势就是阶梯状的:60FPS,30FPS,20FPS,……(60/1,60/2,60/3,……)
    如果每一幅图画的复杂程度是不一致的,且绘制它们需要的时间都在1/60上下。则在1/60时间内画完时,帧速为60FPS,在1/60时间未完成时,帧速为30FPS,这就造成了帧速的跳动。这是很麻烦的事情,需要避免它——要么想办法简化每一画面的绘制时间,要么都延迟一小段时间,以作到统一。

    回过头来看前面的问题。如果使用了大量的CPU而且速度很快无法看清,则打开垂直同步可以解决该问题。当然如果你认为垂直同步有这样那样的缺点,也可以关闭它。——至于如何打开和关闭,因操作系统而异了。具体步骤请自己搜索之。

    当然,也有其它办法可以控制动画的帧速,或者尽量让动画的速度尽量和帧速无关。不过这里面很多内容都是与操作系统比较紧密的,况且它们跟OpenGL关系也不太大。这里就不做介绍了。


    4、计算帧速
    不知道大家玩过3D Mark这个软件没有,它可以运行各种场景,测出帧速,并且为你的系统给出评分。这里我也介绍一个计算帧速的方法。
    根据定义,帧速就是一秒钟内播放的画面数目(FPS。我们可以先测量绘制两幅画面之间时间t,然后求它的倒数即可。假如t=0.05s,则FPS的值就是1/0.05=20。
    理论上是如此了,可是如何得到这个时间呢?通常C语言的time函数精确度一般只到一秒,肯定是不行了。clock函数也就到十毫秒左右,还是有点不够。因为FPS为60和FPS为100的时候,t的值都是十几毫秒。
    你知道如何测量一张纸的厚度吗?一个粗略的办法就是:用很多张纸叠在一起测厚度,计算平均值就可以了。我们这里也可以这样办。测量绘制50幅画面(包括垂直同步等因素的等待时间)需要的时间t',由t'=t*50很容易的得到FPS=1/t=50/t'
    下面这段代码可以统计该函数自身的调用频率,(原理就像上面说的那样),程序并不复杂,并且这并不属于OpenGL的内容,所以我不打算详细讲述它。

    <span style="font-size:14px;">#include <time.h>
    double CalFrequency()
    {
        static int count;
        static double save;
        static clock_t last, current;
        double timegap;
    
        ++count;
        if( count <= 50 )
            return save;
        count = 0;
        last = current;
        current = clock();
        timegap = (current-last)/(double)CLK_TCK;
        save = 50.0/timegap;
        return save;
    }</span>

    最后,要把计算的帧速显示出来,但我们并没有学习如何使用OpenGL把文字显示到屏幕上。——但不要忘了,在我们的图形窗口背后,还有一个命令行窗口~使用printf函数就可以轻易的输出文字了。
    #include <stdio.h>

    double FPS = CalFrequency();
    printf("FPS = %f\n", FPS);
    最后的一步,也被我们解决了——虽然做法不太雅观,没关系,以后我们还会改善它的。


    时间过得太久,每次给的程序都只是一小段,一些朋友难免会出问题。
    现在,我给出一个比较完整的程序,供大家参考。

    <span style="font-size:14px;">#include <GL/glut.h>
    #include <stdio.h>
    #include <time.h>
    
    // 太阳、地球和月亮
    // 假设每个月都是12天
    // 一年12个月,共是360天
    static int day = 200; // day的变化:从0到359
    
    double CalFrequency()
    {
        static int count;
        static double save;
        static clock_t last, current;
        double timegap;
    
        ++count;
        if( count <= 50 )
            return save;
        count = 0;
        last = current;
        current = clock();
        timegap = (current-last)/(double)CLK_TCK;
        save = 50.0/timegap;
        return save;
    }
    
    void myDisplay(void)
    {
        double FPS = CalFrequency();
        printf("FPS = %f\n", FPS);
    
        glEnable(GL_DEPTH_TEST);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(75, 1, 1, 400000000);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(0, -200000000, 200000000, 0, 0, 0, 0, 0, 1);
    
        // 绘制红色的“太阳”
        glColor3f(1.0f, 0.0f, 0.0f);
        glutSolidSphere(69600000, 20, 20);
        // 绘制蓝色的“地球”
        glColor3f(0.0f, 0.0f, 1.0f);
        glRotatef(day/360.0*360.0, 0.0f, 0.0f, -1.0f);
        glTranslatef(150000000, 0.0f, 0.0f);
        glutSolidSphere(15945000, 20, 20);
        // 绘制黄色的“月亮”
        glColor3f(1.0f, 1.0f, 0.0f);
        glRotatef(day/30.0*360.0 - day/360.0*360.0, 0.0f, 0.0f, -1.0f);
        glTranslatef(38000000, 0.0f, 0.0f);
        glutSolidSphere(4345000, 20, 20);
    
        glFlush();
        glutSwapBuffers();
    }
    
    void myIdle(void)
    {
        ++day;
        if( day >= 360 )
            day = 0;
        myDisplay();
    }
    
    int main(int argc, char *argv[])
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
        glutInitWindowPosition(100, 100);
        glutInitWindowSize(400, 400);
        glutCreateWindow("太阳,地球和月亮");
        glutDisplayFunc(&myDisplay);
        glutIdleFunc(&myIdle);
        glutMainLoop();
        return 0;
    }</span>

    小结:
    OpenGL
    动画和传统意义上的动画相似,都是把画面一幅一幅的呈现在观众面前。一旦画面变换的速度快了,观众就会认为画面是连续的。
    双缓冲技术是一种在计算机图形中普遍采用的技术,绝大多数OpenGL实现都支持双缓冲技术。
    通常都是利用CPU空闲的时候绘制动画,但也可以有其它的选择。
    介绍了垂直同步的相关知识。
    介绍了一种简单的计算帧速(FPS)的方法。
    最后,我们列出了一份完整的天体动画程序清单。


    展开全文
  • 目前市场上,对二维动画和三维动画的需求越来越多,那么这两种动画在表现形式有什么不同,我们又该如何区分呢?下面就来了解一下吧。 首先,我们先了解一下二维动画 二维动画是根据某个场景的人和物的画面绘制,然后...

    目前市场上,对二维动画和三维动画的需求越来越多,那么这两种动画在表现形式有什么不同,我们又该如何区分呢?下面就来了解一下吧。
    首先,我们先了解一下二维动画
    二维动画是根据某个场景的人和物的画面绘制,然后把一幅幅的图片再连续起来做成动画。二维动画其实就是一个在平面上的图画,无论怎样去看,画面的内容都不会发生改变。

    上图为二维动画真实图片
    二维动画的特点:
    1、纯手工绘制的传统动画,画面清晰生动。
    2、修改方便,可将事先手工制作的原动画逐帧输入计算机,加以修改。
    3、可以使动画更加形象,表现较为夸张。
    其次,来看看三维动画三维动画
    三维动画是现在应用最广泛的一种技术,又被人们称之为3D动画,其利用人眼看事物时的一种立体视觉现象所制作而成的绘画作品,运用了人眼对光影、明暗、虚实的感觉得到立体的感觉。真正的三维画面,画中景物无论从哪个角度去看,都能够看到不同的内容。

    图为真实三维动画
    三维动画是怎么制作的呢,简单地说一下。首先利用三维动画软件在电脑中建起一个虚拟世界,然后设计师就在虚拟的三维世界中,按照要展示的内容来建立场景或模型,再根据客户的要求来设定该模型的动画参数,最后在这个模型上加入特定的材质,并打上灯光。完成后利用计算机来自动运算,生成最后的画面。
    三维动画的特点:
    1、特效效果诸多;如爆炸、光影、烟雾、下雨、光效等。
    2、不需要利用机器拍摄画面。
    3、一些实现不了的画面,都可以利用三维动画软件制作而成。
    4、画面可以出乎人的意料之外。
    通过以上的讲解,想必大家对二维动画和三维动画已经有了一定的了解。二维动画的画面是静止的,三维动画的画面是立体的,真实感极强,说到最后,也就是平面与立体的区别。

    本文地址: http://www.chinasjha.com/article-84-1.html

    展开全文
  • OpenGL萌谷手册视频教程

    万人学习 2017-12-09 08:50:20
    OpenGL视频培训课程,本课程带领完全没有基础的学员打下坚实的OpenGL学习基础,内容包括OPenGL框架搭建、矩阵、光照、纹理、3D模型绘制、键盘鼠标、模型渲染、纹理贴图等详细内容。
  •  增强现实技术AR:--融合了三维动画、立体视觉和图像处理;--建模、渲染、位置标定、图像融合;2. OpenGL是一种用于创建实时3D图像的编程接口。3. 三维这个术语表示一个正在描述或显示的物体具有三维维度:宽度、...

    第一讲

    1.    增强现实技术AR:

    --融合了三维动画、立体视觉和图像处理;

    --建模、渲染、位置标定、图像融合;

    2.    OpenGL是一种用于创建实时3D图像的编程接口。

    3.    三维这个术语表示一个正在描述或显示的物体具有三维维度:宽度、高度、深度;

    --计算机3D图形实质上也是平面的;

    --在计算机屏幕上显示的二维图像,提供深度(或第三维)的错觉;

    2D+透视 = 3D

    透视使人产生深度的错觉。

    4.    真正的3D是通过人的两只眼睛观察同一个物体,在视网膜上生成具有视差的两个图像,在人的大脑产生真正的3D视觉感受。

    5.    名词解释:渲染,将数学和图形数据转换成3D空间图像的操作。

    6.    变换:平移、旋转和缩放。

    7.    投影:将3D坐标转换成二维坐标。

    8.    光栅化:使用像素进行图形填充。

    9.    纹理贴图:纹理是一幅贴到三角形或多边形上的图片。

    10.  视口映射:

    --把绘图坐标映射到窗口坐标

    --从逻辑笛卡尔坐标映射到物理屏幕像素坐标;

    --视口就是窗口内部用于绘制裁剪区域的客户区域;视口不一定就是整个窗口,逻辑坐标的每个单位不一定与屏幕像素一一对应。

     

    11.  投影:从3D到2D,两种投影方式:正投影和透视投影。

    12.  正投影:也叫平行投影;

    特点:没有畸变,视觉不真实;

    主要用于建筑设计、CAD、2D绘图;

     

    13.  透视投影:

    近大远小、视觉真实。

     

    14.  什么是OpenGL?

    Open Graphics Library

    定义:图形硬件的一种软件接口;

    最初由SGI创建,用于在不同硬件体系的图形设备上进行二维、三维图形的绘制。OpenGL不是编程语言,特点是并行浮点运算速度极快,但不能进行流程控制。

     

    15.  ARB:标准扩展;

    EXT:多家支持的扩展;

     

    16.  背面剔除:画家算法:

    --将需要绘制的图元排序,首先绘制最远的,依次靠近。

    第二讲

    1.    物质由原子组成,3D图形由图元组成。

    2.    点:每个顶点在屏幕上都是一个单独的点。

    3.    线:每一对顶点定义一个线段。

    4.    线带:从第一个顶点依次经过后续顶点而绘制的线条。

    5.    线环:最后一个顶点和第一个顶点连接。

    6.    什么是向量?

    三维向量用一个三元组(X,Y,Z)表示。

    --顶点是一个向量:表示空间中的一个位置;

    --三维坐标可以表示一个向量:向量有长度,也有方向,所以,向量=向+量。

     

    7.    向量的定义:

    --向量是从坐标系原点到点(x,y,z)的带箭头的线段。

    --空间中的一个点,既是顶点,又是向量。

    8.单位向量:

    --长度为1的向量称为单位向量;

    --将一个任意向量转化为单位向量,称为归一化。将该向量除以向量的长度。

     

    8.    点乘:

    --两个三维向量的点乘是一个标量;

    --表示一个向量投影到另外一个向量的长度;

    --在单位向量中,两个向量的点乘是夹角的余弦值;

     

    9.    叉乘:

    两个向量的叉乘得到的是垂直于这两个向量的第三个向量;

    用途:计算平面的法向;

    特点:顺序不可交换;

     

    10.  矩阵:是一个由行和列构成的数据结构;在程序中一般以二维数组存放。

    11.  矩阵的作用:

    --三维空间中的仿射变换都是使用矩阵运算进行的:旋转、平移、缩放;

    --OpenGL中的矩阵:视图变换、模型变换、投影变换。

     

    12.  几个基本概念

    视图变换:设定观察者或摄像机的位置;

    模型变换:在场景中移动物体;

    模型视图:模型和视图的一致性;

    投影变换:设定视景体的大小和形状;

    视口变换:窗口缩放

     

    13.  视图变换:

    --视图变换的作用就是设定观察者的位置,以及视线;

    --可以理解为在场景中摆放摄像机;摄像机所在的位置,摄像机对准的方向;

    --在任何其他变换之前应该先使用视图变换,能够保证与视觉坐标系一致;

    --默认从(0,0,0)看向Z轴负方向;

     

    14.  模型变换:

    --模型变换用于操作模型和其中的特定对象;

    --将对象移动到需要的位置,然后进行旋转和缩放;

     

    15.  投影变换:在模型变换、视图变换之后应用;

    投影变换实际上定义了视景体并创建了裁剪平面

    投影变换分为正投影和透视投影。

     

    16.  视口变换

    --从颜色缓冲区到窗口像素之间的映射;

    影响画面显示的比例;

    可以进行最终画面的缩放;

     

    17.  模型视图矩阵

    --模型视图矩阵是一个4*4矩阵;

    --原始顶点坐标是一个四维向量,与模型视图矩阵相乘,得到变换后的新坐标;

    --注意:在数学上向量应该放在右边,左乘一个变换矩阵;

    --在OpenGL中,向量是行向量,矩阵式列主矩阵,相当于整体转置了;

     

    18.  平移:将一个向量沿着一个或者多个坐标轴方向移动。

    19.缩放:绕着三个坐标轴方向分别按照设定的因子放大或者缩小向量。

     

     

     

     

     

    第三讲

    1.    颜色只是某种波长的光,真实世界中的各种颜色是由许多不同类型的光组合而成的,这些类型的光是通过他们的波长来区分的。

     

    2.    光的波长是根据光波相邻波峰之间的距离来测量的。

    3.    白色的物体均匀的反射了所有波长的颜色;而黑色物体均匀的吸收了所有波长的颜色。

    4.    OpenGL通过分别制定红R、绿G、蓝B成分的强度来指定一种颜色。

    5.    对所有可用的颜色进行建模,创建立方体,成为RGB颜色空间;

    --原点(0,0,0),黑色;

    --对角线顶点(255,255,255),白色;

    --从原点到每根轴的方向,分别是红绿蓝的饱和分布;

     

    6.    光照模型就是用于计算几何物体表面任一点上的光亮度和色彩组成的数学计算公式。

    光照模型就是用数学方法来描述现实世界中的光照情况。

    局部光照模型:光强仅与被照明物体和光源有关;

    全局光照模型:光强与场景中任一点都相关;

     

    7.    局部光照模型:假定光是点光源,物体是非透明物体,且表面光滑,透射光和散射光近似于零。

    --局部光照模型中只考虑反射光的作用;

    --反射光包括环境光漫反射光镜面反射光

     

    8.    光照概述:

    光照通常是在纹理映射之前进行的;

    光照效果:

    --可以看到纹理贴图

    --光照可以大幅度增加场景的真实感

    --启用光照,将看不到物体表面的颜色信息;

    --启用光照,可以看到物体表面的材质信息;

    --物体表面的法线,将决定光的反射方向;

     

    9.    OpenGL中的光照模型:

    --环境光;

    --漫反射光;

    --镜面光;

     

    (1)环境光:

    --环境光并不来自任何特定的方向,他来自某个光源,但是光线在场景中四处反射;

    --环境光将物体的各个方向的表面均匀照亮;

    --颜色与旋转、观察角度无关;

     

    环境光是全局光源,只有颜色,没有方向和位置,且只有一个。

    OpenGL至少支持8个独立光源,具有位置照射方向

     

     

     

    (2)漫反射光:

    --OpenGL的漫反射光具有方向性,来自一个特定的方向;

    --根据入射光线的角度在表面均匀的反射,是分布在各个方向上的;

    --从任何角度看上去,光照效果都是一样的;

     

    (3)镜面光:

    --镜面光具有很强的方向性;

    --照射表面形成亮点;

    --反射方向几乎是一致的;

    --镜面反射可以使物体看起来闪闪发亮;

    --不同的角度,镜面反射的效果是不一样的;

     

    10.全局光照模型:光线跟踪算法,辐射度算法。

     

     

     

    第四讲

    1.    雾:可以使远处的物体呈现出朦胧的感觉,距离视点很远的物体几乎就看不见了。雾是一种有效的深度暗示。

    2.    积累缓冲区

    原理:

    (1)  OpenGL在渲染到颜色缓冲区之后,不是直接显示在窗口上,而是复制到积累缓冲区;

    (2)  在积累缓冲区反复混合后,再执行缓冲区交换进行显示。

     

    作用:

    (1)  使用不同的视点多次渲染场景,积累后可以达到整个场景的完全抗锯齿,效果优于多重采样;

    (2)  实现运动模糊的效果;

     

    3.    抖动:使用少量的颜色生成丰富的颜色。

     

    4.    位图和像素图

    --位图用2色(1位)表示一个点;

    --像素图用256色(8位)表示一个点;

     

     

    5.    将图像映射到屏幕的两种方式:

    (1)  使用像素图绘制:图像像素与屏幕像素严格对应;

    (2)  纹理贴图:图像像素经过一定变换后映射到屏幕像素;

     

    6.    纹理贴图:

    基本概念:

    (1)  纹理贴图就是把图像数据应用到三维图元中;

    (2)  纹理贴图给三维图形带来了丰富的表面特征;

    (3)  纹理单元是纹理中的个体图像元素;

     

    7.    凹凸纹理分为:

    (1)  位移映射;

    (2)  法线映射;

     

    8.    位移映射:位移贴图是使用高度图将经过纹理化的表面上实际几何点位置沿着表面法线根据保存在纹理中的数值进行移位的技术。

     

     

     

     

     

     

     

    第五讲

    1.    渲染:计算机根据模型创建图像

    --模型是由几何图元构成的,而几何图元是通过顶点来指定的,OpenGL将点、直线、多边形、图形和位图视为图元。

    --最终渲染的图像由屏幕像素组成;

     

    2.    渲染的过程:

    (1)  建模:使用几何图元建立模型,从而得到物体的数学描述;

    (2)  变换:在三维空间排列物体,选择观察场景的有利位置;

    (3)  着色:计算所有物体的颜色;

    (4)  光栅化:将物体的数学描述和相关的颜色信息转换为屏幕像素;

     

    3.    什么是渲染管线?

    当我们把绘制的图形传递给OpenGL后,OpenGL还要做许多才能完成3D空间到屏幕的投影。这一系列的过程称为OpenGL的渲染管线。

    一般的渲染步骤如下:

    (1)  显示列表;

    (2)  求值程序;

    (3)  顶点操作;

    (4)  图元装配;

    (5)  像素操作;

    (6)  纹理装配;

    (7)  光栅化;

    (8)  片段操作;

     

    4.    OpenGL建立三维模型的基本步骤:

    (1)  视点变换

    (2)  模型变换

    (3)  投影变换

    (4)  视口变换

    这样,一个三维空间里的物体就可以用相应的二维平面物体表示了,也就能在二维的计算机屏幕上正确显示了。

     

    5.    OpenGL中的渲染管线主要分为两个阶段:

    (1)  首先是基于顶点的操作,然后图元被光栅化,产生片段;

    (2)  在片段写入到帧缓冲之前进行纹理、雾和其他基于片段的操作

     

    6.    顶点处理分为4个阶段:顶点变换、光照、纹理坐标和变换、裁剪。

    7.    基于片段操作的结果是一个颜色值。

    8.    OpenGL着色语言(GLSL)是一种对GPU进行编程的高级语言,具有紧凑的代码,良好的可读性和更高的效率。

    GLSL的语法和C语言非常接近。

    GLSL使用两种类型的对象:着色器对象程序对象

     

    第六讲

    1.    什么是动画?

    (1)  从制作层面上讲:动画是指不使用真人表演拍摄,而是用各种技术手段产生的具有艺术价值的活动影像;

    (2)  从技术层面上讲:动画是将一系列静态图像顺序播放,利用人的视觉滞留效应,产生连续运动的观赏效果。

    视觉滞留效应:当被观察者的物体消失后,影像仍能在大脑中停留一段时间,大约为1/10s.

     

    2.    三维动画的种类:变形动画、骨骼动画。

    3.    动作引擎技术:与物理引擎类似,在游戏引擎中引入动作引擎。主要处理动作控制和动作反馈。

     

     

    第八讲(考试要点复习)

    1.    什么是OpenGL?

    (1)  OpenGL = Open Graphics Library

    (2)  定义:图形硬件的一种软件接口;

    (3)  最初由SGI创建,用于在不同硬件体系结构的图形设备上进行二维和三维图形的绘制;

    (4)  OpenGL不是编程语言,但是包含了GLSL,其特点是并行浮点矢量运算速度极快,但不能进行流程控制。

     

    2.    OpenGL的扩展机制:

    (1)  ARB:标准扩展;

    (2)  EXT:多家支持的扩展;

     

    3.    OpenGL与平台

    (1)  面向嵌入式平台的OpenGL ES;

    (2)  面向浏览器的WebGL;

    (3)  面向MS Windows的wgl;

    (4)  面向mac os的cgl;

    (5)  面向X Windows的glx;

     

    4.    OpenGL与相关工具

    (1)跨平台工具箱:GLUT = OpenGL Utility Toolkit

    --glut由SGI开发;

    --能够兼容win/linux/mac;

    --最新开源的freeglut;

     

    (2)处理扩展的包装库:GLEW

     

    5.    OpenGL状态机

    (1)  OpenGL使用一组状态变量的集合来保持图形渲染管线的状态;

    (2)  OpenGL使用了一种状态模型(状态机)来跟踪所有状态变量;

    (3)  当一个值被设置后,就一直保持这个状态;

    6.基本几何图元

    (1)GL_POINTS:每个顶点在屏幕上都是一个单独的点;

    (2)GL_LINES:每一对顶点定义一个线段;

    (3)GL_LINE_STRIP:从第一个顶点依次经过后续顶点而绘制的线条;

    (4)GL_LINE_LOOP:同上,但最后一个顶点和第一个顶点连接;

    (5)GL_TRIANGLES:每三个顶点定义一个新的三角形;

    (6)GL_TRIANGLE_STRIP:公用一个条带上的顶点的一组三角形;

    (7)GL_TRIANGLE_FAN:以一个原点为中心呈扇形排列,共用相邻顶点的一组三角形;

     

    6.    三角形的环绕属性:

    逆时针为正方向,可以通过glFrontFace(GL_CW)修改。

     

    7.    背面的剔除

    (1)  画家算法

    --将需要绘制的图元排序,首先绘制最远的,依次靠近;

    --低效和资源占用;

    (2)隐面剔除

    -- glEnable(GL_CULL_FACE)

    -- glDisable(GL_CULL_FACE)

     

    8.    深度测试的对比

    自遮挡的对象,没有启用深度测试就会产生显示错误。

     

    9.    多边形偏移:当图元的坐标非常接近,即使启用深度测试,也会产生闪烁,Z值相同的情况。

     

    10.  什么是向量?

    三维向量用一个三元组(X,Y,Z)表示。

    (1)  顶点是一个向量,表示空间中的一个位置;

    (2)  三维坐标可以表示一个向量,向量有长度,向量也有方向,所以,向量=向+量。

     

    11.  向量的定义

    (1)  向量是从坐标系原点到点(X,Y,Z)的带箭头的线段;

    (2)  空间中的一个点,既是顶点,又是向量;

     

    12.向量在图形中的作用

    (1)表示位置:顶点;

    (2)表示方向:视线方向,平面法线;

     

    13.单位向量

    (1)长度为1的向量称为单位向量;

    (2)将一个任意向量转化为单位向量,称为归一化,将该向量除以向量的长度。

    14.点乘

    (1)两个三维向量的点乘是一个标量;

    (2)表示一个向量投影到另外一个向量的长度;

    (3)在单位向量中,两个向量的点乘是其夹角的余弦值;

     

    15.叉乘

    (1)两个向量的叉乘得到的是垂直于这两个向量的第三个向量;

    (2)用途:计算平面的法向;

    (3)特点:顺序不可交换;

     

    16.矩阵

    (1)矩阵是一个由行和列构成的数据结构;

    (2)在程序中一般以二维数组存放;

    (3)OpenGL是以列主存放的;

     

    17.矩阵的作用:空间变换

    (1)三维空间中的仿射变换都是使用矩阵运算进行的:旋转、平移、缩放;

    (2)OpenGL中的矩阵:视图变换、模型变换、投影变换;

     

    19.  几个基本概念

    (1)  视图变换:设定观察者或摄像机的位置;

    (2)  模型变换:在场景中移动物体;

    (3)  模型视图:模型和视图的一致性;

    (4)  投影变换:设定视景体的大小和形状;

    (5)  视口变换:窗口缩放;

     

    20.  视图变换

    (1)  视图变换的作用就是设定观察者的位置,以及视线防线;

    (2)  可以理解为在场景中摆放摄像机:

    --摄像机所在的位置;

    --摄像机对准的方向;

    (3)在任何其他变换之前先用视图变换,能够保证与视觉坐标系一致;

    (4)默认从(0,0,0)看向Z轴负方向;

    (5)正投影中,视点在Z轴正无穷远处,可以看到视景体中的任何物体;

     

    21.  模型变换

    (1)  模型变换用于操作模型和其中的特定对象;

    (2)  将对象移动到需要的位置,然后进行旋转和缩放;

     

    22.  模型和视图的一致性:模型变换和视图变换最后形成一个统一的模型视图矩阵。

    23.  模型视图矩阵

    (1)  模型视图矩阵是一个4*4矩阵;

    (2)  原始顶点坐标是一个四维向量,与模型视图矩阵相乘,得到变换后的新坐标;

    (3)  注意:在数学上向量应该放在右边,左乘一个变换矩阵;

    (4)  在OpenGL中,向量是行向量,矩阵是列主矩阵,相当于整体转置了;

     

    24.  什么是投影?

    从三维裁剪空间到二维屏幕空间。

     

    25.  投影的方式及其特点?

    正投影

    透视投影

     

    26.  正投影

    特点:没有畸变,视觉不真实;

    主要用于建筑设计、CAD、或2D绘图。

    视景体为方形。

     

    27.  透视投影

    特点:近大远小,视觉真实。

    视景体为平截头体;

     

    28.  OpenGL通过分别指定红、绿、蓝成分的强度来指定一种颜色。

    29.  对所有可用的颜色进行建模,创建立方体,称为RGB颜色空间。

    --原点(0,0,0),黑色;

    --对角线顶点(255,255,255),白色;

    --从原点到每根轴的方向,分别是红绿蓝的饱和分布。

     

    30.  光照模型

    (1)  局部光照模型:光强仅与被照明的物体和光源有关;

    (2)  全局光照模型:光强与场景中任一点都相关;

     

    31.  局部光照模型:假定光是点光源,物体是非透明物体,且表面光滑,透射光和散射光将近似于零。

    --局部光照模型中只考虑反射光的作用;

    --反射光包括环境光漫反射光镜面反射光

     

    32.  环境光

    (1)  环境光并不来自任何特定的方向,他来自某个光源,但是光线在场景中四处反射。

    (2)  环境光将物体的各个方向的表面均匀照亮。

    (3)  颜色与旋转和观察角无关。

    (4)  照射在物体上的光来自各个方向,又均匀向各个方向反射

     

    33.  散射光

    (1)  OpenGL的散射光具有方向性,来自一个特定的方向;

    (2)  根据入射光线的角度在表面均匀地反射

    (3)  在点光源的照射下,物体表面的不同部分亮度不同,亮度的大小依赖于物体表面的朝向以及它与点光源之间的距离。

    (4)  漫反射特点:光源来自一个方向,反射光均匀地射向各个方向。

     

    34.  镜面光

    (1)  镜面光具有很强的方向性;

    (2)  照射表面形成亮点;

     

    35.  镜面反射

    (1)  反射方向是几乎一致的;

    (2)  镜面反射可以使物体看起来闪闪发光;

    (3)  不同的角度,镜面反射的效果是不一样的;

     

    36.  表面法线:法线的方向决定了多边形正面的朝向。

     

     

    37.  局部光照模型的局限:

    (1)  仅考虑从光源直接发出的光线对物体表面光亮度的贡献;

    (2)  没有考虑光线在物体之间的相互反射和透射。

     

    38.  全局光照模型:Whitted模型

    可模拟现实世界中景物表面之间的镜面反射透射现象的贡献。

     

    39.  Whitted模型

    假设从某一观察方向V所观察到的物体表面某点P的光亮度的贡献来自三个方面:

    (1)  由光源直接照射引起的反射光亮度;

    (2)  环境镜面反射光;

    (3)  环境规则透射光;

     

    40.  为什么会走样?

    连续几何空间离散屏幕像素之间的矛盾。

     

    41.  多重采样

    反锯齿功能的局限性:在复杂场景中,需要对所有图元进行前后排序。

     

    几个术语:

    全屏反锯齿;

    超级采样抗锯齿;

    多重采样抗锯齿;

     

    42.  积累缓冲区

    原理:

    (1)  OpenGL在渲染到颜色缓冲区之后,不是直接显示在窗口上,而是复制到积累缓冲区;

    (2)  在积累缓冲区反复混合后,再执行缓冲区交换进行显示;

     

    作用:

    (1)  使用不同的视点多次渲染场景,积累后可以达到整个场景的完全抗锯齿,效果优于多重采样;

    (2)  实现运动模糊效果;

     

    43.位图和像素图

    (1)位图用2色(1位)表示一个点;

    (2)像素图用256色(8位)表示一个点;

     

    43.  纹理贴图基本概念

    (1)  纹理贴图就是把图像数据应用到三维图元中;

    (2)  纹理贴图给三维图形带来了丰富的表面特征;

    (3)  纹理单元是纹理中的个体图像元素;

     

    44.  最临近过滤

    (1)  最临近过滤:会出现马赛克;

    (2)  线性过滤:平滑更接近真实;

     

    45.  为什么使用mipmapping?

    (1)  解决闪烁的问题;

    (2)  减少纹理加载的浪费;

    mipmapping纹理由一系列纹理图像组成,每个图形的大小都是前面的一半大小。

    Mipmapping是一种LOD技术

     

    46.  纹理对象

    (1)  纹理对象可以使我们一次加载多个图像,并且在这些纹理对象之间切换;

    (2)  纹理对象是一个无符号整数;

     

    47.  各向异性过滤

    (1)  对周围各个方向上的像素进行取样计算后映射到目标像素上的技术;

    (2)  与双线性过滤和三线性过滤相比,它在大角度显示方面具有更高的精度,令画面更逼真,但计算量也更大,对显卡的要求更高。

     

    48.  OpenGL渲染管线,什么是渲染管线?

    (1)  当我们把绘制的图形传递给OpenGL后,OpenGL还要做许多步骤才能完成3D空间到屏幕的投影,这一系列的过程称为OpenGL渲染流水线。

    (2)  一般的渲染流水线有如下几步:

    --显示列表;

    --求值程序;

    --顶点操作;

    --图元装配;

    --像素操作;

    --纹理装配;

    --光栅化;

    --片段操作;

     

     

    49.  OpenGL中的固定管线总结:OpenGL中的渲染管线主要分为两个阶段:

    (1)  首先是基于顶点的操作,然后图元被光栅化,产生片段;

    (2)  在片段写入到帧缓冲区之前进行纹理、雾以及其他基于片段的操作

     

    50.  固定的顶点处理:

    --基于顶点的阶段从一组顶点属性开始;

    --这些属性包括对象空间位置,法线,主颜色和辅助颜色以及纹理坐标;

    --基于顶点的处理的结果是裁剪空间位置、正面和背面主颜色和辅助颜色、一个雾坐标、纹理坐标、点大小;

    --顶点处理分为4个阶段:顶点变换、光照、纹理坐标变换、裁剪

     

    51.  固定的片段操作

    --用一个片段以及与它相关的数据作为输入,包括纹理坐标、主颜色和辅助颜色、雾坐标;

    --基于片段操作的结果是一个颜色值

    --基于片段的固定功能管线分为4个阶段:

    (1)纹理应用和环境;

    (2)颜色求和;

    (3)雾应用;

    (4)抗锯齿应用;

     

    52.可编程渲染管线

    --使用着色器替代固定管线中的部分阶段;

    --着色器也可以称为程序;

    --着色器实质是应用程序所定义的自定义程序,用于接替固定功能管线阶段的职责;

     

    52.  OpenGL着色语言

    --OpenGL着色语言(GLSL)是一种对GPU进行编程的高级语言,具有紧凑的代码,良好的可读性和更高的效率;

    --GLSL语法和C语言的非常接近;

     

    53.  着色器对象

    --GLSL使用两种类型的对象:着色器对象程序对象

    --着色器对象加载着色器文本并对它进行编译;

    --着色器对象是最小的作用单元,但是不能独立运行,需要绑定到“程序”中执行。

     

    54.  着色器统一值

    --属性是每个顶点位置、表面法向和纹理坐标等都需要的,而统一值则用于整个图元批次想保持不变的着色器传递数据;

    --对于顶点着色器,统一值可能是变换矩阵;

    --统一值是只读的;

     

    55.  高度图和凹凸纹理

    --使用高度图的像素值确定物体表面的光照特性;

    --凹凸纹理分为:位移映射和法线映射;

     

    位移映射:位移贴图是使用高度图将经过纹理化的表面上实际几何点位置沿着表面法线根据保存在纹理中的数值进行移位的技术。

     

     

    56.  顶点数组:使用顶点数组可以加速数据载入,在多次绘制间保存和共享数据。

     

    57.  索引顶点数组:索引顶点数组不是按顺序从头遍历顶点数组,由一个单独的索引数组指定。

    优点:两个三角形带之间共享顶点,节省内存,减少变换开销;

     

    58.  动画的分类:

    按照制作方式分类:

    (1)  传统动画:手绘动画;

    (2)  定格动画:粘土动画、木偶动画;

    (3)  计算机动画:二维动画、三维动画;

     

    59.  三维动画的种类

    (1)  变形动画;

    (2)  骨骼动画;

     

    60.  变形动画的优点:

    (1)  能够精细的控制形状的变化;

    (2)  针对面部表情动画特别适用;

     

    变形动画的缺点:

    (1)  动画数据量大;

    (2)  制作复杂度高;

    (3)  很难在多个角色间重用;

     

    61.  骨骼动画技术:

    --模型创建;

    --骨骼创建;

    --骨骼绑定;

    --动画设定:关键帧、动作数据

     

    62.  朝向的表示:

    (1)  使用矩阵表示;

    (2)  使用欧拉角;

    (3)  使用四元数;

     

    63.  动作捕捉的优点:

    --真实记录了每个动作细节;

     

    缺点:

    --难以修改:对动作数据的修改很容易导致失真;

    --难以控制:没有很好的方法对捕获的动作进行控制;

    --难以重用:应用到不同的角色、骨架;

     

     

    其他:

    1.    视口映射

    --把视图坐标映射到窗口坐标;

    --从逻辑笛卡尔坐标映射到物理屏幕像素坐标;

    --视口就是窗口内部用于绘制裁剪区域的客户区域;视口不一定是整个窗口,逻辑坐标的每个单位不一定与屏幕像素一一对应。

     

    2.    着色器

    (1)  顶点着色器;

    (2)  片段着色器;

     

    3.    深度测试也是一个高效消除隐藏表面的技术。

    自遮挡的对象,没有启用深度测试就会产生显示错误。

     

    4.    多边形偏移:当图元的坐标非常接近,z值相同的情况,即使启用了深度测试,也会产生闪烁。

     

    5.模型变换和视图变换之后形成一个统一的视图模型矩阵。

     

    5.    投影变换其实是定义了视景体并创建了裁剪平面。

    6.    OpenGL中的矩阵不是二维数组、而是一维数组;

    7.    局部光照模型只考虑反射光的作用;

    8.    法线方向决定了多边形正面的朝向。

    9.    所谓的镜面加亮,就是几乎所有光线都照射在一个物体的表面并发射回来。

    10.  OpenGL中光源本身是不能被看到的。

    11.  Whitted模型的解法:光线跟踪算法、辐射度算法;

    12.  渲染的过程:建模、变换、着色、光栅化;

     

    13.  关键帧动画

    --动画师指定少量关键帧的骨骼姿势;

    --计算机通过差值算法计算中间姿势;

     

    14.  插值技术:线性插值,非线性插值;

     

    线性插值技术:

    优点:实现单一、计算快速;

    缺点:运动单一、过渡生硬;

     

    非线性插值技术:

    优点:过渡运动连续;

     

    15.  朝向的表示:矩阵、欧拉角、四元数。

    16.  动作引擎技术主要处理动作控制和动作反馈。

    17. 处理扩展的包装库:GLEW;

     

    17.  OpenGL状态机

    (1)  OpenGL使用了一组状态变量的集合来保持图形渲染管线的状态;

    (2)  OpenGL使用了一种状态模型(状态机)来跟踪所有状态变量;

    (3)  当一个值被设置后,就一直保持这个状态;

     

    18.  向量在图形学中的作用:

    表示位置:顶点;

    表示方向:视线方向,平面法向;

     

    矩阵的作用:空间变换;

     

    19.  视图变换:

    视图变换的作用就是设定观察点的位置,以及视线方向。

    可以理解为在场景中摆放摄像机

    a)      摄像机所在的位置

    b)      摄像机对准的方向

    c)       在任何其他变换之前应用视图变换,能够保证与视觉坐标系一致!

    默认从(0,0,0)看向Z轴负方向

    正投影中,视点在Z轴正无穷远处,可以看到视景体中的任何物体

     

     

    20.  模型变换:

    模型变换用于操纵模型和其中的特定对象

    将对象移动到需要的位置,然后进行旋转和缩放

     

    21.  模型视图矩阵:

    模型视图矩阵是一个4x4矩阵

    原始顶点坐标是一个四维向量,与模型视图矩阵相乘,得到变换后的新坐标

    注意:在数学上向量应该放在右边,左乘一个变换矩阵

    在OpenGL程序中,向量是行向量,矩阵是列主矩阵,相当于整体转置了

     

    22.  欧拉角:

    Yaw(偏航):欧拉角向量的y轴

    Pitch(俯仰):欧拉角向量的x轴

    Roll(翻滚): 欧拉角向量的z轴

     

    23.  环境光:

    环境光并不来自任何特定的方向,他来自某个光源,但是光线在场景中四处反射

    环境光将物体的各个方向的表面均匀照亮

    颜色与旋转和观察角度无关

     

    24.  法线平均:

    每个多边形一个法线:球面不够光滑

    每个顶点一个法线:法线如何计算

    a)      计算顶点相邻多边形分别计算法线

    b)      平均球的该顶点的法线

     

    25.  雾的变化曲线

    GL_EXP:模糊程度随着距离快速增强

    GL_EXP2:近处更清楚,远处更模糊

     

    26.  积累缓冲区:

    原理:

    1、OpenGL在渲染到颜色缓冲区之后,不是直接显示在窗口上,而是复制到积累缓冲区

    2、在积累缓冲区反复混合后,再执行缓冲区交换进行显示

    作用:

    1、使用不同的视点多次渲染场景,积累后可以达到整个场景的完全抗锯齿,效果优于多重采样

    2、实现运动模糊的效果

     

    27. 为什么使用Mipmapping

    –     1、解决闪烁的问题

    –     2、减少纹理加载的浪费

    mipmapping纹理由一系列纹理图像组成,每个图形的大小都是前面的一半大小

     

    正方形的图像经过Mipmapping会增加1/3的大小

     

    27.  各向异性过滤

    --对周围各个方向上的像素进行取样计算后映射到目标像素上的技术。

    --与双线性过滤和三线性过滤相比,它在大角度显示方面具有更高的精度,令画面更逼真,但计算量也更大对显卡的要求更高。

     

    28. 使用高度图(Heightmap)的像素值确定物体表面的光照特性

    凹凸纹理(Bump mapping)分为:

    –     1、位移映射

    –     2、法线映射

     

    28.  传统动画的制作流程:

    (1)创建剧本

    (2)创建主要角色

    (3)绘制故事版(Story Board)

    (4)高级动画师绘制关键帧(Key frame)

    (5)初级动画师绘制中间帧(In-between)

    (6)使用摄像机逐个图片拍摄

    (7)使用放映机按照一定帧率播放

     

    29.  动作捕捉的特点:

    优点:

    a)      真实记录了每个动作细节

    缺点:

    b)      难以修改

    c)       难以控制

    d)      难以重用

     

    展开全文
  • openGL 3D图形和openGL简介

    千次阅读 2017-07-13 20:38:18
    基本概念与说明OpenGL是一个图形API,用来绘制三维物体(也可以是2D物体),OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL三维图形 API 的子集。 Android平台下,对于OpenGL ES有一套Java的封装,唯一非Java...
  • 安徽地产企业宣传片,合肥做制作地产三维动画公司,为芜湖-六安房地产制作公司,合肥地产三维动公司.
  • 从这篇文章开始,接下来会连载一系列的OpenGL相关博文,好好探讨...对于Android开发者来说,OpenGL就是用来绘制三维图形的技术手段,当然OpenGL并不仅限于展示静止的三维图形,也能用来播放运动着的三维动画。不管是三
  • matlab 画三维动画

    千次阅读 2015-12-09 11:16:02
    set(gcf, 'doublebuffer', 'on') for i=1:length(x)  plot3(x(1:i),y(1:i),z(1:i),'*');  axis([-0.5 2.5 -1.0 3.0 2.2 2.5 -1 1]);  drawnow;  pause(0.1); end
  • OpenGL导入三维模型

    千次阅读 2015-06-20 15:07:41
    这周为了游戏课的大作业尝试了用OpenGL导入三维模型,特在此记录以防忘记。 现在我已知的导入三维模型的方式有两种,一是3DS,一是MD2 3ds可以用3dmax直接导出,但是貌似只能静态的 MD2需要利用插件导出...
  • 三维动画制作流程细节

    千次阅读 2014-02-20 13:18:14
    随着三维技术的成熟,三维动画运用到各种宣传手法中,三维动画带给人不一样的视觉体验。今天江苏风雷传媒给大家讲解三维动画的整个流程细节: 1.前期策划 1)剧本,造型设定,故事板也称做为脚本。 2)概念设计—...
  • OPENGL三维图形绘制讨论

    千次阅读 2008-02-21 15:28:00
    由于OpenGL(Open GraphicsLibrary)具有跨平台性、简便、高效、功能完善,目前已经成为了三维图形制作方法中事实上的工业标准。自从WindowsNT3.51在微机平台上支持OpenGL以后,现在微软公司在Windows95OSR2、Windo
  • C#利用DirectX显示.x三维动画

    千次阅读 2015-07-16 10:48:37
    C# winform 利用DirectX技术载入.x文件进行三维动画展示!
  • ArcGlobe3D开发
  • 如何利用R语言画出三维动画

    万次阅读 2015-05-04 17:03:02
    rgl包提供了OpenGL图形库的3D绘图接口,我们可以利用play3d()函数画出三维散点图,之后利用surface3d()在三维图上添加预测曲面,然后再用movie3d()函数让三维图动起来。 注:以上程序参考《R数据可视化手册》
  • QT与OpenGL三维旋转

    千次阅读 2012-12-11 13:17:50
    在这篇文章中,将要展现的效果是在3D场景中移动位图,得到简单的动画效果。便于大家共同学习,给出全部代码: 在开始前,你应该在pro中添加 LIBS += glut.lib glut32.lib 同时你也应该将这两个库加到QT的bin目录...
  • MD2文件的读取及三维动画显示

    千次阅读 2010-03-12 11:03:00
    摘要 本文介绍了运用OpenGL,通过读取MD2文件开发复杂三维动画的方法,从而实现OpenGL与其它软件相结合创建复杂场景的能力,为快速开发复杂三维动画程序提供了捷径,并给出了一个实例。关键词 开放图形库; 文件...
  • ArcGlobe三维开发之六——动画(前言)

    千次阅读 2014-04-04 11:49:29
    在Globe下使用动画可以让用户以一种动态
  • 在研究机械臂运动,想用opengl实现 根据 实时传回 的机械臂关节点(6个及以内)空间坐标数据 来显示 机械臂运动过程中的 三维位姿 模拟运动 动画。 注:1.机械臂运动缓慢; 2. 机械臂可以用 圆柱 模拟代替 ,但动画...
  • 动画开发中,录制的一个动画可能只有一个Track也可能有多个Track。前面的博文提到动画的实现方式有两种,这里采用基于Camera的动画。这里我做的比较简单,首先来看实现效果图: 下面,我们来看,如何在Globe下...
  • VTK简单三维模型动画

    千次阅读 2018-11-27 15:01:49
    VTK在linux 下cmake make时很多案例过不去,有如下提示—— error This file requires compiler and library support for the ISO C++ 2011 standard 可以通过下边的方法解决该问题—— 打开CMakeLists.txt ...
  • Maya 2019 for Mac(玛雅三维动画软件)Maya2019 Mac永久激活版 Maya2019中文版是三维动画、建模、仿真和渲染软件,为用户提供了一个功能强大的集成工具集;可用于动画、环境、运动图形、虚拟现实和角色创建。maya ...
  • 动画的实现方式主要有两种:IAnimationTrack和ICamera。 一、Animation (1)、基于关键帧 (2)、设置每个关键帧的ImeStamp来确定播放时间(该帧占总播放时间的百分比) (3)、便于使用,集成了视频输出接口。可...
  • 例子路径:C:\codetyphon\CodeOcean\OpenGL\samples\b_ParticleLines  可执行程序下载:http://pan.baidu.com/s/1jGnBswA 2M多一点!   源码下载:http://pan.baidu.com/s/1nt5glLJ         aaaa
  • 三维动画类别及应用领域,在所有不同类型的动画中,三维动画是最有魅力并应用最广泛的,从简单的几何体模型,到复杂的人物模型;从静态、单个的产品展示,到动态、复杂的场景如房产酒店三维漫游、三维虚拟城市等,...
  • 这里我封装了一个生成动画的类,用于动画的操作,目前只是实现了动画的生成,动画的保存以及动画的加载,后面的博文再陆续探讨动画的播放控制等功能。创建动画类代码如下: /// /// 根据路径创建飞行动画 /// ...
  • wpf实现三维漫游动画效果

    千次阅读 2008-03-20 10:45:00
    wpf技术支持在2D应用程序中进行3D模型的渲染和交互操作,这使得我们的程序在展现方面更具有视觉冲击力,更能使人机交互的体验有“身临其境”的感觉。下面我展示一个自己做的demo给大家体验下3d场景漫游效果。...

空空如也

1 2 3 4 5 ... 20
收藏数 71,575
精华内容 28,630
关键字:

三维动画