1 / 51

基于 OpenGL 的三维光照简介

基于 OpenGL 的三维光照简介. 上节课主要内容. 三维绘制流程 三维绘制中的变换 照相机系统和相机模型. Quake II (Id Software). 主要授课内容. 一般的 OpenGL 介绍 绘制元素:点、线、三角形 绘制模式 光照 纹理映射 绘制属性设置. 应该掌握的内容. 应该能写一个基本的交互图形绘制程序,包括: 三维物体绘制流程 光照 纹理映射 能为以后的高级课题打下基础. 光照的基本原理. • 光照参数 光源 物体表面材质 空气衰减 相机成像. 光照模拟. OpenGL?. 图形绘制 API

laurie
Download Presentation

基于 OpenGL 的三维光照简介

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 基于OpenGL的三维光照简介

  2. 上节课主要内容 • 三维绘制流程 • 三维绘制中的变换 • 照相机系统和相机模型

  3. Quake II (Id Software) 主要授课内容 • 一般的OpenGL介绍 • 绘制元素:点、线、三角形 • 绘制模式 • 光照 • 纹理映射 • 绘制属性设置

  4. 应该掌握的内容 • 应该能写一个基本的交互图形绘制程序,包括: • 三维物体绘制流程 • 光照 • 纹理映射 • 能为以后的高级课题打下基础

  5. 光照的基本原理 • 光照参数 • 光源 • 物体表面材质 • 空气衰减 • 相机成像

  6. 光照模拟

  7. OpenGL? • 图形绘制API • 高质量的、专业级的绘制引擎 • 跨平台 • 跨操作系统 • 1990年由SGI公司推出

  8. 顶点操作 求值器 显示列表 逐个象素操作 帧缓冲 CPU 光栅化 纹理 后象素处理 OpenGL 架构

  9. OpenGL 的绘制功能 • 支持的几何元素 • 点、线、多边形 • 图像元素 • 图像与位图 • 对于几何和图像有不同的渲染管道 • 通过纹理映射连接起来 • 绘制状态机 • 颜色, 材质, 光源等.

  10. 编程起步 • 头文件 • #include <GL/gl.h> • #include <GL/glu.h> • #include <GL/glut.h> • 库文件:opengl.lib, glaux.lib, glu32.lib • 支持类型(系统之间兼容) • GLfloat, GLint, GLenum, etc.

  11. GLUT • 一个教学、培训用的跨平台的API • 主要功能 • 配置与开窗口 • 初始化 OpenGL 状态 • 重要的Callback 函数 • Render:绘制 • Resize:窗口大小变化的时候重新设置视区等 • input: 键盘、鼠标等. • 输入事件处理循环

  12. Glut例程 void main( int argc, char** argv ) { //RGB模式、双缓冲区 int mode = GLUT_RGB|GLUT_DOUBLE; //初始化图形模式 glutInitDisplayMode( mode ); //创建窗口 glutCreateWindow( argv[0] ); init(); //绘制回调函数 glutDisplayFunc( display ); // Resize回调函数 glutReshapeFunc( resize ); //鼠标输入回调函数 glutKeyboardFunc( key ); //Idle函数 glutIdleFunc( idle ); //事件处理循环 glutMainLoop(); }

  13. OpenGL 初始化 设置OpenGL状态 void init( void ) { //屏幕清为黑色 glClearColor( 0.0, 0.0, 0.0, 1.0 ); //深度清为最远处(0.0-1.0) glClearDepth( 1.0 ); //打开光源0 glEnable( GL_LIGHT0 ); //打开光照 glEnable( GL_LIGHTING ); //深度测试 glEnable( GL_DEPTH_TEST ); }

  14. GLUT 回调函数 • 当某个事件发生时,所调用的函数 • 窗口的尺寸变换、重绘函数 • 用户输入 • 动画 • “注册” 回调函数 glutDisplayFunc( display ); glutIdleFunc( idle ); glutKeyboardFunc( keyboard );

  15. 绘制回调函数 void display( void ) { //对颜色缓冲区清零 glClear( GL_COLOR_BUFFER_BIT ); //绘制三角形带 glBegin( GL_TRIANGLE_STRIP ); glVertex3fv( v[0] ); glVertex3fv( v[1] ); glVertex3fv( v[2] ); glVertex3fv( v[3] ); glEnd(); //交换缓冲区 glutSwapBuffers(); }

  16. Idle 回调函数 可用于动画制作,连续更新画面 glutIdleFunc( idle ); void idle( void ) { //时间变化 t += dt; glutPostRedisplay(); }

  17. 用户输入回调函数 • 处理键盘输入 glutKeyboardFunc( keyboard ); void keyboard( unsigned char key, int x, int y ) { switch( key ) { case ‘q’ : case ‘Q’ : exit( EXIT_SUCCESS ); break; case ‘r’ : case ‘R’ : rotate = GL_TRUE; glutPostRedisplay(); break; } }

  18. 基本绘制流程 • 几何基本元素 • OpenGL状态管理 • OpenGL 缓冲器管理

  19. GL_LINES GL_POLYGON GL_LINE_STRIP GL_LINE_LOOP GL_POINTS GL_TRIANGLES GL_QUADS GL_TRIANGLE_FAN GL_TRIANGLE_STRIP GL_QUAD_STRIP OpenGL 几何元素 • 所有的几何元素由顶点给出

  20. 简单的绘制例子 void drawRhombus( GLfloat color[] ) { glBegin( GL_QUADS ); glColor3fv( color ); glVertex2f( 0.0, 0.0 ); glVertex2f( 1.0, 0.0 ); glVertex2f( 1.5, 1.118 ); glVertex2f( 0.5, 1.118 ); glEnd(); }

  21. OpenGL 命令格式 glVertex3fv( v ) 数据类型 向量 元素数目 b - byte ub - unsigned byte s - short us - unsigned short i - int ui - unsigned int f - float d - double omit “v” for scalar form glVertex2f( x, y ) 2 - (x,y) 3 - (x,y,z) 4 - (x,y,z,w)

  22. 指定几何元素 • 绘制基本元素的指定方式 glBegin( primType ); glEnd(); • primType决定顶点的组织方式 • GLfloat red, green, blue; • Glfloat coords[3]; • glBegin( primType ); • for ( i = 0; i < nVerts; ++i ) { • glColor3f( red, green, blue ); • glVertex3fv( coords ); • } • glEnd();

  23. 基本元素实例(演示)

  24. 绘制模式

  25. OpenGL状态机 • 所有绘制数学都封装在OpenGL状态中 • 绘制风格 • 绘制方程 • 光照 • 纹理映射

  26. OpenGL 状态处理 • 绘制结果由当前状态设定 for each ( primitive to render ) { update OpenGL state render primitive } • 逐个顶点设置状态的方式 glColor*() / glIndex*() glNormal*() glTexCoord*()

  27. 状态控制的一般方式 • 设置状态 glPointSize( size ); //点的尺寸 glLineStipple( repeat, pattern );//线绘风格 glShadeModel( GL_SMOOTH );//渲染模型 • 打开或关闭某个属性 glEnable( GL_LIGHTING );//打开光照 glDisable( GL_TEXTURE_2D );//关闭二维纹理

  28. OpenGL中的变换 • 建模 • 相机变换 • 相机定位 • 投影 • 相机运动 • 投影到屏幕

  29. OpenGL例子(Look At相机) Void DisplayScene () { glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0f, 0.0f, 0.0f); glLoadIdentity (); gluLookAt (0.0, 0.0, 10.0, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0); glBegin (GL_TRIANGLE); glVertex3f (10.0f, 0.0f, 0.0f); glVertex3f (0.0f, 10.0f, 0.0f); glVertex3f (-10.0f, 0.0f, 0.0f); glEnd(); glFlush (); }

  30. 设置相机的另一种方法: 变换场景 • gluLookAt函数显式地定义相机。另外一种方法式将场景进行旋转(glRotate)和平移(glTranslate)同时,将相机置于缺省的世界坐标系统. • 旋转和平移的累积效果构成了最终的相机变换. • 当然, glTranslate和 glRotate也可用作其他用途

  31. OpenGL例子(变换场景) //viewing a scene centered at origin from +X direction: Void DisplayScene () glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0f, 0.0f, 0.0f); glLoadIdentity (); glTranslatef (0.0, 0.0, -10.0); glRotatef (-90.0, 0.0, 1.0, 0.0); // glBegin (GL_TRIANGLE); glVertex3f (10.0f, 0.0f, 0.0f); glVertex3f (0.0f, 10.0f, 0.0f); glVertex3f (-10.0f, 0.0f, 0.0f); glEnd(); glFlush (); }

  32. ModelView 矩阵 • ModelView变换式建模矩阵M和相机变换V的乘积 C = VM • 所有在OpenGL中的变换函数只能设置modelview 矩阵. 因此, ModelView 在物体被操作之前被调用. • 例如: glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glScalef (2.0f, 2.0f, 2.0f); DrawScene ();

  33. ModelView 矩阵堆栈 • 矩阵堆栈的顶部矩阵就是当前的ModelView 矩阵 (C). • glPushMatrix ():将当前的矩阵加入到矩阵堆栈 • glPopMatrix ():将顶部矩阵删除,并将所有其他矩阵往上移动一位。 • 矩阵堆栈的好处:允许一系列位置(代表了坐标系统)保留下来,并在需要的时候使用它们。 M1 M2 M3

  34. 矩阵阵列 • 建模变换: • glLoadIdentity : C  I • glLoadMatrix(m) : C  m • glMultiMatrix(m) : C  C m • glRotatef(q,x,y,z) : C  C RL(q) • glTranslatef(x,y,z) : C  C T(x,y,z) • glScalef(x,y,z) : C  C S(x,y,z) • 最后定义的变换最先被执行.

  35. 投影变换 • 投影变换设置视域体,从而定义裁剪面和投影矩阵以及投影方式。 • 投影矩阵在ModelView矩阵之后被实行,因此,视域体是定义 在相机坐标系统中的。 • 透视投影与平行投影

  36. 平行(正交)投影 • 定义正交视域体: glOrtho (left, right, bottom, top, near, far); 或者:glOrtho2D (left, right, bottom, top); • 定义投影矩阵: glMatrixMode (GL_PROJECTION); glLoadIdentity ( ); glOrtho (left, right, bottom, top, near, far) 视域体 • (Left, righ, bottom, top) 定义视域体的最小、最大的 X 和Y坐标; (near, far) 定义视域体的近和远平面到X-Y平面的距离. Y 成像平面 X VCS Z

  37. 透视投影 • 视域四堎锥的定义: glFrustum (left, right, bottom, top, near, far) • 视域体的形成是:将原点与前面的四个顶点连接起来,并由Z方向的近平面和远平面限制。 • 投影矩阵 glMatrixMode (GL_PROJECTION); glLoadIdentity (); glFrustum(left, right, bottom, top, near, far) 视域四堎锥 Y 成像平面 X 原点 Z

  38. 透视投影(II) • 视域体的定义 glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (angle, aspect, near, far) angle: y方向张的视角 aspect:方正率 (成像平面的宽度/高度). Y X Z

  39. 视区 • 视区是窗口的绘制区域,特殊的视区是全屏幕 • 缺省视区是窗口本身 • 视区矩阵将投影后的成像平面投到视区 glViewport (GLint left, GLint bottom, GLint width, GLint height) • (left, bottom, width, height) 定义在窗口系统中(象素级) 窗口 (right, top) 视区 (left, bottom)

  40. 用户定义矩阵 • 可随意装入矩阵: GLfloat m[16] = {1.0, 0.0, 0.0, ……}; glLoadMatrixf (m); • 矩阵乘法: glMultMatrixf (m);

  41. 变换实例(演示)

  42. 投影变换实例(演示)

  43. 深度缓冲与动画生成 • 双缓冲区机制与动画 • 用深度缓冲进行消隐

  44. Per Vertex Poly. Frag FB Raster CPU DL Texture Pixel 1 1 2 2 4 4 Front Buffer Back Buffer 8 8 16 16 Display 双缓冲机制

  45. 利用双缓冲进行动画设置 • 需要初始化一个颜色双缓冲glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); • 清除颜色缓冲区 glClear( GL_COLOR_BUFFER_BIT ); • 绘制场景 • 将前缓冲器与后缓冲器交换 glutSwapBuffers(); • 重复 2 – 4步,获得动画效果

  46. 1 1 2 2 4 4 Color Buffer Depth Buffer 8 8 16 16 Display 深度缓冲器与消隐

  47. OpenGL中的深度缓冲 • 深度缓冲器设置 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); • 打开深度测试 glEnable( GL_DEPTH_TEST ); • 对颜色和深度缓冲器清零 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); • 绘制场景 • 交换颜色缓冲器

  48. 动画示例 void main( int argc, char** argv ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); glutCreateWindow( “Tetrahedron” ); init(); glutIdleFunc( idle ); glutDisplayFunc( display ); glutMainLoop(); }

  49. 动画示例(续) • void init( void ){ glClearColor( 0.0, 0.0, 1.0, 1.0 );}void idle( void ){ glutPostRedisplay();}

  50. 动画示例(续) • void drawScene( void ) • { GLfloat vertices[] = { … }; GLfloat colors[] = { … }; glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glBegin( GL_TRIANGLE_STRIP ); /* calls to glColor*() and glVertex*() */ glEnd(); glutSwapBuffers(); • }

More Related