参考书籍:《计算机图形学及其实践教程》-----黄静(机械工业出版社)
小白第一练
实验目的: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); //模型矩阵模式
}
一.设置线框模式
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//添加多边形模式设置语句观看效果(线框模式)
glLineWidth(2.0); //设置线宽
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//重回多边形填充模式
以上代码放在display函数中。
二.在图形中添加字符
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函数中。
效果图:
(两个颜色的线框分别截图)——相当于红色和黄色六边形线框一起旋转。
【将闲置函数转化为时间函数】
// 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出了问题)
好像这是解决办法,我去试试先。。。。
有需要的小伙伴可以先运行这段代码试试,欢迎交流学习,共同进步嘻嘻!