Opengl
This presentation is the property of its rightful owner.
Sponsored Links
1 / 51

基于 OpenGL 的三维光照简介 PowerPoint PPT Presentation


  • 131 Views
  • Uploaded on
  • Presentation posted in: General

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

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Opengl

基于OpenGL的三维光照简介


Opengl

上节课主要内容

  • 三维绘制流程

  • 三维绘制中的变换

  • 照相机系统和相机模型


Opengl

Quake II

(Id Software)

主要授课内容

  • 一般的OpenGL介绍

  • 绘制元素:点、线、三角形

  • 绘制模式

  • 光照

  • 纹理映射

  • 绘制属性设置


Opengl

应该掌握的内容

  • 应该能写一个基本的交互图形绘制程序,包括:

    • 三维物体绘制流程

    • 光照

    • 纹理映射

  • 能为以后的高级课题打下基础


Opengl

光照的基本原理

• 光照参数

  • 光源

  • 物体表面材质

  • 空气衰减

  • 相机成像


Opengl

光照模拟


Opengl1

OpenGL?

  • 图形绘制API

    • 高质量的、专业级的绘制引擎

    • 跨平台

    • 跨操作系统

    • 1990年由SGI公司推出


Opengl2

顶点操作

求值器

显示列表

逐个象素操作

帧缓冲

CPU

光栅化

纹理

后象素处理

OpenGL 架构


Opengl3

OpenGL 的绘制功能

  • 支持的几何元素

    • 点、线、多边形

  • 图像元素

    • 图像与位图

    • 对于几何和图像有不同的渲染管道

      • 通过纹理映射连接起来

  • 绘制状态机

    • 颜色, 材质, 光源等.


Opengl

