您的位置:首页 > 理论基础

计算机图形学-实验3-掌握利用OpenGL函数进行鼠标、键盘操作,创建菜单

2017-04-24 13:57 1416 查看
实验三:(2学时)

 

一、 实验目的:

掌握利用OpenGL函数进行鼠标、键盘操作,创建菜单等

 

二、 实验内容:

1、用鼠标拖动画直线,线段终点始终跟随鼠标移动;画线可以利用实验1或实验2中已经实现的画线功能;

2、使用菜单界面修改直线的颜色;

3、利用键盘控制直线在屏幕上移动;

 

三、 实现效果及步骤(或流程)

1、用鼠标拖动画直线,线段终点始终跟随鼠标移动;

(1)画线采用实验二的方法。

(2)编写鼠标响应事件,实现按下标记第一个点,抬起获得第二个点并画线。代码如图:



(3)获取鼠标实时移动坐标,实现随鼠标位置移动的画线效果。代码如图:

 


(4)实现效果如下图:



2、使用菜单界面修改直线的颜色。

(1)在主函数里添加菜单的回调函数,再添加若干菜单项,参数value用以标记菜单项。实现代码如图:

 


(2)实现效果如图:

 


3、利用键盘控制直线在屏幕上移动;

(1)主函数中添加键盘响应的回调函数:
glutSpecialFunc(ProcessSpecialKeyboead);
(2)编写回调函数代码,根据键盘输入,修改线的坐标并重新绘制直线。代码如图:
 


(3)实现效果如图:
 


向上移动后;
 


四、 创新设计和实现方法

1、创建菜单的子菜单;

(1)利用glutAddSubMenu函数将其他菜单加入到该项下作为子菜单。

(2)编写逻辑函数,参数value接收输入。

 


(3)实现效果如下图:



源码如下:

// test3.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <math.h>
#include <GL/glut.h>

#define GLUT_LEFT_BUTTON    0
#define GLUT_MIDDLE_BUTTON  1
#define GLUT_RIGHT_BUTTON    2
#define GLUT_DOWN        0
#define GLUT_UP          1
int Width = 500, Height = 500;
int x01, y01, x02, y02;
int FirstPointHaveDraw = 0;
int RightButtonDown = 0;
float red = 0.0f, green = 0.0f, blue = 0.0f;
int moveSpeed = 2;
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);  // Set display-window color to white.
glMatrixMode(GL_PROJECTION);       // Set projection parameters.
gluOrtho2D(0.0, Width, 0.0, Height);  //设置窗口坐标范围
}

void lineBres(int x0, int y0, int xEnd, int yEnd, int red, int green, int blue)
{
glPointSize(4);
glColor3f(red, green, blue);
glBegin(GL_POINTS);
//画第一个点
if (x0 > xEnd)
{
int t;
t = x0; x0 = xEnd; xEnd = t;
t = y0; y0 = yEnd; yEnd = t;
}
int x = x0;
int y = y0;
glVertex2i(x, y);
//当线段垂直时。
if (x0 == xEnd)
{
while (y < yEnd)
{
y++;
glVertex2i(x, y);
}
glEnd();
glFlush();
return;
}
//当线段水平时。
if (y0 == yEnd)
{
while (x < xEnd)
{
x++;
glVertex2i(x, y);
}
glEnd();
glFlush();
return;
}
int dx = xEnd - x0;
int dy = yEnd - y0;
int twoDx = 2 * dx;
int twoDy = 2 * dy;
int twoDyMinusDx = 2 * (dy - dx);
int twoDxMinusDy = 2 * (dx - dy);
int twoDxAddDy = 2 * (dx + dy);
int p;
double k = (double)(yEnd - y0) / (double)(xEnd - x0);
//斜率
//当线段斜率0<k<=1时。
if (0 < k && k <= 1)
{
p = 2 * dy - dx;
while (x < xEnd)
{
x++;
if (p < 0)
{
p += twoDy;
}
else
{
y++;
p += twoDyMinusDx;
}
glVertex2i(x, y);
}
glEnd();
glFlush();
return;
}
//当线段斜率-1<=k<0时。
if (k < 0 && k >= -1)
{
p = 2 * dy + dx;
while (x < xEnd)
{
x++;
if (p >= 0)
p += twoDy;
else
{
y--;
p += twoDxAddDy;
}
glVertex2i(x, y);
}
glEnd();
glFlush();
return;
}
//当线段斜率k<-1时。
if (k < -1)
{
p = 2 * dx - dy;
while (y > yEnd)
{
y--;
if (p >= 0)
p -= twoDx;
else
{
x++;
p -= twoDxAddDy;
}
glVertex2i(x, y);
}
glEnd();
glFlush();
return;
}
//当线段斜率k>1时。
if (k > 1)
{
p = dy;
while (y < yEnd)
{
y++;
if (p < 0)
{
p += twoDx;
}
else
{
x++;
p -= twoDyMinusDx;
}
glVertex2i(x, y);
}
glEnd();
glFlush();
return;
}
}

