#include #include #include #include #include #include using namespace std; const int NumVAOs = 1; const int NumBuffers = 1; GLuint VAOs[NumVAOs]; GLuint Buffers[NumBuffers]; GLint ProjectionLoc; vector vertices; GLuint PointCount; ShaderInfo shaders[] = { { GL_VERTEX_SHADER, "vertex.glsl" }, { GL_FRAGMENT_SHADER, "fragment.glsl"}, { GL_NONE, NULL} }; void DoErrorReport(string header ) { GLenum err = GL_NO_ERROR; bool firstPass = true; while ((err = glGetError()) != GL_NO_ERROR) { if(firstPass) { cout << header << endl; firstPass = false; } cout << "Got error " << err << ": " ; cout << gluErrorString(err) << endl; } } void BrokenBennettLine(float x1, float x2, float y1, float y2) { float x,y; vec3 point; float m = (y1-y2)/(x1-x2); float b = y1-m*x1; PointCount = 0; point.y = y1; for(point.x=x1; point.x<= x2; point.x+=1) { point.y = m * point.x + b; vertices.push_back(point); PointCount++; } return; } void DDA (float x1, float x2, float y1, float y2) { float dy = y2-y1; float dx = x2-x1; vec3 point; float change; if (fabs(dy) > fabs(dx) ) { // y is the axis of major change; change = dx/dy; point.x = x1; for (point.y=y1; point.y <= y2; point.y+= 1) { point.x+= change; vertices.push_back(point); PointCount++; } } else { change = dy/dx; point.y = y1; for(point.x=x1;point.x<=x2; point.x++) { point.y+= change; vertices.push_back(point); PointCount++; } } return; } void Bressenhams(int x1, int y1, int x2, int y2) { int x,y; int dx, dy, diff1, diff2, D; vec3 point; dx = x2-x1; dy = y2-y1; if (dy /float(dx) <= 1 and dy/float(dx) >= 0){ diff1 = -2*dy; diff2 = 2*dx + diff1; D = dx + diff1; y = y1; for(x=x1; x<= x2; x++) { point.x = x; point.y = y; vertices.push_back(point); PointCount++; if (D > 0) { D += diff1; } else { y++; D+= diff2; } } } return; } void setup(int lineAlgorithm, float x1, float x2, float y1, float y2) { GLuint program; switch (lineAlgorithm) { case 2: cout << "Bressenham's " << endl; Bressenhams(x1, y1, x2, y2); break; case 1: cout << "DDA" << endl; DDA(x1, x2, y1, y2); break; case 0: default: cout << "y=mx+b" << endl; BrokenBennettLine(x1, x2, y1, y2); } glClearColor(1.0, 1.0, 1.0, 1.0); program = LoadShaders(shaders); glUseProgram(program); ProjectionLoc = glGetUniformLocation(program, "Projection"); glGenVertexArrays(NumVAOs, VAOs); glBindVertexArray(VAOs[0]); glGenBuffers(NumBuffers, Buffers); glBindBuffer(GL_ARRAY_BUFFER, Buffers[0]); glBufferData(GL_ARRAY_BUFFER, PointCount * sizeof(vec3), vertices.data(), GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); glEnableVertexAttribArray(0); DoErrorReport("End of Setup"); return; } void display(){ glClear(GL_COLOR_BUFFER_BIT); glBindVertexArray(VAOs[0]); glDrawArrays(GL_POINTS, 0, PointCount); glFlush(); DoErrorReport("End of Display"); return; } void resize(int w, int h) { mat4 projection; float width = ceilf(w/100.0); float height = ceilf(h/100.0); if (width > height) { glPointSize(height); glViewport(0, 0, h, h); } else { glPointSize(width); glViewport(0, 0, w, w); } projection = Ortho(0, 100, 0, 100, -10, 10); glUniformMatrix4fv(ProjectionLoc, 1, GL_TRUE, projection); return; } void GetLineParams(float & x1, float & x2, float & y1, float & y2) { cout << "Enter X start => "; cin >> x1; cout << "Enter Y start => "; cin >> y1; cout << "Enter X end => "; cin >> x2 ; cout << "Enter Y end => "; cin >> y2 ; cout << endl; return; } void keypress(unsigned char key, int x, int y) { switch(key) { case 'q': exit(0); } glutPostRedisplay(); return; } void Usage() { int width = 30; cout << setfill('.'); cout << "q" << setw(width) << "Quit" << endl; cout << endl; cout << setfill(' '); return; } int main(int argc, char * argv[]) { float x1 = 0; float x2 = 100.0; float y1 = 0; float y2 = 100; int lineAlgorithm = 0; Usage(); if (argc > 1) { lineAlgorithm = atoi(argv[1]); } GetLineParams(x1, x2, y1, y2); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutInitWindowSize(512, 512); glutInitContextVersion(3,0); glutInitContextProfile(GLUT_CORE_PROFILE); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutKeyboardFunc(keypress); glutReshapeFunc(resize); glewExperimental = GL_TRUE; if (glewInit()) { cerr << "Unable to initialize glew, exiting " << endl; exit (-1); } setup(lineAlgorithm, x1, x2, y1, y2); glutMainLoop(); return 0; }