实验三 OpenGL的简单交互绘制new

合集下载

opengl学习(三)----绘制简单图形(一)

opengl学习(三)----绘制简单图形(一)

opengl学习(三)----绘制简单图形(⼀)今天说⼀说⼏种简单的图元。

所有的⼏何图元都是根据它们的顶点来描绘的。

⽽顶点就是它们在屏幕上的坐标位置。

我喜欢把这⼏个简单的图元称为点线⾯。

点,可以看到⼀个顶点;线,就是两个顶点指定的⼀条有限长度的线段;⾯,其实更准确讲是⼀个凸多边形。

opengl⾥所讲的多边形是内部⽤颜⾊填充的,视觉上称为⾯我个⼈认为是更贴近的。

当然,多边形也是由指定的顶点组成的。

需要注意的是,要想被opengl按照设计被绘制必须正确的认识到,所谓的多边形是顶点都处于⼀个平⾯上,凸多边形。

凸多边形不能理解的,请问度娘。

来看⼀个例⼦:C++代码1. glBegin(GL_POLYGON);2. glVertex2f(0.0, 0.0);3. glVertex2f(0.0, 3.0);4. glVertex2f(4.0, 3.0);5. glVertex2f(6.0, 1.5);6. glVertex2f(4.0, 0.0);7. glEnd();先不去关⼼代码本⾝,这段代码最终的结果是要指定5个顶点绘制⼀个凸五边形。

注意,不是5条线段⽽是⼀个凸五边形的平⾯。

不管是点线⾯的哪⼀种,都是需要指定⼀组顶点的。

如何判定顶点指定的开始和结束就是glBegin和glEnd的⼯作。

引⽤void glBegin(Glenum mode);标志着⼀个顶点数据列表的开始,它描述了⼀个⼏何图元。

mode参数指定了图元的类型。

void glEnd(void);标志着⼀个顶点数据列表的结束。

mode设置的不同,代表着将要绘制的图元也不同。

下⾯这个表就是图元的名称和含义:值含义GL_POINTS 单个的点GL_LINES ⼀对顶点被解释为⼀条直线GL_LINE_STRIP ⼀系列的连接直线GL_LINE_LOOP 和上⾯相同,但第⼀个顶点和最后⼀个顶点彼此相连GL_TRIANGLES 3个顶点被解释为⼀个三⾓形GL_TRIANGLES_STRIP 三⾓形的连接串GL_TRIANGLES_FAN 连接成扇形的三⾓形系列GL_QUADS 4个顶点被解释为⼀个四边形GL_QUADS_STRIP 四边形的连接串GL_POLYGON 简单的凸多边形的边界试想着,如果将glBegin(GL_POLYGON)修改为glBegin(GL_POINTS),绘制出来的将是什么图形呢? 哈哈,那就是5个点⽽已么。

OpenGL 3基本图形绘制

OpenGL 3基本图形绘制

模型-视图变换过程就是一个将顶点坐标从世界坐标变换到 视觉坐标的过程。这里很重要的是对两个坐标系的认识。 世界坐标系也称为全局坐标系。它是一个右手坐标系,可 以认为该坐标系是固定不变的,在初始态下,其x轴为沿屏

幕水平向右,y轴为沿屏幕垂直向上,z轴则为垂直屏幕面
向外指向用户。

视觉坐标系(即观察坐标系)也称为局部坐标系。它是一个
(1)确定当前矩阵栈 void glMatrixMode(Glenum mode); 参数取值:
GL_MODELVIEW:模型视图矩阵
GL_PROJECTION:投影矩阵 GL_TEXTURE:纹理矩阵 默认的选定矩阵为模型-视图变换。
矩阵栈及其操作(2/8)
清矩阵栈栈顶
void glLoadIdentity(void); •将栈顶矩阵替换为单位矩阵 •取消之前变换的作用 M … I

