Streaming input to OpenGL program on Linux

Hi,

I have a program which outputs the values of x and y coordinates
.Now, what I want is that I pipe the output of this program to my OpenGL program and as they are coming, my OpenGL program prints those coordinates on the screen…Note that I dont want to get all the input first.

It’s like…i get one coordinate from the piped input…and i display it on the screen…and so on…

How do I do this?

This isn’t really an OpenGL question, but in UNIX/Linux, this is simple. Write your OpenGL program to read the numbers from standard input, and then pipe the output of your xy_generator program to this program when you execute the commands:

xy_generator | my_gl_reader

When xy_generator exits (or closes its stdout), then my_gl_reader gets EOF on its stdin.

Alternatively, you can invoke xy_generator internal to my_gl_reader via popen(), and get a handle to its stdout that way too.

There are other ways as well.

Amulyaa,

Here is a very basic sample using a generator pipelined with a GL program.

The generator (genpoints[.c]) :


#include <stdio.h>

int main(int argc, char **argv)
{
	float x=-5;
	for(;;)
	{
		printf("%f %f %f
", x,0,0);
		if(x<5)
		{
			x+=0.01;
		}else{
			x=-5;
		}
	}
	return 0;
}

The basic OpenGL program (glpipe[.c]):


#include <GL/glut.h>    // Header File For The GLUT Library 
#include <GL/gl.h>	// Header File For The OpenGL32 Library
#include <GL/glu.h>	// Header File For The GLu32 Library
#include <unistd.h>     // needed to sleep
#include <stdio.h>

/* ASCII code for the escape key. */
#define ESCAPE 27

/* The number of our GLUT window */
int window;

// float step=-5;
int ready=0;
float posx=0, posy=0, posz=0;

void ReadAndDrawPoint()
{
	 if( fscanf(stdin,"%f %f %f", &posx, &posy, &posz) > 0 )
	 {
		printf("POS READ : %f %f %f %d 
", posx, posy, posz);
		ready = 1;
	 }

	 glColor3f(1.0f,1.0f,1.0f);
         glBegin(GL_POINTS);
		if(ready)
		{
			ready=0;
			printf("POS WRITE : %f %f %f 
", posx, posy, posz);
		}
		glVertex3f(posx,posy,posz);
		// glVertex3f(step,0,0);
		// step += 0.01;
	glEnd();
}


/* A general OpenGL initialization function.  Sets all of the initial parameters. */
void InitGL(int Width, int Height)	        // We call this right after our OpenGL window is created.
{
  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);		// This Will Clear The Background Color To Black
  glClearDepth(1.0);				// Enables Clearing Of The Depth Buffer
  glDepthFunc(GL_LESS);			        // The Type Of Depth Test To Do
  glEnable(GL_DEPTH_TEST);		        // Enables Depth Testing
  glShadeModel(GL_SMOOTH);			// Enables Smooth Color Shading

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();				// Reset The Projection Matrix

  gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);	// Calculate The Aspect Ratio Of The Window

  glMatrixMode(GL_MODELVIEW);
}

/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
void ReSizeGLScene(int Width, int Height)
{
  if (Height==0)				// Prevent A Divide By Zero If The Window Is Too Small
    Height=1;

  glViewport(0, 0, Width, Height);		// Reset The Current Viewport And Perspective Transformation

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
  glMatrixMode(GL_MODELVIEW);
}

/* The main drawing function. */
void DrawGLScene()
{
  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);	// Clear The Screen And The Depth Buffer

  glLoadIdentity();				// Reset the transformation matrix.
  glTranslatef(0.0f,0.0f,-7.0f);		// Move Right 3 Units, and back into the screen 7
	
  ReadAndDrawPoint();

  // swap the buffers to display, since double buffering is used.
  glutSwapBuffers();
}

/* The function called whenever a key is pressed. */
void keyPressed(unsigned char key, int x, int y) 
{
    /* avoid thrashing this call */
    usleep(100);

    /* If escape is pressed, kill everything. */
    if (key == ESCAPE) 
    { 
      /* shut down our window */
      glutDestroyWindow(window); 
      
      /* exit the program...normal termination. */
      exit(0);                   
    }
}

int main(int argc, char **argv) 
{  
  /* Initialize GLUT state - glut will take any command line arguments that pertain to it or 
     X Windows - look at its documentation at http://reality.sgi.com/mjk/spec3/spec3.html */  
  glutInit(&argc, argv);  

  /* Select type of Display mode:   
     Double buffer 
     RGBA color
     Alpha components supported 
     Depth buffered for automatic clipping */  
  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);  

  /* get a 640 x 480 window */
  glutInitWindowSize(640, 480);  

  /* the window starts at the upper left corner of the screen */
  glutInitWindowPosition(0, 0);  

  /* Open a window */  
  window = glutCreateWindow("Jeff Molofee's GL Code Tutorial ... NeHe '99");  

  /* Register the function to do all our OpenGL drawing. */
  glutDisplayFunc(&DrawGLScene);  

  /* Go fullscreen.  This is as soon as possible. */
  glutFullScreen();

  /* Even if there are no events, redraw our gl scene. */
  glutIdleFunc(&DrawGLScene);

  /* Register the function called when our window is resized. */
  glutReshapeFunc(&ReSizeGLScene);

  /* Register the function called when the keyboard is pressed. */
  glutKeyboardFunc(&keyPressed);

  /* Initialize our window. */
  InitGL(640, 480);
  
  /* Start Event Processing Engine */  
  glutMainLoop();  

  return 1;
}

And the Makefile :


all : glpipe genpoints

