LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-13-2003, 10:05 AM   #1
chichibabin
Member
 
Registered: Sep 2003
Posts: 63

Rep: Reputation: 15
A simple graphical display


Hi all,
I am working on a project in c++ which involves generating the 2D positions of a number of small disks (or points) over a period of time. The coordinates of the disks are stored in a simple array:
r[2][400]
The 2 corresponds to the x and y coordinates and the 400 represents the number of disks. Throughout the program the coordinates are modified numerous times. What I am trying to produce is a visual window which can display the movement of the disks as line trajectories. .i.e a straight line is drawn from the previous position to the new one for each of the 400 disks throughout the program. I've looked at Xlib and it all seems beyond my experience and I am currently pulling my hair out with QT.
Does anyone know the most simplistic way to go about this or could they even post a sample of code. I do not need buttons, text boxes etc. just a window drawing lines which can be updated during the program. Ideally I require a function that accepts the r[2][400] array and updates the window with the new values.
Many thanks in advance
Sat
 
Old 10-13-2003, 01:27 PM   #2
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Qt seems useful for this. Check the first Qt-tutorial at:

http://doc.trolltech.com/3.2/tutorial.html

It teaches step-bystep how to draw things on a windows.
 
Old 10-14-2003, 01:49 AM   #3
megaspaz
Senior Member
 
Registered: Nov 2002
Location: Silly Con Valley
Distribution: Red Hat 7.3, Red Hat 9.0
Posts: 2,054

Rep: Reputation: 46
maybe look into glut. look for the glut rpm and glut-devel rpms. the latest version right now is 3.7.

http://www.google.com/search?hl=en&l...=Google+Search

check this out for glut tuts.

http://www.google.com/search?hl=en&l...=Google+Search

here's an old project i did in college that's kinda like what you're doing.
the particles generated are connected by lines. they are also random,
but you can make it more structured. you need to create the keyboard input for updating the display. it's unix friendly and compiles using gcc 2.96

Code:
#include <iostream>
//#include <windows.h>
#include <cstdlib>
#include <string>
#include <sstream>
#include <math.h>
#include <exception>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

using namespace std;

#define WIN_SZ_WID 500
#define WIN_SZ_SIZE 500
#define WIN_POS_X 100
#define WIN_POS_Y 100
#define NUM_PARTICLES 1000
#define MAX_NEW 20
#define MIN_NEW 5	 //needs to be greater than 0 
                                 //or no points will be activated
#define MAX_AGE 100
#define CYL_HIEGHT 4.0
#define CYL_BASE_WID 4.0
#define CYL_TOP_WID 1.0
#define QUAD_SLICE 100
#define QUAD_STACK 2
#define D_RING 12
#define D_IN_RAD 0.0
#define LINE_WID 2.0
#define PI 3.14159265

//instantiate quadric
GLUquadricObj *my_cyl;
GLUquadricObj *cyl_top_disk;
GLdouble cyl_base;	//base radius
GLdouble cyl_top;	//top radius
float scaling, rotz, rotx, roty;	//for viewing
int new_particles;

typedef struct particle
{
	float pos[3];
	float prev_pos[3];
	float vel[3];
	float age;
} Particle;

Particle particles[NUM_PARTICLES];
float accel[] = {0.0,0.0,-0.1};

//function prototypes
void instructions ();
void initParticles ();
void initCylinder ();
void moveAndDrawParticles ();
void drawCylinder ();
void init ();
void reshape (int w, int h);
void display ();
void keyboard (unsigned char key, int x, int y);

//start program
int main (int argc, char* argv[])
{
	try
	{
		instructions ();
		glutInit(&argc, argv);
		glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
		glutInitWindowSize (WIN_SZ_WID, WIN_SZ_SIZE);
		glutInitWindowPosition (WIN_POS_X, WIN_POS_Y);
		glutCreateWindow ("PARTICLES BY MEGASPAZ");
		init ();

		initCylinder ();
		initParticles ();
		
		glutDisplayFunc (display);
		glutReshapeFunc (reshape);
		glutKeyboardFunc (keyboard);
		glutIdleFunc (display);
		glutMainLoop ();
		return 0;
	}
	catch (exception& e)
	{
		cout <<"Error: " <<e.what () <<endl;
		return 1;
	}
	catch (...)
	{
		cout <<"An Unknown Error Occurred...Exiting" <<endl;
		return 1;
	}
}

void initParticles ()
{
	int i,j;
	for (i = 0; i < NUM_PARTICLES; i++)
	{
		for (j = 0; j < 3; j++)
		{
			particles[i].pos [j] = 0.0;
			particles[i].vel [j] = 0.0;
		}
		particles[i].age = -1;	//inactive
	}
}