对于二维图形向二维屏幕的投影,则应使用实 用库中的如下函数:
void gluOrtho2D(Gldouble left, Gldouble right,
Gldouble bottom, Gldouble top);

前面提到过,用二维顶点命令绘制的二维物体 的z坐标均为零,而gluOrtho2D()命令假定场景 中的 z 坐标介于-1.0和 1.0 之间。
左手坐标系,该坐标系是可以活动的。在初始态下,其原
点及x、y轴分别与世界坐标系的原点及x、y轴重合,而z轴 则正好相反,即为垂直屏幕面向内。

默认:视点在原点,视线沿Z轴负方向。
坐标系
右手坐标系
y
窗口 x
o z
缺省的观察坐标系
视点变换

View变换可以改变视点的位置和方向,要在 Model变换之前调用。设置任意观察坐标点。

基于OpenGL的三维图形绘制实验

基于OpenGL的三维图形绘制实验

基于OpenGL的三维图形绘制实验基于OpenGL的三维图形绘制实验⽬录实验题⽬:交互图形程序设计基础实验 (3)1.实验⽬的 (3)2.实验内容 (3)2.1 实验内容 (3)2.2 实验任务 (3)3.实验过程 (4)3.1 预处理 (4)3.3 主要函数说明 (5)3.4 过程描述 (6)3.5 运⾏截图 (7)4.实验结果 (7)5.实验体会 (7)实验题⽬:交互图形程序设计基础实验1.实验⽬的1)理解并掌握三维基本图形数据结构表⽰⽅法。

2)掌握编写OpenGL图形程序的基本⽅法.3)掌握OpenGL基本图形表⽰及绘制。

2.实验内容2.1 实验内容基于OpenGL的三维图形绘制实验⽬的是掌握图形信息的表⽰、数据的组织,在此基础上基于OpenGL绘制出三维图形。

实验内容包括OpenGL编程环境搭建、OpenGL程序结构、基本数据类型、核⼼函数等的使⽤;基本图形的绘制(点、线段、折线、闭合折线、多边形、三⾓形、三⾓扇、三⾓条带、四边形、四边形条带等)及图形属性控制(线宽、颜⾊、线型、填充样式等);对指定的若⼲三维模型进⾏建模、绘制,在⼀个程序框架下实现,提交1次程序,1份实验报告。

2.2 实验任务1、使⽤Visual C++建⽴⼀个单⽂档(SDI)程序,完成OpenGL绘制框架程序的设计。

在此基础上参照提供的资料,定义绘制函数,基于⾃定义的若⼲点坐标与颜⾊,分别绘制绘制点、线段、不闭合折线、闭合折线、多边形、三⾓形、四边形、三⾓扇、三⾓条带、四边形条带。

2、使⽤1中建⽴的程序框架,完成如下任务:(1)绘制正棱柱(底⾯多变形的边数及⾼度可以通过对话框输⼊)(2)正棱锥(底⾯多变形的边数及⾼度可以通过对话框输⼊)(3)正棱台(底⾯多变形的边数、台⾼、锥⾼可以通过对话框输⼊)注意模型坐标系的选择和顶点坐标的计算,每个图形的绘制单独写成函数。

加⼊菜单绘制三、四、五、六边的情况,其他边数情况从弹出对话框中输⼊参数,然后绘制。

opengl实验报告

opengl实验报告

opengl实验报告OpenGL实验报告引言:OpenGL(Open Graphics Library)是一种跨平台的图形编程接口,被广泛应用于计算机图形学、游戏开发和科学可视化等领域。

本实验报告将介绍我对OpenGL的实验研究和学习成果。

一、实验目的本次实验的主要目的是掌握OpenGL的基本概念和使用方法,了解图形渲染的原理和过程,以及学习如何在OpenGL中创建和操作图形对象。

二、实验环境本次实验使用的是OpenGL的最新版本,并在Windows操作系统下进行开发。

使用的开发工具是Visual Studio和OpenGL的开发库。

