计算机图形学第四次上机——鼠标回调&图形界面交互实现

计算机图形学第四次上机实验 课程实验报告

目录

计算机图形学第四次上机实验 课程实验报告

一、实验目的

二、实验环境

三、实验内容

3.1绘制曲线

3.2绘制曲面

3.3颜色

3.4鼠标回调

四、实验心得

五、源代码

1

2

3

4

5


一、实验目的

  1. 掌握配置glut库的步骤
  2. 测试运行示例代码

二、实验环境

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绘制曲面

  1. 问题重述

利用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} }

};

  1. 问题求解
  1. 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*()的第一个参数一致。

  1. 使用高层函数来定义网格:

    void glMapGride2{fd}[v](GLint tn,TYPE t1,TYPE t2,GLint sn,TYPE s1,TYPE s2);

建立一个2D映射网格,tn和sn指定了t和s方向网格划分的数量。

  1. 使用点或直线计算网格:

    void glEvalMesh2(GLenum mode,GLint t1,GLint t2,GLint s1,GLint s2);

    计算2D点或直线的网格,mode指定网格应该被计算为点(GL_POINT)、直线(GL_LINE)或填充表面(GL_FILL)。

 

  1. 顶点可视化

我采用了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();

}

用于显示字符串,然后再绘制控制点的循环中实现显示每个顶点的功能。

 

 

 

  1. 绘制结果

网格mode=GL_LINE

网格mode=GL_POINT

网格mode=GL_FILL

3.3颜色

3.3.1颜色线性变化

  1. 问题重述

采用颜色插值的方法显示直线段P0P1, P0的颜色为(R0G0B0), P1点的颜色为( R1G1B1),从P0到P1的各点颜色呈线性变化。

  1. 问题求解

在绘制两个顶点前设置两端颜色即可,OpenGL默认的颜色插值即是线性的。

glBegin(GL_LINES);

glColor3f(0,0,0);//设置两遍颜色即可线性变化

glVertex2f(-30,-30);

glColor3f(1,1,1);

glVertex2f(40,40);

glEnd();

  1. 绘制结果

3.3.2显示小方块

  1. 问题重述

写一个程序,在一个灰色背景上显示黑色、白色、橙色、红色、绿色、蓝色、青色、品红色和黄色小方块,每一个方块与其它方块是相互分离的,大小为n*n像素,n是一个输入的变量。

  1. 问题求解

设置颜色集

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

}

}

  1. 绘制结果

3.4鼠标回调

  1. 问题重述

将屏幕上的鼠标选取点作为多边形顶点进行填充。

  1. 问题求解
  • 鼠标回调函数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);

}

  1. 运行结果

输入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;

}

发布了47 篇原创文章 · 获赞 28 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41122796/article/details/86641273