OpenGL实验一:(简单动画——旋转的多边形)+详细代码

参考书籍:《计算机图形学及其实践教程》-----黄静(机械工业出版社)

小白第一练

实验目的:1.学习OpenGL的闲置函数,时间函数,简单动画功能。

                 2.了解OpenGL裁剪窗口,视区,显示窗口的概念。

*************************************************************************

样本程序:旋转的多边形

// ConsoleApplication3.cpp: 定义控制台应用程序的入口点。
//


#include "stdafx.h"
#include 
#include 
#include 
#include  


#define PI 3.14159  //设置圆周率
int n = 6, R = 10;  //多边形变数,外接圆半径


float theta = 0.0;  //旋转初始角度值
void Keyboard(unsigned char key, int x, int y);
void Display(void);
void Reshape(int w, int h);
void myidle();


int main(int argc, char** argv)
{


	// must/should match the number of strings in argv


	glutInit(&argc, argv);  //初始化GLUT库;
	glutInitWindowSize(400, 400);  //设置显示窗口大小
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);  //设置显示模式;(注意双缓冲)
	glutCreateWindow("A Rotating Square"); // 创建显示窗口
	glutDisplayFunc(Display);  //注册显示回调函数
	glutReshapeFunc(Reshape);  //注册窗口改变回调函数
	glutIdleFunc(myidle);    //注册闲置回调函数
	glutMainLoop();  //进入事件处理循环
	
	


	return 0;
}




void Display(void)
{
	
	glClearColor(0, 1, 1, 0);//设置浅蓝色绘图背景颜色(清屏颜色)
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(0, 0, 1); //设置深蓝色绘图颜色
	glBegin(GL_POLYGON);  //开始绘制六边形
	for (int i = 0; i		glVertex2f(R*cos(theta + i * 2 * PI / n), R*sin(theta + i * 2 * PI / n));
	glEnd();
	glutSwapBuffers();   //双缓冲的刷新模式;


}


void myidle()
{
	theta += 1.0;   //旋转角度增加1度
	if (theta >= 2 * PI) {
		theta -= 2 * PI;   //如果旋转角度大于360度,则复原
	}
		


	glutPostRedisplay();  //重画,相当于重新调用Display(),改编后的变量得以传给绘制函数
}


void Reshape(GLsizei w, GLsizei h)
{
	glMatrixMode(GL_PROJECTION);  //投影矩阵模式
	glLoadIdentity();  //矩阵堆栈清空
	gluOrtho2D(-1.5*R*w / h, 1.5*R*w / h, -1.5*R, 1.5*R);  //设置裁剪窗口大小
	glViewport(0, 0, w, h); //设置视区大小
	glMatrixMode(GL_MODELVIEW);  //模型矩阵模式 
}

OpenGL实验一:(简单动画——旋转的多边形)+详细代码_第1张图片(GIF)截图只能是静止的


一.设置线框模式

        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//添加多边形模式设置语句观看效果(线框模式)
glLineWidth(2.0);  //设置线宽

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//重回多边形填充模式

以上代码放在display函数中。

效果图:OpenGL实验一:(简单动画——旋转的多边形)+详细代码_第2张图片

      二.在图形中添加字符

        glColor3f(0, 0, 0);  //设置红色绘制颜色
glRasterPos2i(30, 20);    //定位当前光标,起始字符位置
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"

三.变色技术

if (k == 1)
{
glColor3f(1, 0, 0);
k = 0;
}
else
{
glColor3f(1, 1, 0);
k = 1;

}

先设置全局变量k=0,让后把以上代码放在myidle函数中。

效果图:

OpenGL实验一:(简单动画——旋转的多边形)+详细代码_第3张图片

OpenGL实验一:(简单动画——旋转的多边形)+详细代码_第4张图片

(两个颜色的线框分别截图)——相当于红色和黄色六边形线框一起旋转。

【将闲置函数转化为时间函数】

// ConsoleApplication3.cpp: 定义控制台应用程序的入口点。
//


#include "stdafx.h"
#include 
#include 
#include 
#include  
#include

#define PI 3.14159  //设置圆周率
int n = 6, R = 10;  //多边形变数,外接圆半径

//定义系统时间变量,时分秒变量
SYSTEMTIME timeNow;
float hh, mm, ss;
int xc, yc;//设置时钟中心点坐标
int xs, ys;
int xm, ym;
int xh, yh;

/*int k = 0;*/


float theta = 0.0;  //旋转初始角度值
void Keyboard(unsigned char key, int x, int y);
void Display(void);
void Reshape(int w, int h);
//void myidle();  改为:
void mytime(int t);
void init(); 

int main(int argc, char** argv)
{
	// must/should match the number of strings in argv

	glutInit(&argc, argv);  //初始化GLUT库;
	glutInitWindowSize(400, 400);  //设置显示窗口大小
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);  //设置显示模式;(注意双缓冲)
	glutCreateWindow("A Rotating Square"); // 创建显示窗口
	init();//子函数调用语句

	glutDisplayFunc(Display);  //注册显示回调函数
	glutReshapeFunc(Reshape);  //注册窗口改变回调函

	/*glutIdleFunc(myidle);    //注册闲置回调函数*/
	//将闲置函数改为时间函数
	glutTimerFunc(1000, mytime, 10);

	glutMainLoop();  //进入事件处理循环
	return 0;
}


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


