user5613947
user5613947

Reputation:

Consistent Freehand line in OpenGL

I know how to draw freehand in opengl, but I'd like it to not have gaps if you move the mouse too fast. This is what I have:

void myMovedMouse(int mouseX, int mouseY)
{
    int x = mouseX;
    int y = IMAGE_Y - mouseY - 1;
    //int brushSize = 20;
    //glRecti(x, y, x + brushSize, y + brushSize);
    drawDot(x, y);
    glFlush();
}

//in main
glutDisplayFunc(myDisplay);
glutMotionFunc(myMovedMouse);

I also tried to use GL_LINE_LOOP, but of course that didn't work.

Upvotes: 3

Views: 996

Answers (2)

Mario Dekena
Mario Dekena

Reputation: 843

Save your mouse position from last update in a global variable. Then connect to your new location using a line. Something like this:

int lastMouseX, lastMouseY;

void myMovedMouse(int mouseX, int mouseY)
{
    int x = mouseX;
    int y = IMAGE_Y - mouseY - 1;

    glBegin(GL_LINES);
    glVertex2i(lastMouseX, lastMouseY);
    glVertex2i(x, y);
    glEnd();
    glFlush();

    lastMouseX = x;
    lastMouseY = y;
}

If you are using a mouse button for drawing, only update your last position when your button is pressed down. Also initialize the last position to the mouse position, when the button is pressed again. The initialization is needed, so your first stroke does not start form the origin (0,0) and further strokes wont connect to the previous ones.

Upvotes: 2

genpfault
genpfault

Reputation: 52083

Append mouse positions to a std::vector & use GL_LINE_STRIP:

#include <GL/glut.h>
#include <vector>

std::vector< int > points;
void mouse( int button, int state, int x, int y )
{
    if( state == GLUT_DOWN )
        points.clear();
    points.push_back( x );
    points.push_back( y );
    glutPostRedisplay();
}

void motion( int x, int y )
{
    points.push_back( x );
    points.push_back( y );
    glutPostRedisplay();
}

void display()
{
    glClearColor( 0, 0, 0, 1 );
    glClear(GL_COLOR_BUFFER_BIT);

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    glOrtho( 0, w, h, 0, -1, 1 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glBegin( GL_LINE_STRIP );
    glColor3ub( 255, 0, 0 );
    for( size_t i = 0; i < points.size(); i += 2 )
    {
        glVertex2i( points[i+0], points[i+1] );
    }
    glEnd();

    glutSwapBuffers();
}

int main( int argc, char** argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
    glutCreateWindow( "GLUT" );
    glutMouseFunc( mouse );
    glutMotionFunc( motion );
    glutDisplayFunc( display );
    glutMainLoop();
    return 0;
}

Upvotes: 2

Related Questions