diff --git a/core/src/processing/opengl/FontTexture.java b/core/src/processing/opengl/FontTexture.java index e32d4f440..8c1c66f5d 100644 --- a/core/src/processing/opengl/FontTexture.java +++ b/core/src/processing/opengl/FontTexture.java @@ -63,11 +63,12 @@ class FontTexture implements PConstants { protected TextureInfo[] glyphTexinfos; protected HashMap texinfoMap; - public FontTexture(PFont font, boolean is3D) { - pgl = PGraphicsOpenGL.pgPrimary.pgl; + + public FontTexture(PGraphicsOpenGL pg, PFont font, boolean is3D) { + pgl = pg.pgl; this.is3D = is3D; - initTexture(PGraphicsOpenGL.pgPrimary, font); + initTexture(pg, font); } @@ -130,15 +131,15 @@ class FontTexture implements PConstants { if (is3D) { // Bilinear sampling ensures that the texture doesn't look pixelated // either when it is magnified or minified... - tex = new Texture(w, h, new Texture.Parameters(ARGB, Texture.BILINEAR, - false)); + tex = new Texture(pg, w, h, + new Texture.Parameters(ARGB, Texture.BILINEAR, false)); } else { // ...however, the effect of bilinear sampling is to add some blurriness // to the text in its original size. In 2D, we assume that text will be // shown at its original size, so linear sampling is chosen instead (which // only affects minimized text). - tex = new Texture(w, h, new Texture.Parameters(ARGB, Texture.LINEAR, - false)); + tex = new Texture(pg, w, h, + new Texture.Parameters(ARGB, Texture.LINEAR, false)); } if (textures == null) { diff --git a/core/src/processing/opengl/FrameBuffer.java b/core/src/processing/opengl/FrameBuffer.java index f7b8f56bf..1e5ef72a6 100644 --- a/core/src/processing/opengl/FrameBuffer.java +++ b/core/src/processing/opengl/FrameBuffer.java @@ -40,6 +40,7 @@ import java.nio.IntBuffer; */ public class FrameBuffer implements PConstants { + protected PGraphicsOpenGL pg; protected PGL pgl; protected int context; // The context that created this framebuffer. @@ -67,16 +68,17 @@ public class FrameBuffer implements PConstants { protected IntBuffer pixelBuffer; - FrameBuffer() { - pgl = PGraphicsOpenGL.pgPrimary.pgl; + FrameBuffer(PGraphicsOpenGL pg) { + this.pg = pg; + pgl = pg.pgl; context = pgl.createEmptyContext(); } - FrameBuffer(int w, int h, int samples, int colorBuffers, + FrameBuffer(PGraphicsOpenGL pg, int w, int h, int samples, int colorBuffers, int depthBits, int stencilBits, boolean packedDepthStencil, boolean screen) { - this(); + this(pg); glFbo = 0; glDepth = 0; @@ -136,13 +138,13 @@ public class FrameBuffer implements PConstants { } - FrameBuffer(int w, int h) { - this(w, h, 1, 1, 0, 0, false, false); + FrameBuffer(PGraphicsOpenGL pg, int w, int h) { + this(pg, w, h, 1, 1, 0, 0, false, false); } FrameBuffer(PGraphicsOpenGL pg, int w, int h, boolean screen) { - this(w, h, 1, 1, 0, 0, false, screen); + this(pg, w, h, 1, 1, 0, 0, false, screen); } @@ -201,7 +203,7 @@ public class FrameBuffer implements PConstants { noDepth = true; } - public void finish(PGraphicsOpenGL pg) { + public void finish() { if (noDepth) { // No need to clear depth buffer because depth testing was disabled. if (pg.getHint(ENABLE_DEPTH_TEST)) { diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index 0a302c1e4..bd4066021 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -52,10 +52,10 @@ public abstract class PGL { protected PGraphicsOpenGL pg; /** OpenGL thread */ - protected static Thread glThread; + protected Thread glThread; /** ID of the GL context associated to the surface **/ - protected static int glContext; + protected int glContext; // ........................................................ @@ -437,7 +437,7 @@ public abstract class PGL { protected Texture wrapBackTexture(Texture texture) { if (texture == null) { - texture = new Texture(); + texture = new Texture(pg); texture.init(pg.width, pg.height, glColorTex.get(backTex), TEXTURE_2D, RGBA, fboWidth, fboHeight, NEAREST, NEAREST, @@ -454,7 +454,7 @@ public abstract class PGL { protected Texture wrapFrontTexture(Texture texture) { if (texture == null) { - texture = new Texture(); + texture = new Texture(pg); texture.init(pg.width, pg.height, glColorTex.get(frontTex), TEXTURE_2D, RGBA, fboWidth, fboHeight, NEAREST, NEAREST, @@ -737,6 +737,9 @@ public abstract class PGL { } + protected abstract void getGL(PGL pgl); + + protected abstract boolean canDraw(); @@ -903,7 +906,8 @@ public abstract class PGL { protected void initTex2DShader() { - if (!loadedTex2DShader || tex2DShaderContext != glContext) { + if (!loadedTex2DShader/* || tex2DShaderContext != glContext*/) { + System.out.println("initializing texture shader"); String vertSource = PApplet.join(texVertShaderSource, "\n"); String fragSource = PApplet.join(tex2DFragShaderSource, "\n"); tex2DVertShader = createShader(VERTEX_SHADER, vertSource); diff --git a/core/src/processing/opengl/PGraphics2D.java b/core/src/processing/opengl/PGraphics2D.java index 18df3b2a6..7229e561d 100644 --- a/core/src/processing/opengl/PGraphics2D.java +++ b/core/src/processing/opengl/PGraphics2D.java @@ -265,7 +265,7 @@ public class PGraphics2D extends PGraphicsOpenGL { } if (svg != null) { - PShapeOpenGL p2d = PShapeOpenGL.createShape2D(pg.parent, svg); + PShapeOpenGL p2d = PShapeOpenGL.createShape2D((PGraphicsOpenGL)pg, svg); return p2d; } else { return null; @@ -280,7 +280,7 @@ public class PGraphics2D extends PGraphicsOpenGL { @Override public PShape createShape(PShape source) { - return PShapeOpenGL.createShape2D(parent, source); + return PShapeOpenGL.createShape2D(this, source); } @@ -292,31 +292,31 @@ public class PGraphics2D extends PGraphicsOpenGL { @Override public PShape createShape(int type) { - return createShapeImpl(parent, type); + return createShapeImpl(this, type); } @Override public PShape createShape(int kind, float... p) { - return createShapeImpl(parent, kind, p); + return createShapeImpl(this, kind, p); } - static protected PShapeOpenGL createShapeImpl(PApplet parent, int type) { + static protected PShapeOpenGL createShapeImpl(PGraphicsOpenGL pg, int type) { PShapeOpenGL shape = null; if (type == PConstants.GROUP) { - shape = new PShapeOpenGL(parent, PConstants.GROUP); + shape = new PShapeOpenGL(pg, PConstants.GROUP); } else if (type == PShape.PATH) { - shape = new PShapeOpenGL(parent, PShape.PATH); + shape = new PShapeOpenGL(pg, PShape.PATH); } else if (type == PShape.GEOMETRY) { - shape = new PShapeOpenGL(parent, PShape.GEOMETRY); + shape = new PShapeOpenGL(pg, PShape.GEOMETRY); } shape.is3D(false); return shape; } - static protected PShapeOpenGL createShapeImpl(PApplet parent, + static protected PShapeOpenGL createShapeImpl(PGraphicsOpenGL pg, int kind, float... p) { PShapeOpenGL shape = null; int len = p.length; @@ -326,49 +326,49 @@ public class PGraphics2D extends PGraphicsOpenGL { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(POINT); } else if (kind == LINE) { if (len != 4) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(LINE); } else if (kind == TRIANGLE) { if (len != 6) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(TRIANGLE); } else if (kind == QUAD) { if (len != 8) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(QUAD); } else if (kind == RECT) { if (len != 4 && len != 5 && len != 8 && len != 9) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(RECT); } else if (kind == ELLIPSE) { if (len != 4 && len != 5) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(ELLIPSE); } else if (kind == ARC) { if (len != 6 && len != 7) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(ARC); } else if (kind == BOX) { showWarning("Primitive not supported in 2D"); diff --git a/core/src/processing/opengl/PGraphics3D.java b/core/src/processing/opengl/PGraphics3D.java index 38b3e775d..77edcc9f0 100644 --- a/core/src/processing/opengl/PGraphics3D.java +++ b/core/src/processing/opengl/PGraphics3D.java @@ -144,7 +144,7 @@ public class PGraphics3D extends PGraphicsOpenGL { if (obj != null) { int prevTextureMode = pg.textureMode; pg.textureMode = NORMAL; - PShapeOpenGL p3d = PShapeOpenGL.createShape3D(pg.parent, obj); + PShapeOpenGL p3d = PShapeOpenGL.createShape3D((PGraphicsOpenGL)pg, obj); pg.textureMode = prevTextureMode; return p3d; } else { @@ -160,7 +160,7 @@ public class PGraphics3D extends PGraphicsOpenGL { @Override public PShape createShape(PShape source) { - return PShapeOpenGL.createShape3D(parent, source); + return PShapeOpenGL.createShape3D(this, source); } @@ -172,31 +172,31 @@ public class PGraphics3D extends PGraphicsOpenGL { @Override public PShape createShape(int type) { - return createShapeImpl(parent, type); + return createShapeImpl(this, type); } @Override public PShape createShape(int kind, float... p) { - return createShapeImpl(parent, kind, p); + return createShapeImpl(this, kind, p); } - static protected PShapeOpenGL createShapeImpl(PApplet parent, int type) { + static protected PShapeOpenGL createShapeImpl(PGraphicsOpenGL pg, int type) { PShapeOpenGL shape = null; if (type == PConstants.GROUP) { - shape = new PShapeOpenGL(parent, PConstants.GROUP); + shape = new PShapeOpenGL(pg, PConstants.GROUP); } else if (type == PShape.PATH) { - shape = new PShapeOpenGL(parent, PShape.PATH); + shape = new PShapeOpenGL(pg, PShape.PATH); } else if (type == PShape.GEOMETRY) { - shape = new PShapeOpenGL(parent, PShape.GEOMETRY); + shape = new PShapeOpenGL(pg, PShape.GEOMETRY); } shape.is3D(true); return shape; } - static protected PShapeOpenGL createShapeImpl(PApplet parent, + static protected PShapeOpenGL createShapeImpl(PGraphicsOpenGL pg, int kind, float... p) { PShapeOpenGL shape = null; int len = p.length; @@ -206,63 +206,63 @@ public class PGraphics3D extends PGraphicsOpenGL { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(POINT); } else if (kind == LINE) { if (len != 4 && len != 6) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(LINE); } else if (kind == TRIANGLE) { if (len != 6) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(TRIANGLE); } else if (kind == QUAD) { if (len != 8) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(QUAD); } else if (kind == RECT) { if (len != 4 && len != 5 && len != 8 && len != 9) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(RECT); } else if (kind == ELLIPSE) { if (len != 4 && len != 5) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(ELLIPSE); } else if (kind == ARC) { if (len != 6 && len != 7) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(ARC); } else if (kind == BOX) { if (len != 1 && len != 3) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(BOX); } else if (kind == SPHERE) { if (len < 1 || 3 < len) { showWarning("Wrong number of parameters"); return null; } - shape = new PShapeOpenGL(parent, PShape.PRIMITIVE); + shape = new PShapeOpenGL(pg, PShape.PRIMITIVE); shape.setKind(SPHERE); } else { showWarning("Unrecognized primitive type"); diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 9596caf9a..adfe00cbe 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -36,11 +36,8 @@ public class PGraphicsOpenGL extends PGraphics { /** Interface between Processing and OpenGL */ public PGL pgl; - /** The main PApplet renderer. */ - protected static PGraphicsOpenGL pgPrimary = null; - /** The renderer currently in use. */ - protected static PGraphicsOpenGL pgCurrent = null; + protected PGraphicsOpenGL currentPG; /** Font cache for texture objects. */ protected WeakHashMap fontMap = @@ -56,8 +53,6 @@ public class PGraphicsOpenGL extends PGraphics { "blendMode(%1$s) is not supported by this hardware (or driver)"; static final String BLEND_RENDERER_ERROR = "blendMode(%1$s) is not supported by this renderer"; - static final String NESTED_DRAW_ERROR = - "Already called drawing on another PGraphicsOpenGL object"; static final String ALREADY_BEGAN_CONTOUR_ERROR = "Already called beginContour()"; static final String NO_BEGIN_CONTOUR_ERROR = @@ -424,7 +419,7 @@ public class PGraphicsOpenGL extends PGraphics { // Screen surface: /** Texture containing the current frame */ - protected Texture texture; + public Texture texture; /** Texture containing the previous frame */ protected Texture ptexture; @@ -535,7 +530,7 @@ public class PGraphicsOpenGL extends PGraphics { inGeo = newInGeometry(this, IMMEDIATE); tessGeo = newTessGeometry(this, IMMEDIATE); - texCache = newTexCache(); + texCache = newTexCache(this); initialized = false; } @@ -686,21 +681,44 @@ public class PGraphicsOpenGL extends PGraphics { } + ////////////////////////////////////////////////////////////// + + // IMAGE METADATA FOR THIS RENDERER + + + @Override + public void setCache(PImage image, Object storage) { + getPrimaryPG().cacheMap.put(image, storage); + } + + + @Override + public Object getCache(PImage image) { + return getPrimaryPG().cacheMap.get(image); + } + + + @Override + public void removeCache(PImage image) { + getPrimaryPG().cacheMap.remove(image); + } + + ////////////////////////////////////////////////////////////// protected void setFontTexture(PFont font, FontTexture fontTexture) { - fontMap.put(font, fontTexture); + getPrimaryPG().fontMap.put(font, fontTexture); } protected FontTexture getFontTexture(PFont font) { - return fontMap.get(font); + return getPrimaryPG().fontMap.get(font); } protected void removeFontTexture(PFont font) { - fontMap.remove(font); + getPrimaryPG().fontMap.remove(font); } @@ -1216,7 +1234,7 @@ public class PGraphicsOpenGL extends PGraphics { fbStackDepth--; FrameBuffer fbo = fbStack[fbStackDepth]; if (currentFramebuffer != fbo) { - currentFramebuffer.finish(pgPrimary); + currentFramebuffer.finish(); currentFramebuffer = fbo; currentFramebuffer.bind(); } @@ -1605,6 +1623,13 @@ public class PGraphicsOpenGL extends PGraphics { @Override public void beginDraw() { + if (primarySurface) { + setCurrentPG(this); + } else { + pgl.getGL(getPrimaryPGL()); + getPrimaryPG().setCurrentPG(this); + } + report("top beginDraw()"); if (!checkGLThread()) { @@ -1615,19 +1640,11 @@ public class PGraphicsOpenGL extends PGraphics { return; } - if (pgCurrent != null && !pgCurrent.primarySurface && - !this.primarySurface) { - // It seems that the user is trying to start another beginDraw()/endDraw() - // block for an offscreen surface, still drawing on another one. - PGraphics.showWarning(NESTED_DRAW_ERROR); - return; - } - - if (!primarySurface && pgPrimary.texCache.containsTexture(this)) { + if (!primarySurface && getPrimaryPG().texCache.containsTexture(this)) { // This offscreen surface is being used as a texture earlier in draw, - // so we should update the rendering up to this point since it will + // so we should update the rendering up to this point since it will be // modified. - pgPrimary.flush(); + getPrimaryPG().flush(); } if (!glParamsRead) { @@ -1642,7 +1659,6 @@ public class PGraphicsOpenGL extends PGraphics { } setDrawDefaults(); // TODO: look at using checkSettings() instead... - pgCurrent = this; drawing = true; report("bot beginDraw()"); @@ -1661,7 +1677,7 @@ public class PGraphicsOpenGL extends PGraphics { flush(); if (PGL.SAVE_SURFACE_TO_PIXELS_HACK && - (!pgPrimary.initialized || parent.frameCount == 0)) { + (!getPrimaryPG().initialized || parent.frameCount == 0)) { // Smooth was disabled/enabled at some point during drawing. We save // the current contents of the back buffer (because the buffers haven't // been swapped yet) to the pixels array. The frameCount == 0 condition @@ -1677,12 +1693,10 @@ public class PGraphicsOpenGL extends PGraphics { endOffscreenDraw(); } - if (pgCurrent == pgPrimary) { - // Done with the main surface - pgCurrent = null; + if (primarySurface) { + setCurrentPG(null); } else { - // Done with an offscreen surface, going back to onscreen drawing. - pgCurrent = pgPrimary; + getPrimaryPG().setCurrentPG(getPrimaryPG()); } drawing = false; @@ -1696,6 +1710,31 @@ public class PGraphicsOpenGL extends PGraphics { } + protected PGraphicsOpenGL getPrimaryPG() { + if (primarySurface) { + return this; + } else { + return (PGraphicsOpenGL)parent.g; + } + } + + protected void setCurrentPG(PGraphicsOpenGL pg) { + currentPG = pg; + } + + protected PGraphicsOpenGL getCurrentPG() { + return currentPG; + } + + protected PGL getPrimaryPGL() { + if (primarySurface) { + return pgl; + } else { + return ((PGraphicsOpenGL)parent.g).pgl; + } + } + + @Override public PGL beginPGL() { flush(); @@ -1764,11 +1803,11 @@ public class PGraphicsOpenGL extends PGraphics { } public void beginReadPixels() { - pgCurrent.beginPixelsOp(OP_READ); + beginPixelsOp(OP_READ); } public void endReadPixels() { - pgCurrent.endPixelsOp(); + endPixelsOp(); } protected void beginPixelsOp(int op) { @@ -2229,7 +2268,7 @@ public class PGraphicsOpenGL extends PGraphics { tessellator.setStrokeWeight(strokeWeight); tessellator.setStrokeCap(strokeCap); tessellator.setStrokeJoin(strokeJoin); - tessellator.setRenderer(pgCurrent); + tessellator.setRenderer(this); tessellator.setTransform(modelview); tessellator.set3D(is3D()); @@ -3505,11 +3544,11 @@ public class PGraphicsOpenGL extends PGraphics { protected void textLineImpl(char buffer[], int start, int stop, float x, float y) { if (textMode == MODEL) { - textTex = pgPrimary.getFontTexture(textFont); + textTex = getFontTexture(textFont); if (textTex == null || textTex.contextIsOutdated()) { - textTex = new FontTexture(textFont, is3D()); - pgPrimary.setFontTexture(textFont, textTex); + textTex = new FontTexture(this, textFont, is3D()); + setFontTexture(textFont, textTex); } textTex.begin(); @@ -3568,7 +3607,7 @@ public class PGraphicsOpenGL extends PGraphics { if (tinfo == null) { // Adding new glyph to the font texture. - tinfo = textTex.addToTexture(pgPrimary, glyph); + tinfo = textTex.addToTexture(this, glyph); } float high = glyph.height / (float) textFont.getSize(); @@ -5327,16 +5366,6 @@ public class PGraphicsOpenGL extends PGraphics { } - - ////////////////////////////////////////////////////////////// - - // PIMAGE METHODS - - // getImage - // setCache, getCache, removeCache - // isModified, setModified - - ////////////////////////////////////////////////////////////// // LOAD/UPDATE PIXELS @@ -5617,16 +5646,16 @@ public class PGraphicsOpenGL extends PGraphics { if (texture == null || texture.contextIsOutdated()) { Texture.Parameters params = new Texture.Parameters(ARGB, sampling, mipmap); - texture = new Texture(width, height, params); + texture = new Texture(this, width, height, params); texture.invertedY(true); texture.colorBuffer(true); - pgPrimary.setCache(this, texture); + setCache(this, texture); } } protected void createPTexture() { - ptexture = new Texture(width, height, texture.getParameters()); + ptexture = new Texture(this, width, height, texture.getParameters()); ptexture.invertedY(true); ptexture.colorBuffer(true); } @@ -5755,7 +5784,7 @@ public class PGraphicsOpenGL extends PGraphics { loadTexture(); if (filterTexture == null || filterTexture.contextIsOutdated()) { - filterTexture = new Texture(texture.width, texture.height, + filterTexture = new Texture(this, texture.width, texture.height, texture.getParameters()); filterTexture.invertedY(true); filterImage = wrapTexture(filterTexture); @@ -5826,7 +5855,7 @@ public class PGraphicsOpenGL extends PGraphics { if (primarySurface) pgl.requestFBOLayer(); loadTexture(); if (filterTexture == null || filterTexture.contextIsOutdated()) { - filterTexture = new Texture(texture.width, texture.height, + filterTexture = new Texture(this, texture.width, texture.height, texture.getParameters()); filterTexture.invertedY(true); filterImage = wrapTexture(filterTexture); @@ -6044,7 +6073,7 @@ public class PGraphicsOpenGL extends PGraphics { return null; } - Texture tex = (Texture)pgPrimary.getCache(img); + Texture tex = (Texture)getCache(img); if (tex == null || tex.contextIsOutdated()) { tex = addTexture(img); if (tex != null) { @@ -6097,8 +6126,8 @@ public class PGraphicsOpenGL extends PGraphics { if (img.parent == null) { img.parent = parent; } - Texture tex = new Texture(img.width, img.height, params); - pgPrimary.setCache(img, tex); + Texture tex = new Texture(this, img.width, img.height, params); + setCache(img, tex); return tex; } @@ -6132,7 +6161,7 @@ public class PGraphicsOpenGL extends PGraphics { img.width = tex.width; img.height = tex.height; img.format = ARGB; - pgPrimary.setCache(img, tex); + setCache(img, tex); return img; } @@ -6194,10 +6223,9 @@ public class PGraphicsOpenGL extends PGraphics { protected void initPrimary() { pgl.initSurface(quality); if (texture != null) { - pgPrimary.removeCache(this); + removeCache(this); texture = ptexture = null; } - pgPrimary = this; initialized = true; } @@ -6247,7 +6275,7 @@ public class PGraphicsOpenGL extends PGraphics { packedDepthStencilSupported; if (PGraphicsOpenGL.fboMultisampleSupported && 1 < quality) { multisampleFramebuffer = - new FrameBuffer(texture.glWidth, texture.glHeight, quality, 0, + new FrameBuffer(this, texture.glWidth, texture.glHeight, quality, 0, depthBits, stencilBits, packed, false); multisampleFramebuffer.clear(); @@ -6257,13 +6285,13 @@ public class PGraphicsOpenGL extends PGraphics { // to doesn't need depth and stencil buffers since they are part of the // multisampled framebuffer. offscreenFramebuffer = - new FrameBuffer(texture.glWidth, texture.glHeight, 1, 1, 0, 0, + new FrameBuffer(this, texture.glWidth, texture.glHeight, 1, 1, 0, 0, false, false); } else { quality = 0; offscreenFramebuffer = - new FrameBuffer(texture.glWidth, texture.glHeight, 1, 1, + new FrameBuffer(this, texture.glWidth, texture.glHeight, 1, 1, depthBits, stencilBits, packed, false); offscreenMultisample = false; } @@ -6331,7 +6359,7 @@ public class PGraphicsOpenGL extends PGraphics { popFramebuffer(); texture.updateTexels(); // Mark all texels in screen texture as modified. - pgPrimary.restoreGL(); + getPrimaryPG().restoreGL(); } @@ -6740,14 +6768,15 @@ public class PGraphicsOpenGL extends PGraphics { } - static protected TexCache newTexCache() { - return new TexCache(); + static protected TexCache newTexCache(PGraphicsOpenGL pg) { + return new TexCache(pg); } // Holds an array of textures and the range of vertex // indices each texture applies to. static protected class TexCache { + PGraphicsOpenGL pg; int size; PImage[] textures; int[] firstIndex; @@ -6756,7 +6785,8 @@ public class PGraphicsOpenGL extends PGraphics { int[] lastCache; boolean hasTextures; - TexCache() { + TexCache(PGraphicsOpenGL pg) { + this.pg = pg; allocate(); } @@ -6792,7 +6822,7 @@ public class PGraphicsOpenGL extends PGraphics { Texture tex = null; if (img != null) { - tex = pgPrimary.getTexture(img); + tex = pg.getTexture(img); } return tex; diff --git a/core/src/processing/opengl/PJOGL.java b/core/src/processing/opengl/PJOGL.java index 8dc1fa95e..6979d4df4 100644 --- a/core/src/processing/opengl/PJOGL.java +++ b/core/src/processing/opengl/PJOGL.java @@ -66,16 +66,16 @@ public class PJOGL extends PGL { // Public members to access the underlying GL objects and context /** Basic GL functionality, common to all profiles */ - public static GL gl; + public GL gl; /** GLU interface **/ - public static GLU glu; + public GLU glu; /** The rendering context (holds rendering state info) */ - public static GLContext context; + public GLContext context; /** The canvas where OpenGL rendering takes place */ - public static Canvas canvas; + public Canvas canvas; /** Selected GL profile */ public static GLProfile profile; @@ -132,32 +132,32 @@ public class PJOGL extends PGL { // Protected JOGL-specific objects needed to access the GL profiles /** The capabilities of the OpenGL rendering surface */ - protected static GLCapabilitiesImmutable capabilities; + protected GLCapabilitiesImmutable capabilities; /** The rendering surface */ - protected static GLDrawable drawable; + protected GLDrawable drawable; /** GLES2 functionality (shaders, etc) */ - protected static GL2ES2 gl2; + protected GL2ES2 gl2; /** GL3 interface */ - protected static GL2GL3 gl3; + protected GL2GL3 gl3; /** GL2 desktop functionality (blit framebuffer, map buffer range, * multisampled renerbuffers) */ - protected static GL2 gl2x; + protected GL2 gl2x; /** The AWT-OpenGL canvas */ - protected static GLCanvas canvasAWT; + protected GLCanvas canvasAWT; /** The NEWT-OpenGL canvas */ - protected static NewtCanvasAWT canvasNEWT; + protected NewtCanvasAWT canvasNEWT; /** The NEWT window */ - protected static GLWindow window; + protected GLWindow window; /** The listener that fires the frame rendering in Processing */ - protected static PGLListener listener; + protected PGLListener listener; /** This countdown latch is used to maintain the synchronization between * Processing's drawing thread and JOGL's rendering thread */ @@ -490,7 +490,7 @@ public class PJOGL extends PGL { protected Texture wrapBackTexture(Texture texture) { if (texture == null || changedBackTex) { if (USE_JOGL_FBOLAYER) { - texture = new Texture(); + texture = new Texture(pg); texture.init(pg.width, pg.height, backTexAttach.getName(), TEXTURE_2D, RGBA, backTexAttach.getWidth(), backTexAttach.getHeight(), @@ -517,7 +517,7 @@ public class PJOGL extends PGL { protected Texture wrapFrontTexture(Texture texture) { if (texture == null || changedFrontTex) { if (USE_JOGL_FBOLAYER) { - texture = new Texture(); + texture = new Texture(pg); texture.init(pg.width, pg.height, backTexAttach.getName(), TEXTURE_2D, RGBA, frontTexAttach.getWidth(), frontTexAttach.getHeight(), @@ -612,6 +612,23 @@ public class PJOGL extends PGL { } + @Override + protected void getGL(PGL pgl) { + PJOGL pjogl = (PJOGL)pgl; + + this.drawable = pjogl.drawable; + this.context = pjogl.context; + this.glContext = pjogl.glContext; + this.glThread = pjogl.glThread; + + this.gl = pjogl.gl; + this.gl2 = pjogl.gl2; + this.gl2x = pjogl.gl2x; + this.gl3 = pjogl.gl3; + } + + + @Override protected boolean canDraw() { return pg.initialized && pg.parent.isDisplayable(); diff --git a/core/src/processing/opengl/PShader.java b/core/src/processing/opengl/PShader.java index d903a5670..97dbbc891 100644 --- a/core/src/processing/opengl/PShader.java +++ b/core/src/processing/opengl/PShader.java @@ -77,7 +77,8 @@ public class PShader implements PConstants { // be called by different renderers within a single application // (the one corresponding to the main surface, or other offscreen // renderers). - protected PGraphicsOpenGL pg; + protected PGraphicsOpenGL primaryPG; + protected PGraphicsOpenGL currentPG; protected PGL pgl; protected int context; // The context that created this shader. @@ -180,7 +181,8 @@ public class PShader implements PConstants { public PShader(PApplet parent) { this(); this.parent = parent; - pgl = PGraphicsOpenGL.pgCurrent.pgl; + primaryPG = (PGraphicsOpenGL)parent.g; + pgl = primaryPG.pgl; context = pgl.createEmptyContext(); } @@ -195,7 +197,8 @@ public class PShader implements PConstants { */ public PShader(PApplet parent, String vertFilename, String fragFilename) { this.parent = parent; - pgl = PGraphicsOpenGL.pgCurrent.pgl; + primaryPG = (PGraphicsOpenGL)parent.g; + pgl = primaryPG.pgl; this.vertexURL = null; this.fragmentURL = null; @@ -233,7 +236,8 @@ public class PShader implements PConstants { */ public PShader(PApplet parent, URL vertURL, URL fragURL) { this.parent = parent; - pgl = PGraphicsOpenGL.pgCurrent.pgl; + primaryPG = (PGraphicsOpenGL)parent.g; + pgl = primaryPG.pgl; this.vertexURL = vertURL; this.fragmentURL = fragURL; @@ -266,7 +270,8 @@ public class PShader implements PConstants { public PShader(PApplet parent, String[] vertSource, String[] fragSource) { this.parent = parent; - pgl = PGraphicsOpenGL.pgCurrent.pgl; + primaryPG = (PGraphicsOpenGL)parent.g; + pgl = primaryPG.pgl; this.vertexURL = null; this.fragmentURL = null; @@ -828,7 +833,7 @@ public class PShader implements PConstants { pgl.uniformMatrix4fv(loc, 1, false, floatBuffer); } else if (val.type == UniformValue.SAMPLER2D) { PImage img = (PImage)val.value; - Texture tex = PGraphicsOpenGL.pgPrimary.getTexture(img); + Texture tex = currentPG.getTexture(img); if (textures == null) textures = new HashMap(); textures.put(loc, tex); @@ -1108,7 +1113,7 @@ public class PShader implements PConstants { protected void setRenderer(PGraphicsOpenGL pg) { - this.pg = pg; + this.currentPG = pg; } @@ -1182,25 +1187,25 @@ public class PShader implements PConstants { protected void setCommonUniforms() { if (-1 < transformMatLoc) { - pg.updateGLProjmodelview(); - setUniformMatrix(transformMatLoc, pg.glProjmodelview); + currentPG.updateGLProjmodelview(); + setUniformMatrix(transformMatLoc, currentPG.glProjmodelview); } if (-1 < modelviewMatLoc) { - pg.updateGLModelview(); - setUniformMatrix(modelviewMatLoc, pg.glModelview); + currentPG.updateGLModelview(); + setUniformMatrix(modelviewMatLoc, currentPG.glModelview); } if (-1 < projectionMatLoc) { - pg.updateGLProjection(); - setUniformMatrix(projectionMatLoc, pg.glProjection); + currentPG.updateGLProjection(); + setUniformMatrix(projectionMatLoc, currentPG.glProjection); } if (-1 < viewportLoc) { - float x = pg.viewport.get(0); - float y = pg.viewport.get(1); - float w = pg.viewport.get(2); - float h = pg.viewport.get(3); + float x = currentPG.viewport.get(0); + float y = currentPG.viewport.get(1); + float w = currentPG.viewport.get(2); + float h = currentPG.viewport.get(3); setUniformValue(viewportLoc, x, y, w, h); } @@ -1208,15 +1213,15 @@ public class PShader implements PConstants { bufferUnit = getLastTexUnit() + 1; setUniformValue(bufferLoc, bufferUnit); pgl.activeTexture(PGL.TEXTURE0 + bufferUnit); - pg.bindFrontTexture(); + currentPG.bindFrontTexture(); } else { bufferUnit = -1; } } protected void bindTyped() { - if (pg == null) { - setRenderer(PGraphicsOpenGL.pgCurrent); + if (currentPG == null) { + setRenderer(primaryPG.getCurrentPG()); loadAttributes(); loadUniforms(); } @@ -1228,8 +1233,8 @@ public class PShader implements PConstants { if (-1 < normalLoc) pgl.enableVertexAttribArray(normalLoc); if (-1 < normalMatLoc) { - pg.updateGLNormal(); - setUniformMatrix(normalMatLoc, pg.glNormal); + currentPG.updateGLNormal(); + setUniformMatrix(normalMatLoc, currentPG.glNormal); } if (-1 < ambientLoc) pgl.enableVertexAttribArray(ambientLoc); @@ -1237,17 +1242,17 @@ public class PShader implements PConstants { if (-1 < emissiveLoc) pgl.enableVertexAttribArray(emissiveLoc); if (-1 < shininessLoc) pgl.enableVertexAttribArray(shininessLoc); - int count = pg.lightCount; + int count = currentPG.lightCount; setUniformValue(lightCountLoc, count); if (0 < count) { - setUniformVector(lightPositionLoc, pg.lightPosition, 4, count); - setUniformVector(lightNormalLoc, pg.lightNormal, 3, count); - setUniformVector(lightAmbientLoc, pg.lightAmbient, 3, count); - setUniformVector(lightDiffuseLoc, pg.lightDiffuse, 3, count); - setUniformVector(lightSpecularLoc, pg.lightSpecular, 3, count); - setUniformVector(lightFalloffLoc, pg.lightFalloffCoefficients, + setUniformVector(lightPositionLoc, currentPG.lightPosition, 4, count); + setUniformVector(lightNormalLoc, currentPG.lightNormal, 3, count); + setUniformVector(lightAmbientLoc, currentPG.lightAmbient, 3, count); + setUniformVector(lightDiffuseLoc, currentPG.lightDiffuse, 3, count); + setUniformVector(lightSpecularLoc, currentPG.lightSpecular, 3, count); + setUniformVector(lightFalloffLoc, currentPG.lightFalloffCoefficients, 3, count); - setUniformVector(lightSpotLoc, pg.lightSpotParameters, 2, count); + setUniformVector(lightSpotLoc, currentPG.lightSpotParameters, 2, count); } if (-1 < directionLoc) pgl.enableVertexAttribArray(directionLoc); @@ -1255,8 +1260,8 @@ public class PShader implements PConstants { if (-1 < offsetLoc) pgl.enableVertexAttribArray(offsetLoc); if (-1 < perspectiveLoc) { - if (pg.getHint(ENABLE_STROKE_PERSPECTIVE) && - pg.nonOrthoProjection()) { + if (currentPG.getHint(ENABLE_STROKE_PERSPECTIVE) && + currentPG.nonOrthoProjection()) { setUniformValue(perspectiveLoc, 1); } else { setUniformValue(perspectiveLoc, 0); @@ -1264,11 +1269,11 @@ public class PShader implements PConstants { } if (-1 < scaleLoc) { - if (pg.getHint(DISABLE_OPTIMIZED_STROKE)) { + if (currentPG.getHint(DISABLE_OPTIMIZED_STROKE)) { setUniformValue(scaleLoc, 1.0f, 1.0f, 1.0f); } else { float f = PGL.STROKE_DISPLACEMENT; - if (pg.orthoProjection()) { + if (currentPG.orthoProjection()) { setUniformValue(scaleLoc, 1, 1, f); } else { setUniformValue(scaleLoc, f, f, f); @@ -1302,7 +1307,7 @@ public class PShader implements PConstants { if (-1 < bufferLoc) { pgl.requestFBOLayer(); pgl.activeTexture(PGL.TEXTURE0 + bufferUnit); - pg.unbindFrontTexture(); + currentPG.unbindFrontTexture(); pgl.activeTexture(PGL.TEXTURE0); } diff --git a/core/src/processing/opengl/PShapeOpenGL.java b/core/src/processing/opengl/PShapeOpenGL.java index eff4ad51e..6db7fddca 100644 --- a/core/src/processing/opengl/PShapeOpenGL.java +++ b/core/src/processing/opengl/PShapeOpenGL.java @@ -290,8 +290,8 @@ public class PShapeOpenGL extends PShape { } - public PShapeOpenGL(PApplet parent, int family) { - pg = PGraphicsOpenGL.pgCurrent; + public PShapeOpenGL(PGraphicsOpenGL pg, int family) { + this.pg = pg; pgl = pg.pgl; context = pgl.createEmptyContext(); @@ -568,20 +568,19 @@ public class PShapeOpenGL extends PShape { // Shape creation (temporary hack) - public static PShapeOpenGL createShape3D(PApplet parent, PShape src) { + public static PShapeOpenGL createShape3D(PGraphicsOpenGL pg, PShape src) { PShapeOpenGL dest = null; if (src.getFamily() == GROUP) { - dest = PGraphics3D.createShapeImpl(parent, GROUP); - copyGroup3D(parent, src, dest); + dest = PGraphics3D.createShapeImpl(pg, GROUP); + copyGroup3D(pg, src, dest); } else if (src.getFamily() == PRIMITIVE) { - dest = PGraphics3D.createShapeImpl(parent, src.getKind(), - src.getParams()); + dest = PGraphics3D.createShapeImpl(pg, src.getKind(), src.getParams()); PShape.copyPrimitive(src, dest); } else if (src.getFamily() == GEOMETRY) { - dest = PGraphics3D.createShapeImpl(parent, PShape.GEOMETRY); + dest = PGraphics3D.createShapeImpl(pg, PShape.GEOMETRY); PShape.copyGeometry(src, dest); } else if (src.getFamily() == PATH) { - dest = PGraphics3D.createShapeImpl(parent, PATH); + dest = PGraphics3D.createShapeImpl(pg, PATH); PShape.copyPath(src, dest); } dest.setName(src.getName()); @@ -592,20 +591,19 @@ public class PShapeOpenGL extends PShape { } - static public PShapeOpenGL createShape2D(PApplet parent, PShape src) { + static public PShapeOpenGL createShape2D(PGraphicsOpenGL pg, PShape src) { PShapeOpenGL dest = null; if (src.getFamily() == GROUP) { - dest = PGraphics2D.createShapeImpl(parent, GROUP); - copyGroup2D(parent, src, dest); + dest = PGraphics2D.createShapeImpl(pg, GROUP); + copyGroup2D(pg, src, dest); } else if (src.getFamily() == PRIMITIVE) { - dest = PGraphics2D.createShapeImpl(parent, src.getKind(), - src.getParams()); + dest = PGraphics2D.createShapeImpl(pg, src.getKind(), src.getParams()); PShape.copyPrimitive(src, dest); } else if (src.getFamily() == GEOMETRY) { - dest = PGraphics2D.createShapeImpl(parent, PShape.GEOMETRY); + dest = PGraphics2D.createShapeImpl(pg, PShape.GEOMETRY); PShape.copyGeometry(src, dest); } else if (src.getFamily() == PATH) { - dest = PGraphics2D.createShapeImpl(parent, PATH); + dest = PGraphics2D.createShapeImpl(pg, PATH); PShape.copyPath(src, dest); } dest.setName(src.getName()); @@ -615,25 +613,25 @@ public class PShapeOpenGL extends PShape { } - static public void copyGroup3D(PApplet parent, PShape src, PShape dest) { + static public void copyGroup3D(PGraphicsOpenGL pg, PShape src, PShape dest) { copyMatrix(src, dest); copyStyles(src, dest); copyImage(src, dest); for (int i = 0; i < src.getChildCount(); i++) { - PShape c = createShape3D(parent, src.getChild(i)); + PShape c = createShape3D(pg, src.getChild(i)); dest.addChild(c); } } - static public void copyGroup2D(PApplet parent, PShape src, PShape dest) { + static public void copyGroup2D(PGraphicsOpenGL pg, PShape src, PShape dest) { copyMatrix(src, dest); copyStyles(src, dest); copyImage(src, dest); for (int i = 0; i < src.getChildCount(); i++) { - PShape c = createShape2D(parent, src.getChild(i)); + PShape c = createShape2D(pg, src.getChild(i)); dest.addChild(c); } } @@ -2413,9 +2411,9 @@ public class PShapeOpenGL extends PShape { PShape tess; if (is3D()) { - tess = PGraphics3D.createShapeImpl(pg.parent, PShape.GEOMETRY); + tess = PGraphics3D.createShapeImpl(pg, PShape.GEOMETRY); } else if (is2D()) { - tess = PGraphics2D.createShapeImpl(pg.parent, PShape.GEOMETRY); + tess = PGraphics2D.createShapeImpl(pg, PShape.GEOMETRY); } else { PGraphics.showWarning("This shape is not either 2D or 3D!"); return null; diff --git a/core/src/processing/opengl/Texture.java b/core/src/processing/opengl/Texture.java index c75b6bcc2..cd9ab6052 100644 --- a/core/src/processing/opengl/Texture.java +++ b/core/src/processing/opengl/Texture.java @@ -83,6 +83,7 @@ public class Texture implements PConstants { public int glWidth; public int glHeight; + protected PGraphicsOpenGL pg; protected PGL pgl; // The interface between Processing and OpenGL. protected int context; // The context that created this texture. protected boolean colorBuffer; // true if it is the color attachment of @@ -118,8 +119,9 @@ public class Texture implements PConstants { // Constructors. - public Texture() { - pgl = PGraphicsOpenGL.pgPrimary.pgl; + public Texture(PGraphicsOpenGL pg) { + this.pg = pg; + pgl = pg.pgl; context = pgl.createEmptyContext(); colorBuffer = false; @@ -134,8 +136,8 @@ public class Texture implements PConstants { * @param width int * @param height int */ - public Texture(int width, int height) { - this(width, height, new Parameters()); + public Texture(PGraphicsOpenGL pg, int width, int height) { + this(pg, width, height, new Parameters()); } @@ -146,8 +148,9 @@ public class Texture implements PConstants { * @param height int * @param params Parameters */ - public Texture(int width, int height, Object params) { - pgl = PGraphicsOpenGL.pgPrimary.pgl; + public Texture(PGraphicsOpenGL pg, int width, int height, Object params) { + this.pg = pg; + pgl = pg.pgl; context = pgl.createEmptyContext(); colorBuffer = false; @@ -249,7 +252,7 @@ public class Texture implements PConstants { dispose(); // Creating new texture with the appropriate size. - Texture tex = new Texture(wide, high, getParameters()); + Texture tex = new Texture(pg, wide, high, getParameters()); // Copying the contents of this texture into tex. tex.set(this); @@ -511,7 +514,7 @@ public class Texture implements PConstants { } if (tempFbo == null) { - tempFbo = new FrameBuffer(glWidth, glHeight); + tempFbo = new FrameBuffer(pg, glWidth, glHeight); } // Attaching the texture to the color buffer of a FBO, binding the FBO and @@ -1237,7 +1240,7 @@ public class Texture implements PConstants { } if (tempFbo == null) { - tempFbo = new FrameBuffer(glWidth, glHeight); + tempFbo = new FrameBuffer(pg, glWidth, glHeight); } // This texture is the color (destination) buffer of the FBO. @@ -1277,7 +1280,7 @@ public class Texture implements PConstants { int texWidth, int texHeight, int x, int y, int w, int h, boolean scale) { if (tempFbo == null) { - tempFbo = new FrameBuffer(glWidth, glHeight); + tempFbo = new FrameBuffer(pg, glWidth, glHeight); } // This texture is the color (destination) buffer of the FBO.