Search code examples
c++openglglut

Why are my points are not drawing where my mouse is in OpenGL?


My points will not draw where my mouse is unless I am exactly half the height of the window. If I am below this half way line, it will draw above the line, if I am above, it will draw below.

Attached is a GIF incase it is not clear: https://gyazo.com/407d679430c70c3235d9e5c43e521347

I would like my coordinate system to start at the bottom left of the screen (as well as draw points where my mouse is). I am developing on a VirtualBox instance of Ubuntu if that helps.

#include <iostream>
#include <vector>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include "Point.h"


const int w = 640;
const int h = 480;

// Prototypes
void display(void);
void myInit(void);
void myMouse(int button, int state, int x, int y);

// Globals
std::vector<Point> points;

int main(int argc, char** argv){    
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE);
    glutInitWindowSize(w, h);
    glutInitWindowPosition(0, 100);
    glutCreateWindow("My First Attempt");
    glutDisplayFunc(display);
    glutMouseFunc(myMouse);
    myInit();
    glutMainLoop();

}

void display(void){
            glClear(GL_COLOR_BUFFER_BIT);
            glBegin(GL_POINTS);
            // for each point in points, draw a point
            for(Point p : points)
                glVertex2i(p._x,p._y);
            glEnd();

            glFlush();
}
void myMouse(int button, int state, int x, int y){
            if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
                Point p;
                p._x = x;
                p._y = y;
                points.push_back(p);
                std::cout << p._x << "   " << p._y << std::endl;
                glutPostRedisplay();

            }
            if(button == GLUT_LEFT_BUTTON && state == GLUT_UP){

            }
}
void myInit(void){

            glClearColor(1.0,1.0,1.0,0.0);
            glColor3f(0,0,0);
            glPointSize(4.0);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            gluOrtho2D(0.0f,w, 0,h);

}

Solution

  • You either need to Y-flip the mouse coordinates or adjust your projection matrix to match their coordinate system:

    // broken
    gluOrtho2D( 0.0f, w, 0, h );
    
    // works
    gluOrtho2D( 0.0f, w, h, 0 );
    

    All together:

    #include <iostream>
    #include <vector>
    #include <GL/glut.h>
    #include <GL/gl.h>
    #include <GL/glu.h>
    
    struct Point
    {
        int _x, _y;
    };
    
    const int w = 640;
    const int h = 480;
    
    // Prototypes
    void display( void );
    void myInit( void );
    void myMouse( int button, int state, int x, int y );
    
    // Globals
    std::vector<Point> points;
    
    int main( int argc, char** argv )
    {
        glutInit( &argc, argv );
        glutInitDisplayMode( GLUT_SINGLE );
        glutInitWindowSize( w, h );
        glutInitWindowPosition( 0, 100 );
        glutCreateWindow( "My First Attempt" );
        glutDisplayFunc( display );
        glutMouseFunc( myMouse );
        myInit();
        glutMainLoop();
    }
    
    void display( void )
    {
        glClear( GL_COLOR_BUFFER_BIT );
        glBegin( GL_POINTS );
        // for each point in points, draw a point
        for( Point p : points )
            glVertex2i( p._x, p._y );
        glEnd();
    
        glFlush();
    }
    
    void myMouse( int button, int state, int x, int y )
    {
        if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
        {
            Point p;
            p._x = x;
            p._y = y;
            points.push_back( p );
            std::cout << p._x << "   " << p._y << std::endl;
            glutPostRedisplay();
        }
    }
    
    void myInit( void )
    {
        glClearColor( 1.0, 1.0, 1.0, 0.0 );
        glColor3f( 0, 0, 0 );
        glPointSize( 4.0 );
        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
        gluOrtho2D( 0.0f, w, h, 0 );
    }