OpenGL beginner...

Hi, I’m new to this board and to opengl/glut in general… I’m starting off by trying to draw lines on the screen using the mouse, but the thing is that I don’t know how to get the mouse co-ordinates in order to draw the lines… What should I do? Thanks! :slight_smile:

-TS

If you are in a MFC window,you can try this:
you can implement these three method:afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

using the CPoint point parameter as the input then translate it into OpenGL coordinates

in a general win32 app you have to capture the mouse coordinates in the MessageLoop (WndProc) by catching
the wm_mousemove event

Here is how to do it really simply with glut.

glutMotionFunc (button_and_motion_func)
glutPassiveMotionFunc (no_button_and_motion_func)
glutMouseFunc (MouseFunc)

void
MouseFunc (int button, int state, int x, int y);

void
MotionFunc (int x, int y);

void
PassiveMotionFunc (int x, int y);

The mouse function is for buttons only. The motion func is for moving mouse while holding down buttons, and the last is for moving the mouse.

Also, if you want to draw simple 2D primitives, don’t forget to avoid any perspective so that your drawings look good (an ortho 2D will be fine).

Hope that helps.

Hi ThunderSoul
I had written some examples before. These programs show you to use from the functions suggested by Jide.Please try to complie them. they can hep you to write some complicated programs.

//How could we use from the glutMotionFunc?
//Note: we use from the single buffer.
//For double buffer we must use from another method.
//Ehsan Kamrani
#include <GL/glut.h>
#include <iostream.h>

GLint xx1, yy1, xx2, yy2;

int wh = 0;
void init()
{
glClearColor( 0.0, 0.0, 0.0, 0.0 );
glColor3f( 1.0f, 1.0f, 0.0f );

}

/////////////////
//Motion Function
/////////////////
void motion( int x, int y )
{
glBegin( GL_POINTS );
glVertex2f( x, wh - y );
glEnd();
glFlush();
}

void reshape( int width, int height )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( 0.0, width, 0.0, height );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glViewport( 0, 0, width, height );

wh = height;

}

void display()
{
glClear( GL_COLOR_BUFFER_BIT );
}

int main( int argc, char* argv[] )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA );
glutInitWindowSize( 500, 500 );
glutCreateWindow( “How could we use from the glutMotionFunc?” );
glutDisplayFunc( display );
glutReshapeFunc( reshape );
/////////////////////
//Motion
/////////////////////
glutMotionFunc( motion );

init();
glutMainLoop();
return 0;

}

==========

//How could we use from glutPassiveMotion Func?
//Note: we use from the single buffer.
//For double buffer we must use from another method.
//Ehsan Kamrani

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

GLint xx1, yy1, xx2, yy2;

int wh = 0;

/////////////////////////
//Passive Motion Function
/////////////////////////
void passiveMotion( int x, int y )
{
static float xx = 0, yy = 0;
glBegin( GL_LINES );
glVertex2f( xx, yy );
glVertex2f( x, wh - y );
glEnd();
glFlush();
xx = x;
yy = wh - y;

}

void init()
{
glClearColor( 0.0, 0.0, 0.0, 0.0 );
glColor3f( 1.0f, 1.0f, 0.0f );
glRasterPos2i( 50,50);

}

void reshape( int width, int height )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( 0.0, width, 0.0, height );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glViewport( 0, 0, width, height );

wh = height;

}

void display()
{
glClear( GL_COLOR_BUFFER_BIT );
glClear( GL_COLOR_BUFFER_BIT );
glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_10, ‘a’ );
}

int main( int argc, char* argv[] )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA );
glutInitWindowSize( 500, 500 );
glutCreateWindow( “How could we use from glutPassiveMotionFunc?” );
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutPassiveMotionFunc( passiveMotion );
init();
glutMainLoop();
return 0;
}

===========

//How could we use from the mouse callback?
//Note: we use from the single buffer.
//For double buffer we must use from another method.
//Right click to see the results, left click to exit
#include <GL/glut.h>
#include <iostream.h>

int wh = 0;
void init()
{
glClearColor( 0.0, 0.0, 0.0, 0.0 );
glColor3f( 1.0f, 1.0f, 0.0f );

}

void reshape( int width, int height )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( 0.0, width, 0.0, height );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glViewport( 0, 0, width, height );

wh = height;

}

void display()
{
glClear( GL_COLOR_BUFFER_BIT );
}

void mouse( int btn, int state, int x, int y )
{
static bool first = true;
static int xx, yy;
if( btn == GLUT_LEFT_BUTTON && state == GLUT_UP )
exit(0);
if( btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN )
{
if( first )
{
first = !first;
xx = x;
yy = wh - y;
}
else
{
first = !first;
glClear( GL_COLOR_BUFFER_BIT );
glBegin( GL_QUADS );
glVertex2f( xx, yy );
glVertex2f( xx, wh - y );
glVertex2f( x, wh - y );
glVertex2f( x, yy );
glEnd();
glFlush();
}
}
}

int main( int argc, char* argv[] )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA );
glutInitWindowSize( 500, 500 );
glutCreateWindow( “How could we use from the mouse callback?” );
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutMouseFunc( mouse );
init();
glutMainLoop();
return 0;
}

==========

//How could we use from the mouse callback?
//Note: we use from the single buffer.
//For double buffer we must use from another method.

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

GLint xx1, yy1, xx2, yy2;

int wh = 0;
void init()
{
glClearColor( 0.0, 0.0, 0.0, 0.0 );
glColor3f( 1.0f, 1.0f, 0.0f );

}

void reshape( int width, int height )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D( 0.0, width, 0.0, height );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glViewport( 0, 0, width, height );

wh = height;

}

void display()
{
glClear( GL_COLOR_BUFFER_BIT );
glClear( GL_COLOR_BUFFER_BIT );
glBegin( GL_QUADS );
glVertex2f( xx1, yy1 );
glVertex2f( xx1, yy2 );
glVertex2f( xx2, yy2 );
glVertex2f( xx2, yy1 );
glEnd();
glFlush();
}

void mouse( int btn, int state, int x, int y )
{
static bool first = true;
static int xx, yy;
if( btn == GLUT_LEFT_BUTTON && state == GLUT_UP )
exit(0);
if( btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN )
{
if( first )
{
first = !first;
xx1 = x;
yy1 = wh - y;
}
else
{
first = !first;
xx2 = x;
yy2 = wh - y;
}
glutPostRedisplay();
}
}

int main( int argc, char* argv[] )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA );
glutInitWindowSize( 500, 500 );
glutCreateWindow( “How could we use from the mouse callback?(2)” );
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutMouseFunc( mouse );
init();
glutMainLoop();
return 0;
}

-Ehsan-

From my experience with glut, I know that glutMouseFunc, glutMotionFunc and glutPassiveMotionFunc work very well both on single and double buffer.

Did I misunderstood what you said Ehsan ?

Originally posted by jide:
[b]From my experience with glut, I know that glutMouseFunc, glutMotionFunc and glutPassiveMotionFunc work very well both on single and double buffer.

Did I misunderstood what you said Ehsan ?[/b]
Hi Jide
Yes they work correctly in both modes.These mouse functions are like the WM_* commands in win32 application. As you see, i have written the drawing codes in my mouse functions.When we use from the single buffer, the mouse functions that produce a WM_MOUSE command are processed and executed.The display function isn’t executed after the mouse functions. So our drawings aren’t cleared.
But what does happen in double buffering?We like to exeute the display function for more than 30 times per second.When we add a WM_MOUSE command, this message is picked, translated and dispatched and the corresponding mouse function is executed( and the objects are drawn ).But immediatly after this drawing, the display function is called and all the drawings are cleared.So for double buffering, we can use from the display lists and save each shape in a new display list and call these lists in our display function.There are some other techniques as well.
-Ehsan-

ok. thanx for sharing that knowledge.

You’re welcome.
-Ehsan-

I don’t know if I should resurrect such an old thread but my problem is really similar. I am trying to learn opengl and as such am trying to write a program that draws a square wherever the mouse is clicked, but it is not working. The only difference that I can see between my program and the example given is that a customized init() func is being called after glutmousefunc and before glutmainloop whereas I am not doing so . Is this why my program is not working? I tried adding an init() but still it won’t work. Please tell me what I am doing wrong.

#include <stdlib.h> 
#include <glut.h>

GLsizei WIDTH = 1300, HEIGHT = 700;
GLsizei MOUSEx, MOUSEy;
GLfloat SIDE=1;

GLfloat RED[3] = {1,0,0};
GLfloat GREEN[3] = {0,1,0};
GLfloat BLUE[3] = {0,0,1};
GLfloat WHITE[3] = {1,1,1};
GLfloat BLACK[3] = {0,0,0};
GLfloat YELLOW[3] = {1,1,0};
GLfloat CYAN[3] = {0,1,1};
GLfloat MAGENTA[3] = {1,0,1};

void drawSquare(int x, int y)
{
	glColor3fv(YELLOW);
	glBegin(GL_POLYGON);
	 	glVertex3f(x+SIDE, y+SIDE,0);
		glVertex3f(x-SIDE, y+SIDE,0);
	 	glVertex3f(x-SIDE, y-SIDE,0);
	    glVertex3f(x+SIDE, y-SIDE,0);
	glEnd();
	glFlush();
}

void drawSquare1()
{
	int x=0,y=0;
	glColor3fv(BLUE);
	glBegin(GL_POLYGON);
	 	glVertex3f(x+SIDE, y+SIDE,0);
		glVertex3f(x-SIDE, y+SIDE,0);
	 	glVertex3f(x-SIDE, y-SIDE,0);
	    glVertex3f(x+SIDE, y-SIDE,0);
	glEnd();
	glFlush();
}

void display (void) {
    glClearColor (0.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT);
    glLoadIdentity(); 
    glTranslatef(0,0,-15);
	drawSquare1();
	glFlush();
}

void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    glMatrixMode (GL_MODELVIEW);
	WIDTH=w;
	HEIGHT=h;
}

void setX(int x)
{
	MOUSEx=x;
}

void setY(int y)
{
	MOUSEy=y;
}

void mouse(int btn, int state, int x, int y)
{
	if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)   
	{
		setX(x);
		setY(y);
		drawSquare(MOUSEx,HEIGHT-MOUSEy);
		glutPostRedisplay();
	}
    if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)   
	{
		exit(1);
	}
}

void init (void)
{
  /* select clearing (background) color */
  glClearColor (1.0, 1.0, 1.0, 0.0);

  /* initialize viewing values */
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, WIDTH, 0, HEIGHT, -1.0, 1.0);
}

int main (int argc, char **argv) {
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize (WIDTH, HEIGHT);
    glutInitWindowPosition (10, 10);
    glutCreateWindow ("New Window");
    glutDisplayFunc (display);
    glutReshapeFunc (reshape);
    glutMouseFunc(mouse);
	init();
	glutMainLoop ();
    return 0;
}