There is a problem on the last bresenham function when the line is more vertical than horizontal
Here a corrected version where you can too :
- dynamically resize the window,
- change the color with the keyboard (r=red g=green b=blue w=white)
- change the point size (+ or -)
- quit using the ESC key
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <GL/glut.h> // GLUT, include glu.h and gl.h
int width = 320;
int height= 200;
int pointSize = 1;
float red = 1.0f;
float green = 1.0f;
float blue = 1.0f;
/* Draw a line between (x0,y0) and (x1, y1) using the Bresenham algorithm */
void bresenham(int x0, int y0,int x1, int y1){
int i, length;
int y = y0;
int x = x0;
int deltax = x1 - x0;
int deltay = y1 - y0;
float error = 0.0;
float deltaerror;
int incy = (deltay > 0 ? 1 : -1);
int incx = (deltax > 0 ? 1 : -1);
glBegin(GL_POINTS);
if ( abs(deltax) >= abs(deltay) )
{
length = abs(deltax);
deltaerror = fabs((float)(deltay)/(float)(deltax));
for( i = 0; i <= length; i++, x+= incx)
{
glVertex3f(x, y, 0);
// printf("point(%d,%d)
", x , y);
error += deltaerror;
if (error >= 0.5)
{
y += incy;
error -= 1.0f;
}
}
}
else
{
length = abs(deltay);
deltaerror = fabs((float)(deltax)/(float)(deltay));
for( i = 0; i <= length ; i++, y += incy)
{
glVertex3f(x, y, 0);
// printf("point(%d,%d)
", x , y);
error = error + deltaerror;
if (error >= 0.5)
{
x += incx;
error -= 1.0f;
}
}
}
glEnd();
}
/* Handler for window-repaint event. Call back when the window first appears and whenever the window needs to be re-painted. */
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClear(GL_COLOR_BUFFER_BIT); // Clear the color buffer (background)
bresenham(0,0, width,height);
bresenham(0,height, width, 0);
bresenham(width/2,0, width/2,height);
bresenham(0,height/2, width, height/2);
glFlush(); // Render now
glutSwapBuffers();
}
/* Handler for window event resize */
void reshape(GLsizei newwidth, GLsizei newheight)
{
width = newwidth;
height = newheight;
// printf("Reshape(%d,%d)
", width, height);
glViewport(0, 0, width, height);
glLoadIdentity();
gluOrtho2D(0, width, 0, height);
glutPostRedisplay();
}
/* Handler for keyboard events */
void keyboard(unsigned char key, int x, int y )
{
switch(key)
{
case '+' : pointSize++; break;
case '-' : if( pointSize > 0) pointSize--; break;
case 'r': red=1.0f; green=blue=0.0f; break;
case 'g': green=1.0f; red=blue=0.0f; break;
case 'b': blue=1.0f; red=green=0.0f; break;
case 'w' : red=green=blue=1.0f; break;
case 27 : exit(0); break;
break;
}
glPointSize(pointSize);
glColor3f(red, green, blue);
glutPostRedisplay();
}
/* Main function: GLUT runs as a console application starting at main() */
int main(int argc, char** argv)
{
glutInit(&argc, argv); // Initialize GLUT
glutCreateWindow("OpenGL Setup Test"); // Create a window with the given title
glutInitWindowSize(width, height); // Set the window's initial width & height
gluOrtho2D(0, width, 0, height); // Init screen coordinates use in the display func
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutKeyboardFunc(keyboard); // Register keyboard handler for keyboard actions
glutReshapeFunc(reshape); // register resize callback handler for window resize
glutDisplayFunc(display); // Register display callback handler for window re-paint
glutMainLoop(); // Enter the event-processing loop
return 0;
}
Note, that you can make the glBegin(GL_POINTS)/glEnd() calls outside the bresenham() function if you want
(only call glBegin(GL_POINTS) before and glEnd() after the bloc of 4x bresenham()'s calls in the display() function)
Cf. minimize the use of glBegin()/glEnd() calls because they can to spend more time to execute than alls glVertex() calls used between them when you have only a small number of vertices to draw …
(but in this precise case, I don’t think that this can really make a big difference because lines traced here by the bresenham() function are relatively longs, so we don’t have a relatively small number of points to display for each line as we don’t use a too small window size )