5

I'm writing a program in C++ that acquires 4 dimensional points data over a UDP socket and then plots the data in 6 separate 2D scatter plots. For example if we name the dimensions: A,B,C,D the six 2d plots would be AxB, AxC, AxD, BxC, BxD, and CxD. Over the course of a few hours the program accrues ~50K points.

Currently I plot each point once, using immediate mode. I don't clear the buffer between draw calls so previously plotted points persist until the buffer is cleared. I'm not happy with this method as immediate mode is slow and deprecated. When I have to clear the buffer, as when a window re-sizes, I lose all previously plotted data. I'd like to come up with a solution that allows data persistence after the buffer is cleared. Additionally it would be nice if the plot could be easily scaled with window re-sizes as well.

I've thought about maintaining a vertex array (with 2 dimensions) for each coordinate system but that would require 6 separate arrays and require 3 times the memory of maintaining an array with all 4 dimensions.

Am I thinking about this in the right way? What is the proper solution to this problem?

The end goal is to have an application that displays the data as close to real-time as possible.

Edit Would it be possible to continue plotting the points one by one as they come in, and when I need to resize the screen grab an image of the screen and then display a resized version of that image?

slayton
  • 20,123
  • 10
  • 60
  • 89

1 Answers1

5

Using Vertex buffer Objects can increase speed rendering, because the geometry to draw can be stored directly in the graphic card memory. However, in your case, if the data always changes, I cannot tell you if this method will be faster than immediate mode because you may have to reconstruct the Vertex Array Object each time the data change. If you only add points, maybe you can make multiple VBOs to group points, and render the last received points using immediate mode until you can create a new group. For instance, if you received 100054 points, maybe you can make 10 groups of 10000 points and render the last 54 points in immediate mode.

Concerning the memory problem, I think it might be possible to store in the graphic card vertexes with 4 elements - then you could use different vertex shaders which select which components of your vertex to use as rendering coordinates. Using this technique, memory usage would only be twice what you received: one for you received data, and one for the vertex buffer object.

neodelphi
  • 2,706
  • 1
  • 15
  • 22
  • 2
    VBOs should be at least not slower than client side arrays and are definitely faster than immediate mode. It's not only the memory copy but also the driver call overhead that VBOs (and vertex arrays in general) are for. – Christian Rau Aug 03 '11 at 16:52
  • One could probably get away with using varying the `stride` and `pointer` arguments to `glVertexPointer` instead of having to have different vertex shaders for the different views. – user786653 Aug 03 '11 at 16:57
  • @Christian Thanks for you comment, I wasn't sure about it. – neodelphi Aug 03 '11 at 16:58
  • 2
    @user786653 Not sure, in the case where he uses coordinates A and D, I don't know how he could skip B and C coordinates. Maybe using uniform attributes will help to use one shader (selection would be done by the shader using the given attributes) but this may not be as fast as using multiple shaders). – neodelphi Aug 03 '11 at 17:01
  • @neodelphi: Oops, you're right, I was too quick. I agree a shader is the best bet. (Another, possibly daft idea to avoid shaders, could be to use the 4-coordinate vector and simply have appropriate 4x4 view/projection matrices for that view zeroing out B&c in the A&D case.) – user786653 Aug 03 '11 at 17:12
  • 2
    Buffers can be mapped. If points are appended, only the diff is sent. Immediate mode shall be avoided as much as possible. – Luca Aug 03 '11 at 17:33
  • @Luca How does openGl detect the diff, or do we need to tell him manually ? This is interesting. – neodelphi Aug 03 '11 at 17:35
  • 1
    @neodelphi You can use `glBufferSubData` or the `map_buffer_range` extension, so the driver may optimize this and copy only the neccessary stuff. – Christian Rau Aug 03 '11 at 18:01
  • @Christian Thank you, did not knew that, great news ! I think I'm gonna love such functionalities. – neodelphi Aug 03 '11 at 18:07