[OpenGL]计算机图形学实验02:多边形世界
2012-11-20 00:46
232 查看
/************************************************************************/ /*Test02: Polygon world /*Author: Wang Haiyang /*Date: 2012/11/20 /*Email: wanghaiyang@139.me /************************************************************************/ #define MAX_POLYGONS 8 #define MAX_VERTICES 10 #define EDITRANGE 30 #include <GL/glut.h> #include <stdlib.h> #include<iostream> #include<fstream> #include <iostream> #include <string> using namespace std; void myMouse(int, int, int, int); void myMotion(int, int); void myDisplay(); void myReshape(int, int); void color_menu(int); void main_menu(int); int pick_polygon(int x, int y); void myInit(); //定义多边形的结构体类型 typedef struct polygon { int color; //颜色索引 bool used; //如果多边形已经被定义则返回true int xmin, xmax, ymin, ymax; //包围盒 float xc, yc; //多边形的中心 int nvertices; //顶点的数目 int x[MAX_VERTICES]; //顶点 int y[MAX_VERTICES]; //顶点 } polygon; //定义标记变量 bool picking = false; //是否处于拾取状态 bool moving = false; //是否处于移动多边形的状态 int in_polygon = -1; //不在任何多边形的内部 int present_color = 0; //默认的颜色 int polygonCount = 0; //记录一共有多少个多边形 GLfloat tempArrayX[MAX_VERTICES]={0}; GLfloat tempArrayY[MAX_VERTICES]={0}; int tempCount = 0; //当前绘制的多边形的临时定点数目 bool tempDrawing = false; //当前是否在绘制多边形的判断 GLsizei wh = 500; //初始化窗口大小 GLsizei ww = 500; //初始化窗口大小 int draw_mode = 0; //绘制模式 bool editPointing = false; //当前是否在编辑顶点 GLfloat colors[8][3] = { { 0.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 }, { 0.0, 1.0, 1.0 }, { 1.0, 0.0, 1.0 }, { 1.0, 1.0, 0.0 }, { 1.0, 1.0, 1.0 } }; polygon polygons[MAX_POLYGONS]; void myReshape(int w, int h) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(0, 0, w, h); ww = w; wh = h; } void myInit() { glClearColor(0.1, 0.1, 0.5, 1.0); //清屏颜色颜色设置为蓝青色 for (int i = 0; i < MAX_POLYGONS; i++) { polygons[i].used = false; //将所有多边形标记为未定义状态 } } void myMouse(int btn, int state, int x, int y) { y = wh - y; //增加顶点 if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN && !picking && !moving&&tempDrawing) { moving = false; picking = false; cout<<"添加了一个顶点!"<<endl; cout<<"in_polygon:"<<in_polygon<<endl; if (polygons[in_polygon].nvertices == MAX_VERTICES) { cout << "超出最大顶点数" << endl; }else{ tempArrayX[tempCount]=x; tempArrayY[tempCount]=y; tempCount++; glutPostRedisplay(); } if (in_polygon >= 0) { if (polygons[in_polygon].nvertices == MAX_VERTICES) { cout << "超出最大顶点数" << endl; } else{ int i = polygons[in_polygon].nvertices; polygons[in_polygon].x[i] = x; cout<<"添加了一个顶点!polygons[in_polygon].x[i] :"<<polygons[in_polygon].x[i] <<endl; polygons[in_polygon].y[i] = y; cout<<"添加了一个顶点!polygons[in_polygon].Y[i] :"<<polygons[in_polygon].y[i] <<endl; polygons[in_polygon].nvertices++; } } } if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN && picking && !moving) { moving = false; picking = false; int j = pick_polygon(x, y); if (j >= 0) { polygons[j].used = false; polygonCount--; in_polygon = -1; glutPostRedisplay(); } } } int pick_polygon(int x, int y) { for (int i=MAX_POLYGONS; i >=0; i--) { cout<<"polygons[i].used="<<polygons[i].used<<endl; if (polygons[i].used) { if ((x >= polygons[i].xmin) && (x <= polygons[i].xmax) && (y >= polygons[i].ymin) && (y <= polygons[i].ymax)) { in_polygon = i; moving = true; return i; } } } cout << "不在多边形里面" << endl; return -1; } void myMotion(int x, int y) { float dx, dy; y = wh - y; int i, j; if(editPointing){ for (int i = 0; i < MAX_POLYGONS; ++i) { if (polygons[i].used) { for (int j = 0; j < polygons[i].nvertices; ++j) { if(x<polygons[i].x[j]+EDITRANGE&&x>polygons[i].x[j]-EDITRANGE &&y<polygons[i].y[j]+EDITRANGE&&y>polygons[i].y[j]-EDITRANGE){ polygons[i].x[j]=x; polygons[i].y[j]=y; } } } } glutPostRedisplay(); } if(tempDrawing){ tempArrayX[tempCount-1]=x; tempArrayY[tempCount-1]=y; glutPostRedisplay(); } if (moving) { j = pick_polygon(x, y); if (j < 0) { cout << "不在多边形里面" << endl; return; } dx = x - polygons[j].xc; dy = y - polygons[j].yc; for (i = 0; i < polygons[j].nvertices; i++) { polygons[j].x[i] += dx; polygons[j].y[i] += dy; } polygons[j].xc += dx; polygons[j].yc += dy; polygons[j].xmax += dx; polygons[j].xmin += dx; polygons[j].ymax += dy; polygons[j].ymin += dy; glutPostRedisplay(); } } void color_menu(int index) { present_color = index; if (in_polygon >= 0) { polygons[in_polygon].color = index; } } void main_menu(int index) { int i= 0; switch (index) { case 1: // 建立一个新的多边形 { tempDrawing = true; tempCount = 0; moving = false; picking = false; editPointing=false; moving = false; for (i = 0; i < MAX_POLYGONS; i++) { if (polygons[i].used == false) { break; } } if (i == MAX_POLYGONS) { cout << "已经达到最大值\n" << endl; exit(0); } cout << "i=" << i << endl; polygons[i].color = present_color; polygons[i].used = true; polygons[i].nvertices = 0; in_polygon = i; picking = false; break; } case 2: // 结束多边形的定义并计算多边形的包围盒和它的中心位置 tempDrawing = false; tempCount = 0; moving = false; picking = false; editPointing=false; if (in_polygon >= 0) { polygons[in_polygon].xmax = polygons[in_polygon].xmin = polygons[in_polygon].x[0]; polygons[in_polygon].ymax = polygons[in_polygon].ymin = polygons[in_polygon].y[0]; polygons[in_polygon].xc = polygons[in_polygon].x[0]; polygons[in_polygon].yc = polygons[in_polygon].y[0]; for (int i = 1; i < polygons[in_polygon].nvertices; i++) { if (polygons[in_polygon].x[i] < polygons[in_polygon].xmin) { polygons[in_polygon].xmin = polygons[in_polygon].x[i]; } else if (polygons[in_polygon].x[i] > polygons[in_polygon].xmax) { polygons[in_polygon].xmax = polygons[in_polygon].x[i]; } if (polygons[in_polygon].y[i] < polygons[in_polygon].ymin) { polygons[in_polygon].ymin = polygons[in_polygon].y[i]; } else if (polygons[in_polygon].y[i] > polygons[in_polygon].ymax) { polygons[in_polygon].ymax = polygons[in_polygon].y[i]; } polygons[in_polygon].xc += polygons[in_polygon].x[i]; polygons[in_polygon].yc += polygons[in_polygon].y[i]; cout<<"polygons[in_polygon].x"<<i<<":"<<polygons[in_polygon].x[i]<<endl; cout<<"polygons[in_polygon].y"<<i<<":"<<polygons[in_polygon].y[i]<<endl; } polygons[in_polygon].xc = polygons[in_polygon].xc / polygons[in_polygon].nvertices; polygons[in_polygon].yc = polygons[in_polygon].yc / polygons[in_polygon].nvertices; } in_polygon = -1; polygonCount++; glutPostRedisplay(); break; case 3: // 设立拾取模式 tempDrawing = false; tempCount = 0; moving = false; picking = true; editPointing=false; break; case 4: //是否移动 tempDrawing = false; tempCount = 0; moving = true; picking = false; editPointing=false; break; case 5: //存储文件 { tempDrawing = false; tempCount = 0; moving = false; picking = false; editPointing=false; in_polygon=-1; std::ofstream file("Polygon.dat",std::ios::ate|std::ios::binary); if(!file) { std::cout<<"文件打开失败!"; abort();//等同于exit } //写文件 for(int i=0;i<MAX_POLYGONS;i++){ cout<<"polygons["<<i<<"].used"<<polygons[i].used<<endl; if(polygons[i].used){ cout<<"我写了一个!!"<<endl; file.write((char*) &polygons[i],sizeof(polygons[i])); cout<<"&polygons[i],sizeof(polygons[i])"<<&polygons[i]<<"size"<<sizeof(polygons[i])<<endl; } } //关闭文件 file.close(); break; } case 6: //读取文件 { in_polygon=-1; tempDrawing = false; tempCount = 0; moving = false; picking = false; editPointing=false; std::ifstream rfile("Polygon.dat",std::ios::binary); //打开文件 //std::ofstream file("Polygon.dat",std::ios::ate|std::ios::binary); if(!rfile) { std::cout<<"文件打开失败!"; return ;//等同于exit } //读文件 for(int i=0;i<MAX_POLYGONS;i++) { cout<<"polygons["<<i<<"].used"<<polygons[i].used<<endl; rfile.read((char*) &polygons[i],sizeof(polygons[i])); cout<<"polygons["<<i<<"].used"<<polygons[i].used<<endl; } glutPostRedisplay(); //关闭文件 rfile.close(); break; } case 7: in_polygon=-1; tempDrawing = false; tempCount = 0; moving = false; picking = false; editPointing = true ; break; } } void myDisplay() { cout<<"myDisplay!"<<endl; glClear(GL_COLOR_BUFFER_BIT); for (int i = 0; i < MAX_POLYGONS; ++i) { if (polygons[i].used&&(i!=in_polygon||moving)) { cout<<"polygons[i].used="<<polygons[i].used<<endl; glColor3fv(colors[polygons[i].color]); cout<<colors[polygons[i].color]<<endl; glBegin(GL_POLYGON); for (int j = 0; j < polygons[i].nvertices; ++j) { glVertex2i(polygons[i].x[j], polygons[i].y[j]); cout<<"X:"<<polygons[i].x[j]<< "Y:"<<polygons[i].y[j]<<endl; } glEnd(); } } if(tempDrawing){ glColor3fv(colors[present_color]); glBegin(GL_LINE_STRIP); for (int j = 0; j <tempCount; ++j) { glVertex2f(tempArrayX[j],tempArrayY[j]); } glEnd(); } glFlush(); } int main(int argc, char **argv) { int c_menu; glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowPosition(400, 100); glutInitWindowSize(500, 500); glutCreateWindow("Polygon Test"); glutDisplayFunc(myDisplay); myInit(); c_menu = glutCreateMenu(color_menu); glutAddMenuEntry("黑色", 0); glutAddMenuEntry("红色", 1); glutAddMenuEntry("绿色", 2); glutAddMenuEntry("蓝色", 3); glutAddMenuEntry("青色", 4); glutAddMenuEntry("紫色", 5); glutAddMenuEntry("黄色", 6); glutAddMenuEntry("白色", 7); glutCreateMenu(main_menu); glutAddMenuEntry("新建多边形", 1); glutAddMenuEntry("结束新建", 2); glutAddMenuEntry("删除", 3); glutAddMenuEntry("移动", 4); glutAddMenuEntry("存档本地文件", 5);//将四边形数据存储到本地文件的选项 glutAddMenuEntry("读取本地文件", 6); glutAddMenuEntry("编辑顶点", 7); glutAddSubMenu("颜色", c_menu); cout <<"c_menu="<< c_menu << endl; glutAttachMenu(GLUT_RIGHT_BUTTON); glutReshapeFunc(myReshape); glutMouseFunc(myMouse); glutMotionFunc(myMotion); glutMainLoop(); }
相关文章推荐
- 关于大四上学期的计算机图形学实验报告123——opengl建模、载入OBJ文件、纹理贴图、光照、交互。
- Andriod OpenGL 教程 02 - 第一个多边形
- [OpenGL]计算机图形学实验01:一个简单的球体
- 计算机图形学(二)输出图元_11_OpenGL多边形填充区函数(上)
- 计算机图形学(二)输出图元_11_OpenGL多边形填充区函数(下)
- 【Qt OpenGL教程】02:你的第一个多边形
- 《计算机图形学》实验一:利用OpenGL实现直线光栅化的DDA算法
- 【Qt OpenGL教程】10:加载3D世界,并在其中漫游
- 03->OpenGL多边形,glut实现三角形条带和三角形扇
- 山东大学 图形学 openGL实验一
- OpenGL研究3.0 多边形区域填充
- OpenGL绘制一个点、线、多边形
- 计算机图形学(三)_图元的属性_16_ 反走样_8_OpenGL反走样函数
- OpenGL 漫游3D世界
- 【机器学习实验】学习Python来分类现实世界的数据
- OpenGL: 模板测试实现半透明多边形运算
- 图形世界分裂的两派——理清Direct3D和OpenGL的脉络
- OpenGL: 填充非凸多边形
- Qt 之路 (02)—你好,世界!
- Qt下的OpenGL 编程(4)进军3D世界