计算机图形学OpenGLC++实现: 橡皮筋技术实现折线和矩形的鼠标实现(附源码)

废话不多说,直接开始

下列是会使用到的函数简单介绍:

  • 初始化背景 void Initial(void)
  • 改变窗口大小 void ChangeSize(int w,int h)
  • 菜单响应函数 chooseWay(int value)
  • 清除当前已经画的图形 void clear(void)
  • 画图函数 void Display(void)
  • 鼠标点击事件响应函数
    void MousePlot(GLint button,GLint action,GLint xMouse,GLint yMouse)
  • 鼠标跟踪函数 void PassiveMouseMove(GLint xMouse,GLint yMouse)

首先,让我们看看主函数

int main(int argc,char* argv[])
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
    //创建窗口,并设置大小为长400宽300
    glutInitWindowSize(400,300);
    glutInitWindowPosition(100,100);
    glutCreateWindow("橡皮筋技术");
	
	//向鼠标右键注册菜单-选择画折线还是矩形
    glutCreateMenu(chooseWay);				//菜单函数
    glutAddMenuEntry("BrokenLine", 1);		//折线选项
    glutAddMenuEntry("Actangle", 2);		//矩形选项
    glutAddMenuEntry("Clear", 0);			//清空选项
    glutAttachMenu(GLUT_RIGHT_BUTTON);		//将该菜单绑定在右键
	Initial();								//初始化函数
	glutReshapeFunc(ChangeSize);			//调用改变窗口函数
    glutDisplayFunc(Display);				//调用画图函数
    glutMouseFunc(MousePlot);				//调用鼠标点击事件函数
    glutPassiveMotionFunc(PassiveMouseMove);//调用鼠标追踪事件函数
    glutMainLoop();

    return 0;
}

初始化函数,glClearColor函数向缓存写入颜色值

//初始化函数
void Initial(void)
{
    glClearColor(0.5f,0.5f,0.75f,1.0f);		//设置背景颜色
}

//改变窗口大小函数

void ChangeSize(int w,int h)
{
    winWidth=w,winHeight=h;
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();               //调用单位矩阵,去除以前投影参数设置
    gluOrtho2D(0.0,winWidth,0.0,winHeight);
}

//清除当前已经画的图形

void clear(void)
{
    int flag = iPointNum;
    iPointNum = 0;
    for (int i = 0; i < flag; ++i)
    {
        x[i] = 0;
        y[i] = 0;
    }
    glutPostRedisplay();				//清除后重画
}

菜单选择函数

void chooseWay(int value)
{
    switch (value)
    {
    case 0:clear(); break;
    case 1:choose=1; break;		//画折线
    case 2:choose=2; break;		//画矩形
    default:
        choose = 1;break;		//默认画折线
    }
}

鼠标点击响应函数

void MousePlot(GLint button,GLint action,GLint xMouse,GLint yMouse)
{
    if (choose == 1)				//画折线
    {
        if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN)	
        //左键按下判定
        {
            if (iPointNum == 0)
            //已经点击的点数
            {
                x[iPointNum] = xMouse;
                y[iPointNum] = winHeight - yMouse;		//坐标转换
                iPointNum += 1;
            }
            else
            {
                x[iPointNum] = xMouse;
                y[iPointNum] = winHeight - yMouse;
                iPointNum += 1;
                glutPostRedisplay();
            }
        }
    }
    if (choose == 2)			//画矩形
    {
        if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN)
        {
            if (iPointNum== 0||iPointNum==2)
            {
                x[0] = xMouse;
                y[0] = winHeight - yMouse;
                iPointNum = 1;
            }
            else
            {
                x[1] = xMouse;
                y[1] = winHeight - yMouse;
                iPointNum = 2;
                glutPostRedisplay();
            }
        }
    }
}

鼠标跟踪函数

void PassiveMouseMove(GLint xMouse,GLint yMouse)
{
    if (choose == 1 && iPointNum >=1)
    {
        x[iPointNum] = xMouse;
        y[iPointNum] = winHeight - yMouse;
        glutPostRedisplay();
    }
    if(choose==2&&iPointNum==1)
    {
        x[iPointNum]=xMouse;
        y[iPointNum]=winHeight-yMouse;
        glutPostRedisplay();
    }
}

画图函数

void Display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    if(choose==1)
    {
        if (iPointNum >= 1)
        {
            glColor3f(1.0f, 0.0f, 0.0f);
            int flag = iPointNum;
            glBegin(GL_LINE_STRIP);
            while (flag)
            {
                glVertex2f(x[flag], y[flag]);
                glVertex2f(x[flag - 1], y[flag - 1]);
                flag--;
            }
            glEnd();
        }
    }
    //画矩形
    if (choose == 2)
    {
        if (iPointNum >=1)
        {
            glColor3f(1.0f, 0.0f, 0.0f);
            glBegin(GL_QUADS);
            glVertex2f(x[0], y[0]);
            glVertex2f(x[0], y[1]);
            glVertex2f(x[1], y[1]);
            glVertex2f(x[1], y[0]);
            glEnd();
        }
    }
    glutSwapBuffers();
}

