实验要求:
-
构建且渲染一个3D风车模型(如下图所例示)。其中,三个叶片(包括中间的黄色三角形)在一个2D平面上,手柄在另外一个离相机更近的2D平面上。三个叶片、中心的三角形、手柄分别用不同的颜色显示。注:图中画的黑色线条是为了方便演示,不要求绘制。
-
实现风车的旋转动画。要求风车的三个叶片以及中间的黄色三角形(在其所在平面上)一起绕着中心一点不停旋转,且将此动画渲染出来。
-
实现通过键盘对动画的交互控制,包括切换旋转方向、增大旋转速度以及减小旋转速度。
-
设计按钮和菜单两个控件,用于动画的交互控制:点击按钮可以切换旋转方向;选择三个菜单项分别可以切换旋转方向、增大旋转速度以及减小旋转速度。
实现思路:
- 绘制部分:绘制风车各种元素,如三个扇叶、中间的三角形,风车把,按钮,按钮上的提示文字等
- 交互部分:鼠标点击按钮的效果,键盘交互的效果,鼠标右键呼叫菜单栏的效果
- 风车运动部分:保持旋转的功能,加速功能,减速功能,逆转方向功能
(另外:注意一些基本函数的使用要点,如旋转函数,位移函数等等,不再赘述)
实现代码:
//my solution
#include <iostream>
#include <string>
#include <cmath>
#include <Windows.h>
#include <Gl/glut.h>
#define MAX_CHAR 128
using namespace std;
double Rdgr = 0;//rotate degree
double velocityAcc = 0;//acceleration of velocity
double incresement = 0.3;
//function part(speed constro & spining direction reverse)
void reverse()
{
velocityAcc = -velocityAcc;
}
void speedUp()
{
if (velocityAcc >= 0)velocityAcc += incresement;
else velocityAcc -= incresement;
}
void speedDown()
{
if (velocityAcc >= 0) velocityAcc -= incresement;
else velocityAcc += incresement;
}
void rotate()
{
Rdgr += velocityAcc;
if (Rdgr > 360) Rdgr = 0;
glutPostRedisplay();
}
//button part
void printCharater(const char* str)
{
glRasterPos2f(-0.06, 0.74);
for (int i = 0; i < strlen(str); i++) glutBitmapCharacter(GLUT_BITMAP_8_BY_13, *(str + i));
}
void mouseFunc(GLint btn, GLint sta, int x, int y)
{
if (btn == GLUT_LEFT_BUTTON && sta == GLUT_DOWN)
if (x >= 360 && x <= 440 && y >= 40 && y <= 80) reverse();
glutPostRedisplay();
}
//menu part
void subFunc(GLint data)
{
switch (data)
{
case 1:speedUp(); break;
case 2:speedDown(); break;
}
}
void menuFunc(GLint data)
{
if (data == 1) reverse();
}
void creatMenu()
{
//创建子菜单
GLint sub = glutCreateMenu(subFunc);
glutAddMenuEntry("Speed Up", 1);
glutAddMenuEntry("Speed Do