三、实验过程1. 熟悉OpenGL的基本概念在开始实验之前,我先学习了OpenGL的基本概念,包括OpenGL的坐标系统、图形渲染管线、着色器等。

了解这些概念对于后续的实验非常重要。

2. 创建窗口和上下文在OpenGL中,我们需要先创建一个窗口和一个OpenGL上下文,以便进行图形渲染。

通过调用相关的OpenGL函数,我成功创建了一个窗口,并初始化了OpenGL的上下文。

3. 绘制基本图形接下来,我开始尝试绘制一些基本的图形,比如点、线和三角形。

通过设置顶点坐标和颜色,我成功绘制出了这些基本图形,并在窗口中显示出来。

4. 添加纹理为了使图形更加逼真和丰富,我学习了如何在OpenGL中添加纹理。

通过加载图片并设置纹理坐标,我成功将纹理贴在了绘制的图形上,使其具有了更加真实的效果。

5. 光照和阴影效果为了增加图形的立体感和真实感,我学习了如何在OpenGL中添加光照和阴影效果。

通过设置光源的位置和属性,以及材质的属性,我成功实现了光照和阴影的效果,使图形看起来更加逼真。

6. 动画效果为了使图形具有动态效果,我学习了如何在OpenGL中实现简单的动画效果。

通过每帧更新顶点的位置和纹理坐标,我成功实现了图形的旋转和平移动画,使其具有了动态的效果。

四、实验结果和分析通过以上的实验过程,我成功掌握了OpenGL的基本概念和使用方法,并实现了一些基本的图形渲染效果。

OpenGL中的交互式绘图技术

OpenGL中的交互式绘图技术
当 OpenGL 处 于 选 择 模 式 时 , 不 以 GL_SELECT 为参数调用glRenderMode(),可以退出选择模式, 这时glRenderMode()返回选中记录的个数,这些 记录存放在glSelectBuffer()提供的数组中。
1.2反馈模式
• 信息反馈为程序设计提供了重要的运行资料。在 反馈模式下,场景渲染的信息存入反馈数组中, 不往屏幕输出。
计算机图形学
计算机图形学
• 粒子系统
OpenGL实例近视点Fra bibliotek远视点
OpenGL不仅可以绘制物体,还可以标记物体,以确定 在指定区域上绘制了哪些物体并返回绘图的信息。 绘制物体是在OpenGL缺省的绘图模式下进行的,而 标记物体和反馈绘图信息则是在选择模式和反馈模 式下完成的。 绘图模式,选择模式和反馈模式构成了OpenGL开发 三维图形应用程序的基础。在绘图模式下,物体的 几何参数,光照与材质参数,纹理参数等构成了交 互程序的绘制基础.选择模式则为用户提供了一种拾 取物体的机制,因而成为交互式程序设计的重要方 法。反馈模式将绘图信息加以组织并返回给应用程 序,成为程序设计的重要资料。
1.1 选择模式
• 在OpenGL中,使用int glRenderMode(GLenum mode)来选 择 不 同 的 模 式 。 其 中 mode 是 一 个 符 号 常 量 , 可 以 是 GL_RENDER,GL_SELECT,GL_FEEDBACK 之 一 , 默 认 的 是 GL_RENDER,也就是绘图模式,GL_SELECT指定选择模式, GL_FEEDBACK指定反馈模式。
选择模式
选择模式用来判断哪些图元将被绘制 在窗口的某个区域内。选择操作通过返回 一个整型名称数组来工作,这个数组存放 了名称堆栈当前的内容,这个数组由函数 glSelectBuffer()来提供。

OpenGL完全教程 第三章 使用OpenGL绘图

