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

目录

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

一、实验目的

二、实验环境

三、实验内容

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;

}

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

  1. 【计算机图形学】小白谈计算机图形学(四)二维三维图形变换—1

    小白谈计算机图形学(四)二维三维图形变换-1 窗口与视图 二维图形的几何变换 平移变换 比例变换 旋转变换 二维图形变换的矩阵表示 三种变换 齐次坐标变换 原二维线性变换 齐次坐标法 复合变换 例题: ...

  2. 计算机图形学实验四 OpenGL的鼠标交互绘制

    一.实验目的 1.掌握OpenGL的鼠标按钮响应函数. 2.掌握OpenGL的鼠标移动响应函数. 3.进一步巩固OpenGL的基本图元绘制基础. 二.实验内容 1.鼠标画草图--实现鼠标点到哪,线就画 ...

  3. 计算机图形学 | 实验四:绘制一个球体

    计算机图形学 | 实验四:绘制一个球体 计算机图形学 | 实验四:绘制一个球体 封装Shader 为什么要封装Shader 如何使用 绘制球模型 球面顶点遍历 构造三角形图元 开启线框模式 开启面剔除 ...

  4. 计算机图形学 第四章 光栅图形学

    第四章 光栅图形学 计算机图形学 第四章 光栅图形学的相关内容,包括:直线段的扫描转换算法.圆弧的扫描转换算法.多边形区域填充.字符的生成.裁剪.反走样 等 Def 光栅显示器:一个像素矩阵(因此,要 ...

  5. 计算机图形学第三次上机作业

    计算机图形学第三次上机作业 读取OBJ文件 仿照群中调用的代码 利用半边数据结构 画出上机作业2中一样的三角形 计算网格面法向 这里的面法向量储存在HE_face中的数据域 facevector中 计 ...

  6. RHEL4- SAMBA服务(四)在x-window下图形界面简单搭建samba服务器

    RHEL4- SAMBA服务(四)在x-window下图形界面简单搭建samba服务器       在<RHEL4- SAMBA服务(一)samba服务的安装与启动>中我讲了如何安装和启动 ...

  7. 【计算机图形学课程】二.MFC鼠标响应函数模拟画图软件

    上一篇文章我们讲述MFC绘制图形的基本函数,包括绘制直线.绘制矩形.绘制椭圆及绘制文字,同时通过绕圆旋转和矩形平移简单的理解了图形学知识.这篇文章我将介绍鼠标响应和键盘响应,通过这些事件让学生实现一个 ...

  8. 计算机图形学——实验四 纹理映射实验

    实验四 纹理映射实验 实验项目性质:设计性实验 所属课程名称:计算机图形学A 实验计划学时:3学时 一.实验目的和要求 掌握纹理映射的基本原理,利用VC++ OpenGL实现纹理映射技术. 二.实验原 ...

  9. 计算机图形学第五次上机——真实感图形绘制(引入光照模型)太阳系动画实现

        计算机图形学       课程实验报告 实验名称    真实感图形绘制     一.实验目的 1.掌握光照模型的编程应用 2.能够编程模拟实现简单的太阳系 1. 用不同的着色和光照参数绘制茶壶 ...

最新文章

  1. PYTHON -MYSQLDB安装遇到的问题和解决办法
  2. spark大数据基本概念整理以及软件下载链接
  3. 纯CSS3实现牛奶般剔透的3D按钮特效
  4. java适合年龄_Java实现三人年龄
  5. Android数据加密解密
  6. android开发学习笔记系列(1)-android起航
  7. bigru参数计算_用飞桨做命名实体识别,手把手教你实现经典模型 BiGRU + CRF
  8. 开源网站项目-静态网址导航网站
  9. Labelme标注软件下载安装教程
  10. 小程序轮播图swiper,自定义的指示点
  11. 寻找协调器FindCoordinatorRequest请求流程
  12. 解决网页版权符号模糊不清
  13. 系统的x86与x64是什么意思以及他们的区别?
  14. 计算机网络连接无线局域网,电脑如何连接无线局域网
  15. 服务器显示未知主机如何解决办法,mc服务器时候说我未知主机
  16. 大数据的python基础_大数据量化之路之python基础
  17. You can't specify target table 'ship_product_cat' for update in FROM clause
  18. python这个语言值得学吗_python和java哪个更值得学
  19. 《我要飞,永远都不会累 》---伤感留言
  20. win10自带输入法总是莫名奇妙变繁体

热门文章

  1. Cython的原理:知其然,知其所以然
  2. Apollo星火计划学习笔记——第一讲 使用Apollo学习自动驾驶
  3. 0x00007FFEB5D49149 处(位于 Project1.exe 中)有未经处理的异常: Microsoft C++ 异常: cv::Exception,位于内存位置 0x000
  4. 方舟手游服务器设置文件翻译,方舟生存进化手游界面中文翻译 语言不通不发愁...
  5. 挑战一个人搭建一套完整直播系统4: 实现网络摄像头视频传输
  6. opencv给图片加中文水印
  7. 史上最全——QQ秘籍之全攻略
  8. 千挑万选, 终于确定了
  9. 今日头条搜索有站长平台!
  10. WebRTC系列-RTCDataChannel发送非音视频数据