Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Consistent Freehand line in OpenGL

Tags:

c++

opengl

glut

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.


2 Answers

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;
}
like image 129
genpfault Avatar answered Jan 21 '26 19:01

genpfault


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.

like image 33
Mario Dekena Avatar answered Jan 21 '26 19:01

Mario Dekena



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!