OpenGL完全教程 第三章 使用OpenGL绘图
glClearColor(0,0,0,1);
3.1.4 绘制之前,清空屏幕和缓冲区
一般地,我们把所有绘制函数的调用写在 RenderScene 过程中。在每次绘制之前,我们都应该清空屏幕和缓冲区。 下面的代码用指定的清空颜色清空它们:
procedure RenderScene;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
图 3.1-1 WindowsGDI 下的窗体坐标 图 3.1-2 OpenGL 所定义的窗体坐标
例如,要设置如图 3.1-3 中的视见区域,我们应该调用函数: glViewPort(100,100,Width,Height);
图 3.1-3 3.1.2 创建投影变换
接下来,我们要设置一种投影变换。投影变换分为平行投影和透视投影。平行投影中,物体无论远近,大小都是 一样的,而透视投影则相反。因此,透视投影更像是我们眼睛所看到的景物。但在某些特殊的时候, 平行投影还是 有它的作用的,比如 3D 建摸程序。图 3.1-4 是甲烷分子模型在平行投影下的渲染结果,而图 3.1-5 是在透视投影下的 渲染结果。可以看到,平行投影下,四个氢原子(绿色的球体)大小是一样的,而在透视投影下,远处的氢原子要小一 些。
private procedure SetView; procedure RenderScene; //渲染函数 procedure InitializeOpenGL; //用于初始化 OpenGL 渲染环境
public { public declarations }
end;
然后,在 FormCreate 过程中添加对过程 SetView 的调用:
图 3.1-7 由 gluPerspective 定义的ห้องสมุดไป่ตู้截头体 我们用下面的代码定义透视投影:

OpenGL实验三

OpenGL实验三

计算机学院12计算机科学与技术专业3班学号3112005883姓名:曲绍霖教师评定:实验三交互与运动的实现一、实验目的掌握OpenGL的纹理贴图绘制方法二、实验要求在Windows平台上用VC++结合GLUT做实验,要求掌握结合VC++和OpenGL的纹理模型的理解及实现,实验完成后要求根据自己的成果撰写一份实验报告。

三、实验环境操作系统:Windows xp开发环境:VC++6.0以及GLUT图形交互设备:鼠标和键盘四、实验内容在前面实验的基础上增加键盘和鼠标交互和物体的运动。

五、存在的问题和感想这次实验相对于前面的实验难度较大,要经过多次的调试才能通过,通过之后还不能达到理想的效果,但是经过我的认真学习关于纹理的知识,最后经过认真学习给的例子,最后还是顺利地做出了实验要求的效果。