void initCylinder ()
{
	cyl_base = CYL_BASE_WID;
	cyl_top = CYL_TOP_WID;
	//init the cylinder
	my_cyl = gluNewQuadric ();
	gluQuadricDrawStyle (my_cyl,GLU_FILL);
	//init cylinder's top - disk
	cyl_top_disk = gluNewQuadric ();
	gluQuadricDrawStyle (cyl_top_disk, GLU_FILL);
}

void moveAndDrawParticles ()
{
	int i,j,numToActivate;

	//retire old particles
	for (i = 0; i < NUM_PARTICLES; i++)
	{
		if (particles[i].age > MAX_AGE)
		{
			particles[i].age = -1;
		}
	}
	//activate some new ones
	numToActivate = new_particles;
	for (i = 0; i < NUM_PARTICLES; i++)
	{
		float r_num, x, y, angle;

		//generate random numbers for angle, x and y coordinates
		r_num = (rand()%1000) / (1000.0 - 0.5) * cyl_top;
		angle = (rand()%1000) / 1000.0 * 2 * PI;
		x = r_num * cos (angle);
		y = r_num * sin (angle);


		if (-1 == particles[i].age)
		{
			particles[i].age = 0;
			particles[i].pos [0] = x;
			particles[i].pos [1] = y;
			particles[i].pos [2] = CYL_HIEGHT;
			particles[i].vel [0] = (rand()%1000) / 1000.0 - 0.5;
			particles[i].vel [1] = (rand()%1000) / 1000.0 - 0.5;
			particles[i].vel [2] = 2.0 + (rand()%1000) / 1000.0;
			
			if (--numToActivate == 0)
			{
				break;
			}
		}
	}
	//move and age the active ones
	for (i = 0; i < NUM_PARTICLES; i++)
	{
		if (particles[i].age != -1)
		{
			particles[i].age += 1;
			for (j = 0; j < 3; j++)
			{
				//get previous position
				particles[i].prev_pos [j] = particles[i].pos [j];
				//assign new position
				particles[i].pos [j] += particles[i].vel [j];
				particles[i].vel [j] += accel[j];
			}
		}
	}
	//deactivate lighting
	glDisable (GL_LIGHTING);
	//draw active ones
	glLineWidth (LINE_WID);	//set line width in pixels
	glBegin( GL_LINES );	//begin drawing lines
	for (i = 0; i < NUM_PARTICLES; i++)
	{
		if (particles[i].age != -1)
		{
			//change color of line based on particle age
			if (particles[i].age < MAX_AGE * 0.25)
			{
				glColor3f (1.0, 1.0, 1.0);	//white
			}
			else if (particles[i].age >= MAX_AGE * 0.25 && particles[i].age < MAX_AGE * 0.5)
			{
				glColor3f (1.0, 1.0, 0.0);	//yellow
			}
			else
			{
				glColor3f (1.0, 0.2, 0.0);	//orange
			}
			glVertex3fv (particles[i].prev_pos);	//start point
			glVertex3fv (particles[i].pos);			//end point
		}
	}
	glEnd ();
	//reactivate lighting
	glEnable (GL_LIGHTING);
}

void drawCylinder ()
{
	gluCylinder (my_cyl, cyl_base, cyl_top, CYL_HIEGHT, QUAD_SLICE, QUAD_STACK);
	//push matrix on stack
	glPushMatrix ();
	//set color for disk
	glColor3f (0.2, 0.0, 0.4);	//purple-ish
	//translate disk to cylinder hieght
	glTranslatef (0.0, 0.0, CYL_HIEGHT);
	//draw top of cylinder
	gluDisk (cyl_top_disk, D_IN_RAD, cyl_top, QUAD_SLICE, D_RING);
	//pop matrix
	glPopMatrix ();
}

void init ()
{
	new_particles = MIN_NEW;
	GLfloat lightPos[] = { 1.0, 0.0, 1.0, 0.0 };
	GLfloat lightPos2[] = { 1.0, 0.0, -1.0, 0.0 };
	GLfloat lt_color[] = { 0.0, 0.0, 1.0, 0.0};	//blue
	GLfloat amb_color[] = { 0.0, 0.0, 0.0, 0.0 };	//black
	glClearColor (0.0, 0.0, 0.0, 0.0);
	glShadeModel (GL_SMOOTH);

	glLightfv (GL_LIGHT0, GL_POSITION, lightPos );
	glLightfv (GL_LIGHT1, GL_POSITION, lightPos2 );
	glLightfv (GL_LIGHT0, GL_DIFFUSE, lt_color );
	glLightfv (GL_LIGHT1, GL_DIFFUSE, lt_color );
	glLightfv (GL_LIGHT0, GL_AMBIENT, amb_color );
	glLightfv (GL_LIGHT1, GL_AMBIENT, amb_color );
	glEnable (GL_LIGHTING);
	glEnable (GL_LIGHT0);
	glEnable (GL_LIGHT1);

	glEnable (GL_DEPTH_TEST);
	scaling = 1.0;
	rotz = rotx = roty = 0.0;
}

