/*------------------------------------ author:XD_G location:SWUN time:09/2015~01/2016 course:Computer Graphics teacher:Tianyun Huang ------------------------------------*/ #include <iostream> #include <vector> #include <GL/glut.h> #pragma comment( lib , "opengl32.lib") #pragma comment( lib , "glu32.lib" ) #pragma comment( lib , "glut32.lib" ) #define x_min View_leftbottom.x #define x_max View_righttop.x #define y_min View_leftbottom.y #define y_max View_righttop.y using namespace std; //point struct class Point { public: int x; int y; unsigned char loc; Point() :x(0), y(0), loc(0) {} Point(int a, int b) :x(a), y(b), loc(0) {} Point(int a, int b, unsigned char c) :x(a), y(b), loc(c) {} Point(const Point& src): x(src.x),y(src.y),loc(src.loc) {} Point& operator=(const Point &src) { if (this != &src) { this->x = src.x; this->y = src.y; this->loc = src.loc; } return *this; } }; enum Wnd{LEFT, RIGHT, BOTTOM, TOP}; //windows_size int L_w = 1366 / 2; int L_h = 768 / 2; //view_windows Point View_leftbottom(-L_w, -L_h); Point View_righttop(L_w, L_h); //lines_set vector<Point > line_points_set; vector<Point > new_line_points_set; //polygon_polygon_points_set vector<Point > polygon_points_set; //color table GLfloat black_color[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat red_color[] = { 1.0,0.0,0.0,1.0 }; GLfloat green_color[] = { 0.0, 1.0, 0.0, 1.0 }; GLfloat blue_color[] = { 0.0, 0.0, 1.0, 1.0 }; GLfloat white_color[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat grey_color[] = { 0.5, 0.5, 0.5, 1.0 }; //clip area_code const unsigned char winLeftBitCode = 0x1;// 0001 const unsigned char winRightBitCode = 0x2;// 0010 const unsigned char winBottomBitCode = 0x4;// 0100 const unsigned char winTopBitCode = 0x8;// 1000
//Functions //Init & Set func inline void setPixel(int x, int y, GLfloat* c){ glColor4fv(c); glBegin(GL_POINTS); glVertex2i(x, y); glEnd(); } //将所求直线变换到斜率0~1之间 inline void translate(int &x0, int &y0, int &x1, int &y1, float k) { if (k > 1) { int temp = x0; x0 = y0; y0 = temp; temp = x1; x1 = y1; y1 = temp; if (x0 > x1) { temp = x0; x0 = x1; x1 = temp; temp = y0; y0 = y1; y1 = temp; } } else if (k >= -1 && k < 0) { y0 = -y0; y1 = -y1; if (x0 > x1) { int temp = x0; x0 = x1; x1 = temp; temp = y0; y0 = y1; y1 = temp; } } else if (k < -1) { int temp = x0; x0 = y0; y0 = -temp; temp = x1; x1 = y1; y1 = -temp; if (x0 > x1) { temp = x0; x0 = x1; x1 = temp; temp = y0; y0 = y1; y1 = temp; } } else { if (x0 > x1) { int temp = x0; x0 = x1; x1 = temp; temp = y0; y0 = y1; y1 = temp; } } } //对称作直线时将生成直线逆向还原到所求 inline void set_line_pixel(int x, int y, float k, GLfloat* color) { if (k > 0 && k <= 1) setPixel(x, y, color); if (k > 1) setPixel(y, x, color); if (k >= -1 && k < 0) setPixel(x, -y, color); if (k < -1) setPixel(-y, x, color); } //从八分圆对称做出完整圆 inline void circlePoint(int x, int y, GLfloat* color){ setPixel(x, y, color); setPixel(y, x, color); setPixel(-x, y, color); setPixel(y, -x, color); setPixel(x, -y, color); setPixel(-y, x, color); setPixel(-x, -y, color); setPixel(-y, -x, color); } //设置多边形顶点集合 void polygon_points() { Point A(-290, 150); Point B(-30, 80); Point C(210, 260); Point D(250, -55); Point E(30, -245); Point F(10, -230); polygon_points_set.push_back(A); polygon_points_set.push_back(B); polygon_points_set.push_back(C); polygon_points_set.push_back(D); polygon_points_set.push_back(E); polygon_points_set.push_back(F); } //设置线段端点集合 void line_points() { Point A(-290, 50); Point B(10, -130); Point C(70, 15); Point D(-45, -255); Point E(30, 210); Point F(26, -280); Point G(30, 15); Point H(180, 80); Point I(50, -250); Point J(50, 250); Point K(-250, 50); Point L(250, 50); line_points_set.push_back(A); line_points_set.push_back(B); line_points_set.push_back(C); line_points_set.push_back(D); line_points_set.push_back(E); line_points_set.push_back(F); line_points_set.push_back(G); line_points_set.push_back(H); line_points_set.push_back(I); line_points_set.push_back(J); line_points_set.push_back(K); line_points_set.push_back(L); } //作直线 inline void GL_Line(int x0, int y0, int x1, int y1, GLfloat* color, int width = 1) { glColor4fv(color); glLineWidth(width); glBegin(GL_LINES); glVertex3f(x0, y0, 0.0f); glVertex3f(x1, y1, 0.0f); glEnd(); } //作直线 inline void GL_Line(Point p1, Point p2, GLfloat* color, int width = 1) { glColor4fv(color); glLineWidth(width); glBegin(GL_LINES); glVertex3f(p1.x, p1.y, 0.0f); glVertex3f(p2.x, p2.y, 0.0f); glEnd(); } //设置观察窗口大小 inline void set_ViewWindows(int xmin, int xmax, int ymin, int ymax) { x_min = xmin; x_max = xmax; y_min = ymin; y_max = ymax; GL_Line(x_min, y_min, x_min, y_max, grey_color); GL_Line(x_min, y_min, x_max, y_min, grey_color); GL_Line(x_max, y_min, x_max, y_max, grey_color); GL_Line(x_min, y_max, x_max, y_max, grey_color); }
//Algorithms func //DDA直线算法 void DDALine(int x0, int y0, int x1, int y1, GLfloat* color){ int i; float dx, dy, length, x, y; if (fabs(x1*1.0 - x0) >= fabs(y1*1.0 - y0)) length = fabs(x1*1.0 - x0); else length = fabs(y1*1.0 - y0); dx = (x1 - x0) / length; dy = (y1 - y0) / length; i = 1; x = x0; y = y0; while (i < length){ setPixel(int(x + 0.5), int(y + 0.5), color); x = x + dx; y = y + dy; i++; } } //Bresenham直线算法(全斜率_对称) void Bresenham_Line(int x0, int y0, int x1, int y1, GLfloat* color){ float k = (y1 - y0) * 1.00 / (x1 - x0) * 1.00; translate(x0, y0, x1, y1, k); int dx, dy, e, i, x, y; dx = x1 - x0, dy = y1 - y0, e = 2 * dy - dx; x = x0, y = y0; for (i = 0; i <= dx; i++){ set_line_pixel(x, y, k, color); x++; if (e >= 0){ y++; e = e + 2 * dy - 2 * dx; } else{ e = e + 2 * dy; } } } //中点画椭圆 void MidpointEllipse(int xc, int yc, int a, int b, GLfloat* color){ long aa = a*a, bb = b*b; long twoaa = 2 * aa, twobb = 2 * bb; long x = 0, y = b; long long d; long dx = 0; long dy = twoaa * y; d = long(bb + aa*(-b + 0.25) + 0.5); setPixel(xc + x, yc + y, color); setPixel(xc + x, yc - y, color); setPixel(xc - x, yc + y, color); setPixel(xc - x, yc - y, color); while (dx < dy){ x++; dx += twobb; if (d < 0) d += bb + dx; else{ dy -= twoaa; d += bb + dx - dy; y--; } setPixel(xc + x, yc + y, color); setPixel(xc + x, yc - y, color); setPixel(xc - x, yc + y, color); setPixel(xc - x, yc - y, color); } d =long long( bb*(x + 0.5)*(x + 0.5) + aa*(y - 1)*(y - 1) - aa*bb + 0.5); cout << "X:" << x << endl; cout << "1:" << long long (bb*(x + 0.5)*(x + 0.5)) << endl; cout << "2:" << aa*(y - 1)*(y - 1) << endl; cout << "3:" << aa*bb << endl; cout << "D:" << d << endl; while (y > 0){ y--; dy -= twoaa; if (d > 0) d += aa - dy; else{ x++; dx += twobb; d += aa - dy + dx; } setPixel(xc + x, yc + y, color); setPixel(xc + x, yc - y, color); setPixel(xc - x, yc + y, color); setPixel(xc - x, yc - y, color); } } //中点画圆 void MidPointCircle(int r, GLfloat* color){ int x, y; int e; x = 0; y = r; e = 1 - r; circlePoint(x, y, color); while (x <= y){ x++; if (e < 0){ e += 2 * x + 1; } else{ y--; e += 2 * (x - y) + 1; } circlePoint(x, y, color); } } //中点画抛物线 //mode1:y=a*x^2+bx+c //mode2:x=a*y^2+by+c void MidPointParabola(float a, float b, float c, int mode, GLfloat* color) { int flag = 1; if (a < 0) { a = -a; b = -b; c = -c; flag = -1; } cout << a << endl; float px = -b / (2 * a); float py = (4 * a*c - b*b) / (4 * a); if (a == 0) { setPixel(0.0 + px, 0.0 + py, color); return; } float x = 0, y = 0; float e = 0; if (mode == 1) { setPixel(x + px, y + py, color); setPixel(-x + px, y + py, color); } else { setPixel(y + py, x + px, color); setPixel(y + py, -x + px, color); } while (x <= 1 / (2 * a)) { //area_1 if (e <= 0) { e += -(2 * x + 3) * a + 1; ++y; } else { e += -(2 * x + 3) * a; } if (mode == 1) { if (flag == 1) { setPixel(x + px, y + py, color); setPixel(-x + px, y + py, color); } else { setPixel(x + px, -y - py, color); setPixel(-x + px, -y - py, color); } } else { if (flag == 1) { setPixel(y + py, x + px, color); setPixel(y + py, -x + px, color); } else { setPixel(-y - py, x + px, color); setPixel(-y - py, -x + px, color); } } ++x; } x -= 1;//上句多加1 e = (x + 0.5)*(x + 0.5) * a - y - 1; while (x < 100) {//area_2 if (e <= 0) { e += (2 * x + 2) * a - 1; x++; } else { e -= 1; } if (mode == 1) { if (flag == 1) { setPixel(x + px, y + py, color); setPixel(-x + px, y + py, color); } else { setPixel(x + px, -y - py, color); setPixel(-x + px, -y - py, color); } } else { if (flag == 1) { setPixel(y + py, x + px, color); setPixel(y + py, -x + px, color); } else { setPixel(-y - py, x + px, color); setPixel(-y - py, -x + px, color); } } y++; } } //中点画线 void MidPointLine(int x0, int y0, int x1, int y1, GLfloat* color) { float k = (y1 - y0)*1.00 / (x1 - x0)*1.00; translate(x0, y0, x1, y1, k); int dx = x1 - x0, dy = y1 - y0; float b = (dx*y1 - dy*x1) / dx; float d0 = dx*(y0 + 0.5) - dy*(x0 + 1) - dx*b; int x = x0, y = y0; double d = d0; while (x <= x1) { set_line_pixel(x, y, k, color); x++; if (d >= 0) { d = d - dy; } else { y++; d = d - dy + dx; } } }
//通过顶点集合绘制多边形 void polygon(vector<Point>* set, GLfloat* color, int width = 1) { for (auto pr = set->begin() + 1; pr != set->end(); ++pr) { auto pl = pr - 1; GL_Line(pl->x, pl->y, pr->x, pr->y, color, width); } GL_Line((set->end() - 1)->x, (set->end() - 1)->y, set->begin()->x, set->begin()->y, color, width); } //将线段端点集合绘制成为线段 void lines(vector<Point>* set, GLfloat* color, int width = 1) { for (auto pr = set->begin() + 1; pr <= set->end() - 1; pr += 2) { auto pl = pr - 1; GL_Line(pl->x, pl->y, pr->x, pr->y, color, width); if (pr == set->end() - 1) break; } } //设置点的区域编码 void set_PointLoc(Point* pr) { pr->loc = 0; if (pr->x < x_min) pr->loc |= winLeftBitCode; if (pr->x > x_max) pr->loc |= winRightBitCode; if (pr->y < y_min) pr->loc |= winBottomBitCode; if (pr->y > y_max) pr->loc |= winTopBitCode; } //设置点集合的区域编码 void set_Loc(vector<Point>* set) { for (auto pr = set->begin(); pr < set->end(); ++pr) set_PointLoc(&*pr); } //交换两点坐标 void swapPoints(Point &p1, Point &p2) { Point _temp; _temp = p1; p1 = p2; p2 = _temp; } //判断点是否在窗口内 inline bool insideornot(Point p) { return !(p.loc); } //判断是否两点都在窗口外 inline unsigned char both_out(Point p1, Point p2) { return p1.loc & p2.loc; } //判断是否两点都在窗口内 inline unsigned char both_in(Point p1, Point p2) { return !(p1.loc | p2.loc); } //单条线段裁剪_CouhenSutherland void LineClip_CouhenSutherland(Point p1, Point p2, GLfloat* color, int width = 1) { bool done = false, plot = false; double m = 0; if (p1.x != p2.x) m = (float)(p2.y - p1.y) / (float)(p2.x - p1.x); while (!done) { set_PointLoc(&p1); set_PointLoc(&p2); if (both_in(p1, p2)) { done = true; plot = true; } else if (both_out(p1, p2)) { done = true; } else { if (insideornot(p1)) { swapPoints(p1, p2); } if (p1.loc & winLeftBitCode) { p1.y += (x_min - p1.x)*m; p1.x = x_min; } else if (p1.loc & winRightBitCode) { p1.y += (x_max - p1.x)*m; p1.x = x_max; } else if (p1.loc & winBottomBitCode) { if (p2.x != p1.x) p1.x += (y_min - p1.y) / m; p1.y = y_min; } else if (p1.loc & winTopBitCode) { if (p2.x != p1.x) p1.x += (y_max - p1.y) / m; p1.y = y_max; } } } if (plot) GL_Line(p1.x, p1.y, p2.x, p2.y, color, width); } //线段集合裁剪_CouhenSutherland void LineSetClip_CouhenSutherland(vector<Point>* set, GLfloat* color, int width = 1) { set_Loc(set);//设置线段端点区域码 for (auto pr = set->begin() + 1; pr <= set->end() - 1; pr += 2) { auto pl = pr - 1; LineClip_CouhenSutherland(*pl, *pr, color, width); if (pr == set->end() - 1) break; } } //计算Liang算法中的p值 double calculate_pk(const Point p1, const Point p2, int type) { switch (type) { case 0: return -(p2.x - p1.x); break; case 1: return p2.x - p1.x; break; case 2: return -(p2.y - p1.y); break; case 3: return p2.y - p1.y; break; } } //计算Liang算法中的q值 double calculate_qk(const Point p1, const Point p2, int type) { switch (type) { case 0: return p1.x - x_min; break; case 1: return x_max - p1.x; break; case 2: return p1.y - y_min; break; case 3: return y_max - p1.y; break; } } bool LineClip_test(const double p, const double q, double &u1, double &u2) { double u = q / p; if (p < 0) { if (u > u2) return false; else if (u > u1) { u1 = u; return true; } } else if (p > 0) { if (u < u1) return false; else if (u < u2) { u2 = u; return true; } } else if (q < 0) return false; } //单条线段裁剪_LiangBarsky void LineClip_LiangBarsky(Point p1, Point p2, GLfloat* color, int width = 1) { double u1 = 0, u2 = 1, u = 0;; int dx = p2.x - p1.x; int dy = p2.y - p1.y; vector<double > pk; vector<double > qk; for (int i = 0; i < 4; ++i) { double temp; temp = calculate_pk(p1, p2, i); pk.push_back(temp); temp = calculate_qk(p1, p2, i); qk.push_back(temp); } if (LineClip_test(pk[LEFT], qk[LEFT], u1, u2)) { if (LineClip_test(pk[RIGHT], qk[RIGHT], u1, u2)) { if (LineClip_test(pk[BOTTOM], qk[BOTTOM], u1, u2)) { if (LineClip_test(pk[TOP], qk[TOP], u1, u2)) { if (u2 < 1) { p2.x = p1.x + u2 * dx; p2.y = p1.y + u2 * dy; } if (u1 > 0) { p1.x = p1.x + u1 * dx; p1.y = p1.y + u1 * dy; } GL_Line(p1.x, p1.y, p2.x, p2.y, color, width); } } } } } //线段集合裁剪_LiangBarsky void LineSetClip_LiangBarsky(vector<Point>* set, GLfloat* color, int width = 1) { for (auto pr = set->begin() + 1; pr <= set->end() - 1; pr += 2) { auto pl = pr - 1; LineClip_LiangBarsky(*pl, *pr, color, width); if (pr == set->end() - 1) break; } } //判断点是否在边界内 bool isPointinsideEdge(Point p, const int mode) { set_PointLoc(&p); switch (mode) { case LEFT: if ((p.loc & winLeftBitCode) == winLeftBitCode) return false; else return true; case RIGHT: if ((p.loc & winRightBitCode) == winRightBitCode) return false; else return true; case BOTTOM: if ((p.loc & winBottomBitCode) == winBottomBitCode) return false; else return true; case TOP: if ((p.loc & winTopBitCode) == winTopBitCode) return false; else return true; } } //判断线段是否与边界相交 bool isLinecrossEdge(Point p1, Point p2, const int mode) { if (isPointinsideEdge(p1, mode) == isPointinsideEdge(p2, mode)) return false; return true; } //计算线段与边界直线的交点 Point intersect(Point p1, Point p2, const int mode) { /*if (p1.x == p2.x) exit(0);*/ Point result; switch (mode) { case LEFT: result.x = x_min; result.y = p1.y + (x_min - p1.x) * (p2.y - p1.y) / (p2.x - p1.x); return result; break; case RIGHT: result.x = x_max; result.y = p1.y + (x_max - p1.x) * (p2.y - p1.y) / (p2.x - p1.x); return result; break; case BOTTOM: result.y = y_min; result.x = p1.x + (y_min - p1.y) / ((double)(p2.y - p1.y) / (double)(p2.x - p1.x)); return result; break; case TOP: result.y = y_max; result.x = p1.x + (y_max - p1.y) / ((double)(p2.y - p1.y) / (double)(p2.x - p1.x)); return result; break; } } //水平垂直情况下的线段顶点的添加 void parallelClip(Point p1, Point p2, vector<Point >* set, const int mode) { if (p1.x == p2.x) {//垂直 switch (mode) { case LEFT: if (p1.x >= x_min)//II2 set->push_back(p2); break; case RIGHT: if (p1.x <= x_max)//II2 set->push_back(p2); break; case BOTTOM: if ((p1.y >= y_min) && (p2.y >= y_min))//II2 set->push_back(p2); else if ((p1.y >= y_min) && (p2.y < y_min)) {//IOX Point temp(p1.x, y_min); set->push_back(temp); } else if ((p1.y < y_min) && (p2.y >= y_min)) {//OIX2 Point temp(p1.x, y_min); set->push_back(temp); set->push_back(p2); } break; case TOP: if ((p1.y <= y_max) && (p2.y <= y_max))//II2 set->push_back(p2); else if ((p1.y > y_max) && (p2.y <= y_max)) {//OIX2 Point temp(p1.x, y_max); set->push_back(temp); set->push_back(p2); } else if ((p1.y <= y_max) && (p2.y > y_max)) {//IOX Point temp(p1.x, y_max); set->push_back(temp); } break; } return; } else if (p1.y == p2.y) {//水平 switch (mode) { case LEFT: if ((p1.x >= x_min) && (p2.x >= x_min))//II2 set->push_back(p2); else if ((p1.x < x_min) && (p2.x >= x_min)) {//OIX2 Point temp(x_min, p1.y); set->push_back(temp); set->push_back(p2); } else if ((p1.x >= x_min) && (p2.x < x_min)) {//IOX set->push_back(p1); Point temp(x_min, p1.y); set->push_back(temp); } break; case RIGHT: if ((p1.x <= x_max) && (p2.x <= x_max))//II2 set->push_back(p2); else if ((p1.x <= x_max) && (p2.x > x_max)) {//IOX set->push_back(p1); Point temp(x_max, p1.y); set->push_back(temp); } else if ((p1.x > x_max) && (p2.x <= x_max)) {//OIx2 Point temp(x_max, p1.y); set->push_back(temp); set->push_back(p2); } break; case BOTTOM: if (p1.y >= y_min)//II2 set->push_back(p2); break; case TOP: if (p1.y <= y_max)//II2 set->push_back(p2); break; } return; } } //各种方向下多边形裁剪 void PolygonEdgeClip(vector<Point>* set, vector<Point>* newset, const int mode) { for (auto pl = set->begin(); pl != set->end(); ++pl) { if (pl == (set->end() - 1)) break; auto pr = pl + 1; if (isPointinsideEdge(*pl, mode)) { if (isPointinsideEdge(*pr, mode)) {//II2 newset->push_back(*pr); } else {//IOX newset->push_back(intersect(*pl, *pr, mode));// } } else if (!isPointinsideEdge(*pl, mode)) { if (isPointinsideEdge(*pr, mode)) {//OIX2 newset->push_back(intersect(*pl, *pr, mode)); newset->push_back(*pr); } } } if (((set->end() - 1)->x == (set->begin())->x) || ((set->end() - 1)->y == (set->begin())->y)) parallelClip(*(set->end() - 1), *(set->begin()), newset, mode); else if (isPointinsideEdge(*(set->end() - 1), mode)) { if (isPointinsideEdge(*(set->begin()), mode)) {//II2 newset->push_back(*(set->begin())); } else if (!isPointinsideEdge(*(set->begin()), mode)) {//IOX newset->push_back(intersect(*(set->end() - 1), *(set->begin()), mode));// } } else if (!isPointinsideEdge(*(set->end() - 1), mode)) { if (isPointinsideEdge(*(set->begin()), mode)) {//OIX2 newset->push_back(intersect(*(set->end() - 1), *(set->begin()), mode)); newset->push_back(*(set->begin())); } } } //多边形裁剪 void PolygonClip(vector<Point>* set, GLfloat* color, int width = 1) { vector<Point > set_L, set_R, set_B, set_result; PolygonEdgeClip(set, &set_L, LEFT);//四个方向上各裁剪一次 PolygonEdgeClip(&set_L, &set_R, RIGHT); PolygonEdgeClip(&set_R, &set_B, BOTTOM); PolygonEdgeClip(&set_B, &set_result, TOP); polygon(&set_result, color, 3); }
//Frame func void display(){ glClear(GL_COLOR_BUFFER_BIT); DDALine(0,-L_h,0,L_h,black_color);//坐标轴 DDALine(-L_w, 0, L_w, 0, black_color); /*----各种图形生成算法.start:----*/ MidPointParabola(1.0000 / 50,1,2,1,blue_color); //中点画抛物线 Bresenham_Line(180, -150, -350, 470, red_color);//全斜率直线 MidPointCircle(175, green_color);//中点画圆 MidpointEllipse(0, 0, 250, 140, black_color);//中点画椭圆 MidPointLine(-110, 150, 350, 270, red_color);//中点画线 /*----各种图形生成算法.end!----*/ /*----线段裁剪.start:----*/ line_points();//设置线段点集合 lines(&line_points_set, green_color, 3);//画线 set_ViewWindows(-200, 200, -200, 200);//设置窗口 LineSetClip_CouhenSutherland(&line_points_set, red_color, 3);//Couhen_Sutherland线段裁剪 LineSetClip_LiangBarsky(&line_points_set, red_color, 3);//LiangBarsky线段裁剪 /*----线段裁剪.end!----*/ /*----多边形裁剪.start:----*/ polygon_points();//设置多边形顶点 polygon(&polygon_points_set, green_color, 3);//绘制原始多边形 set_ViewWindows(-200, 200, -200, 200);//设置窗口 PolygonClip(&polygon_points_set, red_color, 3);//多边形裁剪 /*----多边形裁剪.end!----*/ glFlush(); } //Display Init void init(void){ glClearColor(1.0, 1.0, 1.0, 0.0);//设置清屏颜色 glMatrixMode(GL_PROJECTION);//设置投影矩阵 glLoadIdentity();//单位化上述投影矩阵 gluOrtho2D(-L_w*1.0, L_w*1.0, -L_h*1.0, L_h*1.0);//设置具体投影矩阵为平面正交投影4/3 } void main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); glutInitWindowPosition(50, 50); glutInitWindowSize(L_w*2, L_h*2); glutCreateWindow("Graphic Display"); init(); glutDisplayFunc(&display); glutMainLoop(); }
时间: 2024-10-19 21:21:44