实现代码:#include<windows.h>#include <stdlib.h>#include<stdio.h>#include <GL/glew.h>#include <GL/glut.h>//模式选择开关int iModel=1;//图形旋转方向开关int ispin=1;static GLfloat xRot = 0.0f; //x方向旋转参数static GLfloat yRot = 0.0f; //y方向旋转参数//初始化OpenGL绘制环境void init(void){glClearColor(1.0,1.0,1.0,0.0);//背景颜色为白色glEnable(GL_DEPTH_TEST);//这句是启用深度测试,这样,在后面的物体会被挡着glShadeModel(GL_SMOOTH);glEnable(GL_CULL_FACE);glFrontFace(GL_CCW);}void myDisplay(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存glLoadIdentity();// 重置当前的模型观察矩阵gluLookAt(2.0,2.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);//设置图元描述的视角//设置正方体旋转并绘制glRotatef(xRot, 1.0f, 0.0f, 0.0f);glRotatef(yRot, 0.0f, 1.0f, 0.0f);glBegin(GL_QUADS);glColor3f(0.0f,1.0f,0.0f); // 颜色改为绿色glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点(顶面)glColor3f(1.0f,0.0f,0.0f); //颜色改为红色glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点(顶面)glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左下顶点(顶面)glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右下顶点(顶面)glColor3f(0.0f,1.0f,0.0f); // 颜色改为绿色glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右上顶点(底面)glColor3f(1.0f,0.0f,0.0f); //颜色改为红色glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左上顶点(底面)glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(底面)glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(底面)glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右上顶点(前面)glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左上顶点(前面)glColor3f(1.0f,0.0f,0.0f); //颜色改为红色glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左下顶点(前面)glColor3f(0.0f,1.0f,0.0f); // 颜色改为绿色glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右下顶点(前面)glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右上顶点(后面)glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左上顶点(后面)glColor3f(1.0f,0.0f,0.0f); //颜色改为红色glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左下顶点(后面)glColor3f(0.0f,1.0f,0.0f); // 颜色改为绿色glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右下顶点(后面)glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的右上顶点(左面)glColor3f(1.0f,0.0f,0.0f); //颜色改为红色glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点(左面)glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(左面)glColor3f(1.0f,0.0f,0.0f); //颜色改为红色glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的右下顶点(左面)glColor3f(0.0f,1.0f,0.0f); // 颜色改为绿色glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点(右面)glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的左上顶点(右面)glColor3f(0.0f,1.0f,0.0f); // 颜色改为绿色glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的左下顶点(右面)glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(右面)glEnd();//正方体绘制结束glFlush();//强制刷新glutSwapBuffers(); //双缓冲}//设窗口的坐标void reshape(int w,int h){glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(40.0,(GLfloat)w/(GLfloat)h,1.0,20.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}//键盘控制void SpecialKeys(int key,int x,int y){//上下左右键控制正方体旋转if(iModel==2){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();}void keyboard(unsigned char key, int x, int y){switch (key){case 27: // 当按下键盘的esc键的时候退出exit(0);break;}}//鼠标控制旋转轴void mouse(int btn, int state, int x, int y){if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)ispin=~ispin;}//设置刷新时间void TimerFunction(int value){glutPostRedisplay();//设置自动旋转if(iModel==1){if(ispin==1){yRot+=10;if(yRot>=360)yRot-=360;}else{xRot+=10;if(xRot>=360)xRot-=360;}}glutTimerFunc(100,TimerFunction,1);}//菜单选项设置void nMenu(int value){switch(value){//1、2为旋转自动或手动case 1:iModel=1;xRot=0,yRot=0;ispin=1;break;case 2:iModel=2;xRot=0,yRot=0;ispin=1;break;}glutPostRedisplay();}int main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowPosition(100, 100);glutInitWindowSize(800,600);// 设置窗口大小800*600glutCreateWindow("键盘鼠标交互下的正方体");//创建右键选择菜单int nRotatefMenu = glutCreateMenu(nMenu);glutAddMenuEntry("自动旋转",1); //创建图元描述菜单glutAddMenuEntry("手动旋转",2);int nMainMenu = glutCreateMenu(nMenu); //创建主菜单glutAddSubMenu("旋转", nRotatefMenu);glutAttachMenu(GLUT_RIGHT_BUTTON);glutTimerFunc(100,TimerFunction,1);init();glutSpecialFunc(SpecialKeys);glutKeyboardFunc(keyboard);glutMouseFunc (mouse);glutDisplayFunc(myDisplay);glutReshapeFunc(reshape);glutMainLoop();return 0;}运行结果:鼠标右键菜单选择旋转模式自动旋转鼠标左键控制旋转轴(左图)手动旋转键盘控制旋转方向(右图)。

OPENGL_实验指导书

OPENGL_实验指导书

虚拟飞行技术基础实验指导书梅跃松实验1. OpenGL程序框架及基础图形绘制一、实验目的:了解OpenGL的程序框架,并学会在Windows环境下绘制点、线、面等基础图形,并会设置背景及对象颜色。

二、实验内容:要求创造一个窗口,窗口标题为“绘制几何图元”,窗口大小为320*240,窗口左上角坐标(100,150),在创建窗口时使用单缓冲区窗口(GLUT_SINGLE)并使用RGB颜色模式(GLUT_RGB),背景白色,在(50.0,50.0),(150.0,60.),(100.0,200.0)位置各画三个点,点大小为4个像素,以(200.0,50.0),(300.0,70.0),(290.0,100.0),(210.0,200.0)为四个顶点画四边形,点和四边形皆为红色,裁剪区域为(0,0)到(300,240)。

