Using the Mouse Event Function

Hello! I’m a beginner to programming in OpenGl and could use some help with the mouse function. The code I have draws 3 squares of different colors on a white background. What I want the mouse function to do is to check and see if the cursor was over a square when the left mouse is clicked. If so, I want to make that square disappear, or basically change it’s color to the background color so it is “invisible.” Below is the code I have so far. I have read about the mouse function in that I know what parameters it takes on, I’m just not sure how to execute it the way that I want to.


#include <GL/glut.h>

float R1 = 1.0, G1 = 0.0, B1 = 0.0, 
      R2 = 0.0, G2 = 1.0, B2 = 0.0, 
      R3 = 0.0, G3 = 0.0, B3 = 1.0;    //colors of squares
float BGR = 1.0, BGG = 1.0, BGB = 1.0; //background colors
int   X1 = 50, Y1 = 50, 
      X2 = 200, Y2 = 100,
      X3 = 225, Y3 = 300;              //coords of squares
int   W = 30;                          //width of squares     

void init (void)
{
  glClearColor (BGR, BGG, BGB, 0.0);
  glShadeModel (GL_FLAT);
}

void drawSquare (int x, int y, int w)
{
  glBegin(GL_POLYGON);
    glVertex2i(x, y);
    glVertex2i(x + w, y);
    glVertex2i(x + w, y + w);
    glVertex2i(x, y + w);
  glEnd();
}

void display (void)
{
  glClear (GL_COLOR_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0, 400, 0, 400);
  glPolygonMode(GL_FRONT, GL_FILL);
  glColor3f (R1, G1, B1);
  drawSquare (X1, Y1, W);
  glColor3f (R2, G2, B2);
  drawSquare (X2, Y2, W);
  glColor3f (R3, G3, B3);
  drawSquare (X3, Y3, W);

  glFlush ();
  glutSwapBuffers();
}

void disappearingSquares(int button, int state, int x, int y)
{
  glColor3f(1.0f, 1.0f, 1.0f);  //code not executing
  drawSquare(x, y, 30);       //code not executing
}

int main (int argc, char** argv)
{
  glutInit (&argc, argv);
  glutInitDisplayMode (GLUT_SINGLE|GLUT_RGB);
  glutInitWindowSize (400, 400);
  glutInitWindowPosition (100, 100);
  glutCreateWindow (argv[0]);
  init ();
  glutDisplayFunc (display);
  glutMouseFunc(disappearingSquares);
  glutMainLoop ();
  return 0;
}

As you can see, what I tried was to redeclare the color and then attempt to draw a new square over the coordinates returned by the mouse function. However, the program does not work this way and I’m not sure what I need to do to accomplish my goal. Any help is greatly appreciated. Thanks!

First, you aren’t calling glFlush() after drawing the square, so the commands probably won’t be sent to the driver. Most OpenGL functions simply append the command to a buffer. Buffered commands are sent to the driver whenever the buffer fills up or you call glFlush() or glFinish() (glutSwapBuffers() performs an implicit glFlush()).

But more significantly, the next time that the display function is called, it will draw the original scene without any changes.

In short: don’t try to update the display incrementally. The display function should draw the scene based upon data (e.g. a list of squares to be drawn). Input events should modify that data then call glutPostRedisplay() to trigger a redraw.

And avoid single-buffered rendering. For complex scenes, the resulting flicker is annoying. Single-buffered rendering is something of a hack, which had some utility for “temporary” updates (e.g. dragging objects with the mouse) on older systems in applications where a full redraw might be slow. On modern systems it’s unnecessary.