计算机图形学报告3

西安电子科技大学

 

计算机图形学 课程实验报告

实验名称 第3次上机实验

计算机 学院 1803012

姓名 曹王欣 学号 18030100167

同作者

实验日期 2020

实验地点 实验批次

 

指导教师评语:

 

 

 

 

 

指导教师:

实验报告内容基本要求及参考格式

一、实验目的

二、实验所用仪器(或实验环境)

三、实验基本原理及步骤(或方案设计及理论计算)

四、实验数据记录(或仿真及软件设计)

五、实验结果分析及回答问题(或测试环境及测试结果)

 

 

第三次上机作业

  1. 绘制曲线(借鉴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样条曲线,并绘制出曲线。

 

  1. 其它(借鉴以前课上的例程)
    1. 编写程序,使一物体沿着一条直线匀速移动。
    2. 编写程序,使一物体围绕屏幕上一点匀速旋转。

    注:物体可以是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;

}

截图如下:

可以看到,我们画出了此曲线,还根据R1R4画了切向量,这条曲线是正确的(在(01)处突然向量突然急剧变化,所以可能有点看不清楚)

 

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;

}

实验截图如下:

 

其中红色的曲线是贝塞尔曲线,可以看到他由四个控制点控制,经过控制点14,而且切线方向分别是1-23-4,而蓝色的比较短的曲线是BLine,可以看到他并不过这四个点,所以我们成功完成了此次实验

 

  1. 其它(借鉴以前课上的例程)

编写程序,使一物体沿着一条直线匀速移动

 

此程序我的源代码如下:

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

 

}

 

 

我先定义了两条导轨,然后让小球沿着这两条导轨运动,红色的小球不断远离我的视线,截图效果如下(在下面):

 

在这个程序中,我的观察方向和导轨延申的方向相同,所以可以看到小球不断原理我

 

这就是完成了所谓的小球沿直线运动

 

  1. 编写程序,使一物体围绕屏幕上一点匀速旋转。

注:物体可以是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);

 

从(005)朝(000)观看,法线是(010

 

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;

}

实验截图如下,画出了一个红色的线框茶壶:

posted @ 2021-01-22 23:31  coolwx  阅读(629)  评论(0编辑  收藏  举报