JOGL / OPENGL 中的大型线带管理...?
我正在尝试制作 3D 旋转 Lorenz Attractor 的 Java 屏幕保护程序 我使用 java 和 jogl (OPENGL) 来渲染图形...... 我有 2 门课程,一门是主程序设置 OPENGL 等...... 另一个只存储 Point3d 的 LinkedList 这是线的顶点.. 每帧渲染只添加一个新点到列表中......
我遇到的问题是渲染速度非常慢,我的问题是这样...... 1.是否有更好/简单的方法来缓冲屏幕或线条带,这样我只需要绘制最后一行...... 2. VBO 可以用于 LINE_STRIP 吗?如果我每一步都必须向缓冲区添加一个顶点,这真的会加快速度吗...?
这真的很烦人... glBegin()/ glEnd() 工作正常,最多大约 100 行,然后严重崩溃。 非常需要帮助来加快渲染速度,我们将非常感激...
我已经添加了下面的工作代码才能使其工作,您必须链接到 JOGL opengl lib 的
代码
LorenzSim.java
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import javax.media.opengl.glu.GLU;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.vecmath.Point3d;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.*;
import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.gl2.GLUT;
import java.util.*;
import java.awt.event.*;
import sun.misc.*;
public class LorenzSim implements GLEventListener, KeyListener {
private static final int MIN_X = -20;
private static final int MAX_X = 20;
private static final int MIN_Y = -20;
private static final int MAX_Y = 20;
private static final double MIN_Z = 0;
private static final double MAX_Z = 40;
/**
* @param args
*/
// GLOBAL PARTS
boolean started = false;
int index = 0; // ANIMATOR COUNTER
String consoleLine = "";
// GENERAL OPEN GL
GLProfile glp = null;
GLCapabilities caps = null;
GLCanvas canvas = null;
GraphicsEnvironment ge = null;
GraphicsDevice gd = null;
Frame frame = null;
// GL _ CAM
double camX = 30;
double camY = 30;
double camZ = 50;
Lorenz myLorenz = null;
public LorenzSim ()
{
// GENERAL OPEN GL AND AWT SETUP
glp = GLProfile.getDefault();
caps = new GLCapabilities(glp);
canvas = new GLCanvas(caps);
ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gd = ge.getDefaultScreenDevice();
frame = new Frame("QuadSim");
frame.setSize(600,600);
//frame.setUndecorated(true);
//gd.setFullScreenWindow(frame);
frame.setVisible(true);
canvas.setSize(frame.getWidth(),frame.getHeight());
frame.add(canvas);
// SETUP EVENT LISTENERS
canvas.addGLEventListener(this);
canvas.addKeyListener(this);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
frame.dispose();
System.exit(0);
}
});
started = true;
FPSAnimator animator = new FPSAnimator(canvas, 60);
animator.add(canvas);
animator.start();
caps.setDoubleBuffered(true);
myLorenz = new Lorenz();
myLorenz.doSteps(0);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Welcome to Quad Simulator v0.1 - by Phil Poore");
LorenzSim mySim = new LorenzSim();
}
//############################################
// GL EVENT INTERFACE
//############################################
@Override
public void display(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
if (started)
{
update();
render(drawable);
//System.out.println("Drisplay_index:"+index);
}
}
private void update() {
// TODO Auto-generated method stub
index++;
myLorenz.step();
}
private void render(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
drawable.swapBuffers();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// START OF RENDER CYCLE
setCamera(gl,glu);
drawAxis(gl);
drawBox(gl);
drawLorenz(gl);
drawHUD(gl);
}
private void drawLorenz(GL2 gl) {
// TODO Auto-generated method stub
gl.glBegin(GL.GL_LINE_STRIP);
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glLineWidth(0.1f);
for (int i = 0; i < myLorenz.myPoints.size() - 1; i++)
{
//float dx = (float) (myLorenz.myPoints.get(i).x - myLorenz.myPoints.get(i+1).x);
//float dy = (float) (myLorenz.myPoints.get(i).y - myLorenz.myPoints.get(i+1).y);
//float dz = (float) (myLorenz.myPoints.get(i).z - myLorenz.myPoints.get(i+1).z);
//float dc = (Math.abs(dx) + Math.abs(dy) + Math.abs(dz))/3.0f;
//gl.glColor3d(dc,dc,dc);
gl.glVertex3d(
myLorenz.myPoints.get(i).x,
myLorenz.myPoints.get(i).y,
myLorenz.myPoints.get(i).z);
}
gl.glEnd();
}
private void drawBox(GL2 gl) {
// TODO Auto-generated method stub
Point3d a = new Point3d(MIN_X,MIN_Y,MIN_Z);
Point3d b = new Point3d(MAX_X,MIN_Y,MIN_Z);
Point3d c = new Point3d(MAX_X,MAX_Y,MIN_Z);
Point3d d = new Point3d(MIN_X,MAX_Y,MIN_Z);
Point3d aa = new Point3d(MIN_X,MIN_Y,MAX_Z);
Point3d ab = new Point3d(MAX_X,MIN_Y,MAX_Z);
Point3d ac = new Point3d(MAX_X,MAX_Y,MAX_Z);
Point3d ad = new Point3d(MIN_X,MAX_Y,MAX_Z);
gl.glBegin(GL.GL_LINE_STRIP);
gl.glVertex3d(a.x, a.y, a.z);
gl.glVertex3d(b.x, b.y, b.z);
gl.glVertex3d(c.x, c.y, c.z);
gl.glVertex3d(d.x, d.y, d.z);
gl.glVertex3d(a.x, a.y, a.z);
gl.glEnd();
gl.glBegin(GL.GL_LINE_STRIP);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glVertex3d(ab.x, ab.y, ab.z);
gl.glVertex3d(ac.x, ac.y, ac.z);
gl.glVertex3d(ad.x, ad.y, ad.z);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glEnd();
gl.glBegin(GL.GL_LINES);
gl.glVertex3d(a.x, a.y, a.z);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glVertex3d(b.x, b.y, b.z);
gl.glVertex3d(ab.x, ab.y, ab.z);
gl.glVertex3d(c.x, c.y, c.z);
gl.glVertex3d(ac.x, ac.y, ac.z);
gl.glVertex3d(d.x, d.y, d.z);
gl.glVertex3d(ad.x, ad.y, ad.z);
gl.glEnd();
}
private void drawHUD(GL2 gl) {
// TODO Auto-generated method stub
gl.glRasterPos2d(10,10);
gl.glWindowPos2d(10, 10);
gl.glColor3d(0.8, 0.8, 0.8);
GLUT glut = new GLUT();
//DecimalFormat df = new DecimalFormat("#.##");
glut.glutBitmapString(GLUT.BITMAP_8_BY_13,
":");
}
@Override
public void dispose(GLAutoDrawable arg0) {
// TODO Auto-generated method stub
}
@Override
public void init(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
//gl.glOrtho(0,100,-5,25,0,100);
gl.glEnable( GL.GL_LINE_SMOOTH );
gl.glHint( GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST );
}
@Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
int arg4) {
// TODO Auto-generated method stub
}
private void drawAxis(GL2 gl) {
gl.glLineWidth((float) 1.0);
gl.glBegin(GL.GL_LINES);
// X
gl.glColor3f(1, 0, 0);
gl.glVertex3d(0,0,0);
gl.glVertex3d(1,0,0);
// Y
gl.glColor3f(0, 1, 0);
gl.glVertex3d(0,0,0);
gl.glVertex3d(0,1,0);
// Z
gl.glColor3f(0, 0, 1);
gl.glVertex3d(0,0,0);
gl.glVertex3d(0,0,1);
gl.glEnd();
}
private void setCamera(GL2 gl,GLU glu)
{
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(120, 1.0, 5, 100);
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt(camX, camY, camZ,
0.0,0.0 ,0.0 ,
0.0,0.0, 1.0);
gl.glRotated(0.0+index, 0, 0, 1);
// gl.glTranslated(MAX_X-MIN_X, MAX_Y-MIN_Y, MAX_Z-MIN_Z);
}
//############################################
// KEY LISTENER INTERFACE
//############################################
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == 27)
System.exit(0);
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Lorenz.java
import javax.vecmath.*;
import java.awt.geom。 ; 导入java.util.;
公共课 Lorenz {
public static final double rho = 28.0;
public static final double sigma = 10.0;
public static final double beta = 8.0/3.0;
private static final double step = 200.0;
public LinkedList<Point3d> myPoints = null;
public Lorenz ()
{
myPoints = new LinkedList<Point3d>();
Point3d first = new Point3d(0.1,0.1,0.1);
myPoints.add(first);
}
public void step()
{
System.out.println("stepping..."+myPoints.size());
Point3d last = myPoints.get(myPoints.size()-1);
double dx = (sigma * (last.y - last.x))/step;
double dy = ((last.x*(rho-last.z))-last.y)/step;
double dz = ((last.x*last.y - beta*last.z))/step;
Point3d next = new Point3d(last.x+dx,last.y+dy,last.z+dz);
myPoints.add(next);
}
public void doSteps(int count)
{
for (int i = 0; i < count; i++)
{
step();
}
}
public void dump()
{
System.out.println(myPoints.toString());
}
}
Phil
Im trying to make a Java screensaver of a 3D rotating Lorenz Attractor
Im using java and jogl (OPENGL) to render the graphics...
i have 2 classes one is the main program setup OPENGL etc...
and another that just stores a LinkedList of Point3d's That are the vertex of the line..
Only one new point is added to the List every frame render.....
The problem i am having is render speed is very slow, my question is this...
1. Is there a Better / Easy way of buffering either the screen or the line strip so i only need to draw the last line....
2. Can VBO's be used for LINE_STRIP's and if i have to add one vertex to the buffer every step is this really going to speed things up...?
Its really quite annoying... glBegin()/ glEnd() works fine up to about 100 lines then crashes badly.
Help much needed to speed up render and would be greatly apreaciated.....
Ive added the working code below to get it to work you have to link to JOGL opengl lib's
CODE
LorenzSim.java
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import javax.media.opengl.glu.GLU;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.vecmath.Point3d;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.*;
import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.gl2.GLUT;
import java.util.*;
import java.awt.event.*;
import sun.misc.*;
public class LorenzSim implements GLEventListener, KeyListener {
private static final int MIN_X = -20;
private static final int MAX_X = 20;
private static final int MIN_Y = -20;
private static final int MAX_Y = 20;
private static final double MIN_Z = 0;
private static final double MAX_Z = 40;
/**
* @param args
*/
// GLOBAL PARTS
boolean started = false;
int index = 0; // ANIMATOR COUNTER
String consoleLine = "";
// GENERAL OPEN GL
GLProfile glp = null;
GLCapabilities caps = null;
GLCanvas canvas = null;
GraphicsEnvironment ge = null;
GraphicsDevice gd = null;
Frame frame = null;
// GL _ CAM
double camX = 30;
double camY = 30;
double camZ = 50;
Lorenz myLorenz = null;
public LorenzSim ()
{
// GENERAL OPEN GL AND AWT SETUP
glp = GLProfile.getDefault();
caps = new GLCapabilities(glp);
canvas = new GLCanvas(caps);
ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gd = ge.getDefaultScreenDevice();
frame = new Frame("QuadSim");
frame.setSize(600,600);
//frame.setUndecorated(true);
//gd.setFullScreenWindow(frame);
frame.setVisible(true);
canvas.setSize(frame.getWidth(),frame.getHeight());
frame.add(canvas);
// SETUP EVENT LISTENERS
canvas.addGLEventListener(this);
canvas.addKeyListener(this);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
frame.dispose();
System.exit(0);
}
});
started = true;
FPSAnimator animator = new FPSAnimator(canvas, 60);
animator.add(canvas);
animator.start();
caps.setDoubleBuffered(true);
myLorenz = new Lorenz();
myLorenz.doSteps(0);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Welcome to Quad Simulator v0.1 - by Phil Poore");
LorenzSim mySim = new LorenzSim();
}
//############################################
// GL EVENT INTERFACE
//############################################
@Override
public void display(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
if (started)
{
update();
render(drawable);
//System.out.println("Drisplay_index:"+index);
}
}
private void update() {
// TODO Auto-generated method stub
index++;
myLorenz.step();
}
private void render(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
drawable.swapBuffers();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// START OF RENDER CYCLE
setCamera(gl,glu);
drawAxis(gl);
drawBox(gl);
drawLorenz(gl);
drawHUD(gl);
}
private void drawLorenz(GL2 gl) {
// TODO Auto-generated method stub
gl.glBegin(GL.GL_LINE_STRIP);
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glLineWidth(0.1f);
for (int i = 0; i < myLorenz.myPoints.size() - 1; i++)
{
//float dx = (float) (myLorenz.myPoints.get(i).x - myLorenz.myPoints.get(i+1).x);
//float dy = (float) (myLorenz.myPoints.get(i).y - myLorenz.myPoints.get(i+1).y);
//float dz = (float) (myLorenz.myPoints.get(i).z - myLorenz.myPoints.get(i+1).z);
//float dc = (Math.abs(dx) + Math.abs(dy) + Math.abs(dz))/3.0f;
//gl.glColor3d(dc,dc,dc);
gl.glVertex3d(
myLorenz.myPoints.get(i).x,
myLorenz.myPoints.get(i).y,
myLorenz.myPoints.get(i).z);
}
gl.glEnd();
}
private void drawBox(GL2 gl) {
// TODO Auto-generated method stub
Point3d a = new Point3d(MIN_X,MIN_Y,MIN_Z);
Point3d b = new Point3d(MAX_X,MIN_Y,MIN_Z);
Point3d c = new Point3d(MAX_X,MAX_Y,MIN_Z);
Point3d d = new Point3d(MIN_X,MAX_Y,MIN_Z);
Point3d aa = new Point3d(MIN_X,MIN_Y,MAX_Z);
Point3d ab = new Point3d(MAX_X,MIN_Y,MAX_Z);
Point3d ac = new Point3d(MAX_X,MAX_Y,MAX_Z);
Point3d ad = new Point3d(MIN_X,MAX_Y,MAX_Z);
gl.glBegin(GL.GL_LINE_STRIP);
gl.glVertex3d(a.x, a.y, a.z);
gl.glVertex3d(b.x, b.y, b.z);
gl.glVertex3d(c.x, c.y, c.z);
gl.glVertex3d(d.x, d.y, d.z);
gl.glVertex3d(a.x, a.y, a.z);
gl.glEnd();
gl.glBegin(GL.GL_LINE_STRIP);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glVertex3d(ab.x, ab.y, ab.z);
gl.glVertex3d(ac.x, ac.y, ac.z);
gl.glVertex3d(ad.x, ad.y, ad.z);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glEnd();
gl.glBegin(GL.GL_LINES);
gl.glVertex3d(a.x, a.y, a.z);
gl.glVertex3d(aa.x, aa.y, aa.z);
gl.glVertex3d(b.x, b.y, b.z);
gl.glVertex3d(ab.x, ab.y, ab.z);
gl.glVertex3d(c.x, c.y, c.z);
gl.glVertex3d(ac.x, ac.y, ac.z);
gl.glVertex3d(d.x, d.y, d.z);
gl.glVertex3d(ad.x, ad.y, ad.z);
gl.glEnd();
}
private void drawHUD(GL2 gl) {
// TODO Auto-generated method stub
gl.glRasterPos2d(10,10);
gl.glWindowPos2d(10, 10);
gl.glColor3d(0.8, 0.8, 0.8);
GLUT glut = new GLUT();
//DecimalFormat df = new DecimalFormat("#.##");
glut.glutBitmapString(GLUT.BITMAP_8_BY_13,
":");
}
@Override
public void dispose(GLAutoDrawable arg0) {
// TODO Auto-generated method stub
}
@Override
public void init(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
//gl.glOrtho(0,100,-5,25,0,100);
gl.glEnable( GL.GL_LINE_SMOOTH );
gl.glHint( GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST );
}
@Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
int arg4) {
// TODO Auto-generated method stub
}
private void drawAxis(GL2 gl) {
gl.glLineWidth((float) 1.0);
gl.glBegin(GL.GL_LINES);
// X
gl.glColor3f(1, 0, 0);
gl.glVertex3d(0,0,0);
gl.glVertex3d(1,0,0);
// Y
gl.glColor3f(0, 1, 0);
gl.glVertex3d(0,0,0);
gl.glVertex3d(0,1,0);
// Z
gl.glColor3f(0, 0, 1);
gl.glVertex3d(0,0,0);
gl.glVertex3d(0,0,1);
gl.glEnd();
}
private void setCamera(GL2 gl,GLU glu)
{
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(120, 1.0, 5, 100);
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt(camX, camY, camZ,
0.0,0.0 ,0.0 ,
0.0,0.0, 1.0);
gl.glRotated(0.0+index, 0, 0, 1);
// gl.glTranslated(MAX_X-MIN_X, MAX_Y-MIN_Y, MAX_Z-MIN_Z);
}
//############################################
// KEY LISTENER INTERFACE
//############################################
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == 27)
System.exit(0);
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
Lorenz.java
import javax.vecmath.*;
import java.awt.geom.;
import java.util.;
public class Lorenz {
public static final double rho = 28.0;
public static final double sigma = 10.0;
public static final double beta = 8.0/3.0;
private static final double step = 200.0;
public LinkedList<Point3d> myPoints = null;
public Lorenz ()
{
myPoints = new LinkedList<Point3d>();
Point3d first = new Point3d(0.1,0.1,0.1);
myPoints.add(first);
}
public void step()
{
System.out.println("stepping..."+myPoints.size());
Point3d last = myPoints.get(myPoints.size()-1);
double dx = (sigma * (last.y - last.x))/step;
double dy = ((last.x*(rho-last.z))-last.y)/step;
double dz = ((last.x*last.y - beta*last.z))/step;
Point3d next = new Point3d(last.x+dx,last.y+dy,last.z+dz);
myPoints.add(next);
}
public void doSteps(int count)
{
for (int i = 0; i < count; i++)
{
step();
}
}
public void dump()
{
System.out.println(myPoints.toString());
}
}
Phil
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这可能听起来很有趣,但尝试删除 step() 方法中的 System.out.println() 。在java中打印到控制台相当慢/不可预测,所以不要每帧都这样做。
回答你的问题:
2) VBO 对于大型(较大)数据集来说速度很快,并且最好用于很少或部分更新的数据。它们可以表示您喜欢的任何图元,例如三角形、线带等。每一帧添加一个顶点并不是一个好主意,因为它们是静态分配的。您仍然可以通过预测要渲染的最大顶点数量来使用它们,并简单地先验分配此缓冲区。
如果您决定使用 VBO,则必须进行以下更改:
- 分配一个VBO,它将确定图的最大顶点数量
- 每帧仅上传新顶点
- 停止在最大值或考虑一个环形缓冲区,但您可能需要一个额外的缓冲区用作索引缓冲区来实现此
提示:使用 JOGL 的调试管道,一旦 OpenGL 设置错误代码,它就会尝试抛出异常。这可能有助于解决您提到的崩溃问题。
http://michael-bien.com/mbien/entry/jogl_2_composeable_pipline
this may sound funny but try to remove the System.out.println() in the step() method. Printing to console is fairly slow/unpredictable in java so don't do this every frame.
to answer your question:
2) VBOs are fast for large(er) datasets and best used with rarely or partly updating data. They can represent any primitive you like, triangles, line strips etc. Adding one vertex every frame is not a good idea since they are allocated statically. You can still use them by predicting the maximum amount of vertices you would like to render and simply allocate this buffer a-priory.
if you decide to use VBOs you will have to make this changes:
- allocate a VBO which will determine the max amount of vertices of the graph
- upload only the new vertices per frame
- stop at max or think about a ringbuffer, but you will probably need an additional buffer used as indexbuffer to implement this
tipp: use JOGL's debug pipeline, it will try to throw an exception as soon as OpenGL sets an error code. This will may help to fix the crash issue you mentioned.
http://michael-bien.com/mbien/entry/jogl_2_composeable_pipline
尝试为您的一组线路创建多个 VBO。这样,您只需为每条新线更新较少数量的顶点,并且大部分几何体已经(可能)在视频内存中。
Try creating multiple VBOs for your set of lines. That way you only have to update a smaller number of vertices for each new line and the bulk of your geometry is already (probably) in video memory.