PDA

View Full Version : Polygon using Mouse Feedback



GlutNewbie
02-27-2003, 07:35 AM
Hi.

I'm trying to create a program where the user can interactively create a polygon using mouse clicks. For some reason I can't get the polygon to display on the screen. Here's what I do:


if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINE);
glVertex2f(x, winHeight - y);
glVertex2f(x+20, winHeight - y+20);
glEnd();
}

That's what I have in my mouse function. What am I missing here? A call to the display callback? Other code that I'm not aware of?

Thanks

nexusone
02-27-2003, 08:06 AM
Never draw things in the mouse/keyboard/etc routines. Works for tutor but not a full program.
You need to use variables:

when mouse click is down put data in a start of line variable.

when mouse click is up put data in a end line variable.

In your draw routine, you draw your line with the two variable.

To make an polygon, create a array in which to place the two variables after the line is completed..
they draw it also in your display routine.


Don't have time to right not to go through all of it...but I have answered this same question before on here.

When I get a bit more time will post more.



Originally posted by GlutNewbie:
Hi.

I'm trying to create a program where the user can interactively create a polygon using mouse clicks. For some reason I can't get the polygon to display on the screen. Here's what I do:


if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINE);
glVertex2f(x, winHeight - y);
glVertex2f(x+20, winHeight - y+20);
glEnd();
}

That's what I have in my mouse function. What am I missing here? A call to the display callback? Other code that I'm not aware of?

Thanks

Lemmy
02-27-2003, 08:14 AM
Here is some code i created for a project a while back. Hope it helps you !!!!!
Heres how it works :

The program will draw 100 lines of 100 points each.


The commands are as follows :


To begin drawing lines press the 'b' key and leftclick to create them.

To delete points press the 'd' key and leftclick beside the point to be deleted.

To move a point press the 'm' key ,then leftclick beside the point to be moved and rightclick where
you want to move it.

To quit out of the application press the 'q' key.

To clear the screen and arrays press the 'r' key.

To input a .dat file press the 'c' key.

NOTE*(the file I have inputting at the moment is the included dino.dat file.
If you wish to change this to input a different file simply go to the myKeyboard method case 'c':
and change the

drawPolyLineFile("dino.dat");

to

drawPolyLineFile("YOUR FILE HERE");

#include<windows.h>
#include<gl/Gl.h>
#include<gl/glut.h>
#include <iostream.h>
#include <math.h>
#include <stdio.h>
#include <fstream.h>


#define NUM20 100 //these variables specifies the size of the arrays
#define NUM60 100


struct GLintPoint {

int x,y; //x and y coordinates for the points

};

struct GLintPointArray {

public: GLintPoint pt[NUM20]; //an array to hold the points


};

GLintPointArray List[NUM60]; //an array to hold the polylines
int last2 =0;
int last = 0;

int ToBeDeleted1a = 0;//these variables hold the positions in the arrays..
int ToBeDeleted2b = 0;//..for the closest point to the mouse click

int distance=0; //a variable to hold the shortest distance between two points
int current=1000; //a variable to hold the distance between the closest point and the mouse click

void Print(); //method declarations
void setArray();
void drawLines();
void drawPolyLineFile(char * fileName);

int screenHeight = 480.0;
int screenWidth = 640.0;


void myInit(void) {
setArray(); //set the array

glClearColor(1.0,1.0,1.0,0.0);
glColor3f(0.0f,0.0f,0.0f);
glPointSize(4.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,640.0,0.0,480.0);


}


void myDisplay() {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
drawLines(); //draw the lines currently in the arrays
}

void drawPolyLineFile(char * fileName)
{
fstream inStream;
inStream.open(fileName, ios ::in); // open the file
if(inStream.fail())
return;
glClear(GL_COLOR_BUFFER_BIT); // clear the screen
GLint numpolys, numLines, x ,y;
inStream >> numpolys; // read the number of polylines



for(int j = last2+1; j < numpolys; j++) // read each polyline
{
inStream >> numLines;
// draw the next polyline
for (int i = 0; i < numLines; i++)
{
inStream >> x >> y; // read the next x, y pair

if(x != 0 && y!= 0){

List[j].pt[i].x = x; //put the points into the arrays
List[j].pt[i].y = y;

}

}

}
last2=j+1; //go to the next position in the List array
inStream.close();
drawLines();
Print();
}

void setArray(){ //set all the points in the array to -1

for(int i = 0; i<NUM20; i++){
for(int j = 0; j<NUM60; j++){

List[i].pt[j].x = -1;
List[i].pt[j].y = -1;
}
}
}


void drawLines() { //draw all the lines in the arrays


for(int i = 0; i<NUM60; i++)
{
for(int j = 0; j<NUM20; j++)
{

if(List[i].pt[j].x > 0 && List[i].pt[j].y > 0)
{
glBegin(GL_LINE_STRIP);
//draw the polyline

glVertex2i(List[i].pt[j].x, List[i].pt[j].y);

}
}
glEnd();

}
glFlush();


}


void pointsToArray(int button, int state, int x, int y){

//add the points to the arrays
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && last < NUM20 && last2 < NUM60 ) {
List[last2].pt[last].x = x;
List[last2].pt[last].y = screenHeight - y;
last++; //go to the next position in the pt array
Print();

}


}

