Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Plotting Points inside a function

  1. #1
    Newbie Newbie
    Join Date
    May 2013
    Posts
    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. #2
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    250
    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)
    Last edited by The Little Body; 05-01-2013 at 02:52 PM.
    @+
    Yannoo

  3. #3
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    250
    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 )
    Last edited by The Little Body; 05-01-2013 at 05:46 PM.
    @+
    Yannoo

Posting Permissions

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