OpenGL图形编程4网格化曲线曲面及实体造型(陈永强)
计算机图形学陈永强PPT课件
点光源
N
L
8
第8页/共60页
P
图2 漫反射
漫反射光(Diffuse Reflection)
对于彩色
I p (I pR , I pG , I pB )
IdR I pR KdR (L N )
IdG I pG KdG (L N )
IdB I pB KdB (L N )
对于多个漫反射光源
Ks (KsR , KsG , KsB )
16
第16页/共60页
颜色
光强计算公式:
n
n
I R IaR KaR f (di )I pR,i KdR (Li N ) f (di )I pR,i KsR (Hi N )n
i 1
i 1
n
n
IG IaG KaG f (di )I pG,i KdG (Li N ) f (di )I pG,i KsG (Hi N )n
37
第37页/共60页
Whitted光照模型
Whitted在简单光照模型中增加了环境镜面反
射光和环境规则透射光,以模拟周围环境的光投
射在景物表面上产生的理想镜面反射和规则透射
现象。
R
N
I Ilocal Ks I s Kt It
V 视点
T
图11 物体表面的镜面反射和透射
38
第38页/共60页
对于每一像素光线,对场景中的所有物体表面进 行测试以确定其是否与该光线相交,并计算出交 点的深度,深度最大(z值)的交点即为该像素 对应的可见点。然后,继续考察通过该可见点的 从属光线(Secondary Rays)。
40
第40页/共60页
光线跟踪算法步骤
对每条从属光线重复过程:与场景中的所有物体 求交。然后递归地在沿从属光线方向最近的物体 表面上生成下一折射和反射光线。当由每个像素 出发的光线在场景中被反射和折射时,逐个将相 交物体表面加入到一个二叉光线跟踪树中。当树 中的一束光线到达预定的最大深度或到达某光源 时,就停止跟踪。
OpenGL基础
InitializeOpenGL() SetPixelFormat() SetLogicalPalette()
wglGetCurrent() wglGetCurrentDC() wglMakeCurrent() wglUseFontBitmaps()
OpenGL图形的实现方式
OpenGL与Windows绘图方式的区别: OpenGL与Windows绘图方式的区别: Windows采用GDI绘图(DCWindows采用GDI绘图(DC-设备描述表) OpenGL采用渲染上下文RC绘图(RC-渲染描述表) OpenGL采用渲染上下文RC绘图(RC-渲染描述表) OpenGL使用特殊的像素格式 OpenGL使用特殊的像素格式
MFC环境OpenGL单文档应用程序框架 MFC环境OpenGL单文档应用程序框架
(1) VC6.0下创建一个MFC工程: VC6.0下创建一个MFC工程 下创建一个MFC工程: File→New →MFC AppWiazard(exe)→A Simple Application →Finish (2) 添加包含文件和库文件路径 Tools →Options →Directories →添加Include路径 (gl.h glu.h glaux.h glut.h的目录) (3) 添加OpenGL库 添加OpenGL OpenGL库 Project →Settings… →Link → Object/library Module添加 “opengl.lib glu32.lib glaux.lib →OK (4) 添加消息响应函数: 添加消息响应函数: WM_CREATE,WM_DESTORY,WM_SIZE,WM_TIMER (5)修改StdAfx.h文件添加 .h” (5)修改StdAfx.h文件添加“.h”说明 修改StdAfx.h文件添加“ (6)修改View.h添加成员函数说明和成员变量 (6)修改View.h添加成员函数说明和成员变量 修改View.h (7)修改View.cpp函数 P10(7)修改View.cpp函数(见P10-P15) 修改View.cpp函数( (8)编译运行 (8)编译运行
OpenGL编程精粹
《OpenGL编程精粹》实验报告班级:计科083姓名:许银学号:0804641004指导教师:陈永强2011 年6 月 4 日一、实验目的通过本实验,使自己了解OpenGL的有关原理、算法及系统,掌握基本图形学显示程序设计方法,及三维图形程序设计方法,还要学习OpenGL光源、光照模型、物体材质、明暗处理、深度测试等生成真实世界的基本方法,为进一步学习计算机辅助设计方面的设计知识打下基础,同时通过此课程设计提高动手实践能力和学习分析能力。
二、实验要求这次课程设计的要求是通过OpenGL编程,模拟太阳、地球、月亮三者之间公转与自转的运动关系。
三、开发环境基于OpenGL的Microsoft Visual C++ 6.0四、实验内容//外部变量定义static GLfloat a = 3.5;static GLfloat b = 2;static GLfloat x = 0.0;static GLfloat y = 2.0;static GLfloat spin = 0.0;static GLfloat right = 0.0;static GLfloat left = 0.0;static GLfloat up = 0.0;static GLfloat down = 0.0;static sun_rotate = 0.0;static m = 0.0;static n = 0.0;static m_spin = 0.0;static m_x = 1.0;static m_y = 0.0;void sunfunc(void){sun_rotate+=2.0;if(sun_rotate>360.0)sun_rotate-=360.0;glutPostRedisplay();}{right+=2.0;if(right>360)right-=360;glutPostRedisplay(); }void leftfunc(void) {left+=2.0;if(left>360)left-=360;glutPostRedisplay(); }void upfunc(void) {up+=2.0;if(up>360.0)up-=360.0;glutPostRedisplay(); }void downfunc(void) {down+=2.0;if(down>360.0)down-=360.0;glutPostRedisplay(); }void spinfunc(void) {spin+=0.006;if(spin>360)spin-=360.0;x=a*sin(spin);y=b*cos(spin);glutPostRedisplay(); }{m_spin+=2;if(m_spin>360.0)m_spin-=360;m_x=sin(m_spin);m_y=cos(m_spin);glutPostRedisplay();}//初始化void init(void){//设置背景色glClearColor(0.0, 0.0, 0.0, 0.0);//设置平滑着色glShadeModel(GL_SMOOTH);//启用深度测试消隐glEnable(GL_DEPTH_TEST);//全局环境光GLfloat model_ambient[]={0.1,0.1,0.1,1.0};//光源位置GLfloat light_position[]={1.0, 1.0, 1.0, 0.0};//光的环境强度 GLfloat light_ambient[]={1.0, 1.0, 1.0, 1.0};//光的散射强度GLfloat light_diffuse[]={1.0, 1.0, 1.0, 1.0};//光的镜面强度GLfloat light_specular[]={1.0, 1.0, 1.0, 1.0};//设置背景色glClearColor(0.0, 0.0, 0.0, 0.0);//设置平滑着色glShadeModel(GL_SMOOTH);//启用深度测试消隐glEnable(GL_DEPTH_TEST);glLightfv(GL_LIGHT0,GL_POSITION,light_position);glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);//光照模型glLightModelfv(GL_LIGHT_MODEL_AMBIENT,model_ambient);//启用光照 glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);//启用混合glEnable(GL_BLEND);//启用抗锯齿glEnable(GL_POINT_SMOOTH);glEnable(GL_LINE_SMOOTH);glEnable(GL_POLYGON_SMOOTH);//启用雾// glEnable(GL_FOG);}//回调void display(void){//地球材质属性GLfloat mat_ambient[] = { 0.2, 0.2, 0.9, 1.0 };GLfloat mat_diffuse[] = { 0.2, 0.2, 0.9, 1.0 };GLfloat mat_specular[] = { 0.2, 0.1, 0.8, 1.0 };GLfloat mat_shininess[] = { 10.0 };GLfloat mat_emission[] = {0.1, 0.1, 0.1, 0.0};//太阳材质属性GLfloat sun_ambient[] = { 0.9, 0.2, 0.1, 1.0 };GLfloat sun_diffuse[] = { 0.9, 0.2, 0.2, 1.0 };GLfloat sun_specular[] = { 0.9, 0.3, 0.1, 1.0 };GLfloat sun_shininess[] = { 20.0 };GLfloat sun_emission[] = {0.1, 0.1, 0.1, 0.0};//月球材质属性GLfloat mom_ambient[] = { 0.5, 0.5, 0.5, 1.0 };GLfloat mom_diffuse[] = { 0.5, 0.5, 0.5, 1.0 };GLfloat mom_specular[] = { 0.5, 0.5, 0.5, 1.0 };GLfloat mom_shininess[] = { 50.0 };GLfloat mom_emission[] = {0.1, 0.1, 0.1, 0.0};glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glColor4f(1.0,1.0,1.0,0.0);glPushMatrix();glPushMatrix();glEnable(GL_LIGHTING);//设置太阳材质属性glMaterialfv(GL_FRONT, GL_AMBIENT, sun_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, sun_specular); glMaterialfv(GL_FRONT, GL_SHININESS, sun_shininess); glMaterialfv(GL_FRONT, GL_EMISSION, sun_emission); //太阳自传sunfunc();glRotatef(sun_rotate,1.0,1.0,0.0);glutSolidSphere(0.8,100,100);glPopMatrix();//轨道旋转glRotatef(right, 0.0, 1.0, 0.0);glRotatef(-left, 0.0, 1.0, 0.0);glRotatef(-up, 1.0, 0.0, 0.0);glRotatef(down, 1.0, 0.0, 0.0);glPushMatrix();glTranslatef(x,y,0);glEnable(GL_LIGHTING);//地球材质设置glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);glutSolidSphere(0.3, 100, 100);glDisable(GL_LIGHTING);glutSolidTorus(0.004,0.56,100,100);glPushMatrix();{glRotatef(-m_spin,0,0,1);glTranslatef(0.4,0.4,0);m_spinfunc();glEnable(GL_LIGHTING);//月球材质设定glMaterialfv(GL_FRONT, GL_AMBIENT, mom_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, mom_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, mom_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mom_shininess); glMaterialfv(GL_FRONT, GL_EMISSION, mom_emission); glutSolidSphere(0.14,100,100);}glPopMatrix();glPopMatrix();glPushMatrix();//绘制轨道禁用光照glDisable(GL_LIGHTING);glScalef(a/b,1.0,1.0);glutSolidTorus(0.003,2.0,100,100);glPopMatrix();glPopMatrix();glutSwapBuffers();}//窗口变化函数void reshape(int w,int h){//视口变换glViewport( 0, 0, (GLsizei)w,(GLsizei)h);//选择投影矩阵glMatrixMode(GL_PROJECTION);//重置投影矩阵glLoadIdentity();//正投影if(w>=h)glOrtho(-3.0*(GLfloat)w/(GLfloat)h, 3.0*(GLfloat)w/(GLfloat)h, -3.0, 3.0, -10.0, 10.0);elseglOrtho(-3.0, 3.0, -3.0*(GLfloat)w/(GLfloat)h,3.0*(GLfloat)w/(GLfloat)h, -10.0, 10.0);//透视投影// gluPerspective(45.0, (GLfloat)w/(GLfloat)h, 1.0, 100.0);//选择模型视图矩阵glMatrixMode(GL_MODELVIEW);//重置模型视图矩阵glLoadIdentity();//下面可以设置观察点 glLookAt() 或是变换场景局部坐标系glTranslate() glRotate() glScale()// gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);}//鼠标响应void mouse(int button, int state, int x, int y){switch(button){case GLUT_LEFT_BUTTON:if(state==GLUT_DOWN)glutIdleFunc(spinfunc);break;case GLUT_RIGHT_BUTTON:if(state==GLUT_DOWN)glutIdleFunc(m_spinfunc);break;case GLUT_MIDDLE_BUTTON:if(state==GLUT_DOWN)break;}}//主函数int main(int argc,char **argv){glutInit(&argc,argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(850,600);glutInitWindowPosition(100,100);glutCreateWindow(argv[0]);init();glutReshapeFunc(reshape);glutMouseFunc(mouse);glutKeyboardFunc(keyboard);glutDisplayFunc(display);glutMainLoop();return 0;}实验结果如下:五、实验总结及心得体会通过这次实验,使我学习了更多的基于OpenGL的编程方法,在实验过程中多多少少出现过各式各样的问题,我也不断在学习解决这些问题,编程就是要将理论付诸于实践,二者相辅相成,所以要多多练习OpenGL的编程,提高自己的编程能力,同时不断地掌握新的理论知识。
OpenGL图形编程6位图图像(陈永强)
9
以上有不当之处,请大家给与批评指正, 谢谢大家!
10
OpenGL图形编程
武汉纺织大学数学与计算机学院 授课教师:陈永强 教授
1
5.位图图像
像的区别 位图的每个像素仅包含一位信息,图像的每 个像素一般含有多种信息(R、G、B、 Alpha); 位图用于掩码,遮盖别的图像;图像数据则 覆盖先前数据或与先前数据混合。
6
5.2图像
像素复制
void glCopyPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum buffer);
7
5.2图像
图像缩放
void glPixelZoom(GLfloat zoomx,GLfloat zoomy);
8
5.2图像
3
5.1位图
当前光栅位置
void glRasterPos{234}{sifd}[v](TYPE x,TYPE y,TYPE z,TYPE w);
显示
void glBitmap(GLsize width,GLsizei height, GLfloat xbo,GLfloat ybo,GLfloat xbi,GLfloat ybi,const GLubyte* bitmap);
4
5.1位图
例子 红皮书drawf.c
5
5.2图像
像素读写 读
void glReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid* pixels);
写
void glDrawPixels(GLsizei width,GLsizei height, GLenum format,GLenum type,GLvoid* pixels);
图形学实验报告 OpenGL中的实体模型与层次模型
《计算机图形学基础》实验3OpenGL中的实体模型与层次模型一、实验目的及要求1.掌握GLUT库中的多面体函数的绘制方法;2.掌握GLUT库中的二、三次曲面的绘制方法;3.掌握绘制实体或线框模型的绘制方法;4.掌握显示列表的用法;二、实验环境主要是软件开发环境:VC 6.0三、实验内容1.利用OpenGL绘制简单多面体、二次及三次曲线的例子。
2.利用OpenGL绘制奥运五环标志。
四、实验结果1、利用OpenGL绘制简单多面体、二次及三次曲线的例子。
2、利用OpenGL绘制奥运五环标志五、程序代码1、利用OpenGL绘制简单多面体、二次及三次曲线#include <gl/glut.h>static GLsizei iMode = 1;static GLfloat xRot = 0.0f; //x方向旋转参数static GLfloat yRot = 0.0f; //y方向旋转参数GLUquadricObj *obj; //二次曲面对象void Initial(void){glClearColor(1.0f, 1.0f, 1.0f, 1.0f);glColor3f(0.0f, 0.0f, 0.0f);obj = gluNewQuadric( );gluQuadricDrawStyle(obj, GLU_LINE); //以线框方式绘制二次曲面对象}void ChangeSize(int w, int h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D (-1.5f, 1.5f, -1.5f, 1.5f);}void Display(void){glClear(GL_COLOR_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glRotatef(xRot, 1.0f, 0.0f, 0.0f); //旋转图形glRotatef(yRot, 0.0f, 1.0f, 0.0f); //旋转图形//指定需要绘制的图元switch(iMode) {case 1:glutWireTetrahedron(); break;case 2:glutSolidTetrahedron(); break;case 3:glutWireOctahedron(); break;case 4:glutSolidOctahedron(); break;case 5:glutWireSphere(1.0f,15,15); break;case 6:glutSolidSphere(1.0f,15,15); break;case 7:glutWireTeapot(1.0f); break;case 8:glutSolidTeapot(1.0f); break;case 9:gluSphere(obj, 1.0f, 15, 15); break;case 10:gluCylinder(obj,1.0f,0.0f,1.0f,15,15);break;case 11:gluPartialDisk(obj,0.3f,0.8f,15,15,30.0f,260.0f); break;default: break;}glFlush();}void ProcessMenu(int value){iMode = value;glutPostRedisplay();}void SpecialKeys(int key, int x, int y){if(key == GLUT_KEY_UP) xRot-= 5.0f;if(key == GLUT_KEY_DOWN) xRot += 5.0f;if(key == GLUT_KEY_LEFT) yRot -= 5.0f;if(key == GLUT_KEY_RIGHT) yRot += 5.0f;if(xRot > 356.0f) xRot = 0.0f;if(xRot < -1.0f) xRot = 355.0f;if(yRot > 356.0f) yRot = 0.0f;if(yRot < -1.0f) yRot = 355.0f;glutPostRedisplay();}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(400,400);glutInitWindowPosition(100,100);glutCreateWindow("OpenGL模型绘制函数示例");//创建菜单并定义菜单回调函数int nGlutPolyMenu = glutCreateMenu(ProcessMenu);glutAddMenuEntry("线框正四面体",1); //创建GLUT多面体绘制菜单glutAddMenuEntry("实体正四面体",2);glutAddMenuEntry("线框正八面体",3);glutAddMenuEntry("实体正八面体",4);int nGlutCurveMenu = glutCreateMenu(ProcessMenu); //创建GLUT曲面绘制菜单glutAddMenuEntry("线框球面",5);glutAddMenuEntry("实体球面",6);glutAddMenuEntry("线框茶壶",7);glutAddMenuEntry("实体茶壶",8);int nGluCurveMenu = glutCreateMenu(ProcessMenu); //创建GLU曲面绘制菜单glutAddMenuEntry("线框球面",9);glutAddMenuEntry("线框圆锥面",10);glutAddMenuEntry("线框圆环面",11);int nMainMenu = glutCreateMenu(ProcessMenu); //创建主菜单glutAddSubMenu("GLUT多面体", nGlutPolyMenu);glutAddSubMenu("GLUT曲面", nGlutCurveMenu);glutAddSubMenu("GLU曲面", nGluCurveMenu);glutAttachMenu(GLUT_RIGHT_BUTTON);glutDisplayFunc(Display);glutReshapeFunc(ChangeSize);glutSpecialFunc(SpecialKeys);Initial();glutMainLoop();return 0;}2、利用OpenGL绘制奥运五环标志#include <gl/glut.h>GLuint OlympicRings;void Initial(void){glClearColor(1.0f, 1.0f, 1.0f, 1.0f);OlympicRings = glGenLists(1);glNewList(OlympicRings, GL_COMPILE);glColor3f(1.0, 1.0, 0.0);glTranslatef(-22.0, 0.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); //绘制黄色环glColor3f(0.0, 1.0, 0.0);glTranslatef(44.0, 0.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); //绘制绿色环glColor3f(0.0, 0.0, 0.0);glTranslatef(-22.0, 30.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); //绘制黑色环glColor3f(0.0, 0.0, 1.0);glTranslatef(-42.0, 0.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); //绘制蓝色环glColor3f(1.0, 0.0, 0.0);glTranslatef(84.0, 0.0, 0.0);glutSolidTorus(0.5, 20.0, 15, 50); //绘制红色环glEndList();}void ChangeSize(int w, int h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D (-70.0f, 70.0f, -70.0f, 70.0f);}void Display(void){glClear(GL_COLOR_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glCallList(OlympicRings); //调用显示列表glFlush();}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(400,400);glutInitWindowPosition(100,100);glutCreateWindow("OpenGL模型绘制函数示例");glutDisplayFunc(Display);glutReshapeFunc(ChangeSize);Initial();glutMainLoop();return 0;}六、心得体会多面体画出来,如果函数引用缺少一部分,那么会很小。
OpenGL图形编程1介绍(陈永强)
18
1.1OpenGL的主要功能
位图和图像处理
OpenGL 还提供了专门对位图和图象进行操作的 函数。
19
1.1OpenGL的主要功能
纹理映射
三维景物因缺少景物的具体细节而显得不够真实,为了更 加逼真地表现三维景物,OpenGL 提供了纹理映射的 功能。OpenGL 提供的一系列纹理映射函数使得开发 者可以十分方便地把真实图象贴到景物的多边形上,
32位整数 32位浮点数 64位浮点数
short
long float double
S
L F D
GLubyte,GLboolean
GLshort GLuint,GLenum,GLbitfield
位图字体以及把文本放在窗口的某一位置等这些函数把
Windows 和 OpenGL 揉合在一起。
34
1.4OpenGL基本语法
组成
Win32 API 函数库
这部分函数没有专用的前缀,主要用于处理像素 存储格式和双帧缓存。
35
1.4OpenGL基本语法
函数命名规则
OpenGL函数都遵循一个命名约定,即采用以下格
从而可以在视窗内绘制逼真的三维景观。
20
1.1OpenGL的主要功能
实时动画
为了获得平滑的动画效果,需要先在内存中生成 下一幅图象,然后把已经生成的图象从内存拷 贝到屏幕上,这就是 OpenGL 的双缓存技术 (double buffer)。OpenGL 提供了双缓存 技术的一系列函数。
21
1.1OpenGL的主要功能
交互技术
目前有许多图形应用需要人机交互,OpenGL 提
供了方便的三维图形人机交互接口,用户可以选
计算机图形学1陈永强-文档资料
构想(Imagination):生动形象地反映设计者 的思想。
45
虚拟现实的关键技术
能以实时的速度生成有逼真感的景物图形。 能高精度的跟踪用户的头和手。 头戴显示器能产生高分辨率图象和较大的视角。 能对用户的动作产生力反馈。 实例(VRML,虚拟现实建模语言)
17
计算机图形学研究的对象
图形的要素: 几何要素和非几何要素。
计算机图形学中所研究的图形 从客观世界物体中抽象出来的带有颜色
及形状信息的图和形。
18
图形的表示
点阵法是用具有颜色信息的点阵来表示图形的一
种方法,它强调图形由哪些点组成,并具有什么 灰度或色彩。
参数法是以计算机中所记录图形的形状参数与属
10
主要参考书目
Donald Hearn,M.Pauline Baker著, 蔡士杰等译,计算 机图形学(第三版),电子工业出版社,2005。
孙家广,计算机图形学基础教程(第2版),清华大学 出版社,2009。
向世明,OpenGL编程与实例,电子工业出版社, 1999 。
Dave Shreiner等著,OpenGL编程指南(原书第7版), 机械工业出版社,2010。
课程学时安排
总学时:48 理论学时:32 实验学时:16
周四3-5节 1-10周 11-16周
理论课内容
绪论 计算机图形设备 交互式技术 几何造型技术 基本图形生成算法* 二维图形变换及二维观察* 三维图形变换及三维观察* OpenGL图形编程
9
实验课内容
实验1:直线与圆的生成算法 实验2:直线的2D变换 实验3:三角形的绘制与2D变换 实验4:长方体的绘制 实验5:球的绘制 实验6:球和长方体的颜色设置
用OpenGL进行曲线、曲面的绘制
⽤OpenGL进⾏曲线、曲⾯的绘制实验⽬的理解Bezier曲线、曲⾯绘制的基本原理;理解OpenGL中⼀维、⼆维插值求值器的⽤法。
掌握OpenGL中曲线、曲⾯绘图的⽅法,对⽐不同参数下的绘图效果差异;代码1:⽤四个控制点绘制⼀条三次Bezier曲线#include "stdafx.h"#include <stdlib.h>#include <time.h>#include <GL/glut.h>//4个控制点的3D坐标——z坐标全为0GLfloat ctrlpoints[4][3] = {{ -4, -4, 0 }, { -2, 4, 0 }, { 2, -4, 0 }, { 4, 4, 0 }};void init(void){//背景⾊glClearColor(0.0, 0.0, 0.0, 1.0);//将控制点坐标映射为曲线坐标//参数1:GL_MAP1_VERTEX_3,3维点坐标//参数2和3:控制参数t或u的取值范围[0, 1]//参数4:曲线内插值点间的步长3————3维坐标//参数5:曲线间的补偿为顶点数4个————总步长为12//参数6:控制点⼆维数组⾸元素地址//注意: 若是在这⾥设置了相关参数,后续对ctrlpoints内容更改曲线不变glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);//打开开关——允许3维坐标控制点到参数点转换开关glEnable(GL_MAP1_VERTEX_3);glShadeModel(GL_FLAT);//代码开关2:去掉本注释,可启⽤反⾛样/*glEnable(GL_BLEND);glEnable(GL_LINE_SMOOTH); //允许直线反⾛样glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); // Antialias the linesglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);*/}void display(void){int i;glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 1.0, 1.0);//代码开关1:去掉本注释,查看动态的曲线绘图效果:动态更新控制点坐标/*for(int t = 0; t < 4; t++) {for(int j = 0; j < 3; j++)ctrlpoints[t][j] = (rand() % 1024 / 1024.0 - 0.5) * 10;}//动态映射glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);*/glLoadIdentity();glColor3f(1.0, 0.0, 0.0);//绘制连续线段glBegin(GL_LINE_STRIP);//参数t或u取值为i/30,共计31个点for (i = 0; i <= 30; i++)glEvalCoord1f((GLfloat)i / 30.0); //根据4个控制点坐标的参数化插值glEnd();/* 显⽰控制点 */glPointSize(5.0);glBegin(GL_POINTS);for (i = 0; i < 4; i++)glVertex3fv(&ctrlpoints[i][0]);glEnd();glTranslatef(-0.1f, 0.1f, 0.0f);glColor3f(0.0, 1.0, 0.0);//glLineWidth(2.0);//绘制连续线段——线段数越多,曲线越光滑glBegin(GL_LINE_STRIP);//设置参数t或u取值为i/60,共计61个点//实验:若让t从-2变化到+2,可看到什么效果for (i = 0; i <= 60; i++)glEvalCoord1f((GLfloat)i / 60.0); //根据4个控制点坐标的参数化插值glEnd();glTranslatef(-0.1f, 0.1f, 0.0f);glColor3f(1.0, 1.0, 1.0);//绘制连续线段glBegin(GL_LINE_STRIP);//设置参数t或u取值为i/60,共计61个点//实验:若让t从-2变化到+2,可看到什么效果for (i = 0; i <= 100; i++)glEvalCoord1f((GLfloat)i / 100.0);glEnd();glutSwapBuffers();}//3D空间中绘制2D效果,采⽤正交投影void reshape(GLsizei w, GLsizei h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if (w <= h)glOrtho(-5.0, 5.0, -5.0*(GLfloat)h / (GLfloat)w, 5.0*(GLfloat)h / (GLfloat)w, -5.0, 5.0);elseglOrtho(-5.0*(GLfloat)w / (GLfloat)h, 5.0*(GLfloat)w / (GLfloat)h, -5.0, 5.0, -5.0, 5.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void keyboard(unsigned char key, int x, int y){switch (key){case'x':case'X':case27: //ESC键exit(0);break;default:break;}}int main(int argc, char** argv){srand((unsigned int)time(0));glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);//使⽤双缓存模式和深度缓存 glutInitWindowSize(800, 800);glutInitWindowPosition(0, 0);glutCreateWindow("2D Bezier曲线");init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutKeyboardFunc(keyboard);glutIdleFunc(display);//设置空闲时调⽤的函数glutMainLoop();return0;}此时我们打开代码开关1,查看动态Bezier曲线绘制效果:关闭代码开关1,打开代码开关2,查看直线反⾛样效果:对⽐刚开始的效果图,我们发现,使⽤了直线反⾛样后,绘制出的曲线很光滑,看着很舒服。
OpenGL图形编程3二维观察与三维变换(陈永强)讲课讲稿
3.2.2模型视图矩阵
平移 旋转 比例
19
3.2.2模型视图矩阵
平移
void glTranslate{fd}(TYPE x,TYPE y,TYPE z);
参数x,y,z就是目标分别沿三个轴的正向平移的 偏移量。这个函数用这三个偏移量生成的矩阵 完成乘法。
当参数是(0.0,0.0,0.0)时,生成的矩阵是单位 矩阵,此时对物体没有影响。
,这样就有效地排除了视见空间之外的所有数据。 4. 由修剪坐标除以w坐标,得到规格化的设备坐标。注意,在变换
过程中,模型视图矩阵和投影视图矩阵都有可能改变坐标的 w 值。 5. 坐标三元组被视见区变换影射到一个2D平面。这也是一个矩阵 变换,但在OpenGL中不能直接指定或修改它,系统会根据指 定给 glViewport 的值在内部设置它。
这段代码绘制了两个球,第一个绘制的球的球心沿x轴正向移动了10个单 位,而第二球不仅沿y轴正向移动10个单位,也沿x轴正向移动10个 单位。这就是效果积累。
27
3.2.3矩阵操作
单位矩阵
glTranslatef(10.0f, 0.0f, 0.0f); glutSolidSphere(1.0f, 15, 15);
glLoadIdentity();
3
3.1.2指定裁剪窗口
定义二维裁剪窗口
gluOtho2D(xwmin, xwmax, ywmin, ywmax);
其 中 , 双 精 度 浮 点 数 xwmin, xwmax, ywmin, ywmax分别对应裁剪窗口的左、右、下、上四条边 界。
默 认 的 裁 剪 窗 口 , 四 条 边 界 分 别 为 wxl=-1.0, wxr=1.0,wyt=-1.0,wyb=1.0。
OpenGL图形编程2基本图形绘制(陈永强)只是分享
这个函数采用一个参数来指定画点时以象素为单位的近似 直径。
7
2.2点的绘制
点的属性(大小)
通常使用下面的代码来获取点大小的范围和它们之间最小的中间值:
GLfloat sizes[2]; //保存绘制点的尺寸范围
GLfloat step;
将指定的各个顶点用于创建单个的点
GL_LINES GL_LINE_STRIP GL_LINE_LOOP
GL_TRIANGLES
将指定的顶点用于创建线段。每两个顶点指定一条单独的线 段。如果顶点个数是奇数,则忽略后一个
将指定的顶点用于创建线条。第一个顶点之后的每个顶点指 定的是线条延伸到的下一个点
特性和GL_LINE_STRIP 相似,只不过最后一条线段是在 指定的后一个和第一个顶点之间绘制。典型情况下,这用于 绘制那些可能违反了 GL_POLYGON 用法规则的封闭区域
glBegin(GL_LINE_STRIP); glVertex3f(0.0f,0.0f,0.0f); glVertex3f(10.0f,10.0f,0.0f); glVertex3f(20.0f,5.0f,0.0f);
glEnd();
在xy平面内绘制了两条直线(0,0,0)到(10,0,0)和(0,10,0)到(20,5,0)。
OpenGL图形编程2基本图形绘 制(陈永强)
2.1glBegin/glEnd
OpenGL的图元绘制放在函数glBegin和 glEnd之间,由函数glBegin的参数指定绘制 图元的类型。
2.1glBegin/glEnd
模式
GL_POINTS
表 glBegin可支持的OpenGL图元
OpenGL编程轻松入门之NURBS曲线和曲面
OpenGL编程轻松入门之NURBS曲线和曲面2006-05-22 09:53作者:黄燕出处:天极开发责任编辑:方舟上一节讲了一般的曲线与曲面的绘制,本节讲NURBS曲线和曲面的绘制。
例11:此例绘制两个相同形状的NURBS曲面,不同之处是一个为线框式,一个是由实多边形组成。
运行后可以看到其中的区别,如图十三所示。
#include <windows.h>#include <GL/glut.h>GLUnurbsObj *theNurb1;GLUnurbsObj *theNurb2;GLfloat ctrlpoints[5][5][3] = {{{-3,0.5,0},{-1,1.5,0},{-2,2,0},{1,-1,0},{-5,0,0}},{{-3,0.5,-1},{-1,1.5,-1},{-2,2,-1},{1,-1,-1},{-5,0,-1}},{{-3,0.5,-2},{-1,1.5,-2},{-2,2,-2},{1,-1,-2},{-5,0,-2}},{{-3,0.5,-3},{-1,1.5,-3},{-2,2,-3},{1,-1,-3},{-5,0,-3}},{{-3,0.5,-4},{-1,1.5,-4},{-2,2,-4},{1,-1,-4},{-5,0,-4}}};//控制点GLfloat mat_diffuse[] = {1.0,0.5,0.1,1.0};GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};GLfloat mat_shininess[] = {100.0};GLfloat light_position[] = {0.0,-10.0,0.0,1.0};void myInit(void){glClearColor(1.0,1.0,1.0,0.0);//设置背景色/*为光照模型指定材质参数*/glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);glLightfv(GL_FRONT,GL_POSITION,light_position);//设置光源参数glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);//设置光照模型参数/*激活光照*/glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glDepthFunc(GL_LEQUAL);glEnable(GL_DEPTH_TEST);glEnable(GL_LEQUAL);glEnable(GL_AUTO_NORMAL);glEnable(GL_NORMALIZE);/*设置特殊效果*/glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE);glEnable(GL_BLEND);glFrontFace(GL_CW);glShadeModel(GL_SMOOTH);glEnable(GL_LINE_SMOOTH);theNurb1 = gluNewNurbsRenderer();//创建NURBS对象theNurb1 gluNurbsProperty(theNurb1,GLU_SAMPLING_TOLERANCE,25.0); gluNurbsProperty(theNurb1,GLU_DISPLAY_MODE,GLU_OUTLINE_POLYGON);theNurb2 = gluNewNurbsRenderer();//创建NURBS对象theNurb2 gluNurbsProperty(theNurb2,GLU_SAMPLING_TOLERANCE,25.0); gluNurbsProperty(theNurb2,GLU_DISPLAY_MODE,GLU_FILL);}int spin = 0;/*接收键盘指令*/static void myKey(unsigned char key,int x,int y){switch(key){case'd':spin = spin + 1;glRotatef(spin,1.0,1.0,0.0);glutPostRedisplay();break;case 27:exit(0);default:break;}}/*绘制曲面*/void myDisplay(void){GLfloat knots[10] = {0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0};glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glRotatef(50.0,1.0,1.0,0.0);/*第一个曲面*/glPushMatrix();glTranslatef(1.0,0.0,0.0);gluBeginSurface(theNurb1);/*定义曲面形状*/gluNurbsSurface(theNurb1,10,knots,10,knots,5*3,3,&ctrlpoints[0][0][0],5,5,GL_MAP2_VE RTEX_3);gluEndSurface(theNurb1);glPopMatrix();/*第二个曲面*/glPushMatrix();glTranslatef(7.0,0.0,0.0);gluBeginSurface(theNurb2);/*定义曲面形状*/gluNurbsSurface(theNurb2,10,knots,10,knots,5*3,3,&ctrlpoints[0][0][0],5,5,GL_MAP2_VE RTEX_3);gluEndSurface(theNurb2);glPopMatrix();glutSwapBuffers();}void myReshape(GLsizei w,GLsizei h){glViewport(0,0,w,h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(50.0,(GLfloat)w/(GLfloat)h,1.0,15.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glTranslatef(0.0,0.0,-9.0);}int main(int argc,char ** argv){/*初始化*/glutInit(&argc,argv);glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH); glutInitWindowSize(600,400);glutInitWindowPosition(200,200);/*创建窗口*/glutCreateWindow("NURBS surface");/*绘制与显示*/myInit();glutKeyboardFunc(myKey);glutReshapeFunc(myReshape);glutDisplayFunc(myDisplay);/*进入GLUT事件处理循环*/glutMainLoop();return(0);}·GLUnurbsObj* glNewNurbsRenderer()创建一个NURBS对象,并返回一个指向该对象的指针。
2013结合OpenGL的图形编程教学模式研究_陈永强
调 函 数 里,通 过 glutDisplayFunc函 数 作 为 注 册 函 数 将 显 示回调函数注册指定为当前窗口的显示内容函数。类似 地,可以用 GLUT 提 供 的 其 它 注 册 函 数 注 册 相 应 事 件 的 回调函数,处理用户输入或系统状态改变等事件 。
最后用 gluMainLoop函数启 动 主 GLUT 事 件 处 理 循 环,运行程序显示绘制窗口 。
关 键 词 :图形编程;计算机图形学;教学模式;OpenGL 中 图 分 类 号 :TP434 文 献 标 识 码 :A 文 章 编 号 :1672-7800(2013)006-0148-02
1 国 内 教 学 现 状
为有助于学生学习和理解计算机图形学的基本概念、 原理与算法,需要结合形象化的图形编程实例和实验 来 补 充说明和练习。国内教材和教学中计算机图形学案例和 实验图形编程 选 用 的 编 程 语 言 有 C、C+ + 和 Java。Java 主要面向嵌入式设备和网络 使 用 ,目 前 PC 机 上 软 件 编 程 教学通常采用 C 和 C++编程语言,选择的图形开发 环 境 是在 VC++里使 用 控 制 台 应 用 程 序、MFC 可 执 行 程 序、 OpenGL 开放图形库、Direct3D 图形库等几种方式 。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
函数指定轮廓线的一个顶点。
4.1网格化
删去网格化对象
void gluDeleteTess(GLUtesselator *tessobj ); 删去网格化对象tessobj,并释放其占用的内存。
4.1网格化
例子 红皮书tess.c
4.2 曲线曲面
4.2.1Bezier曲线曲面
4.2.2B样条曲线曲面
glEvalMesh1(GLenum mode,GLint n1,GLint n2);
参数mode取值为GL_POINT或GL_LINE,表示以点或折线的形式 显示曲线
14
4.2.1Bezier曲线曲面
Bezier曲面
Bezier曲面的求值函数:
void glMap2{fd}(GLenum target, TYPE u1, TYPE u2,
OpenGL图形编程
武汉纺织大学数学与计算机学院 授课教师:陈永强 教授
1
4.网格化曲线曲面与实体造型
4.1网格化 4.2曲线曲面 4.3实体
4.1网格化
OpenGL只能直接显示简单的凸多边形。简单 凸多边形就是多边形的边只在顶点处相交,没 有重复的顶点,并且任何顶点都只有两条边相 遇。 如果需要显示凹多边形、中间有洞的多边形或 者具有相交边的多边形,就必须分解为简单的 凸ቤተ መጻሕፍቲ ባይዱ边形,即网格化。
16
4.2.1Bezier曲线曲面
Bezier曲面的生成步骤
第4步还可以用以下函数来生成一组均匀分布的参数值,显示曲面
glMapGrid2{fd}(GLint nu,TYPE u1,TYPE u2, GLint
函数创建一个网格化对象,并返回一个指向该对 象的指针,如果创建失败则返回NULL指针。
4.1网格化
网格化回调函数
void glTessCallback(GLUtesselator* tessobj,GLenum type,void (* fn)() );
函数将回调函数fn与网格化对象tessobj关联起 来,类型由参数type指定。
13
4.2.1Bezier曲线曲面
Bezier曲线的生成步骤
第4步还可以用以下函数来生成一组均匀分布的参数值,显示曲线
//指定曲线参数t从t1开始经过n步均匀地变为t2。
glMapGrid1{fd}(GLint n,TYPE t1,TYPE t2); //指定从第n1个到第n2个参数(由glMapGrid1算出)绘制
参数points为指向控制点坐标数组的指针。
15
4.2.1Bezier曲线曲面
Bezier曲面的生成步骤
1.指定控制点坐标;
2.设定求值函数;
3.激活求值函数 glEnable(GL_MAP2_VERTEX_3) 4.计算沿样条路径的位置并显示曲面 glEvalCoord2{fd}(TYPE u, TYPE v);
GLint ustride, GLint uorder, TYPE v1, TYPE v2, GLint vstride, GLint vorder, const TYPE *points);
参数u1,u2,v1,v2分别表示Bezier曲面参数u和v的最大最小值。
参数ustride和vstride分别表示数组points中相邻控制点的偏移量。 参数uorder和vorder指定Bezier曲面的阶数。
void glTessBeginContour(GLUtesselator *tessobj); void glTessEndContour(GLUtesselator *tessobj );
此对函数指定一条封闭的轮廓线,默认将轮廓线中最后一个顶点和第 一顶点相连。
void gluTessVertex(GLUtesselator *tessobj,GLdouble coords[3],void *vertex_data);
11
4.2.1Bezier曲线曲面
Bezier曲线
Bezier曲线的求值函数:
void glMap1{fd}(GLenum target, TYPE t1, TYPE t2, GLint stride, GLint order, const TYPE *points); 参数target给出控制点数组表示的内容,一般取GL_MAP1_VERTEX_3,表示控制 点数组存储控制点的三维点坐标。 参数t1,t2表示Bezier曲线参数t的最小和最大值,一般为0.0和1.0。 参数stride表数组points中一个坐标位置到另一个坐标位置的偏移量,对三维坐标数 组,stride=3。 参数order指定Bezier曲线的阶数。
参数points为指向控制点数组的指针。
12
4.2.1Bezier曲线曲面
Bezier曲线的生成步骤
1.指定控制点坐标;
2.设定求值函数;
3.激活求值函数 glEnable(GL_MAP1_VERTEX_3) 4.计算沿样条路径的位置并显示曲线 void glEvalCoord1{fd}(TYPE t);
4.1网格化
网格化属性
void gluTessProperty(GLUtesselator *tessobj,GLenum property,GLdouble value );
函数设置网格化对象tessobj的property属性, 其值设为value。 最重要最复杂的是环绕规则,决定了多边形的“ 内部”和“外部”。
4.1网格化
void glTessBeginPolygon(GLUtesselator *tessobj,void *user_data ); void glTessEndPolygon(GLUtesselator *tessobj );
定义多边形
此对函数将多边形同网格对象tessobj关联起来,参数user_data指 向用户定义的数据。可以定义一条或多条轮廓线。
4.1网格化
复杂多边形网格化步骤:
创建一个网格化对象 注册在网格化期间执行操作的回调函数 指定网格化属性 指定一个或多个封闭多边形组成的轮廓,以创建并 渲染分割后的多边形 删除网格化对象
4.1网格化
创建网格化对象
GLUtesselator* gluNewTess(void);