void Print(){ //a printout of the x,y coordinates currently in the array and the list number
drawLines();
system("cls");
for(int i = 0; i<NUM60; i++){
if(List[i].pt[0].x >0 && List[i].pt[0].y > 0) {
cout <<"i no. " <<i<< "\n";

for(int j = 0; j<NUM20; j++){
if(List[i].pt[j].x >0 && List[i].pt[j].y > 0) {
cout << "x " << List[i].pt[j].x ;
cout <<" y " << List[i].pt[j].y << "\n";
}
cout.flush();
}
cout.flush();
}
}
}

void movePoint(int button, int state, int x, int y){


if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {

glClear(GL_COLOR_BUFFER_BIT);

distance=0;
current=1000;
int truey=screenHeight-y;//variable to hold the true y coordinate

for(int i = 0; i<NUM60; i++){
for(int j = 0; j<NUM20; j++){

if(List[i].pt[0].x >0 && List[i].pt[0].y >0) { //if x and y in the array are greater..
//..than 0
//function to get the shortest distance between two points
distance = sqrt(((x-List[i].pt[j].x)*(x-List[i].pt[j].x)) + ((truey-List[i].pt[j].y)*(truey-List[i].pt[j].y)));


if(distance < current){

current = distance;
ToBeDeleted1a = i;
ToBeDeleted2b = j;
}


}

}

}
}

if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {

glClear(GL_COLOR_BUFFER_BIT);

List[ToBeDeleted1a].pt[ToBeDeleted2b].x=x; //set the closest point to a new point specified by..
List[ToBeDeleted1a].pt[ToBeDeleted2b].y=screenHeight-y;//..a right click

drawLines(); //redraw the lines

}


}

void deletePoly(int button, int state, int x, int y){

if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {

glClear(GL_COLOR_BUFFER_BIT);

distance=0; //functions to find the closest point to the click ..as above
current=1000;
int truey=screenHeight-y;

for(int i = 0; i<NUM60; i++){
for(int j = 0; j<NUM20; j++){


if(List[i].pt[j].x >0 && List[i].pt[j].y >0) {

distance = sqrt(((x-List[i].pt[j].x)*(x-List[i].pt[j].x)) + ((truey-List[i].pt[j].y)*(truey-List[i].pt[j].y)));


if(distance < current){

current = distance;
ToBeDeleted1a = i;
ToBeDeleted2b = j;


}
}


}
}


//set the x,y coordinates of the closest point to -1
List[ToBeDeleted1a].pt[ToBeDeleted2b].x=-1;
List[ToBeDeleted1a].pt[ToBeDeleted2b].y=-1;

Print();
drawLines();
}

}

