1. 程式人生 > >計算機圖形學2——Line Style and Line Width

計算機圖形學2——Line Style and Line Width

計算機圖形學實驗:
通過控制’q’改變線形
通過控制’w’改變線寬

完整程式碼如下:

// ====== Computer Graphics Experiment #4 ======
// |      Line style using pixel mask          |
// |         and line width                    |
// =============================================
//
// Requirement:
// (1) Implement a general Bresenham's Line Drawing Algorithm.
// (2) Implement solid, dashed, dotted and dot-dashed line styles // using pixel mask. // (3) Implement keyboard function so that the user can switch // line style by pressing a key. // Only use GL_POINTS drawing mode. // Do not use OpenGL line drawing capability. // Use bit shift statement in C: "<<" or ">>"
// to implement pixel mask . #include <windows.h> #include <GL/glut.h> #include <math.h> #define PI 3.14159265359 int width, height; int line_style=0,line_width=1; unsigned int pixel_mask[4]={0xffff,0xeeee,0xaaaa,0xebae}; int bit_mask=0x8000; void line_style_width(int x,int y) { int pmask=
pixel_mask[line_style]; if(pmask&bit_mask) { for(int i=0;i<line_width;i++)//控制線寬 { glVertex2i(x+i, y); glVertex2i(x-i, y); } } bit_mask=bit_mask>>1; if(bit_mask==0) bit_mask=0x8000; } // Bresenham line algorithm with line style and line width void MyLine(int xs, int ys, int xe, int ye) { int dx,dy,x,y,p,i; dx=xe-xs; dy=ye-ys; x=xs,y=ys; if(dx==0) { if(dy>0) { glBegin(GL_POINTS); for (i = 0; y < ye; ++i) { line_style_width(x,y); y++; } glEnd(); } else { glBegin(GL_POINTS); for (i = 0; y > ye; ++i) { line_style_width(x,y); y--; } glEnd(); } } else if(dy==0) { if(dx>0) { glBegin(GL_POINTS); for (i = 0; x < xe; ++i) { line_style_width(x,y); x++; } glEnd(); } else { glBegin(GL_POINTS); for (i = 0; x > xe; ++i) { line_style_width(x,y); x--; } glEnd(); } } else if (dx > 0 && dy > 0)//1 { if (dx > dy) { p = 2 * dy - dx; glBegin(GL_POINTS); for (i = 0; i < dx; ++i) { line_style_width(x,y); ++x; if (p < 0) { p += 2 * dy; } else { ++y; p += 2 * dy - 2 * dx; } } glEnd(); } else { p = 2 * dx - dy; glBegin(GL_POINTS); for (i = 0; i < dy; ++i) { line_style_width(x,y); ++y; if (p < 0) { p += 2 * dx; } else { ++x; p += 2 * dx - 2 * dy; } } glEnd(); } } else if (dx < 0 && dy < 0)//3 { if (dx < dy) //-1 >-2 { // dx = -dx; dy = -dy; dx = dx; dy = dy; p = 2 * dy - dx; glBegin(GL_POINTS); for (i = 0; i < -dx; ++i) { line_style_width(x,y); --x; if (p > 0) { p += 2 * dy; } else { --y; p += 2 * dy - 2 * dx; } } glEnd(); } else { // dy=-dy; p = 2 * dx - dy; glBegin(GL_POINTS); for (i = 0; i < -dy; ++i) { line_style_width(x,y); --y; if (p > 0) { p += 2 * dx; } else { --x; p += 2 * dx - 2 * dy; } } glEnd(); } } else if (dx > 0 && dy < 0)//4 { if (abs(dy) < dx) { dx = dx; dy = -dy; p = 2 * dy - dx; glBegin(GL_POINTS); for (i = 0; i < dx; ++i) { line_style_width(x,y); ++x; if (p < 0) { p += 2 * dy; } else { --y; p += 2 * dy - 2 * dx; } } glEnd(); } else { dx = dx; dy = -dy; p = 2 * dx - dy; glBegin(GL_POINTS); for (i = 0; i < dy; ++i) { line_style_width(x,y); --y; if (p < 0) { p += 2 * dx; } else { ++x; p += 2 * dx - 2 * dy; } } glEnd(); } } else if (dx < 0 && dy > 0)//2 { if (dy < abs(dx)) { dx = -dx; dy = dy; p = 2 * dy - dx; glBegin(GL_POINTS); for (i = 0; i < dx; ++i) { line_style_width(x,y); --x; if (p < 0) { p += 2 * dy; } else { ++y; p += 2 * dy - 2 * dx; } } glEnd(); } else { dx = -dx; dy = dy; p = 2 * dx - dy; glBegin(GL_POINTS); for (i = 0; i < dy; ++i) { line_style_width(x,y); ++y; if (p > 0) { p -= 2 * dx; } else { --x; p -= 2 * dx - 2 * dy; } } glEnd(); } } } // Initialization function void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); } // Display callback function void display(void) { int i, x0, y0, x, y; double a; glClear (GL_COLOR_BUFFER_BIT); x0=width/2; y0=height/2; glColor3f(1.0, 1.0, 1.0); // Draw lines for (i=0; i<360; i+=15) { a=(double)i/180.0*PI; x=0.45*width*cos(a); y=0.45*height*sin(a); if (i==0 || i==180) y=0; if (i==90 || i==270) x=0; MyLine(x0, y0, x0+x, y0+y); } glFlush(); } // Reshape callback function void reshape(int w, int h) { // Record width and height of program window width=w; height=h; // Set clipping window and viewport equal to // view area of program window glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D (0.0, w, 0.0, h); } // Keyboard callback function void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); case 'q': ++line_style; if(line_style>3) line_style=0; glutPostRedisplay(); break; case 'w': ++line_width; if(line_width>10) line_width=1; glutPostRedisplay(); break; // Write your code for line style switching and line width switching } } // Main program entrance int main(int argc, char* argv[]) { // Create window glutInit(&argc, argv); glutInitDisplayMode (GLUT_RGB); glutInitWindowSize(500, 500); glutCreateWindow("Lines"); // Initialization init(); // Define callback functions glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutDisplayFunc(display); // Main program loop. (Event loop) glutMainLoop(); return 0; }