void Drawline(int button, int state, int x, int y)
{
glPointSize(1);
glColor3f(0.1, 0.0, 0.0);
if (RightButtonDown == 0)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
if (FirstPointHaveDraw == 0)
{
x01 = x;
y01 = Height - y;
glPointSize(2);
glBegin(GL_POINTS);
glVertex2i(x01, y01);
glEnd();
glFlush();
FirstPointHaveDraw = 1;
}
printf("画下点 x:%d,y:%d\n", x01, y01);
}
else
{
x02 = x;
y02 = Height - y;
lineBres(x01, y01, x02, y02, red, green, blue);
FirstPointHaveDraw = 0;
}
}
}
}

void mousemove(int x, int y)
{
glClear(GL_COLOR_BUFFER_BIT);
printf("鼠标移动中, x:%d,y:%d\n", x, Height - y);
lineBres(x01, y01, x, Height - y, red, green, blue);
}

void ColorMenu(int value) {

switch (value)
{
case 1:red = 1.0; green = 0.0; blue = 0.0; break;
case 2:red = 0.0; green = 1.0; blue = 0.0; break;
case 3:red = 0.0; green = 0.0; blue = 1.0; break;
default:break;
}
}

void myMenu(int value)
{
if (value == 0)
{
exit(0);
}
else
{
ColorMenu(value);
}
}

void ProcessSpecialKeyboead(int key, int x, int y)
{
if (GLUT_KEY_UP == key)
{
printf("up\n");
y01 += moveSpeed;
y02 += moveSpeed;
glClear(GL_COLOR_BUFFER_BIT);
lineBres(x01, y01, x02, y02, red, green, blue);
glFlush();
}
if (GLUT_KEY_DOWN == key)
{
printf("down\n");
y01 -= moveSpeed;
y02 -= moveSpeed;
glClear(GL_COLOR_BUFFER_BIT);
lineBres(x01, y01, x02, y02, red, green, blue);
glFlush();
}
if (GLUT_KEY_LEFT == key)
{
printf("left\n");
x01 -= moveSpeed;
x02 -= moveSpeed;
glClear(GL_COLOR_BUFFER_BIT);
lineBres(x01, y01, x02, y02, red, green, blue);
glFlush();
}
if (GLUT_KEY_RIGHT == key)
{
printf("right\n");
x01 += moveSpeed;
x02 += moveSpeed;
glClear(GL_COLOR_BUFFER_BIT);
lineBres(x01, y01, x02, y02, red, green, blue);
glFlush();
}
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);                         // Initialize GLUT.
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);   // Set display mode.
glutInitWindowPosition(100, 100);   // Set top-left display-window position.
glutInitWindowSize(Width, Height);      // 设置窗口在显示器上的大小
glutCreateWindow("An Example OpenGL Program"); // Create display window.

init();                            // Execute initialization procedure.
glClear(GL_COLOR_BUFFER_BIT);
glutMouseFunc(Drawline);
glutMotionFunc(mousemove);
int sub_menu;
sub_menu = glutCreateMenu(ColorMenu);
glutAddMenuEntry("Red", 1);//添加菜单项
glutAddMenuEntry("Green", 2);
glutAddMenuEntry("Blue", 3);
glutCreateMenu(myMenu);//注册菜单回调函数
//glutAddMenuEntry("Rotate", 4);
glutAddSubMenu("Color", sub_menu);
glutAddMenuEntry("Exit", 0);
glutAttachMenu(GLUT_RIGHT_BUTTON);//把当前菜单注册到指定的鼠标键
glutSpecialFunc(ProcessSpecialKeyboead);
glutMainLoop();                    // Display everything and wait.
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