三、实验要求:下课前通过Email:mys001@提交程序。

实验2. OpenGL平移、旋转和缩放技术一、实验目的:了解OpenGL中从未加工的顶点数据到屏幕坐标的过程,掌握平移、旋转和缩放方法。

二、实验内容:要求设计一个正方体,该正方体六个面无重复颜色,并且绕(0,0,0)和(-1,1,0)两点所确定的轴旋转。

三、实验要求:下课前通过Email:mys001@提交程序。

实验3. OpenGL矩阵堆栈技术和投影技术一、实验目的:掌握OpenGL程序的矩阵堆栈技术和投影技术,以及鼠标和键盘的使用。

二、实验内容:仿照课堂上讲解的原子核程序设计一个飞机绕原子核飞行的程序,亦即绘制一个纸飞机,使其替换掉绕Y轴旋转的电子,要求程序中使用投影技术,并且可以用鼠标来控制飞机的飞行,鼠标左键点击,飞机沿逆Y轴方向逆时针飞行,鼠标右键点击,飞机则顺时针飞行。

三、实验要求:下课前通过Email:mys001@提交程序。

实验4. OpenGL光照技术和材质技术一、实验目的:掌握OpenGL程序的光照技术和材质技术,学会环境光、散射光、镜面光和辐射光四种场景光的使用,学会光源的使用,并了解不同材质设定下的不同的作用效果,学会多光源的使用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验三 OpenGL的简单交互绘制一、实验目的1、理解OpenGL坐标系的概念,掌握OpengGL裁剪窗口、视区、显示窗口的概念和它们之间的关系,学会计算世界坐标和屏幕坐标。

2、学会OpenGL的简单键盘交互操作。

3、学会OpenGL的简单字符绘制。

3、进一步掌握OpengGL点、直线、多边形的绘制。

二、实验环境硬件要求:PC机,主流配置,最好为独立显卡,显存512M以上。

软件环境:操作系统:Windows XP。

语言开发工具:Microsoft Visual studio 2008,Visual C++。

程序框架:Win32应用程序三、实验内容与要求3.1 键盘交互1、调出实验一的源代码运行,调整修改使得显示窗口在屏幕中央保持缺省大小(300*300),绘制的矩形在显示窗口中央。

如图2-1所示。

提示:(1)添加修改窗口位置的函数glutInitWindowPosition(int x, int y);其中(x,y)为窗口左上角在屏幕上的位置。

(2)显示窗口的左下角坐标为(-1,-1),右上角坐标为(1,1)。

图2-1未修改前的win32初始源程序参考如下:/*my first program.cpp*/#include"stdafx.h"#include<glut.h>void display(void);void myreshape(GLsizei w, GLsizei h);int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);char *argv[] = {"hello ", " "};int argc = 2; // must/should match the number of strings in argvglutInit(&argc, argv); //初始化GLUT库;glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //设置显示模式;(缓冲,颜色类型)glutInitWindowSize(500, 500);glutInitWindowPosition(1024 / 2 - 250, 768 / 2 - 250);glutCreateWindow("Hello"); //创建窗口,标题为“hello”;glutDisplayFunc(display); //用于绘制当前窗口;glutMainLoop(); //表示开始运行程序,用于程序的结尾;return 0;}void display(void){glClear(GL_COLOR_BUFFER_BIT); //刷新颜色缓冲区glRectf(-0.5,-0.5,0.5,0.5);glFlush(); //用于刷新命令队列和缓冲区,使所有尚未被执行的OpenGL命令得到执行}2、在实验一的基础上添加键盘交互,按W键绘制的矩形上移,按S键矩形下移,按A键矩形左移,按D键矩形右移,如图2-2。

