OpenGL 橡皮筋技术

后天图形学考试,整理了下实验课上的OpenGL关于橡皮筋实验的代码。

 

简单实现了如下功能:

1.右键菜单功能响应

2.右键选择画折线或矩形,可保存(书上例子演变)

3.可选取画线或画矩形的颜色,线宽,像素大小

 

 

 

#include <gl/glut.h>  
#include <stdlib.h>
 
#define NUM 100 //折线的最大折线段  
 
int Flag = 0; //标记是否已经开始绘制折线  
int RFlag = 0; //标记是否已经完成一个矩形  
int Function = 1; //标记选择的功能是画折线还是矩形  
int winWidth = 800, winHeight = 600; //窗口的宽度和高度  
int Mousex, Mousey; //用于记录当前鼠标的位置  
int n = 0; //用于记录折线有几段  
int m = 0; //用于记录矩形个数  
//线性结构体  
struct LineNode {  
    int x1;  
    int y1;  
    int x2;  
    int y2;  
}Line[NUM];  
//矩形结构体  
struct Rectangle {  
    int x1;  
    int y1;  
    int x2;  
    int y2;  
}Rect[NUM];  

static GLsizei iMode = 1;
 
 
void Initial(void)  
{  
    glClearColor(1.0f, 1.0f, 1.0f, 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 ProcessMenu1(int value)  
{  
    Function = value; //接收选择  
 
    n = 0;  
    Flag = 0;  
    m = 0;  
    RFlag = 0;  
    glutPostRedisplay(); 
}  

void ProcessMenu2(int value)  
{  
	iMode = value; 

    n = 0;  
    Flag = 0;  
    m = 0;  
    RFlag = 0;  
    glutPostRedisplay(); 
} 
 
void Display()  
{  
	//默认画笔是红色,是线性模式,不填充
    int i, j;  
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //线性模式画图
	
    glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口  

    glColor3f(1.0f, 0.0f, 0.0f); //指定当前的绘图颜色  

	switch(iMode)
	{
	case 3:
		glColor3f(1.0f, 0.0f, 0.0f); //红色 
		break;
	case 4:
		glColor3f(0.0f, 1.0f, 0.0f); //绿色 
		break;
	case 5:
		glColor3f(0.0f, 0.0f, 1.0f); //蓝色
		break;
	case 6:
		glColor3f(0.0f, 0.0f, 0.0f); //黑色 
		break;
	case 7:
		glLineWidth(2); //像素增大 
		break;
	case 8:
		glLineWidth(1); //像素减小
		break;
	case 9:
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 
		break;
	case 10:
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //线性模式画图 
		break;

	case 11://退出
		exit(0);
		break;

	case 12://清屏
		glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口  
		break;
	}

    if (Function == 1) {  
        for (i = 0; i < n; i++) {  
            glBegin(GL_LINES); //绘制直线段  
                glVertex2i(Line[i].x1, Line[i].y1);  
                glVertex2i(Line[i].x2, Line[i].y2);  
            glEnd();  
        }  
        //动态绘制鼠标动作  
        if (Flag == 1) {  
            glBegin(GL_LINES);  
                glVertex2i(Line[i].x1, Line[i].y1);  
                glVertex2i(Mousex, Mousey);  
            glEnd();  
        }  
    }  
    else {  
        //绘制矩形  
        for (j = 0; j < m; j++) {  
            glRecti(Rect[j].x1, Rect[j].y1, Rect[j].x2, Rect[j].y2);  
        }  
        //动态绘制鼠标动作  
        if (RFlag == 1) {  
            glRecti(Rect[j].x1, Rect[j].y1, Mousex, Mousey);  
        }  
    }  
    glutSwapBuffers(); //交换缓冲区  
}  
 
void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse)  
{  
    if (Function == 1) {  
        if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {  
            if (Flag == 0) {  
                Flag = 1;  
                Line[n].x1 = xMouse;  
                Line[n].y1 = winHeight - yMouse;  
            }  
            else {  
                Line[n].x2 = xMouse;  
                Line[n].y2 = winHeight - yMouse;  
                n++;  
                //折线的第二点作为下一段线的第一个的点  
                Line[n].x1 = Line[n-1].x2;  
                Line[n].y1 = Line[n-1].y2;  
            }  
        }  
    }  
    else {  
        //矩形处理  
        if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {  
            if (RFlag == 0) {  
                RFlag = 1;  
                Rect[m].x1 = xMouse;  
                Rect[m].y1 = winHeight - yMouse;  
            }  
            else {  
                RFlag = 0;  
                Rect[m].x2 = xMouse;  
                Rect[m].y2 = winHeight - yMouse;  
                m++;  
                glutPostRedisplay();  
            }  
        }  
    }  
}  
 
void PassiveMouseMove(GLint xMouse, GLint yMouse)  
{  
    Mousex = xMouse;  
    Mousey = winHeight - yMouse;  
    glutPostRedisplay();  
}  
 
int main(int argc, char *argv[])  
{  
    glutInit(&argc, argv);  
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); //使用双缓存及RGB模型  
    glutInitWindowSize(400, 300); //指定窗口的尺寸  
    glutInitWindowPosition(100, 100); //指定窗口在屏幕上的位置  
    glutCreateWindow("橡皮筋技术");  

    
	int nFunctionMenu=glutCreateMenu(ProcessMenu1);  
    glutAddMenuEntry("画折线", 1);  
    glutAddMenuEntry("画矩形", 2);  

	int nColorMenu = glutCreateMenu(ProcessMenu2);  
	glutAddMenuEntry("Red",3);               //创建右键颜色菜单
	glutAddMenuEntry("Green",4);
	glutAddMenuEntry("Blue",5);
	glutAddMenuEntry("Black",6);

	int nPixelMenu = glutCreateMenu(ProcessMenu2);  //创建右键像素菜单
	glutAddMenuEntry("increase pixel size",7);
	glutAddMenuEntry("decrease pixel size",8);

	int nFilleMenu = glutCreateMenu(ProcessMenu2);  //创建右键填充菜单
	glutAddMenuEntry("fill on",9);
	glutAddMenuEntry("fill off",10);

	int nMainMenu = glutCreateMenu(ProcessMenu2);
	glutAddSubMenu("功能",nFunctionMenu);
	glutAddSubMenu("颜色", nColorMenu);
	glutAddSubMenu("像素大小", nPixelMenu);
	glutAddSubMenu("填充", nFilleMenu);

    glutAttachMenu(GLUT_RIGHT_BUTTON);  //右键

	glutCreateMenu(ProcessMenu2);  
	glutAddMenuEntry("退出", 11);
	glutAddMenuEntry("清屏", 12);

    glutAttachMenu(GLUT_MIDDLE_BUTTON);  //中间键

    glutDisplayFunc(Display);  

    glutReshapeFunc(ChangeSize); //指定窗口再整形回调函数  

    glutMouseFunc(MousePlot); //指定鼠标响应函数  

    glutPassiveMotionFunc(PassiveMouseMove); //指定鼠标移动响应函数  

    Initial();  

    glutMainLoop(); //启动主GLUT事件处理循环  

    return 0;  
} 
#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、付费专栏及课程。

余额充值