Perhaps this is getting a bit off topic, but I thought I'd post my progress so far. I was scared to try to start with, but starting small builds confidence to try new things.
Rather than diving straight in with the GLGraphics Lib, it seemed best to try and learn more about OpenGL and taming it inside Processing. I started here:
http://wiki.processing.org/w/Advanced_OpenGL and managed to get a sphere on the screen fairly quickly. Next, I ported my 'grid' drawing routine over, which again wasn't too tricky.
I then found the GL_POINTS primitive and was able to get points plotted in the space. During this process I learnt that a lot of the slow down I was seeing in the original (non-pure/standard openGL) version of the sketch was due to the way I adding colour, using three map() calls to scale the colour values before drawing each point was a very daft thing to do.
I removed all the colour and stuck with grey for now. I was surprised (although I'm not sure why I should be) that PeasyCam went in straight away, nothing difficult there either.
I now have what I asked for in my original post. A sketch that renders a volume of random points using the GPU, with simple mouse based navigation.
The results are good. I can render 15 million points, but it does take the framerate down below 5fps. I can render 200,000 at 60fps.
My next step is to look at Vertex lists and try and work those out.
I am left with a couple of questions i'm trying to work out.
1) how do I efficiently colour all the points differently?
2) my sketch seems to be locked to 60fps, even rendering nothing other than the grid It won't get higher than 60, rendering the grid and 200,000 points still gives me 60fps. with more points it drops to 30fps and remains there, adding a million points slows it down below 12fps, (on the nVidia 8800GT I'm running this on atm). there seems to be a ceiling of 60fps and a plateau at 30fps (eg, I've never seen 45fps).
In case anyone wants a look, (and I'd welcome any comments on optimisation) here is my code.
- import processing.opengl.*;
- import javax.media.opengl.*;
- import javax.media.opengl.glu.*;
- import peasy.*;
- PeasyCam cam;
- GL gl;
- GLU glu;
- //Declare the Arrays for storing co-ords.
- float[] coords_x = new float[1];
- float[] coords_y = new float[1];
- float[] coords_z = new float[1];
- int data_rows = 1;
- int max_points = 200000;
- int rand = 1000;
- void setup()
- {
- // Not quite fullScreen
- size(screen.width-40, screen.height-100, OPENGL);
-
- //SetUp PeasyCam
- cam = new PeasyCam(this, 1000);
- cam.setWheelScale(10);
- cam.setResetOnDoubleClick(false);
- cam.lookAt(width/2, height/2, (rand/2));
- float fov = PI/3.0;
- float cameraZ = (height/2.0) / tan(fov/2.0);
- perspective(fov, float(width)/float(height),cameraZ/200.0, cameraZ*1000.0);
-
- //SetUp the GL thingys
- gl=((PGraphicsOpenGL)g).gl;
- glu=((PGraphicsOpenGL)g).glu;
-
- //Load the point data into the arrays
- load_data();
- }
- void draw ()
- {
- //note the framerate
- frame.setTitle(str(round(frameRate))+"fps");
- //set BG colour and wipe new frame
- background(0);
- //More GL stuff I don't really understand yet.
- PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;
-
- //All GL drawing commands are wrapped in a beginGL()/endGL() loop
- GL gl = pgl.beginGL();
-
- //Move everything we draw into the middle of the screen (or could just move the camera)
- gl.glTranslatef(width/2, height/2, 0);
-
- //Draw a grid
- drawgrid(10,101,0.1);
- //Draw the points
- draw_points();
- pgl.endGL();
- }
- void drawgrid(float spacing, int gridsize, float gridStroke)
- {
- for (int i = 0; i < gridsize; i++)
- {
- gl.glLineWidth(1);
- //change the apparent size of the lines (via alpha) for Min and Max grid highlights
- gl.glColor4f(1, 1, 1, gridStroke);
- if (i%5 == 0) gl.glColor4f(1, 1, 1, gridStroke+0.05);
- if (i == 0) gl.glColor4f(1, 1, 1, gridStroke+0.1);
-
- //draw the lines using a GL Line primitive.
- gl.glBegin(gl.GL_LINES);
- gl.glVertex3f(-(gridsize*(spacing/2)), (i*spacing)-((gridsize/2)*spacing), 0);
- gl.glVertex3f((gridsize*(spacing/2)), (i*spacing)-((gridsize/2)*spacing), 0);
- gl.glEnd();
- gl.glBegin(gl.GL_LINES);
- gl.glVertex3f((i*spacing)-((gridsize/2)*spacing),-(gridsize*(spacing/2)), 0);
- gl.glVertex3f((i*spacing)-((gridsize/2)*spacing),(gridsize*(spacing/2)), 0);
- gl.glEnd();
- }
- }
- void load_data()
- {
- // originaly this function loaded data from a database or file, where the number of
- // rows was unknown. It would have been easier to do this with an array list, but
- // also it would have been a bit slower for some uses.
-
- //expand arrays to fit.
- coords_x = expand (coords_x,max_points);
- coords_y = expand (coords_y,max_points);
- coords_z = expand (coords_z,max_points);
-
- // fill the arrays with random points.
- for (int i=0; i < max_points; i++)
- {
- coords_x[i] = random(rand);
- coords_y[i] = random(rand);
- coords_z[i] = random(rand);
- }
- }
- void draw_points()
- {
- // set the size of the points to draw
- gl.glPointSize(1);
- //BeginGL to draw points
- gl.glBegin(gl.GL_POINTS);
- for (int i=0; i<max_points; i++)
- {
- // Not using this colour function anymore as the map() function is was _WAY_ too slow.
- // gl.glColor4f(map(coords_x[i],0,max(coords_x),0,1),map(coords_y[i],0,max(coords_y),0,1),map(coords_z[i],0,max(coords_z),0,1), 1);
- gl.glVertex3f(coords_x[i]-(rand/2), coords_y[i]-(rand/2), coords_z[i]);
- }
- gl.glEnd();
- }