参考步骤如下:(1)在主函数里添加注册键盘回调函数glutKeyboardFunc(mykeyboard);此函数可放在 glutDisplayFunc(display);后面。

并在程序头部声明添加键盘回调函数:void mykeyboard(unsigned char key, int x, int y);(2)在display()绘制函数中修改绘制矩形代码,用变量代替数值参数。

例如: glRectf(-0.5,-0.5,0.5,0.5)改为glRectf(x1,y1,x2,y2);程序前面加上变量声明和初始值,如:floatx1=-0.5,y1=-0.5,x2=0.5,y2=0.5; 注意语句的位置。

(3)在程序中增加mykeyboard键盘子函数,可放在display()函数之后。

并在如下代码中进行修改,实现键盘控制矩形移动,运行程序自行测试。

void mykeyboard(unsigned char key, int x, int y){switch(key){ case 'W':case 'w':// 矩形对角坐标变量修改使得矩形上移y1+=0.1; y2+=0.1;break;case 'S':case 's'://矩形对角坐标变量修改使得矩形下移y1-=0.1;y2-=0.1;break;case 'A':case 'a'://矩形对角坐标变量修改使得矩形左移x1-=0.1; x2-=0.1;break;case 'D':case 'd'://矩形对角坐标变量修改使得矩形右移x1+=0.1; x2+=0.1;break;}//参数修改后调用重画函数,屏幕图形将发生改变glutPostRedisplay();}图2-23、设置窗口改变函数,使得矩形的长度和宽度等于100,程序启动时矩形仍在窗口中央,当显示窗口最大化时,绘制矩形也随之增大,如图2-3。

(1)在main函数里添加注册窗口变化函数glutReshapeFunc(myreshape); (放在glutMainLoop()之前)并在程序头部声明添加窗口变换函数:void myreshape(GLsizei w, GLsizei h);(2)在程序中添加窗口改变子函数,参数w,h为当前显示窗口的宽和高 void myreshape(GLsizei w, GLsizei h){glViewport(0,0,w,h); //设置视区位置glMatrixMode(GL_PROJECTION);//设置投影变换模式glLoadIdentity(); //调单位矩阵,清空当前矩阵堆栈gluOrtho2D(0,300,0,300);}3) 此时,矩形的初始变量经重新计算后为:float x1=100,x1=100,x2=200,y2=200;注意:请同学们自己思考为什么矩形初始的初始变量由原来的(-0.5,-0.5,0.5,0.5)变为(100,100,200,200) ?裁剪窗口设置函数gluOrtho2D(xwmin,xwmax,ywmin,ywmax); 和视区设置函数glViewport(startx,starty,viewport_width,viewport_height)的设置有何规律?此时,按下键盘“WADS”键进行交互移动,矩形的移动距离较之前有什么变化?要保持以前的移动频率,程序应该如何修改?a) 显示窗口改变前 b)显示窗口变大后图2-34、在矩形中间添加字符"Hello",观察结果;然后将"Hello"字符改为自己名字的拼音或英文名字。

如图2-4所示。

提示:在绘制矩形后添加如下代码:glColor3f(1,0,0);glRasterPos2i((x1+x2)/2,(y1+y2)/2); //定位当前光标glutBitmapCharacter(GLUT_BITMAP_9_BY_15,'H'); //写字符"H"glutBitmapCharacter(GLUT_BITMAP_9_BY_15,'e'); //写字符"e"glutBitmapCharacter(GLUT_BITMAP_9_BY_15,'l'); //写字符"l"glutBitmapCharacter(GLUT_BITMAP_9_BY_15,'l'); //写字符"l"glutBitmapCharacter(GLUT_BITMAP_9_BY_15,'o'); //写字符"o"注意:运行程序,效果如图2-4所示。

但是如果此时,按下键盘“WADS”键进行交互移动,程序会发生什么变化?要保持矩形白色,字符红色,程序应该如何修改?如果字符颜色设置语句glColor3f(1,0,0);放在定位光标语句glRasterPos2i((x1+x2)/2,(y1+y2)/2); 之后,运行又会发生什么变化?请同学自己总结设置字符颜色语句的顺序规律。

图2-45、自己参照讲义或教材按照自己的构思画二维平面图形,将上面的矩形替换成自己构思的二维平面图形实现交互功能,注意顶点的顺序。

并在画面上标注自己的姓名。

3.2 鼠标交互(1) 鼠标画线阅读OpenGL鼠标画线程序,能够实现在绘制窗口用鼠标交互绘制若干条直线,鼠标左键首先按下,确定直线的起始点,鼠标左键按下同时移动,看到画线过程,鼠标左键松开时,确定直线的终点,可重复画多条直线。

实现主要思路:1) 写出画静止若干条直线程序框架,坐标用变量替代;2) 在主函数里注册鼠标按钮响应函数和鼠标移动响应函数;3) 在鼠标按钮响应子函数里,给出鼠标按钮响应事件;4) 在鼠标移动响应子函数里,给出鼠标移动响应事件;5) 读懂程序并分析程序,保留程序。