glpipe : glpipe.c
	gcc glpipe.c -o glpipe -lGL -lGLU -lglut

genpoints : genpoints.c
	gcc genpoints.c -o genpoints

This use standards unix pipes for to make the streaming :


/home/yannoo/Dev/pipe/genpoints | /home/yannoo/Dev/pipe/glpipe

Note, that this is only a very basic test that only draw a white pixel that move left to right then right to left …

With minors modifications, you can adapt genpoints.c and glpipe.c to your needs.

This is for example a streamed opengled and colored rotated point :


#include <stdio.h>
#include <math.h>

float circle_size = 50.0f;

float Xfunc(float t)
{
	return cos(t) * (t / circle_size);
}

float Yfunc(float t)
{
	return sin(t) * (t / circle_size);

}

float Zfunc(float t)
{
	// return cos(t) * sin(t) * t ;
	return 0.0f;
}

float Wfunc(float t)
{
	return 0.0f;
} 
	

int main(int argc, char **argv)
{
	float t;

	for( t = 0 ;  ; t += 0.005f)
	{
		// X Y Z R G B
		printf("%f %f %f %f %f %f 
", Xfunc(t), Yfunc(t), Zfunc(t), fabs(sin(t)), fabs(cos(t)), fabs(sin(t)*cos(t)) );
	}
	return 0;
}

and minors modifications into the glpipe.c :


#include <GL/gl.h>	// Header File For The OpenGL Library
#include <GL/glu.h>	// Header File For The GLu Library
#include <GL/glut.h>    // Header File For The GLUT Library 

#include <unistd.h>     // needed to sleep
#include <stdio.h>	// needed to IO streaming

/* ASCII code for the escape key. */
#define ESCAPE 27

/* Window size (width x height x bpp) */
#define WIN_WIDTH	320
#define WIN_HEIGHT	200
#define WIN_BPP		32


/* The number of our GLUT window */
int window;

/* The pixel position */
float posx=0, posy=0, posz=0;

/* The pixel color */
float red=1.0f, green=1.0f, blue=1.0f;


/* Read one XYZ RGB position from stdin, and output this to OpenGL via glcolor3f/glVertex3f() calls */    
void ReadAndDrawPoint()
{
		 if( fscanf(stdin,"%f %f %f %f %f %f", &posx, &posy, &posz, &red, &green, &blue) > 0 )
		 {
			printf(   "%f %f %f %f %f %f 
", posx, posy, posz, red, green, blue);
         		glBegin(GL_POINTS);
				glColor3f(red,green,blue);
				glVertex3f(posx,posy,posz);
			glEnd();
		 }
}

=> I project an OpenGL streamer for Wavefront .obj 3D files and/or .MD2/.MD3 quake models in a near futur :slight_smile:

You can too draw on // a string typed from the keyboard for example :

Only add this to the glpipe.c


char keyin[256]="\0";
int  nKeys=0;

void DrawString(char *string)
{
	int i, len;

        glDisable(GL_TEXTURE_2D);
        glColor3f(1.0f,1.0f,1.0f);
	glRasterPos2f(posx,posy);
	len=(int)strlen(string);
        for(i=0;i<len;i++)
        {
               	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,string[i]);
        }
        glEnable(GL_TEXTURE_2D);
}

...

And modify a litte the keyPressed() func for to handle the Del/Suppr keys :


/* The function called whenever a key is pressed. */
void keyPressed(unsigned char key, int x, int y) 
{
    /* avoid thrashing this call */
    usleep(100);

    /* If escape is pressed, kill everything. */
    if (key == ESCAPE) 
    { 
      /* shut down our window */
      glutDestroyWindow(window); 
      
      /* exit the program...normal termination. */
      exit(0);                   
    }

    // printf("key %d 
", key);
    if( (key == 0x7f) || (key == 8) || (key == 13) )
    { 
	keyin[--nKeys] = '\0'; 
    }
    else
    {
    	keyin[nKeys++] = key;
    	keyin[nKeys] = '\0';
    }
}

And the DrawGLScene() func for to handle the string typed on the keyboard :


/* The main drawing function. */
void DrawGLScene()
{
  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);	// Clear The Screen And The Depth Buffer

  glLoadIdentity();				// Reset the transformation matrix.
  glTranslatef(0.0f,0.0f,-7.0f);		// Move Right 3 Units, and back into the screen 7
	
  ReadAndDrawPoint();
  DrawString(keyin);

  // swap the buffers to display, since double buffering is used.
  glutSwapBuffers();
}

And finaly, for to have the streamed coordinates displayed you add DrawPosition() and modify the DrawGLScene() into the glpipe.c :


void DrawPosition()
{
	sprintf(keyin,"(%f-%f %f) \0", posx, posy, posz);
	DrawString(keyin);
} 

...

/* The main drawing function. */
void DrawGLScene()
{
  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);	// Clear The Screen And The Depth Buffer

  glLoadIdentity();				// Reset the transformation matrix.
  glTranslatef(0.0f,0.0f,-7.0f);		// Move Right 3 Units, and back into the screen 7
	
  ReadAndDrawPoint();
  //DrawString(keyin);
  DrawPosition();

  // swap the buffers to display, since double buffering is used.
  glutSwapBuffers();
}

And perhaps modify the scale for to have a more speed animation into genpoints.c :


int main(int argc, char **argv)
{
	float t;

	for( t = 0 ;  ; t += 0.01f)
	{
		// X Y Z R G B
		printf("%f %f %f %f %f %f 
", Xfunc(t), Yfunc(t), Zfunc(t), fabs(sin(t)), fabs(cos(t)), fabs(sin(t)*cos(t)) );
	}
	return 0;
}

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.