# Plotting Points inside a function

• 05-01-2013, 12:40 PM
damian89
Plotting Points inside a function
Hi,

I am doing my first steps with openGL. For a university course I have to implement the Bresenham algorithm, which fills in the appropriate pixels between two points to draw a line. In my example code I cannot see the points the function bresenham() should be drawing. Can anyone help me here?

Code :

```#include <stdio.h> #include <stdlib.h> #include <string.h>   #include <GL/glut.h> // GLUT, include glu.h and gl.h   /* Handler for window-repaint event. Call back when the window first appears and whenever the window needs to be re-painted. */   void bresenham(int x0, int y0,int x1, int y1){ int deltax = x1 - x0; int deltay = y1 - y0; double error = 0; double deltaerror = abs(deltay/deltax); int y = y0; for(int i = 0; i < deltax; i++){ // POINT CREATION IN FOR-LOOP ALLOWED ? glBegin(GL_POINTS); // HERE THE POINTS SHOULD BE CREATED glPointSize(8); glColor3f(1.0f, 0.0f, 0.0f); // Red glVertex3f(x0+i,y,0); glEnd(); error = error + deltaerror; if (error >= 0.5){ y = y+1; error = error - 1; } } }   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(100,100,200,140); // HERE THE BRESENHAM FCN IS CALLED   glFlush(); // Render now }   /* 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(320, 320); // Set the window's initial width & height glutInitWindowPosition(50, 50); // Position the window's initial top-left corner glutDisplayFunc(display); // Register display callback handler for window re-paint glutMainLoop(); // Enter the event-processing loop return 0; }```

I think I messed with the order of functions. Thank you very much!

Damian
• 05-01-2013, 02:14 PM
The Little Body
You have forget a glutSwapBuffers() call at the end your display

And your bresenham implementation have a problem because you use int values instead floats in your division of deltay by deltax at this line
Code :

`double deltaerror = abs(deltay/deltax);`

has to be corrected by

Code :

`double deltaerror = (double)fabs((float)(deltay)/(float)(deltax));`

I have too added one gluOrtho2D(0, 320, 0, 200) call at the begin of the display func for that OpenGL know that vertices values are screen coordinates and not object's coordinates (cf. generally between -1.0f and +1.0f)

Here is your source corrected :
Code :

``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h>   #include <GL/glut.h> // GLUT, include glu.h and gl.h   /* Handler for window-repaint event. Call back when the window first appears and whenever the window needs to be re-painted. */   void bresenham(int x0, int y0,int x1, int y1){   int deltax = x1 - x0; int deltay = y1 - y0;   double error = 0.0; double deltaerror = (double)fabs((float)(deltay)/(float)(deltax));   int y = y0; int i;   int dy = (deltay > 0 ? 1 : -1);   if ( deltax > 0 ) { for( i = 0; i < deltax; i++){ // POINT CREATION IN FOR-LOOP ALLOWED ?   glBegin(GL_POINTS); // HERE THE POINTS SHOULD BE CREATED glPointSize(8); glColor3f(1.0f, 0.0f, 0.0f); // Red glVertex3f(x0 + i, y, 0); printf("(%d,%d) \n", x0+i , y); glEnd();   error += deltaerror; if (error >= 0.5){ y += dy; error -= 1.0f; } } } else { for( i = deltax; i < 0 ; i++){ // POINT CREATION IN FOR-LOOP ALLOWED ?   glBegin(GL_POINTS); // HERE THE POINTS SHOULD BE CREATED glPointSize(8); glColor3f(1.0f, 0.0f, 0.0f); // Red glVertex3f(x0 + i, y, 0); printf("(%d,%d) \n", x0+i , y); glEnd();   error = error + deltaerror; if (error >= 0.5){ y += dy; error -= 1.0f; } } } }   void display() {   gluOrtho2D(0, 320, 0, 200);   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, 320,200); // HERE THE BRESENHAM FCN IS CALLED   glFlush(); // Render now glutSwapBuffers();   }   /* 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(320, 320); // Set the window's initial width & height glutInitWindowPosition(50, 50); // Position the window's initial top-left corner glutDisplayFunc(display); // Register display callback handler for window re-paint glutMainLoop(); // Enter the event-processing loop return 0; }```

Note that it print computed coordinates at the terminal output for that you can see generated coordinates
=> comment the two fprintf lines into the bresenham func if you don't want them

PS : you can too use only one glBegin() call at the begining and one glEnd() at the end in the bresenham function instead to make this for each computed point
(and only one call to glPointSize() and glColor3f() at the beginning since point sizes and colors are always the sames)
• 05-01-2013, 03:31 PM
The Little Body
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

Code :

```#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) \n", 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) \n", 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) \n", 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 :) )