//鼠标画线小程序#include"stdafx.h"#include<glut.h>#define N 1000 //maximum line numbersint ww,hh; // for display window width and heightint line[N][4], k=0; //for line's endpoint coordinates and line numbervoid Myinit(void);void Reshape(int w, int h);void myMouse(int button,int state,int x,int y);void myMotion(int x,int y);void Display(void);void drawlines();int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);char *argv[] = {"hello ", " "};int argc = 2; // must/should match the number of strings in argvglutInit(&argc, argv); //初始化GLUT库;glutInitWindowSize(800, 600); //设置显示窗口大小glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); //设置显示模式;(注意双缓冲)glutCreateWindow("鼠标画线小程序演示"); // 创建显示窗口Myinit();glutDisplayFunc(Display); //注册显示回调函数glutMouseFunc(myMouse); //注册鼠标按钮回调函数glutMotionFunc(myMotion); //注册鼠标移动回调函数glutReshapeFunc(Reshape); //注册窗口改变回调函数glutMainLoop(); //进入事件处理循环return 0;}void Myinit(void){glClearColor(0.0,0.0,0.0,0.0);glLineWidth(3.0);}//渲染绘制子程序--------------------------------------------------------------------------void Display(void){glClear(GL_COLOR_BUFFER_BIT); //刷新颜色缓冲区;drawlines(); //画线子程序;glutSwapBuffers(); //双缓冲的刷新模式;}//-----------------------------------------------void Reshape(int w, int h) //窗口改变时自动获取显示窗口的宽w和高h{glMatrixMode(GL_PROJECTION); //投影矩阵模式glLoadIdentity(); //矩阵堆栈清空glViewport(0, 0, w, h); //设置视区大小gluOrtho2D(0, w, 0, h); //设置裁剪窗口大小ww=w;hh=h;}//鼠标按钮响应事件..void myMouse(int button,int state,int x,int y){if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN){line[k][0]=x; //线段起点x坐标line[k][1]=hh-y; //线段终点y坐标}if(button==GLUT_LEFT_BUTTON&&state==GLUT_UP){line[k][2]=x; //线段起点x坐标line[k][3]=hh-y; //线段终点y坐标k++;glutPostRedisplay();}}//鼠标移动时获得鼠标移动中的坐标----------------------------------------------------- void myMotion(int x,int y){//get the line's motion pointline[k][2]=x; //动态终点的x坐标line[k][3]=hh-y; //动态终点的y坐标glutPostRedisplay();}//画线子程序void drawlines(){for(int i=0;i<=k;i++) //********{glBegin(GL_LINES);glVertex2f(line[i][0],line[i][1]);glVertex2f(line[i][2],line[i][3]);glEnd();}}鼠标画线程序运行后,程序效果如图3-3所示。

相关文档
最新文档