"Dynamic" trajectory graph in OpenGL

Hi folks,

I’d like to draw a ‘dynamic’ trajectory graph in OpenGL. More specifically: I’d like to plot a trajectory (whether in 2D or in 3D). The trajectory results from an integration of some equations of motion. Here is what I want:

  • plot the trajectory during the integration (ie assemble the trajectory by plotting a line between the two current values in the integration because I don’t want to store the data).
  • have the possibility to change automatically some parameters (through an optimization algorithm for instance) and plot the new trajectory. To explain it differently, I want to see the trajectory ‘evolving’ as I’m changing the parameters.

My problem is that I cannot manage to do it… What I see in the Opengl window is just the last segment of the trajectory, the others don’t show up. What I’m doing is that I’m having global variables that tell me where my previous and current trajectory points are, and my display callback function is drawing a line joining those 2 points.

Does somebody have an idea on how to do this properly ? Thanks a lot in advance !

Gregory

Put the whole array of values in the global variable, not just 2 last points.
I don’t see the difficulty here.
“because I don’t want to store the data” well you have to, otherwise it will not possible to see the ‘evolving’ trajectory.

How many points do you have for a trajectory ? thousands ? millions ? more ?

Well, I can have thousands of points, but the number is not really the problem. The issue is that I don’t know the number of points in advance (I’m using a variable step integrator), so if I want to store the entire trajectory I need a to allocate a dynamic array, which is a lot slower than a static array. But I guess you are right, I have no other choice!

To see the trajectory evolving, do I need to use the idle function ? This sounds a little awkward to me (idle is called all the time, but I just want to see a finite number of iterations). Do you see another way to update the graph ?

Thanks for the reply!

Gregory

You don’t have to make the GL calls each frame. You could render your plot to an off-screen surface (framebuffer object or just render to backbuffer and copy the pixels) each time the data changes, and then draw it as a textured screen-aligned quad each time the application window is reshaped and/or occluded by another one (otherwise overlapping windows will make rubbish out of your OpenGL display).

Hello,

How can you avoid making the GL calls each frame ?

Also, I guess you render the plot to an off-screen surface in the display callback function, but I don’t see how I can do that only when the data changes… In the same spirit, I don’t see how I can draw the textured screen-aligned quad only when the window is occluded by another one.

Gregory

you got it backward : in the display callback, only do ‘draw textured screen-aligned quad’.
when data changes, do the ‘render your plot to an off-screen surface’.

What age are you living in? Today computers come with gigs of RAM equipped and crunch GFLOPS, where everone uses interpreted dynamic languages and you complain about performance of dynamic arrays? Again, dynamic arrays are not slower then static arrays, the only performance drop occurs when the array has to grow, but you can preallocate a reasonable number of entries and grow the array in large bits.

You might be able to allocate a fixed-size array if you can place an upper bound on how much memory you’ll need.

Hello,

Thanks! I understand better now. But where can I find a good tutorial on textured screen-aligned quads ? I’m not really an expert…

Gregory

Screen-aligned quad means that you need to draw a quad that fills the whole screen. The classic approach is to set orthographic projection and draw a quad, like this:


	glPushAttrib(GL_VIEWPORT_BIT);
	// set the drawable region of the window
	glViewport(0, 0, w, h);

	// set up the projection matrix 
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();

	// just use orthographic projection
	glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -100.0f, 1000.0f);

	// go back to modelview matrix so we can move the objects about
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glColor4f(1.0, 1.0, 1.0, 0.0);
	glBegin(GL_QUADS);
		glTexCoord2f(0.0, 0.0); glVertex2f(1.0, 1.0);
		glTexCoord2f(0.0, 1.0); glVertex2f(1.0, -1.0);
		glTexCoord2f(1.0, 1.0); glVertex2f(-1.0, -1.0);
		glTexCoord2f(1.0, 0.0); glVertex2f(-1.0, 1.0);
	glEnd();

	glPopAttrib();

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();


Hello,

I came up with some code to do what people suggested me (render to an offscreen surface and then draw screen-aligned quads) but I cannot manage to make it work… So I give you the main lines here. I think I understand that in the display callback I need to draw a textured screen aligned quad, where the texture is obtained from the backbuffer:

glReadBuffer(GL_BACK)
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, left, bottom, width, height)

glDrawBuffer(GL_FRONT)
// I put the code of dletozeun to draw screen-aligned quad here

In the init subroutine, I’m drawing what I want in the backbuffer and convert it into a texture:

glDrawBuffer(GL_BACK)
// …
// I draw what I want to draw here
// …

glGenTextures(1, texture_id)   
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, texture_id(0))
glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)

Is my reasoning correct ?