void clearScreenAndArray(){ //method to clear the screen and reset the arrays

glClear(GL_COLOR_BUFFER_BIT);
glFlush();

for(int a = 0;a<NUM60;a++){
for(int b = 0;b<NUM20;b++){

List[a].pt[B].x = -1;
List[a].pt[B].y = -1;
}

}

last=0;
last2=0;

}

void myKeyboard(unsigned char theKey, int mouseX, int mouseY) {

GLint x = mouseX;
GLint y = screenHeight - mouseY;

switch(theKey) {

case 'b':

glutMouseFunc(pointsToArray);

last=0; //go to the start of the pt array
last2++; //go to the next position in the List array

break;
case 'd':
glutMouseFunc(deletePoly);
break;
case 'm':

glutMouseFunc(movePoint);
break;

case 'q':

exit(-1);
break;
case 'r': //clear screen and reimplement the text file
clearScreenAndArray();

break;

case 'c':


drawPolyLineFile("dino.dat");
break;

default:
break;

}
}

void main(int argc,char **argv) {

glutInit(&argc, argv);//initialise toolkit
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); //set the display mode
glutInitWindowSize(640,480);
glutInitWindowPosition(100,150); //set the window position on screen

glutCreateWindow("Polylines program"); //open the screen window

glutDisplayFunc(myDisplay);
glutKeyboardFunc(myKeyboard);


myInit();
glutMainLoop();

}


///////////////////////////////////////

if your interested heres what the file for the dino looks like (just put it in a seperate text editor like notepad and save it in your folder as a .dat file) :

21
29
32 435
10 439
4 438
2 433
4 428
6 425
10 420
15 416
21 413
30 408
42 406
47 403
56 398
63 391
71 383
79 369
84 356
87 337
89 316
88 302
86 294
83 278
79 256
78 235
79 220
85 204
94 190
98 183
98 182
9
116 189
105 184
98 172
98 156
93 141
93 132
99 122
104 115
104 114
38
153 116
152 112
153 107
154 93
154 81
152 67
146 56
140 47
136 39
133 30
130 17
128 7
127 3
93 2
93 10
96 16
96 20
97 21
101 24
104 27
105 31
107 36
108 40
109 47
111 51
114 58
118 66
120 71
118 79
117 88
116 97
112 105
107 113
107 118
108 126
112 138
116 146
118 148
7
153 95
158 99
159 103
161 108
161 115
160 121
160 122
7
156 80
167 79
182 76
203 73
220 78
235 79
239 80
43
262 154
259 141
259 123
257 110
255 93
259 86
272 74
287 46
290 41
299 30
305 21
307 15
307 12
300 11
299 9
301 2
303 1
313 5
320 7
307 1
312 0
321 0
325 0
331 0
336 2
336 8
334 18
335 24
331 29
327 39
323 45
317 54
312 63
308 70
301 79
297 86
296 97
300 109
303 120
304 126
307 138
306 148
305 152
5
298 86
304 92
310 104
314 114
314 119
7
255 98
251 100
246 105
242 112
236 122
231 131
233 126
7
271 73
264 74
257 76
244 76
236 80
231 84
230 86
24
242 77
242 70
245 61
246 49
248 39
249 30
248 19
245 12
242 9
241 6
243 1
256 3
259 2
266 3
271 4
274 9
277 16
277 24
277 31
277 41
277 48
278 57
278 62
278 66
24
190 73
191 64
193 51
194 39
191 25
189 17
185 7
184 5
177 4
169 4
166 4
159 5
159 6
162 19
163 25
165 32
165 39
165 47
165 57
162 65
161 70
159 75
158 78
157 80
15
96 157
93 163
88 176
82 184
78 193
75 201
72 212
72 224
72 238
73 254
75 267
78 277
82 286
89 298
89 300
9
33 428
33 428
33 427
35 426
36 425
30 427
27 428
27 428
28 428
16
2 435
5 434
10 432
13 431
16 429
19 427
21 426
22 425
24 424
26 423
27 423
30 422
33 422
34 421
36 420
36 419
77
32 436
55 423
67 415
75 409
86 401
92 395
98 389
105 378
107 372
111 362
112 355
116 345
119 338
121 328
124 317
125 312
125 304
126 294
125 288
124 280
125 277
125 258
124 255
125 241
128 235
135 225
141 218
147 211
155 208
166 205
178 203
194 202
209 203
219 204
232 205
249 206
259 207
284 205
300 198
317 189
333 182
345 170
362 153
392 135
430 118
450 104
477 91
509 75
539 65
567 61
599 60
625 59
635 58
632 54
616 51
602 46
593 46
580 45
565 41
546 38
526 36
502 42
487 48
468 53
452 57
434 63
414 71
397 77
378 82
366 86
352 90
338 92
328 91
319 88
307 86
306 85
301 85
14
318 106
333 107
346 109
359 111
369 104
391 100
411 95
431 87
445 81
458 71
473 63
491 59
497 57
499 56
7
244 109
235 104
221 100
208 96
199 97
190 98
190 98
8
160 116
165 119
171 122
172 127
170 135
168 144
170 149
174 149
4
169 118
174 120
179 124
178 126
8
293 132
294 125
297 115
291 94
287 90
290 84
297 79
297 79
6
144 97
143 83
144 72
141 58
136 52
134 49

