计算机图形学报告3
西安电子科技大学
计算机图形学 课程实验报告
实验名称 第3次上机实验
计算机 学院 1803012 班
姓名 曹王欣 学号 18030100167
同作者
实验日期 2020 年 月 日
实验地点 实验批次
指导教师评语:
指导教师: 年 月 日 |
实验报告内容基本要求及参考格式 一、实验目的 二、实验所用仪器(或实验环境) 三、实验基本原理及步骤(或方案设计及理论计算) 四、实验数据记录(或仿真及软件设计) 五、实验结果分析及回答问题(或测试环境及测试结果) |
第三次上机作业
- 绘制曲线(借鉴lec6课件)
1. 证明如下的两条三次曲线段具有C1连续性,但没有G1连续性,并画出两条曲线段。
2. 假定一条三次Hermite曲线的两个端点P1=<0,1>,P4=<3,0>,端点处切向量R1=<0,1>,R4=<-3,0>,请写出Hermite多项式形式,并绘出最后曲线,改变切向量,观察曲线形状变化。
3. 已知4点P1(0,0,0)、P2(1,1,1)、
P3(2,-1,-1)、P4(3,0,0),用其作为特征多边形分别构造一条Bezier曲线、一条B样条曲线,并绘制出曲线。
- 其它(借鉴以前课上的例程)
- 编写程序,使一物体沿着一条直线匀速移动。
- 编写程序,使一物体围绕屏幕上一点匀速旋转。
注:物体可以是2D或3D(如果是3D图形,试着采用透视投影,观察近大远小的效果)
glutWireCube(GLdouble size);//线框立方体
glutWireTeapot(GLdouble size); //线框茶壶
针对(一)的第1题:
当t=1时 p1的点为(0,0),而当t=0,p2的点为(0,0),必定C0,G0连续
而当t=1时,先求导 P1处的导数向量是(0,0),当t=0,P2的导数向量是(0,0),所以C1连续,但是方向无法确定(两个方向都是0),所以G1不连续
画图程序如下:
#include<GL/glut.h>
typedef struct {
float x, y, z;
}Point;
void init()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void DrawCurve(int n)
{
Point p,q;
double t, deltat;
int i;
deltat = 1.0 / (n - 1);
glBegin(GL_LINE_STRIP);
for (i = 0; i < 100; i++)
{
t = i * deltat;
p.x = t * t - 2 * t + 1;//对p求x坐标
p.y = t * t * t - 2 * t * t + t;//对p求y坐标
p.z = 0;
glVertex3f(p.x, p.y, p.z);
}
glEnd();
glBegin(GL_LINE_STRIP);
for (i = 0; i < 100; i++)
{
t = i * deltat;
q.x = t * t;//对q求x坐标
q.y = t * t * t ;//对q求y坐标
q.z = 0;
glVertex3f(q.x, q.y, q.z);
}
glEnd();
glPointSize(5.0);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POINTS);
glVertex3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(1, 1, 0);
glEnd();
}
void RenderScence()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
DrawCurve(100);
glFlush();
}
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat aspectRatio;
if (h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
aspectRatio = (GLfloat)w / (GLfloat)h;
if (w <= h)
glOrtho(-2.0, 2.0, -2.0 / aspectRatio, 2.0 / aspectRatio, 1.0, -1.0);
else
glOrtho(-2.0 * aspectRatio, 2.0 * aspectRatio, -2.0, 2.0, 1.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("第三次上机第一次实验");
init();
glutDisplayFunc(RenderScence);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
实验截图如下:
可以看到,虽然拼接点处是连续的,但是并不是变化光滑的
针对(一)的第二个题目
2. 假定一条三次Hermite曲线的两个端点P1=<0,1>,P4=<3,0>,端点处切向量R1=<0,1>,R4=<-3,0>,请写出Hermite多项式形式,并绘出最后曲线,改变切向量,观察曲线形状变化。
Hermite多项式应该是:
Pt = P1*(2t^3-3t^2+1)+P4*(-2t^3+3t^2)+R1*(t^3-2^t2+t)+R4*(t^3-t^2)
带入这四个点的坐标应该变成
Pt=((-9*t^3+12*t^2) , (3t^3-5t^2+2t)
源程序如下:
#include<GL/glut.h>
typedef struct {
float x, y, z;
}Point;
Point ctrlpoints[4] = { {0.0,1.0,0.0},{3.0,0.0,0.0},{0.0,1.0,0.0},{-3.0,0.0,0.0} };
void init()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void DrawCurve(int n)
{
Point p;
double t, deltat, et0, et1, et2, et3;
int i;
deltat = 1.0 / (n - 1);
glBegin(GL_LINE_STRIP);
for (i = 0; i < 100; i++)
{
t = i * deltat;
et3 = 2 * t * t * t - 3 * t * t + 1;
et2 = -2 * t * t*t + 3 * t * t;
et1 = t * t * t - 2 * t * t + t;
et0 = t * t * t - t * t;
p.x = et3 * ctrlpoints[0].x + et2 * ctrlpoints[1].x + et1 * ctrlpoints[2].x + et0 * ctrlpoints[3].x;
p.y = et3 * ctrlpoints[0].y + et2 * ctrlpoints[1].y + et1 * ctrlpoints[2].y + et0 * ctrlpoints[3].y;
p.z = et3 * ctrlpoints[0].z + et2 * ctrlpoints[1].z + et1 * ctrlpoints[2].z + et0 * ctrlpoints[3].z;
glVertex3f(p.x, p.y, p.z);
}
glEnd();
glPointSize(5.0);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POINTS);
for (i = 0; i < 2; i++)
glVertex3f(ctrlpoints[i].x, ctrlpoints[i].y, ctrlpoints[i].z);
glEnd();
glBegin(GL_LINES);
glVertex3f(0, 1, 0);
glVertex3f(0, 2, 0);//画出向量1
glEnd();
glBegin(GL_LINES);
glVertex3f(3, 0, 0);
glVertex3f(0, 0, 0);//画出向量2
glEnd();
}
void RenderScence()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
DrawCurve(100);
glFlush();
}
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat aspectRatio;
if (h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
aspectRatio = (GLfloat)w / (GLfloat)h;
if (w <= h)
glOrtho(-5.0, 5.0, -5.0 / aspectRatio, 5.0 / aspectRatio, 1.0, -1.0);
else
glOrtho(-5.0 * aspectRatio, 5.0 * aspectRatio, -5.0, 5.0, 1.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("第三次实验第二次实验,hermite曲线");
init();
glutDisplayFunc(RenderScence);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
截图如下:
可以看到,我们画出了此曲线,还根据R1和R4画了切向量,这条曲线是正确的(在(0,1)处突然向量突然急剧变化,所以可能有点看不清楚)
3. 已知4点P1(0,0,0)、P2(1,1,1)、
P3(2,-1,-1)、P4(3,0,0),用其作为特征多边形分别构造一条Bezier曲线、一条B样条曲线,并绘制出曲线。
源程序中的核心代码如下:
glBegin(GL_LINE_STRIP);//先画贝塞尔曲线
for (i = 0; i < 100; i++)
{
t = i * deltat;
et = 1 - t;
t2 = t * t;
et2 = et * et;//画贝塞尔曲线,底下的代码是
t3 = t * t2;
et3 = et * et2;
p.x = et3 * ctrlpoints[0].x + 3 * t * et2 * ctrlpoints[1].x + 3 * t2 * et * ctrlpoints[2].x + t3 * ctrlpoints[3].x;
p.y = et3 * ctrlpoints[0].y + 3 * t * et2 * ctrlpoints[1].y + 3 * t2 * et * ctrlpoints[2].y + t3 * ctrlpoints[3].y;
p.z = et3 * ctrlpoints[0].z + 3 * t * et2 * ctrlpoints[1].z + 3 * t2 * et * ctrlpoints[2].z + t3 * ctrlpoints[3].z;
glVertex3f(p.x, p.y, p.z);
}
glEnd();
以上是画贝塞尔曲线
画BLine的核心代码如下:
//画bline样条曲线
glBegin(GL_LINE_STRIP);
for (i = 0; i < 100; i++)
{
t = i * deltat;
et3 = 1.0 / 6 * (1 - 3 * t + 3 * t * t - t * t * t);
et2 = 1.0 / 6 * (4 - 6 * t * t + 3 * t * t * t);
et = 1.0 / 6 * (-3 * t * t * t + 3 * t * t + 3 * t + 1);
et0 = 1.0 / 6 * (t * t * t);
p.x = et3 * ctrlpoints[0].x +et2 * ctrlpoints[1].x + et * ctrlpoints[2].x + et0 * ctrlpoints[3].x;
p.y = et3 * ctrlpoints[0].y +et2 * ctrlpoints[1].y + et * ctrlpoints[2].y + et0 * ctrlpoints[3].y;
p.z = et3 * ctrlpoints[0].z +et2 * ctrlpoints[1].z + et * ctrlpoints[2].z + et0 * ctrlpoints[3].z;
glVertex3f(p.x, p.y, p.z);
}
glEnd();
全部代码如下:
#include<GL/glut.h>
#include<iostream>
using namespace std;
typedef struct {
float x, y, z;
}Point;
Point ctrlpoints[4] = { {0.0,0.0,0.0},{1,1,1},{2,-1,-1},{3.0,0.0,0.0} };
void init()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void DrawCurve(int n)
{
Point p;
double t, deltat, t2, t3, et, et2, et3,et0;
int i;
deltat = 1.0 / (n - 1);
glColor3f(1, 0, 0);
glBegin(GL_LINE_STRIP);//先画贝塞尔曲线
for (i = 0; i < 100; i++)
{
t = i * deltat;
et = 1 - t;
t2 = t * t;
et2 = et * et;//画贝塞尔曲线,底下的代码是
t3 = t * t2;
et3 = et * et2;
p.x = et3 * ctrlpoints[0].x + 3 * t * et2 * ctrlpoints[1].x + 3 * t2 * et * ctrlpoints[2].x + t3 * ctrlpoints[3].x;
p.y = et3 * ctrlpoints[0].y + 3 * t * et2 * ctrlpoints[1].y + 3 * t2 * et * ctrlpoints[2].y + t3 * ctrlpoints[3].y;
p.z = et3 * ctrlpoints[0].z + 3 * t * et2 * ctrlpoints[1].z + 3 * t2 * et * ctrlpoints[2].z + t3 * ctrlpoints[3].z;
glVertex3f(p.x, p.y, p.z);
}
glEnd();
//然后画包围的点
glPointSize(5.0);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POINTS);
for (i = 0; i < 4; i++)
glVertex3f(ctrlpoints[i].x, ctrlpoints[i].y, ctrlpoints[i].z);
glEnd();
glPointSize(3.0);
glColor3f(0, 0, 1);
//画bline样条曲线
glBegin(GL_LINE_STRIP);
for (i = 0; i < 100; i++)
{
t = i * deltat;
et3 = 1.0 / 6 * (1 - 3 * t + 3 * t * t - t * t * t);
et2 = 1.0 / 6 * (4 - 6 * t * t + 3 * t * t * t);
et = 1.0 / 6 * (-3 * t * t * t + 3 * t * t + 3 * t + 1);
et0 = 1.0 / 6 * (t * t * t);
p.x = et3 * ctrlpoints[0].x +et2 * ctrlpoints[1].x + et * ctrlpoints[2].x + et0 * ctrlpoints[3].x;
p.y = et3 * ctrlpoints[0].y +et2 * ctrlpoints[1].y + et * ctrlpoints[2].y + et0 * ctrlpoints[3].y;
p.z = et3 * ctrlpoints[0].z +et2 * ctrlpoints[1].z + et * ctrlpoints[2].z + et0 * ctrlpoints[3].z;
glVertex3f(p.x, p.y, p.z);
}
glEnd();
glFlush();
}
void RenderScence()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
DrawCurve(100);
glFlush();
}
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat aspectRatio;
if (h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
aspectRatio = (GLfloat)w / (GLfloat)h;
if (w <= h)
glOrtho(-5.0, 5.0, -5.0 / aspectRatio, 5.0 / aspectRatio, 1.0, -1.0);
else
glOrtho(-5.0 * aspectRatio, 5.0 * aspectRatio, -5.0, 5.0, 1.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("DrawBezier");
init();
glutDisplayFunc(RenderScence);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
实验截图如下:
其中红色的曲线是贝塞尔曲线,可以看到他由四个控制点控制,经过控制点1和4,而且切线方向分别是1-2,3-4,而蓝色的比较短的曲线是BLine,可以看到他并不过这四个点,所以我们成功完成了此次实验
- 其它(借鉴以前课上的例程)
编写程序,使一物体沿着一条直线匀速移动
此程序我的源代码如下:
#include<GL/glut.h>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<iostream>
double z = 40;//球的z坐标
double speed = 0.05;//球移动速度
int depth = 1000;//投影视体的深度
int start = 40;
int enable = 1;//运动的使能信号
void myinit();
void Rendscene();
void Changesize(GLsizei w, GLsizei h);
void mykey(unsigned char key, int x, int y);
void specialkey(int key, int x, int y);
void displayc(double x, double y, double z, char str[]);
int main(int argc, char** argv)
{
glutInit(&argc, argv);//初始化固定格式
glutInitWindowPosition(300, 200);//初始化窗口位置
glutInitWindowSize(300, 300);//初始化窗口宽度和高度
glutCreateWindow("小球沿直线运动");
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);//初始化显示模式:双缓存窗口、RGB色彩空间、深度缓存
myinit();//自己定义的初始化函数,设置背景颜色
glutDisplayFunc(Rendscene);//注册显示回调函数
glutReshapeFunc(Changesize);//注册窗口重塑回调函数
glutKeyboardFunc(mykey);//注册键盘回调函数
glutSpecialFunc(specialkey);
glutMainLoop();//进入事件处理循环
}
void myinit()
{
glClearColor(1, 1, 1, 1);//RGBA形式最后一个为透明度,1表示窗体颜色不透明
}
void Changesize(GLsizei w, GLsizei h)
{
float ratio;
if (h == 0)
h = 1;
ratio = (float)w / (float)h;
glViewport(0, 0, w, h);//定义视口
glMatrixMode(GL_PROJECTION);
glLoadIdentity();//定义矩阵模式为投影矩阵,并将矩阵堆栈单位化
gluPerspective(60, ratio, start, depth);//透视矩阵压入堆栈,进行透视变换,四个参数依次为,眼睛睁开角度、宽高比、前透视面距离、后透视面距离(填正值,但其实该透视体处于z负轴)
glEnable(GL_DEPTH_TEST);//开启更新深度缓冲区功能
gluLookAt(0, 10, 40, 0, 0, 0, 0, 1, 0);//相机从(0,10,40)看向(0,0,0,),(0,1,0)为正方向
glMatrixMode(GL_MODELVIEW);//投影变换完了进入绘图模式
glLoadIdentity();
}
void Rendscene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除颜色缓存
glColor3f(1, 0, 0);
glMatrixMode(GL_MODELVIEW);//投影变换完了进入绘图模式
glLoadIdentity();
if (z > depth)
z = 40;
else
z = z + speed;
glTranslated(0.0, 0.0, -z);//把整个场景移到到视图中
glutWireSphere(10, 180, 180);//画半径为10,经度渲染180条和纬度渲染180的球,由于是矩阵堆栈,所以是先移动后转
char str[] = "caowangxin";
displayc(-30, 12, -z, str);
glLoadIdentity();
//画两条平行线当做路
glBegin(GL_LINES);
glColor3f(0, 0, 0);
glVertex3d(-10, -5, 30);
glVertex3d(-15, -5, -depth);
glEnd();
glBegin(GL_LINES);
glColor3f(0, 0, 0);
glVertex3d(10, -5, 30);
glVertex3d(15, -5, -depth);
glEnd();
glFlush();
glutSwapBuffers();//交换缓冲区保证有流畅动画
glLoadIdentity();
if (enable == 1)
glutPostRedisplay();//回调生产动画
}
void mykey(unsigned char key, int x, int y) //响应ASCII对应键,鼠标的当前x和y位置也被返回。
{
switch (key)
{
case 'r':enable = 1;
glutPostRedisplay();
break;
case 's':enable = 0;
glutPostRedisplay();
break;
case 27: exit(-1);
}
}
void specialkey(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_UP:
speed += 1;
break;
case GLUT_KEY_DOWN:
speed -= 1;
break;
}
}
void displayc(double x, double y, double z, char str[])//显示字符函数
{
glColor3f(0, 0, 0);
//glClear(GL_COLOR_BUFFER_BIT);
glRasterPos3d(x, y, z);
for (int i = 0; i < strlen(str); i++)
{
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, str[i]);
}
//glFlush();
}
我先定义了两条导轨,然后让小球沿着这两条导轨运动,红色的小球不断远离我的视线,截图效果如下(在下面):
在这个程序中,我的观察方向和导轨延申的方向相同,所以可以看到小球不断原理我
这就是完成了所谓的小球沿直线运动
- 编写程序,使一物体围绕屏幕上一点匀速旋转。
注:物体可以是2D或3D(如果是3D图形,试着采用透视投影,观察近大远小的效果)
glutWireCube(GLdouble size);//线框立方体
glutWireTeapot(GLdouble size); //线框茶壶
对于此程序,我画了一个茶壶,然后让他可以旋转起来,我这里观察的位置是
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
从(0,0,5)朝(0,0,0)观看,法线是(0,1,0)
gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0);
使用此函数进行窗口的裁剪
这里我定义了鼠标回调函数,用于旋转我的茶壶,尤其是motion函数,可以定义按住鼠标的时候鼠标的动作(此程序也将用于第五次实验之中,那时候我们将加上光照)
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
speed = 0;
rote = 0;
remeberx = x;//当左键按下时记录鼠标坐标
remebery = y;
cout << "left" << endl;
}
}
if (button == GLUT_RIGHT_BUTTON)
{
if (state == GLUT_DOWN)
{
speed += 1.0f;
cout << "right" << endl;
}
}
}
void motion(int x, int y)
{
GLint deltax = remeberx - x;
GLint deltay = remebery - y;
anglex += 360 * (GLfloat)deltax / (GLfloat)WinW;//根据屏幕上鼠标滑动的距离来设置旋转的角度
angley += 360 * (GLfloat)deltay / (GLfloat)WinH;
anglez += 360 * (GLfloat)deltay / (GLfloat)WinH;
remeberx = x;//记录此时的鼠标坐标,更新鼠标坐标
remebery = y;//若是没有这两句语句,滑动是旋转会变得不可控
glutPostRedisplay();
glutPostRedisplay();
}
所有程序如下:
#include <stdlib.h>
#include <GL/glut.h>
#include<iostream>
using namespace std;
GLfloat speed = 0.0;// set rote of speed ying yu bu hao bu zhuang le 设置旋转速率
GLfloat rote = 0.0;//shezhi旋转角度
GLfloat anglex = 0.0;//X 轴旋转
GLfloat angley = 0.0;//Y 轴旋转
GLfloat anglez = 0.0;//Z 轴旋转
GLint WinW = 400;
GLint WinH = 400;
GLfloat remeberx;//当左键按下时记录鼠标坐标
GLfloat remebery;
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 1.0); //背景黑色
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0); //画笔红色
glLoadIdentity(); //加载单位矩阵
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(rote, 0.0f, 1.0f, 0.0f);
glRotatef(anglex, 1.0, 0.0, 0.0);
glRotatef(angley, 0.0, 1.0, 0.0);
glRotatef(anglez, 0.0, 0.0, 1.0);
glutWireTeapot(2);
rote += speed;
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
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)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
speed = 0;
rote = 0;
remeberx = x;//当左键按下时记录鼠标坐标
remebery = y;
cout << "left" << endl;
}
}
if (button == GLUT_RIGHT_BUTTON)
{
if (state == GLUT_DOWN)
{
speed += 1.0f;
cout << "right" << endl;
}
}
}
void motion(int x, int y)
{
GLint deltax = remeberx - x;
GLint deltay = remebery - y;
anglex += 360 * (GLfloat)deltax / (GLfloat)WinW;//根据屏幕上鼠标滑动的距离来设置旋转的角度
angley += 360 * (GLfloat)deltay / (GLfloat)WinH;
anglez += 360 * (GLfloat)deltay / (GLfloat)WinH;
remeberx = x;//记录此时的鼠标坐标,更新鼠标坐标
remebery = y;//若是没有这两句语句,滑动是旋转会变得不可控
glutPostRedisplay();
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("旋转的茶壶");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutIdleFunc(display);
glutMainLoop();
return 0;
}
实验截图如下,画出了一个红色的线框茶壶: