• ### What is your GameDev Story?

#### Archived

This topic is now archived and is closed to further replies.

# select, drag, modify

This topic is 5819 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I have problem about picking, selection with special issue which is "drag and modify" selected object in OpenGL... Helps, tutorials suggestions or references will greatly be appreciated... Thanx you all...

##### Share on other sites
I once did sth with picking and selecting in opengl.
I was so excited about several exercises i did for
my computer graphic lessons, so i wrote a
strategy-game-style-low-graphic-demonstration:

    // glutSelect.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung.//// #include "stdafx.h"#include <GL/glut.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#define	 EDGE		20.0double sq(double n){	return n * n;}struct POINT{	double x, y;};class	CRect{public:	double	x, y;	double	ax, ay;	double	width, height;		double  r, g, b;	bool	selected;	bool	mouseover;	CRect()	{		// position		x = 0.0;		y = 0.0;		// destination		ax = x;		ay = y;		// measures of rect		width = EDGE;		height = EDGE;		// color		r = 1.0;		g = 1.0;		b = 1.0;		selected = false;		mouseover = false;	}	void move()	{		// if position != destination, move the damn rect		if (abs(x - ax) > 0.2 && abs(y - ay) > 0.2)		{			// compute dot product; dont know the english expression			double skalar = sqrt(sq(ax - x) + sq(ay - y));						// the uniformed (normalized?) vector			POINT d = {(ax - x) / skalar, (ay - y) / skalar};			// move the rect in the vector's direction			x += d.x;			y += d.y;			// just for the record:			// it would be better to make			// these calculations once			// since the dx, dy stay constant		}		glutPostRedisplay();	}	void draw()	{		// color depends on state		if (selected)	// red			glColor3d(1.0, 0.0, 0.0);		else		if (mouseover)	// green			glColor3d(0.0, 1.0, 0.0);		else			// white			glColor3d(r, g, b);		glBegin(GL_POLYGON);		glVertex2d(x, y);		glVertex2d(x + width, y + height);		glVertex2d(x, y + height);		glVertex2d(x, y);		glVertex2d(x + width, y);		glVertex2d(x + width, y + height);		glEnd();	}};POINT	select;POINT	cursor;POINT	center;int		screen_height = 500;int		screen_width = 500;// selecting variablesbool	selecting = false;bool	add_select = false;// the reckless rectsCRect	rect[25];void keyboard(unsigned char key, int x, int y){	if (key == 27)		exit(0);}void display(void){	glClearColor(0.4, 0.4, 0.4, 1);	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// draw all rects	for (int i = 0; i < 25; i++)		rect[i].draw();	// Draw Select Box here from stored select position to current cursor position	glColor3d(1.0, 1.0, 1.0);	if (selecting)	{		glBegin(GL_LINES);		// upper border		glVertex2f(select.x, select.y);		glVertex2f(cursor.x, select.y);		// right border		glVertex2f(cursor.x, select.y);		glVertex2f(cursor.x, cursor.y);				// lower border		glVertex2f(cursor.x, cursor.y);		glVertex2f(select.x, cursor.y);			// left border		glVertex2f(select.x, cursor.y);		glVertex2f(select.x, select.y);		glEnd();	}	glutSwapBuffers();}void reshape(int width, int height){	screen_width = width;	screen_height = height;	glViewport(0, 0, width, height);	glMatrixMode(GL_PROJECTION);	glLoadIdentity();	gluOrtho2D(0.0, width, height, 0.0);	glMatrixMode(GL_MODELVIEW);	glLoadIdentity();}// is value bet between a and b?// important for select testingbool between(int bet, int a, int b){	if (a <= bet && bet <= b || 		b <= bet && bet <= a)		return true;	else		return false;}// tests wether a rect is inside the select boxbool selected(int i){	return (between(rect[i].x, select.x, cursor.x) && 			between(rect[i].y, select.y, cursor.y));}// important for rects holding formation while movingPOINT avg(){	POINT	avg = {0.0, 0.0};	int		sum = 0;	for (int i = 0; i < 25; i++)	{		if (rect[i].selected)		{			avg.x += rect[i].x;			avg.y += rect[i].y;			sum++;		}	}	if (sum != 0)	{		avg.x /= sum;		avg.y /= sum;	}	else	{		avg.x = 0.0;		avg.y = 0.0;	}	return avg;}// tests wether mouse cursor is inside a rect// important for click testingbool mouseover(int i){	return (between(cursor.x, rect[i].x, rect[i].x + rect[i].width) && 			between(cursor.y, rect[i].y, rect[i].y + rect[i].height));}void mouse(int button, int state, int x, int y){	cursor.x = x;	cursor.y = y;	if (button == GLUT_LEFT_BUTTON)	{		// if left mouse button is pressed or clicked		if (state == GLUT_DOWN)		{			selecting = true;			// test wether CTRL is pressed			// important for add-selecting			add_select = false;			int mod = glutGetModifiers();			if (mod == GLUT_ACTIVE_CTRL)				add_select = true;			// if CTRL is pressed, dont unselect selected rects			if (!add_select)			{				for (int i = 0; i < 25; i++)					rect[i].selected = false;			}			// store current cursor position in variable select			select.x = cursor.x;			select.y = cursor.y;		}		else		{			// left button is released			// no more selecting			selecting = false;			// if the cursor is inside a rect and the rect is not selected			// select it			// otherwise deselect it			for (int i = 0; i < 25; i++)			{				if (mouseover(i))				{					if (!rect[i].selected) 						rect[i].selected = true;					else						rect[i].selected = false;				}			}		}	}		// right button: sets destination for the rects	if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)	{		// compute center of all selected items		// check avg() for code		center.x = avg().x;		center.y = avg().y;		// for every selected rect, set the destination point		// the current cursor position (x,y) is the destination point for center		// for destination point of a rect, calculate dx,dy from rect to center		// and add (dx, dy) to the current cursor position		// the computed value is the destination point of a rect!!		for (int i = 0; i < 25; i++)		{			if (rect[i].selected)			{				rect[i].ax = x - (center.x - rect[i].x);				rect[i].ay = y - (center.y - rect[i].y);			}		}	}	glutPostRedisplay();}void mouseMotion(int x, int y){	// updates the selected/unselected state of the rects	if (selecting)	{		for (int i = 0; i < 25; i++)		{			// check if rect is inside select box			if (selected(i))				rect[i].selected = true;			else				rect[i].selected = false;		}		// update cursor position		cursor.x = x;		cursor.y = y;	}		glutPostRedisplay();}void mousePassiveMotion(int x, int y){	// update cursor position if no button is pressed	cursor.x = x;	cursor.y = y;	// checks for mouseover event, should be obvious	for (int i = 0; i < 25; i++)	{		if (mouseover(i))			rect[i].mouseover = true;		else			rect[i].mouseover = false;	}	glutPostRedisplay();}void idle(){	// move the rects, if necessary:	// if (position != destination)	// check for code in move()	for (int i = 0; i < 25; i++)	{		rect[i].move();	}}int main(int argc, char* argv[]){	for (int i = 0; i < 25; i++)		rect[i] = CRect();	cursor.x = cursor.y = 0.0;	select.x = select.y = 0.0;	center.x = center.y = 0.0;	//counter for rects	int r = 0;	// (i,j) initial positions of rects	for (i = 10 * EDGE; i < 20 * EDGE; i += 2 * EDGE)	{		for (int j = 10 * EDGE; j < 20 * EDGE; j += 2 * EDGE)		{			rect[r].x = i;			rect[r].y = j;			rect[r].ax = i;			rect[r].ay = j;			r++;		}	}	glutInit(&argc, argv);	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);	glutInitWindowSize(screen_height, screen_width);	glutInitWindowPosition(100, 100);	glutCreateWindow("Select - Rahmen");	glutDisplayFunc(display);	glutKeyboardFunc(keyboard);	glutReshapeFunc(reshape);	glutIdleFunc(idle);	glutMouseFunc(mouse);	glutMotionFunc(mouseMotion);	glutPassiveMotionFunc(mousePassiveMotion);	glutMainLoop();	return 0;}

Hold CTRL for add selecting as noted in the code.
There are some leaks in the selection, but i'm too lazy,
to stuff them.

[edited by - Christian Schlager on February 10, 2003 9:13:14 PM]

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 15
• 14
• 46
• 22
• 27
• ### Forum Statistics

• Total Topics
634046
• Total Posts
3015225
×