计算机图形学第四次上机——鼠标回调&图形界面交互实现
计算机图形学第四次上机实验 课程实验报告
目录
五、源代码
一、实验目的
- 掌握配置glut库的步骤
- 测试运行示例代码
二、实验环境
1.codeblocks-17.12
2.Windows10 SDK 10.0.17134.0
三、实验内容
3.1绘制曲线
1.问题重述
已知4点P1(0,0,0)、P2(1,1,1)、 P3(2,-1,-1)、P4(3,0,0),用其作为控制点分别绘制一条Bezier曲线、一条B样条曲线,并分别计算参数为0、1/3、 2/3、1时它们各自的位置矢量。
2.理论求解
- Bezier曲线多项式:
则其位置矢量:
绘制结果为
- B样条曲线多项式:
则其位置矢量
绘制结果为
3.2绘制曲面
- 问题重述
利用Bezier曲面构造茶壶的表面形状,定义控制点:
float ctrlpoints[4][4][3] = {
{ {-2, -1, 0}, { -2.0, -1.0, 4.0},
{ 2.0, -1.0, 4.0}, { 2, -1, 0} },
{ {-3, 0, 0}, { -3.0, 0, 6.0},
{ 3.0, 0, 6.0}, { 3, 0, 0}},
{ {-1.5, 0.5, 0}, {-1.5, 0.5, 3.0},
{1.5, 0.5, 3.0}, {1.5, 0.5, 0}},
{ {-2, 1, 0}, { -2.0, 1.0, 4.0},
{ 2.0, 1.0, 4.0}, { 2, 1, 0} }
};
- 问题求解
- OpenGL中Bezier曲面定义的函数为:
void glMap2{fd}(GLenum target,TYPE t1,TYPE t2,GLint tstride, GLint torder, TYPE s1,TYPE s2,GLint sstride, GLint sorder,const const TYPE *points);
函数的第一个参数target指出控制顶点的意义,如GL_MAP2_VERTEX_3表示生成顶点坐标三元组;参数points指针可以指向控制点集等; 参数t1和t2,指明变量t的范围,t一般从0变化到1;参数s1和s2,指明变量s的范围,s一般从0变化到1;参数tstride表示跨度,指定了控制点数组中t方向顶点之间的浮点值数量,即两个控制点间的偏移量,比如控制点集ctrlpoints[4][4][3]的跨度就为3;参数torder是次数加1,叫阶数,与控制点数一致;参数sstride表示跨度,指定了控制点数组中s方向顶点之间的浮点值数量,即两个控制点间的偏移量,比如控制点集ctrlpoints[4][4][3]的跨度就为12;参数sorder是次数加1,叫阶数,与控制点数一致。
曲线定义后,必须要启动,才能进行下一步的绘制工作。启动函数是 glEnable(),其中参数与glMap2*()的第一个参数一致。
- 使用高层函数来定义网格:
void glMapGride2{fd}[v](GLint tn,TYPE t1,TYPE t2,GLint sn,TYPE s1,TYPE s2);
建立一个2D映射网格,tn和sn指定了t和s方向网格划分的数量。
- 使用点或直线计算网格:
void glEvalMesh2(GLenum mode,GLint t1,GLint t2,GLint s1,GLint s2);
计算2D点或直线的网格,mode指定网格应该被计算为点(GL_POINT)、直线(GL_LINE)或填充表面(GL_FILL)。
- 顶点可视化
我采用了OpenGL库中的glutBitmapCharacter()函数,将其功能封装如下
void displayc(double x,double y,double z,char str[])//显示字符函数
{
glColor3f(0, 0, 0);
//glClear(GL_COLOR_BUFFER_BIT);
glRasterPos3d(x,y,z);
for(unsigned int i=0;i<strlen(str);i++)
{
glutBitmapCharacter(GLUT_BITMAP_8_BY_13,str[i]);
}
//glFlush();
}
用于显示字符串,然后再绘制控制点的循环中实现显示每个顶点的功能。
- 绘制结果
网格mode=GL_LINE
网格mode=GL_POINT
网格mode=GL_FILL
3.3颜色
3.3.1颜色线性变化
- 问题重述
采用颜色插值的方法显示直线段P0P1, P0的颜色为(R0G0B0), P1点的颜色为( R1G1B1),从P0到P1的各点颜色呈线性变化。
- 问题求解
在绘制两个顶点前设置两端颜色即可,OpenGL默认的颜色插值即是线性的。
glBegin(GL_LINES);
glColor3f(0,0,0);//设置两遍颜色即可线性变化
glVertex2f(-30,-30);
glColor3f(1,1,1);
glVertex2f(40,40);
glEnd();
- 绘制结果
3.3.2显示小方块
- 问题重述
写一个程序,在一个灰色背景上显示黑色、白色、橙色、红色、绿色、蓝色、青色、品红色和黄色小方块,每一个方块与其它方块是相互分离的,大小为n*n像素,n是一个输入的变量。
- 问题求解
设置颜色集
typedef struct{
float r,g,b;
}point;
point C[9]={{0.0,0.0,0.0},{1.0,1.0,1.0},{1.0,0.5,0.0},{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{0.0,1.0,1.0},{1.0,0.0,1.0},{1.0,1.0,0.0}};
然后以n为边长画正方形即可
void Drawsquare(int n)
{
for(int i=0;i<9;i++)
{
glColor3f(C[i].r,C[i].g,C[i].b);
glBegin(GL_QUADS);
float a1=i*n;
float a2=(i+1)*n;
glVertex2f(a1,0.0);
glVertex2f(a1,n);
glVertex2f(a2,n);
glVertex2f(a2,0);
glEnd();
}
}
- 绘制结果
3.4鼠标回调
- 问题重述
将屏幕上的鼠标选取点作为多边形顶点进行填充。
- 问题求解
- 鼠标回调函数glutMouseFunc()
要想在OpenGL中处理鼠标事件非常的方便,GLUT已经为我们的注册好了函数,只要我们提供一个方法。使用函数glutMouseFunc,就可以帮我们注册我们的函数,这样当发生鼠标事件时就会自动调用我们的方法。
函数的原型是:
void glutMouseFunc(void(*func)(int button,int state,int x,int y));
参数:
func:处理鼠标click事件的函数的函数名。
从上面可以看到,处理鼠标单击事件的函数,一定有4个参数。第一个参数表明哪个鼠标键被按下或松开,这个变量可以是下面的三个值中的一个:
GLUT_LEFT_BUTTON
GLUT_MIDDLE_BUTTON
GLUT_RIGHT_BUTTON
第二个参数表明,函数被调用发生时,鼠标的状态,也就是是被按下,或松开,可能取值如下:
GLUT_DOWN
GLUT_UP
当函数被调用时,state的值是GLUT_DOWN,那么程序可能会假定将会有个GLUT_UP事件,甚至鼠标移动到窗口外面,也如此。然而,如果程序调用glutMouseFunc传递NULL作为参数,那么GLUT将不会改变鼠标的状态。
剩下的两个参数(x,y)提供了鼠标当前的窗口坐标(以左上角为原点)
- 图形界面交互
由于未指定绘制的多边形的边数,故我设计了图形界面交互。
利用3.2中我设计好的displayc()函数显示字符串,并注册键盘回调函数glutKeyboardFunc()来接收输入的边数。
我编写的键盘回调函数共接收10个键,分别是3-9数字字符,还有f、l、Esc字符。f表示删除第一个顶点,l表示输出最后的顶点,Esc退出。3-9选择边数。
为增加视觉效果,我编写了set_random_color()函数,使得每个多边形的颜色不一样。
void set_random_color()
{
//srand(time(NULL));
double r =rand()%256;
double g =rand()%256;
double b =rand()%256;
glColor3d(r/256,g/256,b/256);
}
- 运行结果
输入4
按下s键,并点击鼠标
四、实验心得
这次上机实验最大的收获就是自己实现了鼠标回调函数,使得画面可以响应鼠标。并且综合利用鼠标回调和键盘回调函数,实现了图形界面的交互。以往通过标准输入输出函数,在命令行进行程序对标准输入流的输入,这一次通过画面和键盘回调函数,实现了在图形界面的输入,觉得非常有意思!
- 实验源码
1
#include "windows.h"
#include<glut.h>
#include<string>
#include<iostream>
typedef struct{
float x,y,z;
}Point;
using namespace std;
int flag=1;//1为bezier曲线,2为B样条曲线
void init()
{
glClearColor(1.0,1.0,1.0,1.0);
}
void displayc(double x,double y,char str[])//显示字符函数
{
glColor3f(0, 0, 0);
//glClear(GL_COLOR_BUFFER_BIT);
glRasterPos2d(x,y);
for(int i=0;i<sizeof(str);i++)
{
glutBitmapCharacter(GLUT_BITMAP_8_BY_13,str[i]);
}
glFlush();
}
void DrawBezier3D(int n,Point P[])
{
Point p;
double t,deltat,t2,t3,et,et2,et3;
int i;
deltat = 1.0/(n-1);
glBegin(GL_LINE_STRIP);
for(i=0;i<101;i++)
{
t = i*deltat;
et = 1-t;
t2 = t*t;
et2 = et*et;
t3 = t*t2;
et3 = et*et2;
p.x = et3*P[0].x+3*t*et2*P[1].x+3*t2*et*P[2].x+t3*P[3].x;
p.y = et3*P[0].y+3*t*et2*P[1].y+3*t2*et*P[2].y+t3*P[3].y;
p.z = et3*P[0].z+3*t*et2*P[1].z+3*t2*et*P[2].z+t3*P[3].z;
if(i==0)
{
cout<<"Q(0)=("<<p.x<<","<<p.y<<","<<p.z<<")"<<endl;
}
if(i==33)
{
cout<<"Q(1/3)=("<<p.x<<","<<p.y<<","<<p.z<<")"<<endl;
}
if(i==67)
{
cout<<"Q(2/3)=("<<p.x<<","<<p.y<<","<<p.z<<")"<<endl;
}
if(i==100)
{
cout<<"Q(1)=("<<p.x<<","<<p.y<<","<<p.z<<")"<<endl;
}
glVertex3f(p.x,p.y,p.z);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0,1,0);
glPointSize(3);
glBegin(GL_POINTS);
for(i=0;i<4;i++)
{
glVertex2d(P[i].x,P[i].y);
}
glEnd();
displayc(P[0].x,P[0].y,"P1\0");
displayc(P[1].x,P[1].y,"P2\0");
displayc(P[2].x,P[2].y,"P3\0");
displayc(P[3].x,P[3].y,"P4\0");
}
void DrawB3D(int n,Point P[])
{
Point p;
double t,deltat,t2,t3,et,et2,et3;
int i;
deltat = 1.0/(n-1);
glBegin(GL_LINE_STRIP);
for(i=0;i<101;i++)
{
t = i*deltat;
et = 1-t;
t2 = t*t;
et2 = et*et;
t3 = t*t2;
et3 = et*et2;
p.x = et3*P[0].x/6+(3*t3-6*t2+4)*P[1].x/6+(-3*t3+3*t2+3*t+1)*P[2].x/6+t3*P[3].x/6;
p.y = et3*P[0].y/6+(3*t3-6*t2+4)*P[1].y/6+(-3*t3+3*t2+3*t+1)*P[2].y/6+t3*P[3].x/6;
p.z = et3*P[0].z/6+(3*t3-6*t2+4)*P[1].z/6+(-3*t3+3*t2+3*t+1)*P[2].z/6+t3*P[3].z/6;
if(i==0)
{
cout<<"Q(0)=("<<p.x<<","<<p.y<<","<<p.z<<")"<<endl;
}
if(i==33)
{
cout<<"Q(1/3)=("<<p.x<<","<<p.y<<","<<p.z<<")"<<endl;
}
if(i==67)
{
cout<<"Q(2/3)=("<<p.x<<","<<p.y<<","<<p.z<<")"<<endl;
}
if(i==100)
{
cout<<"Q(1)=("<<p.x<<","<<p.y<<","<<p.z<<")"<<endl;
}
glVertex3f(p.x,p.y,p.z);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0,1,0);
glPointSize(3);
glBegin(GL_POINTS);
for(i=0;i<4;i++)
{
glVertex2d(P[i].x,P[i].y);
}
glEnd();
displayc(P[0].x,P[0].y+0.2,"P1\0");
displayc(P[1].x,P[1].y-0.5,"P2\0");
displayc(P[2].x,P[2].y+0.2,"P3\0");
displayc(P[3].x,P[3].y,"P4\0");
}
void RenderScence()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
Point P[4]={{0,0,0},{1,1,1},{2,-1,-1},{3,0,0}};//p1到p4端点
if(flag==1)
DrawBezier3D(100,P);
else
DrawB3D(100,P);
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;
float s=5;
if(w<=h)
glOrtho(-s,s,-s/aspectRatio,s/aspectRatio,1.0,-1.0);
else
glOrtho(-s*aspectRatio,s*aspectRatio,-s,s,1.0,-1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main()
{
cout<<"1为Bezier曲线,2为B样条曲线"<<endl;
cin>>flag;
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
if(flag==1)
glutCreateWindow("DrawBezier");
if(flag==2)
glutCreateWindow("DrawB样条");
init();
glutDisplayFunc(RenderScence);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
2
#include "windows.h"
#include<glut.h>
#include<string>
#include<stdlib.h>
#include<stdio.h>
float ctrlpoints[4][4][3] = {
{ {-2, -1, 0}, { -2.0, -1.0, 4.0},
{ 2.0, -1.0, 4.0}, { 2, -1, 0} },
{ {-3, 0, 0}, { -3.0, 0, 6.0},
{ 3.0, 0, 6.0}, { 3, 0, 0}},
{ {-1.5, 0.5, 0}, {-1.5, 0.5, 3.0},
{1.5, 0.5, 3.0}, {1.5, 0.5, 0}},
{ {-2, 1, 0}, { -2.0, 1.0, 4.0},
{ 2.0, 1.0, 4.0}, { 2, 1, 0} }
};
void init()
{
glClearColor(1.0,1.0,1.0,1.0);
glMap2f(GL_MAP2_VERTEX_3,0.0,1.0,3,4,0.0,1.0,12,4,&ctrlpoints[0][0][0]);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_DEPTH_TEST);
}
void displayc(double x,double y,double z,char str[])//显示字符函数
{
glColor3f(0, 0, 0);
//glClear(GL_COLOR_BUFFER_BIT);
glRasterPos3d(x,y,z);
for(unsigned int i=0;i<strlen(str);i++)
{
glutBitmapCharacter(GLUT_BITMAP_8_BY_13,str[i]);
}
//glFlush();
}
void DrawCurvedSurface(int n,int m)
{
int i,j;
int num=0;
double x,y,z;
char strx[4];
char stry[4];
char strz[4];
char strn[4];
char str[24]="P";
glMapGrid2f(n,0.0,1.0,m,0.0,1.0);
glEvalMesh2(GL_FILL,0,n,0,m);//有GL_POINT GL_LINE GL_FILL三个参数
glPointSize(5.0);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POINTS);
for (i = 0; i < 4; i++)
for(j=0;j<4;j++)
{
x=ctrlpoints[i][j][0];
y=ctrlpoints[i][j][1];
z=ctrlpoints[i][j][2];
glVertex3f(x,y,z);
}
glEnd();
for (i = 0; i < 4; i++)
for(j=0;j<4;j++)
{
x=ctrlpoints[i][j][0];
y=ctrlpoints[i][j][1];
z=ctrlpoints[i][j][2];
char strx[4];
char stry[4];
char strz[4];
char strn[4];
char str[24]="P";
itoa(num,strn,10);
itoa(x,strx,10);
itoa(y,stry,10);
itoa(z,strz,10);
strcat(str,strn);
strcat(str,"(");
strcat(str,strx);
strcat(str,",");
strcat(str,stry);
strcat(str,",");
strcat(str,strz);
strcat(str,")");
num++;
displayc(x,y+0.08,z,str);
}
}
void RenderScence()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(0,1.0,1.0);//控制颜色
glPushMatrix();
glTranslated(0.0,0.0,-8);
glRotatef(35.0,1.0,1.0,1.0);
DrawCurvedSurface(30,8);
glPopMatrix();
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(-4.0,4.0,-4.0/aspectRatio,4.0/aspectRatio,4.0,12.0);
else
glOrtho(-4.0*aspectRatio,4.0*aspectRatio,-4.0,4.0,4.0,12.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main()
{
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
glutCreateWindow("DrawBezier");
init();
glutDisplayFunc(RenderScence);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
3
#include "windows.h"
#include<gl/glut.h>
void init()
{
glClearColor(1,1,1,0);
}
void Drawsline()
{
glLineWidth(3);
glBegin(GL_LINES);
glColor3f(0,0,0);//设置两遍颜色即可线性变化
glVertex2f(-30,-30);
glColor3f(1,1,1);
glVertex2f(40,40);
glEnd();
}
void RenderScence()
{
glClear(GL_COLOR_BUFFER_BIT);
Drawsline();
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(-50.0,50.0,-50.0/aspectRatio,50.0/aspectRatio,1.0,-1.0);
else
glOrtho(-50.0*aspectRatio,50.0*aspectRatio,-50.0,50.0,1.0,-1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main()
{
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutCreateWindow("颜色线性变化");
init();
glutDisplayFunc(RenderScence);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
4
#include "windows.h"
#include<gl/glut.h>
#include<iostream>
using namespace std;
int num;
typedef struct{
float r,g,b;
}point;
point C[9]={{0.0,0.0,0.0},{1.0,1.0,1.0},{1.0,0.5,0.0},{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{0.0,1.0,1.0},{1.0,0.0,1.0},{1.0,1.0,0.0}};
void init()
{
glClearColor(0.5,0.5,0.5,1.0);
}
void Drawsquare(int n)
{
for(int i=0;i<9;i++)
{
glColor3f(C[i].r,C[i].g,C[i].b);
glBegin(GL_QUADS);
float a1=i*n;
float a2=(i+1)*n;
glVertex2f(a1,0.0);
glVertex2f(a1,n);
glVertex2f(a2,n);
glVertex2f(a2,0);
glEnd();
}
}
void RenderScence()
{
glClear(GL_COLOR_BUFFER_BIT);
Drawsquare(num);
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(-10.0,50.0,-30.0/aspectRatio,30.0/aspectRatio,-1.0,1.0);
else
glOrtho(-10.0*aspectRatio,50.0*aspectRatio,-30.0,30.0,-1.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main()
{
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutCreateWindow("我的多色块");
//n=5;
cout<<"请输入象素大小n"<<endl;
cin>>num;
init();
glutDisplayFunc(RenderScence);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
5
/*
* ConnectDots.c
*
* 该程序将屏幕上的鼠标选取点进行连线。
*
* 说明:
* 左键点击选择一个控制点 ,控制点数不超过64;
*
* 按f键擦除到第一个控制点;按l键擦除到最后一个控制点;按Escape键退出。
*
*/
#include "windows.h"
#include "ConnectDots.h"
#include <stdlib.h>
#include <glut.h>
#include <stdio.h>
#include <math.h>
#include<string>
#define MaxNumPts 64
#include<time.h>
float PointArray[MaxNumPts][2];
int NumPts = 0;
int mode=0;
char num[2]="3";
int sum=0;
int WindowHeight;
int WindowWidth;
void displayc(double x,double y,double z,char str[])//显示字符函数
{
//glColor3f(0, 0, 0);
//glClear(GL_COLOR_BUFFER_BIT);
glRasterPos3d(x,y,z);
for(unsigned int i=0;i<strlen(str);i++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,str[i]);
}
//glFlush();
}
void myKeyboardFunc (unsigned char key, int x, int y)
{
switch (key) {
case '3':
{
strcpy(num,"3");
mode=1;
sum=3;
glFlush();
glutPostRedisplay();
break;
}
case '4':
{
strcpy(num,"4");
mode=1;
sum=4;
glFlush();
glutPostRedisplay();
break;
}
case '5':
{
strcpy(num,"5");
mode=1;
sum=5;
glFlush();
glutPostRedisplay();
break;
}
case '6':
{
strcpy(num,"6");
mode=1;
sum=6;
glFlush();
glutPostRedisplay();
break;
}
case '7':
{
strcpy(num,"7");
mode=1;
sum=7;
glFlush();
glutPostRedisplay();
break;
}
case '8':
{
strcpy(num,"8");
mode=1;
sum=8;
glFlush();
glutPostRedisplay();
break;
}
case '9':
{
strcpy(num,"9");
mode=1;
sum=9;
glFlush();
glutPostRedisplay();
break;
}
case 's':
mode = 2;
glutPostRedisplay();
break;
case 'f':
removeFirstPoint();
glutPostRedisplay();
break;
case 'l':
removeLastPoint();
glutPostRedisplay();
break;
case 27:
exit(0);
break;
}
}
void removeFirstPoint() {
int i;
if ( NumPts>0 ) {
NumPts--;
for ( i=0; i<NumPts; i++ ) {
PointArray[i][0] = PointArray[i+1][0];
PointArray[i][1] = PointArray[i+1][1];
}
}
}
void myMouseFunc( int button, int state, int x, int y ) {
if ( button==GLUT_LEFT_BUTTON && state==GLUT_DOWN ) {
float xPos = ((float)x)/((float)(WindowWidth-1));
float yPos = ((float)y)/((float)(WindowHeight-1));
yPos = 1.0f-yPos;
addNewPoint( xPos, yPos );
glutPostRedisplay();
}
}
void removeLastPoint() {
if ( NumPts>0 ) {
NumPts--;
}
}
void addNewPoint( float x, float y ) {
if ( NumPts>=MaxNumPts ) {
removeFirstPoint();
}
PointArray[NumPts][0] = x;
PointArray[NumPts][1] = y;
NumPts++;
}
void title()
{
glColor3f(0, 0, 0);
char str[80]="Please enter the number of sides of the polygon";
displayc(0.03,0.8,0,str);
char str1[20]="Range:3-9";
displayc(0.35,0.65,0,str1);
char str2[20]="Your input is :";
displayc(0.25,0.5,0,str2);
}
void set_random_color()
{
//srand(time(NULL));
double r =rand()%256;
double g =rand()%256;
double b =rand()%256;
glColor3d(r/256,g/256,b/256);
}
void RenderScene(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
if(mode == 0)
{
title();
glColor3f(0,0,0);
char str[30]="The default choice is 3";
displayc(0.2,0.35,0,str);
}
else if(mode==1)
{
title();
glColor3f(1,0,0);
displayc(0.65,0.5,0,num);
glColor3f(0,0,1);
char str[20]="Press 'S' to start!";
displayc(0.3,0.4,0,str);
glColor3f(1,0,1);
char str1[20]="Let's go to game!";
displayc(0.3,0.3,0,str1);
}
else if(mode == 2)
{
// 画连线
//glColor3f(1.0f, 0.0f, 0f);
if ( NumPts>1 ) {
int n=NumPts/sum;
int counter=0;
for ( i=0; i<n; i++ ) {
set_random_color();
glBegin( GL_POLYGON );
for(int j=0;j<sum;j++)
{
glVertex2f( PointArray[counter][0], PointArray[counter][1] );
counter++;
}
glEnd();
}
}
// 画控制点
glColor3f( 0.0f, 0.0f, 0.0f);
glBegin( GL_POINTS );
for ( i=0; i<NumPts; i++ ) {
glVertex2f( PointArray[i][0], PointArray[i][1] );
}
glEnd();
}
glFlush();
}
void init() {
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
// 设置点大小和线宽
glPointSize(8);
glLineWidth(5);
glEnable(GL_POINT_SMOOTH); //点抗锯齿
glEnable(GL_LINE_SMOOTH); //线抗锯齿
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); // 选择特定的渲染,如渲染质量
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glEnable(GL_BLEND); //颜色混合
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void ChangeSize(int w, int h)
{
WindowHeight = (h>1) ? h : 2;
WindowWidth = (w>1) ? w : 2;
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0f, 1.0f, 0.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main()
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("ConnectDots");
init();
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutKeyboardFunc(myKeyboardFunc);
glutMouseFunc(myMouseFunc);
glutMainLoop();
return 0;
}