Управление крупными полосами в JOGL / OPENGL ...? - PullRequest
3 голосов
/ 13 апреля 2011

Я пытаюсь сделать заставку Java для 3D вращающегося Lorenz Attractor Я использую Java и Jogl (OPENGL) для визуализации графики ... у меня есть 2 класса, один из них основной настройки программы OPENGL и т. д ... и другой, который просто хранит LinkedList Point3d, которые являются вершиной линии .. Только одна новая точка добавляется в список каждый кадр рендеринга .....

Проблема, которую я имею, состоит в том, что скорость рендеринга очень медленная, мой вопрос заключается в следующем 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. ; import 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());
}

}

Phil

Ответы [ 2 ]

0 голосов
/ 15 апреля 2011

это может показаться странным, но попробуйте удалить System.out.println () в методе step (). Печать в консоль довольно медленная / непредсказуемая в Java, поэтому не делайте этого каждый кадр.

чтобы ответить на ваш вопрос: 2) VBO бывают быстрыми для больших (er) наборов данных и лучше всего используются с редко или частично обновляемыми данными. Они могут представлять любые примитивы, которые вам нравятся, треугольники, линейные полосы и т. Д. Добавление одной вершины в каждом кадре не очень хорошая идея, поскольку они размещаются статически. Вы по-прежнему можете использовать их, прогнозируя максимальное количество вершин, которые вы хотели бы визуализировать, и просто выделяя этот буфер a-priory.

если вы решите использовать VBO, вам нужно будет внести следующие изменения: - выделить VBO, которое будет определять максимальное количество вершин графа - загружать только новые вершины на кадр - остановитесь на максимуме или подумайте о кольцевом буфере, но вам, вероятно, понадобится дополнительный буфер, используемый в качестве индексного буфера для реализации этого

tipp: используйте отладочный конвейер JOGL, он попытается вызвать исключение, как только OpenGL установит код ошибки. Это может помочь исправить упомянутую проблему сбоев. http://michael -bien.com / mbien / запись / jogl_2_composeable_pipline

0 голосов
/ 13 апреля 2011

Попробуйте создать несколько VBO для вашего набора линий.Таким образом, вам нужно только обновить меньшее количество вершин для каждой новой строки, и большая часть вашей геометрии уже (вероятно) находится в видеопамяти.

...