编程起步

  • 头文件

    • #include <GL/gl.h>

    • #include <GL/glu.h>

    • #include <GL/glut.h>

  • 库文件:opengl.lib, glaux.lib, glu32.lib

  • 支持类型(系统之间兼容)

    • GLfloat, GLint, GLenum, etc.


  • Opengl

    GLUT

    • 一个教学、培训用的跨平台的API

    • 主要功能

      • 配置与开窗口

      • 初始化 OpenGL 状态

      • 重要的Callback 函数

        • Render:绘制

        • Resize:窗口大小变化的时候重新设置视区等

        • input: 键盘、鼠标等.

      • 输入事件处理循环


    Opengl

    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();

    }


    Opengl4

    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 );

    }


    Opengl

    GLUT 回调函数

    • 当某个事件发生时,所调用的函数

      • 窗口的尺寸变换、重绘函数

      • 用户输入

      • 动画

    • “注册” 回调函数

      glutDisplayFunc( display );

      glutIdleFunc( idle );

      glutKeyboardFunc( keyboard );


    Opengl

    绘制回调函数

    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();

    }


    Opengl

    Idle 回调函数

    可用于动画制作,连续更新画面

    glutIdleFunc( idle );

    void idle( void )

    {

    //时间变化

    t += dt;

    glutPostRedisplay();

    }


    Opengl

    用户输入回调函数

    • 处理键盘输入

      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;

      }

      }


    Opengl

    基本绘制流程

    • 几何基本元素

    • OpenGL状态管理

    • OpenGL 缓冲器管理


    Opengl5

    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 几何元素

    • 所有的几何元素由顶点给出


    Opengl

    简单的绘制例子

    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();

    }


    Opengl6

    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)


    Opengl

    指定几何元素

    • 绘制基本元素的指定方式

      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();


    Opengl

    基本元素实例(演示)


    Opengl

    绘制模式


    Opengl7

    OpenGL状态机

    • 所有绘制数学都封装在OpenGL状态中

      • 绘制风格

      • 绘制方程

      • 光照

      • 纹理映射


    Opengl8

    OpenGL 状态处理

    • 绘制结果由当前状态设定

      for each ( primitive to render ) {

      update OpenGL state

      render primitive

      }

    • 逐个顶点设置状态的方式

      glColor*() / glIndex*()

      glNormal*()

      glTexCoord*()


    Opengl

    状态控制的一般方式

    • 设置状态

      glPointSize( size ); //点的尺寸

      glLineStipple( repeat, pattern );//线绘风格

      glShadeModel( GL_SMOOTH );//渲染模型

    • 打开或关闭某个属性

      glEnable( GL_LIGHTING );//打开光照

      glDisable( GL_TEXTURE_2D );//关闭二维纹理


    Opengl9

    OpenGL中的变换

    • 建模

    • 相机变换

      • 相机定位

      • 投影

    • 相机运动

    • 投影到屏幕


    Opengl look at

    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 ();

    }


    Opengl

    设置相机的另一种方法: 变换场景

    • gluLookAt函数显式地定义相机。另外一种方法式将场景进行旋转(glRotate)和平移(glTranslate)同时,将相机置于缺省的世界坐标系统.

    • 旋转和平移的累积效果构成了最终的相机变换.

    • 当然, glTranslate和 glRotate也可用作其他用途


    Opengl10

    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 ();

    }


    Modelview

    ModelView 矩阵

    • ModelView变换式建模矩阵M和相机变换V的乘积 C = VM

    • 所有在OpenGL中的变换函数只能设置modelview 矩阵. 因此, ModelView 在物体被操作之前被调用.

    • 例如:

      glMatrixMode (GL_MODELVIEW);

      glLoadIdentity ();

      glScalef (2.0f, 2.0f, 2.0f);

      DrawScene ();


    Modelview1

    ModelView 矩阵堆栈

    • 矩阵堆栈的顶部矩阵就是当前的ModelView 矩阵 (C).

    • glPushMatrix ():将当前的矩阵加入到矩阵堆栈

    • glPopMatrix ():将顶部矩阵删除,并将所有其他矩阵往上移动一位。

    • 矩阵堆栈的好处:允许一系列位置(代表了坐标系统)保留下来,并在需要的时候使用它们。

    M1

    M2

    M3


    Opengl

    矩阵阵列

    • 建模变换:

      • 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)

    • 最后定义的变换最先被执行.


    Opengl

    投影变换

    • 投影变换设置视域体,从而定义裁剪面和投影矩阵以及投影方式。

    • 投影矩阵在ModelView矩阵之后被实行,因此,视域体是定义 在相机坐标系统中的。

    • 透视投影与平行投影


    Opengl

    平行(正交)投影

    • 定义正交视域体:

      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


    Opengl

    透视投影

    • 视域四堎锥的定义:

      glFrustum (left, right, bottom, top, near, far)

    • 视域体的形成是:将原点与前面的四个顶点连接起来,并由Z方向的近平面和远平面限制。

    • 投影矩阵

      glMatrixMode (GL_PROJECTION);

      glLoadIdentity ();

      glFrustum(left, right, bottom, top,

      near, far)

    视域四堎锥

    Y

    成像平面

    X

    原点

    Z


    Opengl

    透视投影(II)

    • 视域体的定义

      glMatrixMode (GL_PROJECTION);

      glLoadIdentity ();

      gluPerspective (angle, aspect, near, far)

    angle: y方向张的视角

    aspect:方正率 (成像平面的宽度/高度).

    Y

    X

    Z


    Opengl

    视区

    • 视区是窗口的绘制区域,特殊的视区是全屏幕

    • 缺省视区是窗口本身

    • 视区矩阵将投影后的成像平面投到视区

      glViewport (GLint left, GLint bottom, GLint width,

      GLint height)

    • (left, bottom, width, height) 定义在窗口系统中(象素级)

    窗口

    (right, top)

    视区

    (left, bottom)


    Opengl

    用户定义矩阵

    • 可随意装入矩阵:

      GLfloat m[16] = {1.0, 0.0, 0.0, ……};

      glLoadMatrixf (m);

    • 矩阵乘法:

      glMultMatrixf (m);


    Opengl

    变换实例(演示)


    Opengl

    投影变换实例(演示)


    Opengl

    深度缓冲与动画生成

    • 双缓冲区机制与动画

    • 用深度缓冲进行消隐


    Opengl

    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

    双缓冲机制


    Opengl

    利用双缓冲进行动画设置

    • 需要初始化一个颜色双缓冲glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );

    • 清除颜色缓冲区

      glClear( GL_COLOR_BUFFER_BIT );

    • 绘制场景

    • 将前缓冲器与后缓冲器交换

      glutSwapBuffers();

    • 重复 2 – 4步,获得动画效果


    Opengl

    1

    1

    2

    2

    4

    4

    Color

    Buffer

    Depth

    Buffer

    8

    8

    16

    16

    Display

    深度缓冲器与消隐


    Opengl11

    OpenGL中的深度缓冲

    • 深度缓冲器设置

      glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );

    • 打开深度测试

      glEnable( GL_DEPTH_TEST );

    • 对颜色和深度缓冲器清零

      glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    • 绘制场景

    • 交换颜色缓冲器


    Opengl

    动画示例

    void main( int argc, char** argv )

    {

    glutInit( &argc, argv );

    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );

    glutCreateWindow( “Tetrahedron” );

    init();

    glutIdleFunc( idle );

    glutDisplayFunc( display );

    glutMainLoop();

    }


    Opengl

    动画示例(续)

    • void init( void ){ glClearColor( 0.0, 0.0, 1.0, 1.0 );}void idle( void ){ glutPostRedisplay();}


    Opengl

    动画示例(续)

    • 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();

    • }


    Opengl

    课后工作

    • 熟悉OpenGL流程

    • 预习OpenGL高级编程课题


  • Login