void reshape (int w, int h)
{
	glViewport (0,0,(GLsizei) w, (GLsizei) h);
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();
	gluPerspective (90.0, (GLfloat) w / (GLfloat) h, 1.0, 1000.0);
	glMatrixMode (GL_MODELVIEW);
}

void display ()
{
	static float frame = 0;
	glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glPushMatrix ();
	glLoadIdentity ();
	//viewing transfromation
	gluLookAt (0.0,0.0,10.0, 0.0,0.0,0.0, 0.0,1.0,0.0);
	glScalef (scaling,scaling,scaling);
	glRotatef (roty,0.0,1.0,0.0);
	glRotatef (rotx,1.0,0.0,0.0);
	glRotatef (rotz, 0.0,0.0,1.0);
	
	drawCylinder ();
	moveAndDrawParticles ();

	glPopMatrix ();
	glutSwapBuffers ();
}

void keyboard (unsigned char key, int x, int y)
{
	switch (key)
	{
		case 'F':
		case 'f':
			scaling *= 1.1;
			break;
		case 'B':
		case 'b':
			scaling *= 0.9;
			break;
		case 'U':
		case 'u':
			rotx -= 2;
			break;
		case 'D':
		case 'd':
			rotx += 2;
			break;
		case 'R':
		case 'r':
			roty -= 2;
			break;
		case 'L':
		case 'l':
			roty += 2;
			break;
		case 'A':
		case 'a':
			rotz -= 2;
			break;
		case 'Z':
		case 'z':
			rotz += 2;
			break;
		case 'W':
		case 'w':
			cyl_base += 1.0;
			cyl_top += 1.0;
			break;
		case 'E':
		case 'e':
			if (cyl_base > CYL_BASE_WID && cyl_top > CYL_TOP_WID)
			{
				cyl_base -= 1.0;
				cyl_top -= 1.0;
			}
			else
			{
				cyl_base = CYL_BASE_WID;
				cyl_top = CYL_TOP_WID;
			}
			break;
		case 'P':
		case 'p':
			if (new_particles < MAX_NEW)
			{
				new_particles += 1;
			}
			else
			{
				new_particles = MAX_NEW;
			}
			break;
		case 'O':
		case 'o':
			if (new_particles > MIN_NEW)
			{
				new_particles -= 1;
			}
			else
			{
				new_particles = MIN_NEW;
			}
			break;
		case 'Q':
		case 'q':
			exit (0);
			break;
	}
	glutPostRedisplay();
}

