如何解决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.javaimport 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_Z);
Point3d c = new Point3d(MAX_X,MAX_Y,MIN_Z);
Point3d d = new Point3d(MIN_X,MIN_Z);
Point3d aa = new Point3d(MIN_X,MAX_Z);
Point3d ab = new Point3d(MAX_X,MAX_Z);
Point3d ac = new Point3d(MAX_X,MAX_Z);
Point3d ad = new Point3d(MIN_X,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.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.z);
gl.glEnd();
gl.glBegin(GL.GL_LInes);
gl.glVertex3d(a.x,a.z);
gl.glVertex3d(aa.x,aa.z);
gl.glVertex3d(b.x,b.z);
gl.glVertex3d(ab.x,ab.z);
gl.glVertex3d(c.x,c.z);
gl.glVertex3d(ac.x,ac.z);
gl.glVertex3d(d.x,d.z);
gl.glVertex3d(ad.x,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,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);
gl.glVertex3d(0,0);
gl.glVertex3d(1,0);
// Y
gl.glColor3f(0,1,0);
// Z
gl.glColor3f(0,1);
gl.glVertex3d(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,1.0);
gl.glrotated(0.0+index,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
}
}
洛伦兹
import javax.vecmath.*;
导入java.awt.geom。
导入java.util .;
公共类洛伦兹{
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());
}
}
菲尔
解决方法
尝试为您的线路集创建多个VBO。这样,您只需要为每条新线更新较少数量的顶点,并且几何体的大部分已经(可能)已存在于视频内存中。
,这听起来可能很有趣,但是请尝试在step()方法中删除System.out.println()。用Java打印到控制台相当慢/无法预测,因此请不要在每一帧都这样做。
回答您的问题:
2)VBO适用于大型数据集,并且最适合很少或部分更新数据的情况。它们可以表示您喜欢的任何图元,三角形,线带等。每帧添加一个顶点不是一个好主意,因为它们是静态分配的。您仍然可以通过预测要渲染的最大顶点数量并仅按优先级分配此缓冲区来使用它们。
如果您决定使用VBO,则必须进行以下更改:
-分配一个VBO来确定图形的最大顶点数量
-每帧仅上传新顶点
-停在最大位置或考虑使用环形缓冲区,但是您可能需要一个额外的缓冲区作为索引缓冲区来实现此目的
tipp:使用JOGL的调试管道,一旦OpenGL设置了错误代码,它将尝试引发异常。这可能有助于解决您提到的崩溃问题。
http://michael-bien.com/mbien/entry/jogl_2_composeable_pipline
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。