below is the code for spewing the meshes from the fountain, feel free to comment.
package pf;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Random;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.ARBBufferObject;
import org.lwjgl.opengl.ARBVertexBufferObject;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GLContext;
import org.lwjgl.opengl.glu.GLU;
public class GLFountain {
public static boolean EXIT_APP = false;
public static String WINDOW_TITLE = “OpenGL Mesh Fountain”;
public static DisplayMode displayMode;
public static int WINDOW_WIDTH = 1024;
public static int WINDOW_HEIGHT = 768;
public static int WINDOW_DEPTH = 32;
public float FOVY = 80.0f;
public float NEAR_VIEW_DISTANCE = 0.1f;
public float FAR_VIEW_DISTANCE = 1000.0f;
public float EYE_X = 0.0f;
public float EYE_Y = 600.0f;
public float EYE_Z = 350.0f;
public float AT_X = 0.0f;
public float AT_Y = 0.0f;
public float AT_Z = 0.0f;
public float UP_X = 0.0f;
public float UP_Y = 1.0f;
public float UP_Z = 0.0f;
public float [] floatplane = {300.0f,0.0f,-300.0f,300.0f,0.0f,300.0f,-300.0f,0.0f,300.0f,-300.0f,0.0f,-300.0f};
public FloatBuffer plane = BufferUtils.createFloatBuffer(floatplane.length);
public float [] floattriangles = {0.0f,1.0f,0.0f,1.0f,-1.0f,0.0f,-1.0f,-1.0f,0.0f};
public FloatBuffer triangles = BufferUtils.createFloatBuffer(floattriangles.length);
public int [] VBO_ID = new int[2];
public final int MaxObjects = 10000;
int ctr=0;
public int Objects = 0;
public float DistanceTime = 0.1f;
public float Gravity = 9.8f;
public byte randX[] = new byte[1000];
public byte randY[] = new byte[1000];
public byte randZ[] = new byte[1000];
public float[] x = new float[MaxObjects];
public float[] y = new float[MaxObjects];
public float[] z = new float[MaxObjects];
public float[] DirectionX = new float[MaxObjects];
public float[] DirectionY = new float[MaxObjects];
public float[] DirectionZ = new float[MaxObjects];
public float [] rand_R = new float[MaxObjects];
public float [] rand_G = new float[MaxObjects];
public float [] rand_B = new float[MaxObjects];
public float startPointX=0.0f;
public float startPointY=0.0f;
public float startPointZ=0.0f;
public static void main(String[] args) {
GLFountain glfountain = new GLFountain();
glfountain.run();
}
public void run() {
long startTime = System.currentTimeMillis() + 5000;
long fps = 0;
try {
init();
while (!EXIT_APP) {
MainLoop();
Display.update();
if (startTime > System.currentTimeMillis()) {
fps++;
} else {
long timeUsed = 5000 + (startTime - System.currentTimeMillis());
startTime = System.currentTimeMillis() + 5000;
String outdata = fps + " frames in " + (float) (timeUsed / 1000f) + " seconds = "+ (fps / (timeUsed / 1000f))+" FPS";
System.out.println( outdata );
Display.setTitle(WINDOW_TITLE + " " + outdata);
fps = 0;
}
}
cleanup();
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
public void MainLoop() {
if(Display.isCloseRequested()) {
EXIT_APP = true;
}
timePassesBy();
newObject();
render();
}
public void createWindow() throws Exception {
DisplayMode modes[] = Display.getAvailableDisplayModes();
for (int i = 0; i < modes.length; i++) {
if (modes[i].getWidth() == WINDOW_WIDTH
&& modes[i].getHeight() == WINDOW_HEIGHT
&& modes[i].getBitsPerPixel() == WINDOW_DEPTH) {
displayMode = modes[i];
break;
}
}
Display.setDisplayMode(displayMode);
Display.setTitle(WINDOW_TITLE);
Display.create();
}
public void init() throws Exception {
createWindow();
CheckExtensions();
initGL();
CreateVBO();
initializefountain();
}
public void CheckExtensions() {
if (!GLContext.getCapabilities().GL_ARB_vertex_buffer_object ) {
System.out.println("ARB VBO Extension is not supported!");
System.out.println("Dropping Out!");
System.exit(1);
}
}
public void initGL() {
Display.setVSyncEnabled(false);
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glClearDepth(1.0);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthFunc(GL11.GL_LEQUAL);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluPerspective(FOVY,(float) displayMode.getWidth() / (float) displayMode.getHeight(),NEAR_VIEW_DISTANCE,FAR_VIEW_DISTANCE);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GLU.gluLookAt(EYE_X, EYE_Y, EYE_Z, AT_X, AT_Y, AT_Z, UP_X, UP_Y, UP_Z);
}
public void CreateVBO() {
plane.put(floatplane).rewind();
triangles.put(floattriangles).rewind();
VBO_ID[0]=CreateVBOID();
BufferData(VBO_ID[0], plane);
VBO_ID[1]=CreateVBOID();
BufferData(VBO_ID[1], triangles);
}
public int CreateVBOID() {
IntBuffer buffer = BufferUtils.createIntBuffer(1);
ARBVertexBufferObject.glGenBuffersARB(buffer);
return buffer.get(0);
}
public static void BufferData(int id, FloatBuffer buffer) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
}
public void initializefountain() {
Random r = new Random(34567890);
r.nextBytes(randX);
r.nextBytes(randY);
r.nextBytes(randZ);
for (int i = 0; i < MaxObjects; i++) {
rand_R[i] =(float)Math.random();
rand_G[i] =(float)Math.random();
rand_B[i] =(float)Math.random();
}
for (int i = 0; i < 10; i++) {
newObject();
}
}
void newObject(){
if (Objects < MaxObjects){
initObject(Objects);
Objects++;
}
}
void initObject(int p) {
x[p] = startPointX;
y[p] = startPointY;
z[p] = startPointZ;
ctr++;
ctr %= randX.length;
DirectionX[p] = randX[ctr] / 10.0f;
DirectionY[p] = randY[ctr] / 10.0f - 80;
DirectionZ[p] = randZ[ctr] / 10.0f;
}
void timePassesBy(){
for (int i = 0; i < Objects; i++) {
DirectionY[i] += DistanceTime*Gravity;
x[i] -= DistanceTime*DirectionX[i];
y[i] -= DistanceTime*DirectionY[i];
z[i] -= DistanceTime*DirectionZ[i];
if (y[i] < startPointY) {
initObject(i);
}
}
}
public void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glColor3f(0.6f, 0.6f, 0.6f);
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, VBO_ID[0]);
GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);
GL11.glDrawArrays(GL11.GL_QUADS, 0, 12);
for (int i = 0; i < Objects; i++) {
GL11.glColor3f(rand_R[i], rand_G[i], rand_B[i]);
GL11.glPushMatrix();
GL11.glTranslatef(x[i],y[i],z[i]);
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, VBO_ID[1]);
GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 9);
GL11.glPopMatrix();
}
}
public void cleanup() {
IntBuffer del_vbo_id = BufferUtils.createIntBuffer(1);
del_vbo_id.put(0, VBO_ID[0]);
ARBBufferObject.glDeleteBuffersARB(del_vbo_id);
del_vbo_id.put(0, VBO_ID[1]);
ARBBufferObject.glDeleteBuffersARB(del_vbo_id);
Display.destroy();
}
}