void instructions ()
{
	string input;

	cout <<endl <<endl;
	cout <<"Keyboard Commands" <<endl;
	cout <<"-----------------" <<endl;
	cout <<endl;
	cout <<"f - Zoom In" <<endl;
	cout <<"b - Zoom Out" <<endl;
	cout <<"u - Rotate up X Axis" <<endl;
	cout <<"d - Rotate Down X Axis" <<endl;
	cout <<"r - Rotate Down Y Axis" <<endl;
	cout <<"l - Rotate Up Y Axis" <<endl;
	cout <<"a - Rotate Down Z Axis" <<endl;
	cout <<"z - Rotate Up Z Axis" <<endl;
	cout <<"w - Increase Cylinder Radius" <<endl;
	cout <<"e - Decrease Cylinder Radius" <<endl;
	cout <<"p - Increase New Particle Amount" <<endl;
	cout <<"o - Decrease New Particle Amount" <<endl;
	cout <<"q - Quit" <<endl;
	cout <<endl;

	//Microsoft STL getline has bug where you have press enter twice
	//need to ignore buffer after getline as cin will leave garbage.
	//but using ignore will exaserbates the double return problem as all
	//input-ed strings need double return for getline to get the string.
	//But string is as it was input-ed
	cout <<"Enter Any Key To Continue - \"q\" To Quit: ";
	cout <<endl;
	getline (cin,input);	//bad implementation to a good idea
	//uncomment cin.ignore if compiling on Unix or Linux
	//cin.ignore ();	//wouldn't be unnecessary if Microsoft didn't screw up std::getline
	cout <<endl;
	if (input == "Q" || input == "q")
	{
		exit (0);
	}
this is the command to compile it:

g++ -o particles.exe parti.cpp /usr/lib/libglut.so.3.7



edit: assuming your video card has opengl support and that opengl is enabled in your linux configuration.

Last edited by megaspaz; 10-14-2003 at 02:00 AM.
 
Old 10-14-2003, 06:13 AM   #4
chichibabin
Member
 
Registered: Sep 2003
Posts: 63

Original Poster
Rep: Reputation: 15
Thanks for the code. I'm having problems compiling with the command you suggest:
g++ -o particles.exe parti.cpp /usr/lib/libglut.so.3.7
I have glut 3.7 installed and the .so file present in the /usr/lib path??
Cheers
Sat
 
Old 10-14-2003, 11:17 AM   #5
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Quote:
g++ -o particles.exe parti.cpp /usr/lib/libglut.so.3.7[/B]
Try this instead:
Code:
g++ -lglut -o particles.exe parti.cpp
 
Old 10-14-2003, 11:32 AM   #6
chichibabin
Member
 
Registered: Sep 2003
Posts: 63

Original Poster
Rep: Reputation: 15
I still get the same compilation errors:
parti.cpp:10:21: GL/glut.h: No such file or directory
parti.cpp: In function `int main(int, char**)':
parti.cpp:69: `glutInit' undeclared (first use this function)
parti.cpp:69: (Each undeclared identifier is reported only once for each
function it appears in.)
parti.cpp:70: `GLUT_DOUBLE' undeclared (first use this function)
parti.cpp:70: `GLUT_RGB' undeclared (first use this function)
parti.cpp:70: `GLUT_DEPTH' undeclared (first use this function)
parti.cpp:70: `glutInitDisplayMode' undeclared (first use this function)
parti.cpp:71: `glutInitWindowSize' undeclared (first use this function)
parti.cpp:72: `glutInitWindowPosition' undeclared (first use this function)
parti.cpp:73: `glutCreateWindow' undeclared (first use this function)
parti.cpp:79: `glutDisplayFunc' undeclared (first use this function)
parti.cpp:80: `glutReshapeFunc' undeclared (first use this function)
parti.cpp:81: `glutKeyboardFunc' undeclared (first use this function)
parti.cpp:82: `glutIdleFunc' undeclared (first use this function)
parti.cpp:83: `glutMainLoop' undeclared (first use this function)
parti.cpp: In function `void display()':
parti.cpp:278: `glutSwapBuffers' undeclared (first use this function)
parti.cpp: In function `void keyboard(unsigned char, int, int)':
parti.cpp:362: `glutPostRedisplay' undeclared (first use this function)

Cheers,
Sat
 
Old 10-14-2003, 07:50 PM   #7
megaspaz
Senior Member
 
Registered: Nov 2002
Location: Silly Con Valley
Distribution: Red Hat 7.3, Red Hat 9.0
Posts: 2,054

Rep: Reputation: 46
it looks like that the glut.h header file isn't in your include directory. try doing a search for glut.h

for me all my gl files are in /usr/include/GL

Quote:
[prompt]$ dir /usr/include/GL
total 480
-rw-r--r-- 1 root root 60468 Aug 7 1998 fgl.h
-rw-r--r-- 1 root root 7273 Aug 7 1998 fglu.h
-rw-r--r-- 1 root root 10152 Aug 7 1998 fglut.h
-r--r--r-- 1 root root 147494 May 14 06:05 glext.h
-r--r--r-- 1 root root 77761 May 14 06:05 gl.h
-rw-r--r-- 1 root root 5150 Aug 7 1998 glsmap.h
-r--r--r-- 1 root root 15916 May 14 06:05 glu.h
-rw-r--r-- 1 root root 20844 Aug 7 1998 glut.h
-r--r--r-- 1 root root 7828 May 14 06:05 GLwDrawA.h
-r--r--r-- 1 root root 4433 May 14 06:05 GLwDrawAP.h
-r--r--r-- 1 root root 2309 May 14 06:05 GLwMDrawA.h
-r--r--r-- 1 root root 2311 May 14 06:05 GLwMDrawAP.h
-r--r--r-- 1 root root 6817 May 14 06:05 glx.h
-r--r--r-- 1 root root 2543 May 14 06:05 glxint.h
-r--r--r-- 1 root root 2453 May 14 06:05 glxmd.h
-r--r--r-- 1 root root 51727 May 14 06:05 glxproto.h
-r--r--r-- 1 root root 8370 May 14 06:05 glxtokens.h
-r--r--r-- 1 root root 8015 May 14 06:05 osmesa.h
[prompt]$
also, did you install the glut-devel package matching your version of glut? you may need to do that.

Last edited by megaspaz; 10-14-2003 at 10:12 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
No Graphical Display nuttyvishal4u Linux - Hardware 1 02-23-2005 08:09 AM
no graphical display gjo *BSD 6 02-14-2005 07:10 AM
I need my graphical display back! Eileen Linux - Software 11 01-31-2005 11:26 PM
Easy to use graphical firmat for simple pictures fredgt Programming 3 08-14-2004 11:34 AM
Simple graphical linux programming language? Nerd2 Linux - Software 4 05-03-2003 07:12 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:17 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration