Posted by
alicana on
Apr 20, 2015; 8:57pm
URL: https://forum.jogamp.org/VBO-Performance-Misunderstanding-tp4034319p4034346.html
I still have problems with the code that I share below. First of all, my achievement is drawing 1M points on the screen (by accumulating points in vbo). I tried to add some points in time by using glMapBufferRange(), I guess I have a trouble with usage of the buffer offset, position whatever...
1) I allocated a buffer for 1M points. Is this ok? -> (10e6 * FLOAT_SIZE* 3) 3 Stands for XYZ
2) I want to increase points that are drawn, by 1000. But, exception is thrown which says "GL_INVALID_VALUE Out of range: offset 0, length 15378000, ..."
3) Second step is ok when I set increase to 100.
4) Is my drawArrays() call correct or am I trying to draw all points again and again?
5) Performance does it really matter for me

EDIT:
- I found mistake that I have done in second step. I used Buffers.SIZEOF_FLOAT when allocated buffer, but used Buffers.SIZEOF_FLOAT when mapping to buffer. Works now. But still have questions

- My fps rate decreases dramatically.
FPS: 56
FPS: 63
FPS: 49
FPS: 38
FPS: 32
FPS: 28
FPS: 26
FPS: 23
FPS: 22
FPS: 21
FPS: 19
FPS: 19
FPS: 18
FPS: 17
FPS: 16
Is this normal ?
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Random;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.util.FPSAnimator;
@SuppressWarnings("serial")
public class Main extends GLCanvas implements GLEventListener {
private Random random = new Random();
// VBO variables
int[] vbo = new int[] { -1 };
int maxNumberOfPoints = 1000000; // GL_POINTS
int pointVertexSize = 3; // X,Y,Z
int numberOfPointsAdded = 0;
int pointOffset = 0;
int increaseRate = 1000;
// ===================================================
// VBO related functions
// ===================================================
private void initVBO(GL2 gl) {
gl.glGenBuffers(1, vbo, 0);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vbo[0]);
gl.glBufferData(GL2.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * maxNumberOfPoints * pointVertexSize, null,
GL2.GL_DYNAMIC_DRAW);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
}
private void updateVBO(GL2 gl) {
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vbo[0]);
ByteBuffer byteBuffer = gl.glMapBufferRange(GL2.GL_ARRAY_BUFFER, pointOffset, increaseRate * Buffers.SIZEOF_FLOAT * 3,
GL2.GL_MAP_WRITE_BIT | GL2.GL_MAP_UNSYNCHRONIZED_BIT);
FloatBuffer floatBuffer = byteBuffer.order(ByteOrder.nativeOrder()).asFloatBuffer();
for (int i = 0; i < increaseRate; i++) {
floatBuffer.put(random.nextFloat() + random.nextInt(1000)); // X
// coordinate
floatBuffer.put(random.nextFloat() + random.nextInt(1000)); // Y
// coordinate
floatBuffer.put(0);
pointOffset += 3;
numberOfPointsAdded += 1;
}
System.out.println(numberOfPointsAdded);
gl.glUnmapBuffer(GL2.GL_ARRAY_BUFFER);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
}
private void renderVBO(GL2 gl) {
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vbo[0]);
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL2.GL_FLOAT, 0, 0l);
gl.glDrawArrays(GL2.GL_POINTS, 0, pointOffset);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
}
private void deleteVBO(GL2 gl) {
gl.glDeleteBuffers(1, vbo, 0);
}
// ===================================================
// OpenGL Callback Functions
// ===================================================
@Override
public void init(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClearDepth(1.0f);
gl.glEnable(GL2.GL_DEPTH_TEST);
gl.glDepthFunc(GL2.GL_LEQUAL);
gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
gl.glShadeModel(GL2.GL_SMOOTH);
initVBO(gl);
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
GL2 gl = drawable.getGL().getGL2();
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0, 1000, 0, 1000, -1, 1);
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void display(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
updateVBO(gl);
renderVBO(gl);
if (System.currentTimeMillis() - lastTimeInMillis > 1000) {
System.out.println("FPS: " + fpsCounter);
fpsCounter = 0;
lastTimeInMillis = System.currentTimeMillis();
}
fpsCounter++;
}
@Override
public void dispose(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
deleteVBO(gl);
}
// ===================================================
// Main
// ===================================================
private static String TITLE = "JOGL 2.0 Setup (GLCanvas)";
private static final int CANVAS_WIDTH = 320;
private static final int CANVAS_HEIGHT = 240;
private static final int FPS = 60;
private int fpsCounter = 0;
private long lastTimeInMillis = System.currentTimeMillis();
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GLCanvas canvas = new Main();
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
final FPSAnimator animator = new FPSAnimator(canvas, FPS, true);
final JFrame frame = new JFrame();
frame.getContentPane().add(canvas);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
new Thread() {
@Override
public void run() {
if (animator.isStarted())
animator.stop();
System.exit(0);
}
}.start();
}
});
frame.setTitle(TITLE);
frame.pack();
frame.setVisible(true);
animator.start();
}
});
}
public Main() {
this.addGLEventListener(this);
}
}