利用鼠标、键盘,菜单等方式对图元进行交互操作
1、用鼠标拖动画直线,线段终点始终跟随鼠标移动;
2、使用菜单界面修改直线的颜色;
3、利用键盘控制直线在屏幕上移动;
可以改进的设想:
1.做一个画图程序 可以在鼠标移动函数里修改,每次画点,并定义全局数组保存点的坐标;
2.修改颜色时可以弹出一个颜色表,可以用子窗口实现,并且定义模式为拾取模式
3.可以画多根线,然后按下右键,拖动鼠标画一个矩形,在矩形区域内的线段会变色
4.点击某个线,然后拖动线段
5.Ctrl + 滚轮 放大缩小线段
5. 同时按下上方向键和左方向键,然后线段想左上方移动(没思路)
源代码:
/*
IDE:codeblocks
1、用鼠标拖动画直线,线段终点始终跟随鼠标移动;
2、使用菜单界面修改直线的颜色;
3、利用键盘控制直线在屏幕上移动;
*/
#include
#include
#include
#include
using namespace std;
double WINHEIGHT = 0,WINWIDTH = 0;
bool FirstPointHadDraw = false, LineHadDraw = false;
int x0 = 0, y0 = 0, xEnd = 0, yEnd = 0;
double moveSpeed = 3;
void init();
void MyIdle();
void MyReshape(int w, int h);
void display(void);
void drawLine(int x0, int y0,int xEnd,int yEnd);
void setpixel(int x, int y);
void MyMouse(int button, int state, int x, int y);
void MyMouseMotion(int x,int y);
void MyKeyboard(unsigned char key, int x, int y);
void MySpecialKey(int key, int x, int y);
void MyCreateMenu();
void MajorMenu(int value);
void colorMenu(int value);
void linewidthMenu(int value);
void moveSpeedMenu(int value);
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(500,300);
glutCreateWindow("实验2 利用鼠标、键盘,菜单等方式对图元进行交互操作");
init();
MyCreateMenu();
glutReshapeFunc (MyReshape);
//glutIdleFunc(MyIdle);
glutDisplayFunc(display);
glutMouseFunc (MyMouse);
glutMotionFunc(MyMouseMotion);
glutKeyboardFunc (MyKeyboard);
glutSpecialFunc(MySpecialKey);
glutMainLoop();
}
void display(void)
{
cout<<"Displaying... ";
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
cout<<"Displayed! "<
void MyCreateMenu()
{
int majorMenuID = glutCreateMenu(MajorMenu);
int colorMenuID = glutCreateMenu(colorMenu);
int linewidthMenuID = glutCreateMenu(linewidthMenu);
int moveSpeedMenuID = glutCreateMenu(moveSpeedMenu);
glutSetMenu(majorMenuID);//设置当前菜单
glutAttachMenu(GLUT_RIGHT_BUTTON);//绑定到鼠标右键
glutAddSubMenu("颜色变化",colorMenuID);
glutAddSubMenu("粗细变化",linewidthMenuID);
glutAddSubMenu("移动速度变化",moveSpeedMenuID);
glutAddMenuEntry("清屏", 3);
glutAddMenuEntry("退出", 4);
glutSetMenu(colorMenuID);
glutAddMenuEntry("红色", 1);
glutAddMenuEntry("绿色", 2);
glutAddMenuEntry("蓝色", 3);
glutSetMenu(linewidthMenuID);
glutAddMenuEntry("设为1", 1);
glutAddMenuEntry("设为3", 2);
glutAddMenuEntry("设为5", 3);
glutSetMenu(moveSpeedMenuID);
glutAddMenuEntry("设为1", 1);
glutAddMenuEntry("设为3(默认)", 2);
glutAddMenuEntry("设为5", 3);
return;
}
void MajorMenu(int value)
{
switch(value)
{
case 3:
{
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
break;
}
case 4:
exit(0);
}
return;
}
void colorMenu(int value)
{
cout<<"颜色设置中.........."<
{
case 1:
glColor3f(1.0, 0.0, 0.0);
break;
case 2:
glColor3f(0.0, 1.0, 0.0);
break;
case 3:
glColor3f(0.0, 0.0, 1.0);
break;
}
drawLine(x0,y0,xEnd,yEnd);
return;
}
void linewidthMenu(int value)
{
cout<< "线宽设置中.........."<
{
case 1:
glLineWidth(1);
break;
case 2:
glLineWidth(3);
break;
case 3:
glLineWidth(5);
break;
}
drawLine(x0,y0,xEnd,yEnd);
return;
}
void moveSpeedMenu(int value)
{
cout<< "移动速度设置中.........."<
{
case 1:
moveSpeed = 1;
break;
case 2:
moveSpeed = 3;
break;
case 3:
moveSpeed = 5;
break;
}
return;
}
void MyMouse(int button, int state, int x, int y)
{
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
cout<<"左键被按下 ";
x0 = x;
y0 = WINHEIGHT - y;
setpixel(x0,y0);
FirstPointHadDraw = true;
}
if(button == GLUT_LEFT_BUTTON &&state == GLUT_UP)
{
cout<<"左键被释放 "<
}
}
//移动事件 键被按下的同时发生移动
void MyMouseMotion(int x,int y)
{
cout<<"鼠标移动中... ";
if(true ==FirstPointHadDraw)
{
xEnd = x;
yEnd = WINHEIGHT - y;
drawLine(x0,y0,xEnd,yEnd);
}
return;
}
void drawLine(int x, int y,int x2,int y2)
{
cout<<"准备画线:"<< x0<<" "<< y0<<" " << xEnd<<" "<< yEnd<<" "<
glBegin(GL_LINES);
glVertex2f(x,y);
glVertex2f(x2,y2);
glEnd();
cout<<"画线完成 ";
glFlush();
return;
}
void MyKeyboard(unsigned char key, int x, int y)
{
//27为ESC键
if(key==27)
{
exit(0);
}
}
void MySpecialKey(int key, int x, int y)
{
glutGetModifiers();
switch(key)
{
case GLUT_KEY_UP:
{
y0 += moveSpeed;
yEnd += moveSpeed;
break;
}
case GLUT_KEY_DOWN:
{
y0 -= moveSpeed;
yEnd -= moveSpeed;
break;
}
case GLUT_KEY_LEFT:
{
x0 -= moveSpeed;
xEnd -= moveSpeed;
break;
}
case GLUT_KEY_RIGHT:
{
x0 += moveSpeed;
xEnd += moveSpeed;
break;
}
}
drawLine(x0,y0,xEnd,yEnd);
return;
}
glMatrixMode(GL_PROJECTION); if(w<=h) WINWIDTH = w; void setpixel(int x, int y) void MyIdle() void init() cout<<"Initing... "; cout<<"Inited!"<
//返回调整大小后的窗口大小 w,h
void MyReshape(GLsizei w, GLsizei h)
{
//view port 左下角为0,0
//窗口在高度方向变长,截图也要在该方向上拉长相同比例
//宽度方向拉长,截图也要在该方向上拉长相同比例
cout<<"Reshaping... "<
glLoadIdentity();
gluOrtho2D(0,500, 0,500 * h/w);
else
gluOrtho2D(0,500 * w/h, 0,500);
glViewport(0,0,w,h);
WINHEIGHT = h;
cout<<"Reshaped"<
{
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
return;
}
{
glutPostRedisplay();
}
{
//反射任何光,为白色
//gluOrtho2D(left, right, bottom, top);
//glortho(x_min x_max y_min y_max near top)
glClearColor (1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glPointSize(2.0);
glLineWidth(2.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho(0.0f, WINWIDTH, 0.0f, WINHEIGHT, 1.0, -1.0);