Problem with MouseFunc

Hi. I am trying to create a method drawRectangle(). I haven’t implemented the draw portion of it yet but that’s not the problem. The problem is that I am not used to using events in my program. I want to be able to select Draw Rectangle from the menu which will let me select two points for the rectangle. The problem is that after I select Draw Rectangle, every time I left click afterwards, it always says “button down”. Is there any way to only accept two mouse clicks, draw the rectangle and then move on? I don’t want to be stuck in a constant state of accepting a left mouse click for that function. Below are the relevant sections of code from my program. Thanks.


void processMouse(int button, int state, int x, int y)
{
	if(state == GLUT_DOWN && button == GLUT_LEFT_BUTTON)
	{
	     std::cout << "button down";
	}			
}

void drawRectangle()
{	
	glutMouseFunc(processMouse);
	std::cout << "draw rectangle";
}

void processMenuEvents(int option) {

	switch (option) {
		case 0 :
		drawRectangle();			
		break;	
	}
}

void initMenu() {

	int menu;

	menu = glutCreateMenu(processMenuEvents);
	
	glutAddMenuEntry("Create Rectangle", 0);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
}

int main(int argc, char** argv)
{
	global.data = read_img("image.tif", &global.w, &global.h);
	
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
	
	glutInitWindowSize(global.w,global.h);
	glutCreateWindow("SIMPLE DISPLAY");
	glShadeModel(GL_SMOOTH);
	glutDisplayFunc(display_image);	
	glMatrixMode(GL_PROJECTION);
	glOrtho(0,global.w,0,global.h,0,1);	

	initMenu();	

	glutMainLoop();

	return 0;
}


Hi,
To do such a thing, you can create a custom enum (lets say mode) and then toggle the mode on the menu choice. Then in the mouse function check if the current mode is rectangle draw mode. If it is you accept the mouse click. I am not sure what exactly are u looking for but here I am sharing a code that will allow u to generate a rectangle by first clicking the start loc. and then draw rectangle during motion until the mouse click is up see if this is what u were looking for an adapt it if this was not.


#include <gl\glut.h> 
#include <iostream>
#include <ctime>
const int width = 800, height=600;
enum Mode {DRAW_RECT, IDLE};
Mode current_mode = IDLE;
int start_x=0;
int start_y=0;
int end_x=0, end_y=0;
int total_clicks=0;
int down=0;

void OnMouseMove(int x, int y) {
  if(down) {
    end_x = x;
    end_y=height-y;
    glutPostRedisplay();
  }
}
void processMouse(int button, int state, int x, int y)
{
  if(state == GLUT_DOWN && button == GLUT_LEFT_BUTTON)
  {
    if(current_mode==DRAW_RECT){       	   
      start_x = x;
      start_y = height-y;	
      down = 1;
    }
  }		 
}

void Render()
{	
  glClear(GL_COLOR_BUFFER_BIT); 
  if(current_mode==DRAW_RECT)
    glRectf(start_x,  start_y, end_x,  end_y);
}

void processMenuEvents(int option) {
  switch (option) {
    case 0 : current_mode = DRAW_RECT; break;	
  }
}

void initMenu() {
  int menu;
  menu = glutCreateMenu(processMenuEvents);
  glutAddMenuEntry("Create Rectangle", 0);	 
  glutAttachMenu(GLUT_RIGHT_BUTTON);
}

int main(int argc, char** argv)
{	
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
  glutInitWindowSize(width,height);
  glutCreateWindow("SIMPLE DISPLAY");
  glShadeModel(GL_SMOOTH);
  glutDisplayFunc(Render);	
  glutMouseFunc(processMouse);
  glutMotionFunc(OnMouseMove);
  glMatrixMode(GL_PROJECTION);
  glOrtho(0,width,0,height,0,1);	
  initMenu();	
  glutMainLoop();
  return 0;
}

Regards,
Mobeen

Hi. Thanks for the reply. I tried changing my code around using the code you supplied. I couldn’t get a rectangle to be drawn so I copied your code into a separate project and it didn’t draw a rectangle either. Any suggestions? Also, is there a way to draw the rectangle by clicking two points instead of clicking once and then dragging? Thanks.

Well it works fine here check the snapshot. You need to right click first and then select draw rectangle. Then clik on the first point and drag to the end point to draw the rectangle. Are you doing this?

To draw based on two points just create a click counter. increment it on each mouse click. Then check if the count %2 ==0 start a new rectangle. Should be straightforward to extend.

Hi mobeen. I looked at your output and noticed that you have a black background with a white rectangle drawn. When I run the program, the window opens up, however, there is nothing drawn in it; no background and I can see right through the window to my background applications. When I right-click, the menu does appear and I select Draw Rectangle. I then click and drag but nothing in the window changes. Any suggestions? Thanks.

Hi could u add a call to glFinish() at the end of the render fnction. You can also put a call to this code at the end of the render fuinction and tell me what u get in the output.


GLuint error = glGetError();
if(error)
   printf("Error: %d
",error);

Hi mobeen. The glFinish() addition fixed the problem. Thanks for your help. I’ll play around with my code now and see if I can’t get something working.

Sorry, double post.