1. 程式人生 > >OpenGL實驗二 利用滑鼠、鍵盤,選單等方式對圖元進行互動操作

OpenGL實驗二 利用滑鼠、鍵盤,選單等方式對圖元進行互動操作

  • 實驗目的:

利用滑鼠、鍵盤,選單等方式對圖元進行互動操作

 

  • 實驗內容:

1、用滑鼠拖動畫直線,線段終點始終跟隨滑鼠移動;

2、使用選單介面修改直線的顏色;

3、利用鍵盤控制直線在螢幕上移動;

 

可以改進的設想:

1.做一個畫圖程式  可以在滑鼠移動函式裡修改,每次畫點,並定義全域性陣列儲存點的座標;

2.修改顏色時可以彈出一個顏色表,可以用子視窗實現,並且定義模式為拾取模式

3.可以畫多根線,然後按下右鍵,拖動滑鼠畫一個矩形,在矩形區域內的線段會變色

4.點選某個線,然後拖動線段  

5.Ctrl +  滾輪 放大縮小線段

5. 同時按下上方向鍵和左方向鍵,然後線段想左上方移動(沒思路)

 

 

原始碼:

/*

IDE:codeblocks
1、用滑鼠拖動畫直線,線段終點始終跟隨滑鼠移動;
2、使用選單介面修改直線的顏色;
3、利用鍵盤控制直線在螢幕上移動;
*/
#include <windows.h>
#include <GL/glut.h>
#include <iostream>
#include <stdio.h>
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! "<<endl;
}

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<<"顏色設定中.........."<<endl;
    switch(value)
    {
    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<< "線寬設定中.........."<<endl;
    switch(value)
    {
    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<< "移動速度設定中.........."<<endl;
    switch(value)
    {
    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<<"左鍵被釋放  "<<endl;
        LineHadDraw = true;
    }
}

//移動事件  鍵被按下的同時發生移動
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<<" "<<endl;
    glClear(GL_COLOR_BUFFER_BIT);
    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;
}


//返回調整大小後的視窗大小  w,h
void MyReshape(GLsizei w, GLsizei h)
{
    //view port 左下角為0,0
    //視窗在高度方向變長,截圖也要在該方向上拉長相同比例
    //寬度方向拉長,截圖也要在該方向上拉長相同比例
    cout<<"Reshaping...       "<<w<<"  "<<h;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    if(w<=h)
        gluOrtho2D(0,500,    0,500 * h/w);
    else
        gluOrtho2D(0,500 * w/h,  0,500);
    glViewport(0,0,w,h);

    WINWIDTH = w;
    WINHEIGHT = h;
    cout<<"Reshaped"<<endl;
}

void setpixel(int x, int y)
{
    glBegin(GL_POINTS);
    glVertex2i(x,y);
    glEnd();
    return;
}

void MyIdle()
{
    glutPostRedisplay();
}

void init()
{
    //反射任何光,為白色
    //gluOrtho2D(left,  right,   bottom, top);
    //glortho(x_min  x_max  y_min  y_max   near  top)

    cout<<"Initing...    ";
    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);

    cout<<"Inited!"<<endl;
}