pgraphicsopengl.java

来自「This is processing for java examples.」· Java 代码 · 共 2,167 行 · 第 1/5 页

JAVA
2,167
字号
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- *//*  Part of the Processing project - http://processing.org  Copyright (c) 2004-08 Ben Fry and Casey Reas  This library is free software; you can redistribute it and/or  modify it under the terms of the GNU Lesser General Public  License as published by the Free Software Foundation; either  version 2.1 of the License, or (at your option) any later version.  This library is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  Lesser General Public License for more details.  You should have received a copy of the GNU Lesser General  Public License along with this library; if not, write to the  Free Software Foundation, Inc., 59 Temple Place, Suite 330,  Boston, MA  02111-1307  USA*/package processing.opengl;import processing.core.*;import java.awt.*;import java.awt.font.*;import java.awt.geom.*;import java.nio.*;import javax.media.opengl.*;import javax.media.opengl.glu.*;import com.sun.opengl.util.*;/** * Implementation of the PGraphics API that employs OpenGL rendering via JOGL. * <p/> * JOGL requires Java 1.4 or higher, so there are no restrictions on this * code to be compatible with Java 1.1 or Java 1.3. * <p/> * This code relies on PGraphics3D for all lighting and transformations. * Meaning that translate(), rotate(), and any lighting will be done in * PGraphics3D, and OpenGL is only used to blit lines and triangles as fast * as it possibly can. * <p/> * For this reason, OpenGL may not be accelerated as far as it could be, * but I don't have the time to maintain two separate versions of the * renderer. My development time must always be focused on implementation * and covering features first, and optimizing later. * <p/> * Further, the difference may be negligible, as the primary slowdown * in Java is moving pixels (i.e. a large frame buffer is nearly impossible * because Java just can't do a MemoryImageSource at screen resolution) * and the overhead from JNI tends to be significant. In the latter case, * we may even save time in some cases where a large number of calls to * OpenGL would otherwise be used, but that's probably a stretch. * <p/> * The code is also very messy, while features are being added and * removed rapidly as we head towards 1.0. Things got particularly ugly * as we approached beta while both Simon and I were working on it. * Relax, we'll get it fixed up later. * <p/> * When exporting applets, the JOGL Applet Launcher is used. More information * about the launcher can be found at its <A HREF="http://download.java.net/media/jogl/builds/nightly/javadoc_public/com/sun/opengl/util/JOGLAppletLauncher.html">documentation page</A>. */public class PGraphicsOpenGL extends PGraphics3D {  protected GLDrawable drawable;   // the rendering 'surface'  protected GLContext context;     // the rendering context (holds rendering state info)  public GL gl;  public GLU glu;  //public GLCanvas canvas;  //protected FloatBuffer projectionFloatBuffer;  protected float[] projectionFloats;  protected GLUtessellator tobj;  protected TessCallback tessCallback;  /// Buffer to hold light values before they're sent to OpenGL  //protected FloatBuffer lightBuffer;  protected float[] lightArray = new float[] { 1, 1, 1 };  static int maxTextureSize;  int[] textureDeleteQueue = new int[10];  int textureDeleteQueueCount = 0;  /// Used to hold color values to be sent to OpenGL  //protected FloatBuffer colorBuffer;  protected float[] colorBuffer;  /// Used to store empty values to be passed when a light has no ambient value  protected FloatBuffer zeroBuffer;  /// IntBuffer to go with the pixels[] array  protected IntBuffer pixelBuffer;  /**   * Set to true if the host system is big endian (PowerPC, MIPS, SPARC),   * false if little endian (x86 Intel for Mac or PC).   */  static public boolean BIG_ENDIAN =    ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;  public PGraphicsOpenGL() {    glu = new GLU();    tobj = glu.gluNewTess();    // unfortunately glu.gluDeleteTess(tobj); is never called    //glu.gluTessProperty(tobj, GLU.GLU_TESS_WINDING_RULE,    //                  GLU.GLU_TESS_WINDING_NONZERO);    //glu.gluTessProperty(tobj, GLU.GLU_TESS_WINDING_RULE,    //                  GLU.GLU_TESS_WINDING_POSITIVE);    //GLU.GLU_TESS_WINDING_ODD);    //glu.gluTessProperty(tobj, GLU.GLU_TESS_BOUNDARY_ONLY,    //                  GL.GL_TRUE);    tessCallback = new TessCallback();    glu.gluTessCallback(tobj, GLU.GLU_TESS_BEGIN, tessCallback);    glu.gluTessCallback(tobj, GLU.GLU_TESS_END, tessCallback);    glu.gluTessCallback(tobj, GLU.GLU_TESS_VERTEX, tessCallback);    glu.gluTessCallback(tobj, GLU.GLU_TESS_COMBINE, tessCallback);    glu.gluTessCallback(tobj, GLU.GLU_TESS_ERROR, tessCallback);//    lightBuffer = BufferUtil.newFloatBuffer(4);//    lightBuffer.put(3, 1.0f);//    lightBuffer.rewind();  }  //public void setParent(PApplet parent)  // PGraphics  //public void setPrimary(boolean primary)  // PGraphics  //public void setPath(String path)  // PGraphics  //public void setSize(int iwidth, int iheight)  // PGraphics3D  /**   * Called by resize(), this handles creating the actual GLCanvas the   * first time around, or simply resizing it on subsequent calls.   * There is no pixel array to allocate for an OpenGL canvas   * because OpenGL's pixel buffer is all handled internally.   */  protected void allocate() {    if (context == null) {//      System.out.println("PGraphicsOpenGL.allocate() for " + width + " " + height);//      new Exception().printStackTrace(System.out);      // If OpenGL 2X or 4X smoothing is enabled, setup caps object for them      GLCapabilities capabilities = new GLCapabilities();      // Starting in release 0158, OpenGL smoothing is always enabled      if (!hints[DISABLE_OPENGL_2X_SMOOTH]) {        capabilities.setSampleBuffers(true);        capabilities.setNumSamples(2);      } else if (hints[ENABLE_OPENGL_4X_SMOOTH]) {        capabilities.setSampleBuffers(true);        capabilities.setNumSamples(4);      }      // get a rendering surface and a context for this canvas      GLDrawableFactory factory = GLDrawableFactory.getFactory();      /*      if (PApplet.platform == PConstants.LINUX) {        GraphicsConfiguration pconfig = parent.getGraphicsConfiguration();        System.out.println("parent config is " + pconfig);        //      GraphicsDevice device = config.getDevice();        //AbstractGraphicsDevice agd = new AbstractGraphicsDevice(device);        //AbstractGraphicsConfiguration agc = factory.chooseGraphicsConfiguration(capabilities, null, null);        AWTGraphicsConfiguration agc = (AWTGraphicsConfiguration)        factory.chooseGraphicsConfiguration(capabilities, null, null);        GraphicsConfiguration config = agc.getGraphicsConfiguration();        System.out.println("agc config is " + config);      }      */      drawable = factory.getGLDrawable(parent, capabilities, null);      context = drawable.createContext(null);      // need to get proper opengl context since will be needed below      gl = context.getGL();      // Flag defaults to be reset on the next trip into beginDraw().      settingsInited = false;    } else {      // changing for 0100, need to resize rather than re-allocate      //System.out.println("PGraphicsOpenGL.allocate() again for " + width + " " + height);      reapplySettings();    }  }  //public void dispose()  // PGraphics  ////////////////////////////////////////////////////////////  /**   * Get the current context, for use by libraries that need to talk to it.   */  public GLContext getContext() {    return context;  }  /**   * Make the OpenGL rendering context current for this thread.   */  protected void detainContext() {    try {      while (context.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) {//        System.out.println("Context not yet current...");//        new Exception().printStackTrace(System.out);//        Thread.sleep(1000);        Thread.sleep(10);      }    } catch (InterruptedException e) {      e.printStackTrace();    }  }  /**   * Release the context, otherwise the AWT lock on X11 will not be released   */  protected void releaseContext() {    context.release();  }  /**   * OpenGL cannot draw until a proper native peer is available, so this   * returns the value of PApplet.isDisplayable() (inherited from Component).   */  public boolean canDraw() {    return parent.isDisplayable();  }  public void beginDraw() {    //if (!parent.isDisplayable()) return;    // When using an offscreen buffer, the drawable instance will be null.    // The offscreen buffer uses the drawing context of the main PApplet.    if (drawable != null) {      // Call setRealized() after addNotify() has been called      drawable.setRealized(parent.isDisplayable());      //System.out.println("OpenGL beginDraw() setting realized " + parent.isDisplayable());      if (parent.isDisplayable()) {        //System.out.println("  we'll realize it alright");        drawable.setRealized(true);      } else {        //System.out.println("  not yet ready to be realized");        return;  // Should have called canDraw() anyway      }      detainContext();    }    // On the first frame that's guaranteed to be on screen,    // and the component valid and all that, ask for focus.//    if ((parent != null) && parent.frameCount == 1) {//      canvas.requestFocus();//    }    super.beginDraw();    report("top beginDraw()");    gl.glDisable(GL.GL_LIGHTING);    for (int i = 0; i < MAX_LIGHTS; i++) {      gl.glDisable(GL.GL_LIGHT0 + i);    }    gl.glMatrixMode(GL.GL_PROJECTION);    if (projectionFloats == null) {      projectionFloats = new float[] {        projection.m00, projection.m10, projection.m20, projection.m30,        projection.m01, projection.m11, projection.m21, projection.m31,        projection.m02, projection.m12, projection.m22, projection.m32,        projection.m03, projection.m13, projection.m23, projection.m33      };    } else {      projectionFloats[0] = projection.m00;      projectionFloats[1] = projection.m10;      projectionFloats[2] = projection.m20;      projectionFloats[3] = projection.m30;      projectionFloats[4] = projection.m01;      projectionFloats[5] = projection.m11;      projectionFloats[6] = projection.m21;      projectionFloats[7] = projection.m31;      projectionFloats[8] = projection.m02;      projectionFloats[9] = projection.m12;      projectionFloats[10] = projection.m22;      projectionFloats[11] = projection.m32;      projectionFloats[12] = projection.m03;      projectionFloats[13] = projection.m13;      projectionFloats[14] = projection.m23;      projectionFloats[15] = projection.m33;    }    //projection.print();    gl.glLoadMatrixf(projectionFloats, 0);    gl.glMatrixMode(GL.GL_MODELVIEW);    gl.glLoadIdentity();    // Flip Y-axis to make y count from 0 downwards    gl.glScalef(1, -1, 1);    // these are necessary for alpha (i.e. fonts) to work    gl.glEnable(GL.GL_BLEND);    gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);    // this is necessary for 3D drawing    if (hints[DISABLE_DEPTH_TEST]) {      gl.glDisable(GL.GL_DEPTH_TEST);    } else {      gl.glEnable(GL.GL_DEPTH_TEST);    }    // use <= since that's what processing.core does    gl.glDepthFunc(GL.GL_LEQUAL);    // because y is flipped    gl.glFrontFace(GL.GL_CW);    // coloured stuff    gl.glEnable(GL.GL_COLOR_MATERIAL);    gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE);    gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR);    // these tend to make life easier    // (but sometimes at the expense of a little speed)    // Not using them right now because we're doing our own lighting.    //gl.glEnable(GL.GL_NORMALIZE);    //gl.glEnable(GL.GL_AUTO_NORMAL); // I think this is OpenGL 1.2 only    //gl.glEnable(GL.GL_RESCALE_NORMAL);    //gl.GlLightModeli(GL.GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);    report("bot beginDraw()");    // are there other things to do here?    //System.out.println("beginDraw() stop error " + PApplet.hex(gl.glGetError()));  }  public void endDraw() {    //System.out.println("endDraw() error " + PApplet.hex(gl.glGetError()));    report("top endDraw()");    if (hints[ENABLE_DEPTH_SORT]) {      flush();    }    if (drawable != null) {      drawable.swapBuffers();    }    //insideDraw = false;    report("bot endDraw()");    if (drawable != null) {      releaseContext();    }  }  private float ctm[];  // this would also need to set up the lighting.. ?  public GL beginGL() {    //beginDraw();  // frame will have already started    gl.glPushMatrix();    // load p5 modelview into the opengl modelview    if (ctm == null) ctm = new float[16];    ctm[0] = modelview.m00;    ctm[1] = modelview.m10;    ctm[2] = modelview.m20;    ctm[3] = modelview.m30;    ctm[4] = modelview.m01;    ctm[5] = modelview.m11;    ctm[6] = modelview.m21;    ctm[7] = modelview.m31;    ctm[8] = modelview.m02;    ctm[9] = modelview.m12;    ctm[10] = modelview.m22;    ctm[11] = modelview.m32;    ctm[12] = modelview.m03;    ctm[13] = modelview.m13;    ctm[14] = modelview.m23;    ctm[15] = modelview.m33;    // apply this modelview and get to work    gl.glMultMatrixf(ctm, 0);    return gl;  }  public void endGL() {    // remove the p5 modelview from opengl    gl.glPopMatrix();  }  ////////////////////////////////////////////////////////////  // SETTINGS  // checkSettings, defaultSettings, reapplySettings in PGraphics

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?