how can I draw 256 000 points on the screen

Started by
15 comments, last by Timkin 16 years, 9 months ago
Hello there, So, the subject of my post let you know that I have a problem with huge number of points that I want to draw over the screen. In fact, I have 3 arrays of points (doubles), that represent the Y coordinates of my points. Until now I draw these points like this: gl.glColor3d(0.5,0.5,0.5); gl.glLineWidth (1f); gl.glBegin(GL.GL_LINE_STRIP); / or gl.glBegin(GL.GL_POINTS); for(i = 0; i < arraySize; i++){ gl.glVertex2d(i*div, array); } gl.glEnd() But this is not a good solution because if I put this in my display function, OpenGL passes his time in the this loop. Imagine if I try to draw all the 3 arrays at the same time ! (I have 99% CPU usage). Another thing to know is that the div is a parameter modified by the user until the application is running. So I tried to use vertex arrays but the problem with this solution is that the vertex arrays are used almost for static data and not something that could change at anytime. And also I can't find a way to display 3 different arrays that contains the same type of data (GL_DOUBLE). I can display only one array at a time but I want to be able to display the " arrays at the same time. I think also to try using the display lists, but I have the feeling I will have the same result like with the vertex arrays... So is there someone with some good solution or suggestion ? Regards, Anton PS. I'm using Jogl API, that beaucause I have gl.*
Advertisement
Vertex Arrays are not used for static data, that is Display Lists. And you can draw more than one array at time, all you have to do is change which array your glVertexPointer() statement calls to, then use glDrawElements or whatever again. And there you have your 3 sets of data drawn.

Some GPGPU guru here will probably tell you that the best way is to use shaders or some other fancy method, but since I haven't started using shaders I can't advise you there.
Shaders will definately speed up the thing and in your case, where you just want to change the vertex x position your shader will just have 4 lines.

First thing to say is thank you for the posts :)
So I'll try to find some information about the shaders.
It's a good idea to optimize.
Use float instead of double. GPUs don't support doubles.
Use xyz instead of xy.

Quote:
OpenGL passes his time in the this loop.



Maybe arraySize is very large so your CPU spends time doing the loop. In that case try putting your vertices in a VBO.

Quote:
I think also to try using the display lists, but I have the feeling I will have the same result like with the vertex arrays...


VA is fast by DL is faster.
You are using immediate mode for now and a lousy data format.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Quote:Original post by AndyEsser
Vertex Arrays are not used for static data, that is Display Lists.
Since when?

Quote:
Shaders will definately speed up the thing and in your case, where you just want to change the vertex x position your shader will just have 4 lines.

It's actually quite doubtful that shaders will improve anything here. Shaders are not about additional speed, they are about additional control (if anything, that additional control actually causes a reduction in speed). Granted, he might be able to get away with a very small shader that just does a matrix operation, but that isn't likely to have a huge impact given the size of his data set and how he is submitting it.

The bottleneck here is most likely sheer amount of vertex data to be submitted (which presumably cannot be avoided by culling anything offscreen, as that is the cheapest and best available initial optimization), and the method by which that data is submitted. Immediate mode (glVertex, etc) is a particularly slow, inefficient method of sending vertex data across to the card and that becomes particularly apparent when you send a lot of data per frame. Display lists or VBOs are the next thing to look into to improve performance.

Depending on what the vertex data actually represents and is being used for, there might be other options. Can you provide more information, tonkata?
Hi again,

the data is collected from a NMR device, so in this case every point is important.
In the 3 arrays of doubles I have the Y coordinates of the points.
After I collected the data, I'm creating a new bigger array, 2 times the size of the old one and there I'm puting the X and the Y coordinates. The X in my case is going from 0 to the number of collected points.
After that I'm proceeding to display the points.
At present I changed my program to use the vertex arrays, here is some code:

void setupPointers(GLAutoDrawable drawable, double divRe, double divIm,                    boolean showRe, boolean showIm, boolean showMod){ 		   GL gl = drawable.getGL();		   if(showRe){  realVerticesBuf = BufferUtil.newDoubleBuffer(2*DisplayPanel.buffReal.length);    for (int i = 0; i < DisplayPanel.buffReal.length; i++){    realVerticesBuf.put(i*divRe);	//divRe parameter that changes     realVerticesBuf.put(DisplayPanel.buffReal);  }  realVerticesBuf.rewind();  //... I'm doing the same thing for the other 2 arrays}

I'm using this function in my init() and in mu display(). In the display(), to avoid to execture this function every time, I'm detecting is there was a change(zoom IN/OUT over the X axis) made by the user and if there was one, I'm calling the setupPointers().(after the zoom divRe changes too)

In the display function I'm calling some functions that draws the data, here is an example:
public void grapheIm(GLAutoDrawable drawable, boolean showIm, double div){		  GL gl = drawable.getGL();		  if(showIm){			    if(canvas1Listener.drawWithLines){      gl.glColor3f(canvas1Listener.redY,canvas1Listener.greenY,        canvas1Listener.blueY);      gl.glLineWidth (1f);      gl.glVertexPointer(2, GL.GL_DOUBLE, 0, canvas1Listener.imagVerticesBuf);      gl.glDrawArrays(GL.GL_LINE_STRIP,firstPointToDisplay,           lastPointToDisplay);				     }  }}

I have the same type of function for the 2 other arrays.
This solution speed up a little bit the execution of the program, and reduces the CPU usage but compate to other programs, used for the same purpose, my soft is slow.
Another thing, using glDrawArrays I have some bug that comes form the JVM. I think this is beaucause I'm changing firstPointToDisplay and lastPointToDisplay sometimes. May be I sould use glDrawElements, but for that I have to know the indices of the elements that I want to display, and to calculate this every time will be a long operation. In fact I'm using firstPointToDisplay and lastPointToDisplay, to limit the drawn points on the screen when I'm zooming in. Ii'm trying to cut the points that will not be visible ... but for now I have the bug with the JVM.
I was merely stating that display lists, in their nature, are static. Whereas Vertex Arrays can be used for both static AND dynamic data.
Quote:Original post by AndyEsser
I was merely stating that display lists, in their nature, are static. Whereas Vertex Arrays can be used for both static AND dynamic data.
VAs are multiple times faster than display lists. There is no reason to switch back to a list because your stuff is static.

This topic is closed to new replies.

Advertisement