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 9 of 9

Thread: Creating a square where I am able to drag one corner

  1. #1
    Junior Member Newbie
    Join Date
    Feb 2015
    Posts
    4

    Creating a square where I am able to drag one corner

    Hi there,

    I am a total beginner to coding.

    Is there any existing Open GL Glut code which allows One corner of the square to move when you click and drag the mouse around
    inside the window. The corner should follow the mouse pointer

  2. #2
    Member Regular Contributor Agent D's Avatar
    Join Date
    Sep 2011
    Location
    Innsbruck, Austria
    Posts
    281
    Handling mouse clicks, etc. is not part of OpenGL(R). The OpenGL(R) specification onyl specifies an abstract API for rasterization based rendering.

    Managing a window and handling mouse clicks has to be done over platform dependend functions. In your case, that should be abstracted away by
    the GLUT library.

    What you would do is simply registering a GLUT callback that receives mouse events (Please refere to the GLUT documentation for that). If you have
    the click position in window coordinates, and the rectangle vertices in window coordinates (or you could convert the click window coordinates to the
    coordinate space the rect is in), you can determine a distance of the click position to the vertices and if that distance is below a certain threshold, you
    assume a vertex has been clicked. Once a vertex has been clicked, apply a scaled relative movement of the mouse cursor to the selected vertex.

  3. #3
    Junior Member Newbie
    Join Date
    Feb 2015
    Posts
    4
    Hi, I am still trying things out, but can't really figure out that much. This is what i got below

    #include <GL/glut.h>

    void init()
    {
    glClearColor (0.0, 0.0, 0.0, 1.0);
    glColor3f(0.0, 1.0, 1.0);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
    }


    void mydisplay()
    {
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POLYGON);
    glVertex2f(-0.5, -0.5);
    glVertex2f(-0.5, 0.5);
    glVertex2f(0.5, 0.5);
    glVertex2f(0.5, -0.5);
    glEnd();
    glFlush();
    }

    void OnMouseClick(int button, int state, int x, int y)
    {
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
    void glscalef(GLfloat x, GLfloat y, GLfloat z);
    }
    }

    static void
    key(unsigned char key, int x, int y)
    {
    switch (key)
    case 27:
    exit(0);
    }

    int main(int argc, char** argv)
    {
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(0,0);
    glutCreateWindow("simple");
    glutDisplayFunc(mydisplay);
    glutKeyboardFunc(key);
    init();
    glutMainLoop();
    }

  4. #4
    Member Regular Contributor Agent D's Avatar
    Join Date
    Sep 2011
    Location
    Innsbruck, Austria
    Posts
    281
    First of all, that code shouldn't even compile. You have a function declaration inside your OnMouseClick function.

    Second, what was that code intended to do? Scale the polygon when the mouse button is pressed?

    The solution I suggested above would store the vertices of the polygon in variables. When the mouse button is pressed, your OnMouseClick function
    would determine the closest vertex to the mouse cursor is flagged as being draged. When the mouse button is released, all drag flags are cleared.

    In an additional mouse movement callback would add the scaled mouse movement (difference between current and previous mouse position) to the
    vertex that is flagged as being draged.

  5. #5
    Junior Member Newbie
    Join Date
    Feb 2015
    Posts
    4
    Yea I intended for the on mouseclick to scale the square when the edges are dragged with a mouse click.

    Could you guide me a little on what variable I should use to store vertices and do the drag? I understand what you are saying with regards to how it should work, but I am just not sure what I should use even with the documentation. Thanks for the feedback thus far

  6. #6
    Member Regular Contributor Agent D's Avatar
    Join Date
    Sep 2011
    Location
    Innsbruck, Austria
    Posts
    281
    That doesn't make sense. Scaling means multiplying it by some factor. That is something completely different than moving one corner.

    What I had in mind was something like this:
    Code C:
    struct
    {
        float x;
        float y;
    }
    vertices[4];
     
    int dragging = -1;
    ....
     
    void mydisplay()
    {
        unsigned int i;
     
        glClear(GL_COLOR_BUFFER_BIT);
        glBegin(GL_POLYGON);
        for( i=0; i<sizeof(vertices)/sizeof(vertices[0]); ++i )
            glVertex2f(vertices[i].x, vertices[i].y);
        glEnd();
        glFlush();
    }
     
    ....
     
    void OnMouseClick(int button, int state, int x, int y)
    {
        unsigned int i;
     
        if( button != GLUT_LEFT_BUTTON )
             return;
     
        dragging = -1;
     
        if( state == GLUT_DOWN)
        {
            for( i=0; i<sizeof(vertices)/sizeof(vertices[0]); ++i )
            {
                dist = distance( vertices[i], x, y );
                    if( dist < threshold )
                    {
                        dragging = i;
                        break;
                    }
            }
        }
    }
    ....
    void OnMouseMove( int x, int y )
    {
        static int prev_x=0, prev_y=0;
     
        if( dragging >= 0)
        {
              dx = scale_somewhat_x( x - prev_x );
              dy = scale_somewhat_y( y - prev_y );
     
              vertices[dragging].x += dx;
              vertices[dragging].y += dy;
        }
     
        prev_x = x;
        prev_y = y;
    }

  7. #7
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    281
    Here is a simple version that move only the first corner with the initial position (-0.5f, -0.5f)

    Code :
    #include <stdio.h>
    #include <GL/glut.h>
     
    GLuint width = 500;
    GLuint height = 500;
     
    GLfloat xcorner = -0.5f;
    GLfloat ycorner = -0.5f;
     
    int bMoving = 0;
     
    void Screen2GLpos(int x, int y, GLfloat *xpos, GLfloat *ypos)
    {
        *xpos = ((GLfloat)(x) - (GLfloat)(width/2)) / (GLfloat)(width/2);
        *ypos = ((GLfloat)(-y) + (GLfloat)(height/2)) / (GLfloat)(height/2);
        printf("Transform Screen position (%d,%d) to OpenGL position  (%.3f,%.3f) \n", x, y, *xpos, *ypos);
    }
     
    void OnInit()
    {
        glClearColor (0.0, 0.0, 0.0, 1.0);
        glColor3f(0.0, 1.0, 1.0);
        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
        glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
    }
     
     
    void OnDisplay()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glBegin(GL_POLYGON);
            glVertex2f(xcorner, ycorner);
            glVertex2f(-0.5, 0.5);
            glVertex2f(0.5, 0.5);
            glVertex2f(0.5, -0.5);
        glEnd();
        glFlush();
    }
     
     
     
    void OnMouseClick(int button, int state, int x, int y)
    {
        if (button == GLUT_LEFT_BUTTON )
        {
            if( state == GLUT_DOWN)
            {
                printf("button=%d state=%d x=%d y=%d \n", button, state, x, y);
                Screen2GLpos(x,y, &xcorner, &ycorner); 
                glutPostRedisplay();
                bMoving = 1;
            }
            else
            {
                bMoving = 0;
            }
        }
    }
     
    void OnMouseMove(int x, int y)
    {
        if( bMoving )
        {
            printf("OnMouseMove :  x=%d y=%d \n", x, y);
            Screen2GLpos(x,y, &xcorner, &ycorner); 
            glutPostRedisplay();
        }
    }
     
     
     
    static void OnKey(unsigned char key, int x, int y)
    {
        switch (key)
        {
            case 27:
            exit(0);
        }
    }
     
    int main(int argc, char** argv)
    {
        glutInit(&argc,argv);
        glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
        glutInitWindowSize(width,height);
        glutInitWindowPosition(0,0);
        glutCreateWindow("simple");
     
     
        OnInit();
        glutDisplayFunc(OnDisplay);
        glutKeyboardFunc(OnKey);
        glutMouseFunc(OnMouseClick);
        glutMotionFunc(OnMouseMove);
     
     
        glutMainLoop();
     
        return 0;
    }

    If you want to select another corner, you have to extend it for to select the good corner point because this code handle only the moving of the first corner
    Last edited by The Little Body; 02-16-2015 at 02:56 PM. Reason: littles codes corrections
    @+
    Yannoo

  8. #8
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    281
    This version select automatically the nearest corner and handle the resizing of the window

    Code :
    #include <stdio.h>
    #include <GL/glut.h>
     
    typedef struct
    {
        GLfloat x;
        GLfloat y;
    }vertice_t;
     
     
    GLuint width = 500;
    GLuint height = 500;
     
    vertice_t quad[4];
     
    int bMoving = 0;
     
    int corner = 0;
     
     
    void InitQuad()
    {
        quad[0].x = -0.5f;
        quad[0].y = -0.5f;
     
        quad[1].x = -0.5f;
        quad[1].y = 0.5f;
     
     
        quad[2].x = 0.5f;
        quad[2].y = 0.5f;
     
     
        quad[3].x = 0.5f;
        quad[3].y = -0.5f;
    }
     
    void Screen2GLpos(int x, int y, GLfloat *xpos, GLfloat *ypos)
    {
        *xpos = ((GLfloat)(x) - (GLfloat)(width/2)) / (GLfloat)(width/2);
        *ypos = ((GLfloat)(-y) + (GLfloat)(height/2)) / (GLfloat)(height/2);
        printf("Transform Screen position (%d,%d) to OpenGL position  (%.3f,%.3f) \n", x, y, *xpos, *ypos);
    }
     
    int BestCorner(float x, float y)
    {
        int i, idx = -1;
        float dist2, bestdist2 = 1000000;
     
        for( i = 0 ; i < 4 ; i++)
        {
            dist2 = (x - quad[i].x) * (x - quad[i].x) + (y - quad[i].y) * (y - quad[i].y);
            if( dist2 < bestdist2 )
            {
                bestdist2 = dist2;
                idx = i;
            } 
        }
     
        return idx;
    }
     
    void OnInit()
    {
        InitQuad();
     
        glClearColor (0.0, 0.0, 0.0, 1.0);
        glColor3f(0.0, 1.0, 1.0);
        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
        glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
    }
     
     
    void OnDisplay()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glBegin(GL_POLYGON);
            glVertex2f(quad[0].x, quad[0].y);
            glVertex2f(quad[1].x, quad[1].y);
            glVertex2f(quad[2].x, quad[2].y);
            glVertex2f(quad[3].x, quad[3].y);
        glEnd();
        glFlush();
    }
     
     
     
    void OnMouseClick(int button, int state, int x, int y)
    {
        float xmousef, ymousef;
        int corner;
     
        if (button == GLUT_LEFT_BUTTON )
        {
            if( state == GLUT_DOWN)
            {
                printf("button=%d state=%d x=%d y=%d \n", button, state, x, y);
                Screen2GLpos(x,y, &xmousef, &ymousef);
                corner = BestCorner(xmousef, ymousef);
                quad[corner].x = xmousef;
                quad[corner].y = ymousef; 
                glutPostRedisplay();
                bMoving = 1;
            }
            else
            {
                bMoving = 0;
            }
        }
    }
     
    void OnMouseMove(int x, int y)
    {
        GLfloat xmousef, ymousef;
     
        if( bMoving )
        {
            printf("OnMouseMove :  x=%d y=%d \n", x, y);
            Screen2GLpos(x,y, &xmousef, &ymousef); 
            corner = BestCorner(xmousef, ymousef);
            quad[corner].x = xmousef;
            quad[corner].y = ymousef; 
            glutPostRedisplay();
        }
    }
     
     
     
    static void OnKey(unsigned char key, int x, int y)
    {
        switch (key)
        {
            case 27:
            exit(0);
        }
    }
     
    static void OnResize(int w, int h)
    {    
        int i;
     
        printf("Onresize(%d,%d) \n", w, h);
     
        width = w;
        height = h;
     
        glViewport (0, 0, (GLsizei)w, (GLsizei)h);
     
        glutPostRedisplay();
    }
     
     
    int main(int argc, char** argv)
    {
        glutInit(&argc,argv);
        glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
        glutInitWindowSize(width,height);
        glutInitWindowPosition(0,0);
        glutCreateWindow("simple");
     
     
        OnInit();
        glutDisplayFunc(OnDisplay);
        glutKeyboardFunc(OnKey);
        glutMouseFunc(OnMouseClick);
        glutMotionFunc(OnMouseMove);
        glutReshapeFunc(OnResize);
     
     
        glutMainLoop();
     
        return 0;
    }
    @+
    Yannoo

  9. #9
    Junior Member Newbie
    Join Date
    Feb 2015
    Posts
    4
    thanks guys, I tried adding alittle more to your code 'The Little Body'. I wanted to add a function to allow you to press for example the key F1 to move a certain corner of the square just like the mouse click did.

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

    typedef struct
    {
    GLfloat x;
    GLfloat y;
    }vertice_t;


    GLuint width = 500;
    GLuint height = 500;

    vertice_t quad[4];

    int bMoving = 0;

    int corner = 0;


    void InitQuad()
    {
    quad[0].x = -0.5f;
    quad[0].y = -0.5f;

    quad[1].x = -0.5f;
    quad[1].y = 0.5f;


    quad[2].x = 0.5f;
    quad[2].y = 0.5f;


    quad[3].x = 0.5f;
    quad[3].y = -0.5f;
    }

    void Screen2GLpos(int x, int y, GLfloat *xpos, GLfloat *ypos)
    {
    *xpos = ((GLfloat)(x) - (GLfloat)(width/2)) / (GLfloat)(width/2);
    *ypos = ((GLfloat)(-y) + (GLfloat)(height/2)) / (GLfloat)(height/2);
    printf("Transform Screen position (%d,%d) to OpenGL position (%.3f,%.3f) \n", x, y, *xpos, *ypos);
    }

    int BestCorner(float x, float y)
    {
    int i, idx = -1;
    float dist2, bestdist2 = 1000000;

    for( i = 0 ; i < 4 ; i++)
    {
    dist2 = (x - quad[i].x) * (x - quad[i].x) + (y - quad[i].y) * (y - quad[i].y);
    if( dist2 < bestdist2 )
    {
    bestdist2 = dist2;
    idx = i;
    }
    }

    return idx;
    }

    void OnInit()
    {
    InitQuad();

    glClearColor (0.0, 0.0, 0.0, 1.0);
    glColor3f(0.0, 1.0, 1.0);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
    }


    void OnDisplay()
    {
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POLYGON);
    glVertex2f(quad[0].x, quad[0].y);
    glVertex2f(quad[1].x, quad[1].y);
    glVertex2f(quad[2].x, quad[2].y);
    glVertex2f(quad[3].x, quad[3].y);
    glEnd();
    glFlush();
    }



    void OnMouseClick(int button, int state, int x, int y)
    {
    float xmousef, ymousef;
    int corner;

    if (button == GLUT_LEFT_BUTTON )
    {
    if( state == GLUT_DOWN)
    {
    printf("button=%d state=%d x=%d y=%d \n", button, state, x, y);
    Screen2GLpos(x,y, &xmousef, &ymousef);
    corner = BestCorner(xmousef, ymousef);
    quad[corner].x = xmousef;
    quad[corner].y = ymousef;
    glutPostRedisplay();
    bMoving = 1;
    }
    else
    {
    bMoving = 0;
    }
    }
    }

    void OnMouseMove(int x, int y)
    {
    GLfloat xmousef, ymousef;

    if( bMoving )
    {
    printf("OnMouseMove : x=%d y=%d \n", x, y);
    Screen2GLpos(x,y, &xmousef, &ymousef);
    corner = BestCorner(xmousef, ymousef);
    quad[corner].x = xmousef;
    quad[corner].y = ymousef;
    glutPostRedisplay();
    }
    }



    static void OnKey(unsigned char key, int x, int y)
    {
    switch (key)
    {
    case 27:
    exit(0);
    }
    }

    void glutSpecialFunc(int button, int state, int x, int y)
    {
    float xmousef, ymousef;
    int corner;

    if switch (key)
    {
    {case GLUT_KEY_F1 :
    printf("button=%d state=%d x=%d y=%d \n", button, state, x, y);
    Screen2GLpos(x,y, &xmousef, &ymousef);
    corner = BestCorner(xmousef, ymousef);
    quad[corner].x = xmousef;
    quad[corner].y = ymousef;
    glutPostRedisplay();
    bMoving = 1;

    case GLUT_KEY_F2 :
    printf("button=%d state=%d x=%d y=%d \n", button, state, x, y);
    Screen2GLpos(x,y, &xmousef, &ymousef);
    corner = BestCorner(xmousef, ymousef);
    quad[corner].x = xmousef;
    quad[corner].y = ymousef;
    glutPostRedisplay();
    bMoving = 1;

    case GLUT_KEY_F3 :
    printf("button=%d state=%d x=%d y=%d \n", button, state, x, y);
    Screen2GLpos(x,y, &xmousef, &ymousef);
    corner = BestCorner(xmousef, ymousef);
    quad[corner].x = xmousef;
    quad[corner].y = ymousef;
    glutPostRedisplay();
    bMoving = 1;

    case GLUT_KEY_F4 :
    printf("button=%d state=%d x=%d y=%d \n", button, state, x, y);
    Screen2GLpos(x,y, &xmousef, &ymousef);
    corner = BestCorner(xmousef, ymousef);
    quad[corner].x = xmousef;
    quad[corner].y = ymousef;
    glutPostRedisplay();
    bMoving = 1;
    }
    else
    {
    bMoving = 0;
    }
    }


    static void OnResize(int w, int h)
    {
    int i;

    printf("Onresize(%d,%d) \n", w, h);

    width = w;
    height = h;

    glViewport (0, 0, (GLsizei)w, (GLsizei)h);

    glutPostRedisplay();
    }


    int main(int argc, char** argv)
    {
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowSize(width,height);
    glutInitWindowPosition(0,0);
    glutCreateWindow("simple");


    OnInit();
    glutDisplayFunc(OnDisplay);
    glutKeyboardFunc(OnKey);
    glutMouseFunc(OnMouseClick);
    glutMotionFunc(OnMouseMove);
    glutReshapeFunc(OnResize);


    glutMainLoop();

    return 0;
    }
    Am I putting the glutSpecialFunc in the right manner?

Posting Permissions

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