• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 747
  • Last Modified:

What are the Best Practices with using OpenGL to plot a very large list of points in an animation like style?

Firstly I describe my C# program.
I have kept the description as brief as possible, but have hopefully provided sufficient context for my questions.
My questions appear the the bottom of my post.
--------
I define a struct called ColourPoint:
public struct ColourPoint
{
        public Point point;
        public Color colour;

        public ColourPoint(Point point, Color colour)
        {
            this.point = point; this.colour = colour;
        }
}

I define a List of ColourPoints:

List<ColourPoint> colourPointList;

An integer is defined that is the max number of iterations in the loop described in the next paragraph:

int maxPixels;

I have a background worker process containing a loop that calculates the points, and adds them to the ColourPoint list. The loop iterates roughly 300000 times and it adds one ColourPoint to the list per iteration. The loop takes about 30 seconds to complete. Once the loop is completed no further calculations of points are made and no extra points are added to the list, unless there is specific user input.

At any point in time, the user can press a button that allows them to enter in new arguments for the calculation of points. If the user does this, then the background worker process is cancelled, the ColourPoint list is re-initialised to an empty list, and then the background worker process is restarted to start the calculations with the new arguments.

The animation of the ColourPoint list can be described as follows:
1)      The start frame of the animation is a blank graph.
2)      The last frame of the animation is all of the points plotted on the graph.
3)      Each step of the animation should plot the next point (or group of points) from the list on to the graph.
By group of points I mean for example, plotting 1000 points per animation step.

I use the following to implement the animation:

Timer timerAnimation;
TrackBar trackBarAnimation;
Button btnPlayPause;
bool playing;
int TRACKBAR_PIXEL_COUNT_DIVISOR = 1000;

They are initialised as follows:

trackBarAnimation.Minimum = 0;
trackBarAnimation.Maximum = maxPixels / TRACKBAR_PIXEL_COUNT_DIVISOR;

playing = false;

timerAnimation.Interval = 500;
timerAnimation.Enabled = true;

The button changes the value of the playing boolean.

The timer ticks every 500ms and executes the following:
It disables itself, it checks if playing is set to true and if it is it triggers the opengl control's paint event by calling its Refresh() method. The timer is re-enabled at the bottom of the paint event.

To illustrate what I do within the paint event I have pasted the code here:

private void openGlPlotWindow_Paint(object sender, PaintEventArgs e)
{
    int startPixel = (int)(trackBarPixels.Value * TRACKBAR_PIXEL_COUNT_DIVISOR);
    int endPixel = (int)((trackBarPixels.Value + 1) * TRACKBAR_PIXEL_COUNT_DIVISOR);

    if (Playing && endPixel < colourPointList.Count)
    {
        Gl.glLoadIdentity();        

        Gl.glPolygonMode(Gl.GL_FRONT_AND_BACK, Gl.GL_POINT);

        Gl.glBegin(Gl.GL_POLYGON);
 
        for (int i = startPixel; i < endPixel; i++)
        {
           Color colour = colourPointList[i].colour;
           Point point = colourPointList[i].point;
           
           Gl.glColor3f((float)colour.R / 255f, (float)colour.G / 255f, (float)colour.B / 255f);
           Gl.glVertex2f(point.X, point.Y);
        }

        Gl.glEnd();
        Gl.glFlush();

        trackBarPixels.Value += 1;
     }
     timerAnimation.Enabled = true;
}


QUESTIONS:

My implementation works, but I am unsure how to implement the following:
If the user moves the track bar then the graph should be painted appropriately.
For example, if the animation has currently plotted 100000 points and then the user moves the track bar slide and the slide points to the value representing 50000 points, then the graph should change to a plot of the first 50000 points.
In other words the user should be able to scroll to any point of the animation, provided that that part of the animation has been calculated of course.

I am also quite sure that the current way I have implemented the animation / painting of the graph is not best practice and is definitely not very efficient and would love for someone to point out to me how it should be done.

Additionally I would like the user to be able to zoom in on the image. I sort of know how to do this, but am pretty sure that it wouldnt work with my current paint event due to the fact that I am not clearing the window.

Please ask if you would like me to provide any more information.

Thanks
0
dparnis
Asked:
dparnis
  • 5
  • 4
1 Solution
 
ikeworkCommented:
hi dparnis,

firstable, you only render points right? then replace the:

  Gl.glBegin(Gl.GL_POLYGON);

with

  Gl.glBegin(Gl.GL_POINTS);

and the Gl.glPolygonMode is obsolete as well then


>> In other words the user should be able to scroll to any point of the animation

normally you could just put a glTranslatef in the begin of your render-function, but as you said, you dont clear the screen in the render-function ..

>> I am also quite sure that the current way I have implemented the animation / painting of the graph is not best practice

you could start only rendering the visible points, then when the user uses the scrollbar or the zoom, do it again ..


i didn't quite understand, why you dont render all points at once, then you could clear the screen .. can you explain that a bit?


ike


0
 
ikeworkCommented:
you said animation .. do you mean a *slowly* rendered graph or the points are not static and change over time like an oscilloscope viewing a changing input signal?
0
 
dparnisAuthor Commented:
I mean a slowly rendered graph. The points are static.

>> In other words the user should be able to scroll to any point of the animation
By this I don't mean spatially on the plot, i mean percentage plotted of the graph.

The reason I don't clear every time the paint event fires is because it fires for every step of the animation which displays the next 100 pixels, and due to the large size of the list of points the animation slows extremely down because plotting 100 pixels, then 200 pixels, then 300, then 400, then 500, all the way up to 300000 takes a very long time.

Maybe I should display all the pixels within the Paint event and use  glFlush() every so many pixels to achieve the animation effect. The problem I can see with this is that the List of points is being created at the same time paint is fired and hence all the pixels would not exist.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
ikeworkCommented:
> you could start only rendering the visible points

1) you render 300000 points .. you can hardly see 300000 points on a normal screen, you can have the same result with less points .. so what about just rendering the *significant* points meaning either every n-th and just in the visible range

2) i guess you are rendering a 2d function, like f(x) = y. a next step of optimization could be just only to calulate the points in the visible region of the x-axis and render those with an optimal x-stepsize of 1 pixel
0
 
dparnisAuthor Commented:
it's a polar plot...
0
 
ikeworkCommented:
ok .. so its  f(angle)=r

so read:

the points in the visible region of alpha ..

so what about the optimisation suggestions?
0
 
dparnisAuthor Commented:
Sorry I'm taking long to respond... Im am in the process of a complete redesign of my application making an effort to keep the design neat and sticking to object oriented principles.

It was a complete mess before and I wasn't sure what was where.

I like your idea about only plotting the significant points. I will see what I can do.

What do you mean by "the points in the visible region of alpha" ?
The coordinate (0,0) is in the middle of the screen so wouldn't their be no limits on
the visible angle range?
0
 
dparnisAuthor Commented:
or by alpha are you refering the the magnitude?
0
 
ikeworkCommented:
> The coordinate (0,0) is in the middle of the screen so wouldn't their be no limits on the visible angle range?

right .. :) but you said something about a slider and:

> In other words the user should be able to scroll to any point of the animation

maybe i misunderstood the the slider/scroll thing ..


> plotting the significant points.

f(alpha) = radius

delta-alpha should be somewhat of a function of the last magnitude/radius

the bigger the magnitude, the shorter should be the step of alpha ..
the smaller the magnitude the less points you need in that region, thus the bigger alpha can be there
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now