http://www.opengl.org/discussion_boards/ubb/biggrin.gif

Lemmy
02-27-2003, 08:56 AM
Hope this is what your looking for.

Nexus any chance of answering my question
Its a teny tiny bit harder

http://www.opengl.org/discussion_boards/ubb/smile.gif

nexusone
02-28-2003, 09:49 AM
Here is a little glut program let's you draw lines on the screen, with rubber band effect.

Also have a routine adjustment to make it draw quads also, is not ready as of this post.

left mouse down starts line, mouse up ends line.
ESC = quit
No save or load at this time.
Limited to 50 lines!!




// GlutDrawWindow.c
// By Eric Stringer 2002
// Simple examples of OpenGL and Glut usage.
// Keyboard input
// 'v' = view ortho/perspective
// 'l' = lighting on/off


#include <windows.h> // This header file will be needed for some windows compilers
//#include <GL/gl.h> // gl.h and glu.h also maybe needed for some compilers
//#include <GL/glu.h>
#include <GL/glut.h> // glut (gl utility toolkit) basic windows functions, keyboard, mouse.
#include <stdio.h> // standard (I/O library)
#include <stdlib.h> // standard library (set of standard C functions
#include <math.h> // Math library (Higher math functions )

int window_1, window_2;

// lighting
GLfloat LightAmbient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat LightDiffuse[]= { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat LightPosition[]= { 5.0f, 25.0f, 15.0f, 1.0f };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };

typedef struct VECTOR_3D
{
GLfloat x, y ,z;
}v3D;

// Define temp line variables
int line_start;

VECTOR_3D line_temp[2];

// Storage for our lines
VECTOR_3D line_array[100];
static int line_index = 0;


static int view_state = 0, light_state = 0;

static float Mouse_x, Mouse_y, Win_x, Win_y;

int spin;

// I use this to put text on the screen
void Sprint( int x, int y, char *st)
{
int l,i;

l=strlen( st ); // see how many characters are in text string.
glRasterPos2i( x, y); // location to start printing text
for( i=0; i < l; i++) // loop until i is greater then l
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]); // Print a character on the screen
}

}


// This creates the spinning of the cube.
static void TimeEvent(int te)
{

spin++; // increase cube rotation by 1
if (spin > 360) spin = 0; // if over 360 degress, start back at zero.
glutSetWindow(window_1);
glutPostRedisplay(); // Update screen with new rotation data
glutSetWindow(window_2);
glutPostRedisplay();
glutTimerFunc( 100, TimeEvent, 1); // Reset our timmer.
}


// Setup our Opengl world, called once at startup.
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0); // When screen cleared, use black.
glShadeModel (GL_SMOOTH); // How the object color will be rendered smooth or flat
glEnable(GL_DEPTH_TEST); // Check depth when rendering
// Lighting is added to scene
glLightfv(GL_LIGHT1 ,GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1 ,GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1 ,GL_POSITION, LightPosition);
glEnable(GL_LIGHTING); // Turn on lighting
glEnable(GL_LIGHT1); // Turn on light 1
}

// Draw our world
void display_1(void)
{
int i;

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the screen

glMatrixMode (GL_PROJECTION); // Tell opengl that we are doing project matrix work
glLoadIdentity(); // Clear the matrix
glOrtho(-8.0, 8.0, -8.0, 8.0, 0.0, 30.0); // Setup an Ortho view
glMatrixMode(GL_MODELVIEW); // Tell opengl that we are doing model matrix work. (drawing)
glLoadIdentity(); // Clear the model matrix
// print view state on screen
glColor3f( 1.0, 1.0, 1.0);
Sprint(-2, 4, "Ortho view");


// Lighting on/off
if (light_state == 1)
{
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
}else
{
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
}

if (line_start == 1)
{
glColor3f( 1.0, 0.0, 0.0); // Line Color
glBegin(GL_LINES);
glVertex2f(line_temp[0].x, line_temp[0].y);
glVertex2f(line_temp[1].x, line_temp[1].y);
glEnd();
}

// Process lines drawn
for(i = 0; i < line_index; i+=2)
{
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex2f(line_array[i].x, line_array[i].y);
glVertex2f(line_array[i+1].x, line_array[i+1].y);
glEnd();
}

glutSwapBuffers();
}

// This is called when the window has been resized.
void reshape_1 (int w, int h)
{
Win_x = w;
Win_y = h;
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
}

// Read the keyboard
void keyboard (unsigned char key, int x, int y)
{
switch (key)
{

case 'v':
case 'V':
view_state = abs(view_state -1);
break;
case 'l':
case 'L':
light_state = abs(light_state -1);
break;
case 27:
exit(0); // exit program when [ESC] key presseed
break;
default:
break;
}


}

void mouse(int button, int state, int x, int y)
{

Mouse_x = -8 + 16 * (x/Win_x);
Mouse_y = 8 - 16 * (y/Win_y);


if ((button == GLUT_LEFT_BUTTON) &amp;&amp; (state == GLUT_DOWN))
{
line_start = 1;
line_temp[0].x = Mouse_x;
line_temp[0].y = Mouse_y;
}

if ((button == GLUT_LEFT_BUTTON) &amp;&amp; (state == GLUT_UP))
{
line_start = 0;
line_temp[1].x = Mouse_x;
line_temp[1].y = Mouse_y;
line_array[line_index] = line_temp[0];
line_array[line_index+1] = line_temp[1];
line_index += 2;
}

}


void mouse_motion( int x, int y)
{

Mouse_x = -8 + 16 * (x/Win_x);
Mouse_y = 8 - 16 * (y/Win_y);
if (line_start == 1)
{
line_temp[1].x = Mouse_x;
line_temp[1].y = Mouse_y;
}
}


// Main program
int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutTimerFunc( 10, TimeEvent, 1);
glutInitWindowSize (500, 500);
glutInitWindowPosition (10, 10);
window_1 = glutCreateWindow (argv[0]);
glutSetWindowTitle("GlutDraw");
glutDisplayFunc(display_1);
glutReshapeFunc(reshape_1);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(mouse_motion);
init ();

glutMainLoop();
return 0;
}


[This message has been edited by nexusone (edited 02-28-2003).]