把上述拼接起来就可以完整运行,希望对你有所帮助!

#include "stdafx.h" #include <GL/glut.h> #include <stdlib.h> #include <stdio.h> #define stripeImageWidth 32 GLubyte stripeImage[4 * stripeImageWidth]; #ifdef GL_VERSION_1_1 static GLuint texName; #endif void makeStripeImage(void) { int j; for (j = 0; j < stripeImageWidth; j++) { stripeImage[4 * j] = (GLubyte)((j <= 4) ? 255 : 0); stripeImage[4 * j + 1] = (GLubyte)((j>4) ? 255 : 0); stripeImage[4 * j + 2] = (GLubyte)0; stripeImage[4 * j + 3] = (GLubyte)255; } } /* planes for texture coordinate generation */ static GLfloat xequalzero[] = { 1.0, 0.0, 0.0, 0.0 }; static GLfloat slanted[] = { 1.0, 1.0, 1.0, 0.0 }; static GLfloat *currentCoeff; static GLenum currentPlane; static GLint currentGenMode; static float roangles; static float roangles1; float roangles2 = -2; float roangles3 = -3; void SpecialKeys(int key, int x, int y) { if (key == GLUT_KEY_F1) roangles += 2.0f; roangles2 += 0.05; roangles3 += 1; if (key == GLUT_KEY_F2) roangles1 += 2.0f; if (roangles2 >= 3) roangles2 = -3; // 使用新的坐标重新绘制场景 glutPostRedisplay(); } void init(void) { glClearColor(1.0, 1.0, 1.0, 0.0); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); makeStripeImage(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); #ifdef GL_VERSION_1_1 glGenTextures(1, &texName;); glBindTexture(GL_TEXTURE_1D, texName); #endif glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); #ifdef GL_VERSION_1_1 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, stripeImageWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, stripeImage); #else glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, stripeImage); #endif glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); currentCoeff = xequalzero; currentGenMode = GL_OBJECT_LINEAR; currentPlane = GL_OBJECT_PLANE; glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode); glTexGenfv(GL_S, currentPlane, currentCoeff); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_1D); //glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glFrontFace(GL_CW); //glCullFace(GL_BACK); glMaterialf(GL_FRONT, GL_SHININESS, 64.0); roangles = 45.0f; roangles1 = 362.0f; } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glBegin(GL_QUADS); glColor3f(1, 0, 1); glVertex3f(-1, -1, 0); glColor3f(1, 0, 1); glVertex3f(-3, -1, 0); glColor3f(1, 0, 1); glVertex3f(1, -1, 0); glColor3f(1, 0, 1); glVertex3f(-1, -2, 0); glEnd(); glPopMatrix(); glPushMatrix(); glTranslated(roangles2, 2, -3); glRotatef(roangles, 0.0, 1.0, 0.0); #ifdef GL_VERSION_1_1 glBindTexture(GL_TEXTURE_1D, texName); #endif //glutSolidTeapot(2.0); glutSolidSphere(0.8, 32, 32); glPopMatrix(); glFlush(); glPushMatrix(); glTranslated(1, 2, -3); glRotatef(roangles1, 1.0, 0.0, 0.0); glRotatef(roangles3, 0.0, 1.0, 0.0); #ifdef GL_VERSION_1_1 glBindTexture(GL_TEXTURE_1D, texName); #endif //glutSolidTeapot(2.0); glTranslated(-1, -3, -0); glRotatef(90, 1.0f, 0.0f, 0.0f); glRotatef(180, 0.0f, 1.0f, 0.0f); glRotatef(-30, 0.0f, 0.0f, 1.0f); glutSolidCone(1, 2, 32, 32); glPopMatrix(); glFlush(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-3.5, 3.5, -3.5*(GLfloat)h / (GLfloat)w, 3.5*(GLfloat)h / (GLfloat)w, -3.5, 3.5); else glOrtho(-3.5*(GLfloat)w / (GLfloat)h, 3.5*(GLfloat)w / (GLfloat)h, -3.5, 3.5, -3.5, 3.5); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void idle() { roangles += 0.1f; glutPostRedisplay(); } int main(int argc, char** argv) { glutInit(&argc;, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(600, 600); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); //glutIdleFunc(idle); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutSpecialFunc(SpecialKeys); glutMainLoop(); return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值