计算机图形学 实验二 OpenGL简单动画

一、 实验目的

  1. 掌握OpenGL的闲置函数
  2. 掌握OpenGL的时间函数
  3. 掌握OpenGL的简单动画功能
  4. 了解OpenGL裁剪窗口、视区、显示窗口的概念和它们之间的关系
  5. 进一步掌握OpenGL基本图元的绘制

二、 实验环境

操作系统:Windows 10 1909版本 64位
语言开发环境:Microsoft Visual Studio 2017
程序框架:Win32 桌面应用程序。

三、 实验要求与内容
实验步骤:

  1. 闲置函数的使用与简单动画

    1. 旋转的六边形如图。

在这里插入图片描述

观察到六边形按照程序视窗中心点逆时针旋转,要更改旋转速度,可通过更改myidle()闲置函数的属性值theta大小实现。
2) 添加多边形模式设置与线宽设置观看效果

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glLineWidth(2.0);

观察到旋转的多边形变成空心线框模式。
回到多边形填充模式修改代码:

	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  1. 在图形中增加字符“Hello”,代码如下
	glColor3f(1, 0, 0);
	glRasterPos2i(3, 2);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13, 'H');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13, 'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13, 'l');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13, 'l');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13, 'o');

观察到“Hello”字符串在设定的坐标点定位显示
在这里插入图片描述

  1. 变色技术。
    设置全局变量 int k = 0;
    在myidle函数添加代码
if (k == 1) {
		glColor3f(1, 0, 0);
		k = 0;
	}
	else {
		glColor3f(1, 1, 0);
		k = 1;
	}
	观察到旋转的六边形图案颜色红黄闪烁。
  1. 修改代码,使六边形保持静止,以六边形中心为起点直线,终点为六边形某一顶点,使直线绕中心点旋转
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glColor3f(1, 1, 0);
glBegin(GL_POLYGON);
	for (int i = 0; i < n; i++) {		//绘制正六边形
		glVertex2f(R*cos(theta + i * 2 * PI / n), R*sin(theta + i * 2 * PI / n));
		}
glEnd();
glBegin(GL_LINES);
		  glColor3f(1, 1, 1);
		  glVertex2f(0, 0);
		  glVertex2f(R*cos(theta_line + 2 * PI / n), R*sin(theta_line + 2 * PI / n));
		  glEnd();
glutSwapBuffers();

效果如图:观察到六边形静止,直线单独旋转
在这里插入图片描述

思考:要使直线保持与及其时钟秒针拍温和,可在myidle函数中设置Sleep(1000)延时一秒,并设置theta=+= 6*PI/180; 使得每秒转过6°,一分钟转一周。

  1. 时间函数的使用和简单动画。
  1. 在主程序中:glutTimerFunc(1000, mytime, 10); 注册闲置回调函数,每隔1000ms调用一次mytime函数
  2. 编写mytime(t)函数:
    }
void mytime(int t) {
	
	theta += 6*PI/180;
	if (theta_line >= 2 * PI) theta_line -= 2 * PI;
	glutPostRedisplay();		//重绘函数
	glutTimerFunc(1000, mytime, 10);		//回调函数,1000ms后回调自身
}

观察到时间函数的作用效果,即每隔1000ms变换一次图形,使直线旋转theta度。
3.简单时钟设计
1) 在程序头部定义系统时间变量、时分秒变量

SYSTEMTIME timeNow;		//系统时间变量
float hh, mm, ss;

2)定义PI变量

#define PI 3.1415926

3)引入数学文件、时间头文件

#include<cmath>
#include<ctime>

4)在初始化函数中获取系统时间,分别获取时分秒数据。

void init()
{
	GetLocalTime(&timeNow);		//获取系统时间
	hh = timeNow.wHour;
	mm = timeNow.wMinute;
	ss = timeNow.wSecond;
}

5)绘制函数display()中计算时、分、秒,确定绘制时分秒针的起始点坐标。

//xc,yc为时针中心点坐标
	//xs,ys为秒针终止点坐标
	//xm,ym为分针终止点坐标
	float xs, ys, xm, ym, xh, yh;
	float xc = 0, yc = 0;
	//Calculate
	xs = xc + R * cos(PI / 2.0 - ss / 60 * 2 * PI);
	ys = yc + R * sin(PI / 2.0 - ss / 60 * 2 * PI);
	xm = xc + R * cos(PI / 2.0 - (mm + ss / 60.0) / 60.0*2.0*PI);
	ym = yc + R * sin(PI / 2.0 - (mm + ss / 60.0) / 60.0*2.0*PI);
	xh = xc + (R - 5)*cos(PI / 2.0 - (hh + (mm + ss / 60.0) / 60.0) / 12.0*2.0*PI);
yh = yc + (R - 5)*sin(PI / 2.0 - (hh + (mm + ss / 60.0) / 60.0) / 12.0*2.0*PI);
6)以直线方式绘制时、分、秒针。
	glColor3f(1, 0, 0);
	glBegin(GL_LINES);
	glVertex2f(xc, yc);
	glVertex2f(xs, ys);
	glEnd();

	glColor3f(1, 1, 0);
	glBegin(GL_LINES);
	glVertex2f(xc, yc);
	glVertex2f(xm, ym);
	glEnd();

	glColor3f(0, 1, 1);
	glBegin(GL_LINES);
	glVertex2f(xc, yc);
	glVertex2f(xh, yh);
	glEnd();

7)绘制静止正六边形

	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glLineWidth(2.0);
	
	glColor3f(1, 1, 1);
	glBegin(GL_POLYGON);
	for (int i = 0; i < n; i++) {		//绘制正六边形
		glVertex2f(R*cos(theta + i * 2 * PI / n), R*sin(theta + i * 2 * PI / n));
	}
	glEnd();

8)在时间函数mytime(t)中设置重复获取系统当前时间。

void idletime(int t) {
	GetLocalTime(&timeNow);		//获取系统时间
	hh = timeNow.wHour;
	mm = timeNow.wMinute;
	ss = timeNow.wSecond;

	glutTimerFunc(1000, idletime, 10);
	glutPostRedisplay();		//重绘函数
}

观察到简单时钟的显示,时分针秒针以时钟的形式呈现在视区中,并以当前的时间正确显示。
效果图
在这里插入图片描述
在这里插入图片描述
完整代码:

  • 6
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值