PDA

View Full Version : Streaming input to OpenGL program on Linux



AMULYA
06-08-2011, 05:04 PM
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?

Dark Photon
06-09-2011, 04:02 AM
I have a program which outputs the values of x and y coordinates. ... pipe the output of this program to my OpenGL program ... my OpenGL program prints those coordinates on the screen........Note that I dont want to get all the input first. ... 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.

The Little Body
07-13-2011, 12:21 PM
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\n", 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", &amp;posx, &amp;posy, &amp;posz) > 0 )
{
printf("POS READ : %f %f %f %d \n", 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 \n", 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(&amp;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(&amp;DrawGLScene);

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

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

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

/* Register the function called when the keyboard is pressed. */
glutKeyboardFunc(&amp;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 \n", 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", &amp;posx, &amp;posy, &amp;posz, &amp;red, &amp;green, &amp;blue) > 0 )
{
printf( "%f %f %f %f %f %f \n", 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 :)

The Little Body
07-13-2011, 08:53 PM
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,strin g[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 \n", 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();
}

The Little Body
07-14-2011, 12:32 PM
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 \n", Xfunc(t), Yfunc(t), Zfunc(t), fabs(sin(t)), fabs(cos(t)), fabs(sin(t)*cos(t)) );
}
return 0;
}