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 + -
显示快捷键?