void Display(void)
{
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//添加多边形模式设置语句观看效果(线框模式)
	glLineWidth(2.0);  //设置线宽
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//重回多边形填充模式

	glClearColor(0, 1, 1, 0);//设置浅蓝色绘图背景颜色(清屏颜色)
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(0, 0, 1); //设置深蓝色绘图颜色
	glBegin(GL_POLYGON);  //开始绘制六边形
	for (int i = 0; i		glVertex2f(R*cos(theta + i * 2 * PI / n), R*sin(theta + i * 2 * PI / n));


	/*glColor3f(0, 0, 0);  //设置红色绘制颜色
	glRasterPos2i(30, 20);    //定位当前光标,起始字符位置
	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"*/


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


	//以直线方式建议绘制时,分,秒针
	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();


	glEnd();
	glutSwapBuffers();   //双缓冲的刷新模式;


}

void mytime()
{
	
	/*if (k == 1)
	{
		glColor3f(1, 0, 0);
		k = 0;
	}
	else
	{
		glColor3f(1, 1, 0);
		k = 1;
	}
	*/
	GetLocalTime(&timeNow);  //获取系统时间
	hh = timeNow.wHour; //获取小时时间
	mm = timeNow.wMinute;
	ss = timeNow.wSecond;

	theta += 1.0;   //旋转角度增加1度
	if (theta >= 2 * PI) {
		theta -= 2 * PI;   //如果旋转角度大于360度,则复原
	}
		


	glutPostRedisplay();  //重画,相当于重新调用Display(),改编后的变量得以传给绘制函数
	glutTimerFunc(1000, mytime, 10);
}


void Reshape(GLsizei w, GLsizei h)
{
	glMatrixMode(GL_PROJECTION);  //投影矩阵模式
	glLoadIdentity();  //矩阵堆栈清空
	gluOrtho2D(-1.5*R*w / h, 1.5*R*w / h, -1.5*R, 1.5*R);  //设置裁剪窗口大小
	glViewport(0, 0, w, h); //设置视区大小
	glMatrixMode(GL_MODELVIEW);  //模型矩阵模式 
}

(我自己运行出来emmmm报了 error LNK2019 ---是我自己的VS2017出了问题)

好像这是解决办法,我去试试先。。。。


有需要的小伙伴可以先运行这段代码试试,欢迎交流学习,共同进步嘻嘻!

你可能感兴趣的:(OpenGL)