Thread: Plotting Points inside a function

1. 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

2. 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)

3. 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);
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 )

Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•