protected void createPackedDepthStencilBuffer() { if (screenFb) return; if (width == 0 || height == 0) { throw new RuntimeException("PFramebuffer: size undefined."); } pg.pushFramebuffer(); pg.setFramebuffer(this); glDepthStencilBufferID = pg.createRenderBufferObject(); pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthStencilBufferID); if (multisample) { pgl.glRenderbufferStorageMultisample( PGL.GL_RENDERBUFFER, nsamples, PGL.GL_DEPTH24_STENCIL8, width, height); } else { pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, PGL.GL_DEPTH24_STENCIL8, width, height); } pgl.glFramebufferRenderbuffer( PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID); pgl.glFramebufferRenderbuffer( PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID); pg.popFramebuffer(); }
/** Copy texture to pixels. Involves video memory to main memory transfer (slow). */ public void get(int[] pixels) { if (pixels == null) { throw new RuntimeException("Trying to copy texture to null pixels array"); } if (pixels.length != width * height) { throw new RuntimeException("Trying to copy texture to pixels array of " + "wrong size"); } if (tempFbo == null) { tempFbo = new FrameBuffer(parent, glWidth, glHeight); } // Attaching the texture to the color buffer of a FBO, binding the FBO and // reading the pixels from the current draw buffer (which is the color // buffer of the FBO). tempFbo.setColorBuffer(this); pg.pushFramebuffer(); pg.setFramebuffer(tempFbo); tempFbo.readPixels(); pg.popFramebuffer(); tempFbo.getPixels(pixels); convertToARGB(pixels); if (invertedX) flipArrayOnX(pixels, 1); if (invertedY) flipArrayOnY(pixels, 1); }
public void setColorBuffers(PTexture[] textures, int n) { if (screenFb) return; if (numColorBuffers != PApplet.min(n, textures.length)) { throw new RuntimeException("Wrong number of textures to set the color buffers."); } for (int i = 0; i < numColorBuffers; i++) { colorBufferTex[i] = textures[i]; } pg.pushFramebuffer(); pg.setFramebuffer(this); // Making sure nothing is attached. for (int i = 0; i < numColorBuffers; i++) { pgl.glFramebufferTexture2D( PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, PGL.GL_TEXTURE_2D, 0, 0); } for (int i = 0; i < numColorBuffers; i++) { pgl.glFramebufferTexture2D( PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, colorBufferTex[i].glTarget, colorBufferTex[i].glID, 0); } pgl.validateFramebuffer(); pg.popFramebuffer(); }
// Copies source texture tex into this. protected void copyTexture( int texTarget, int texName, int texWidth, int texHeight, int x, int y, int w, int h, boolean scale) { if (tempFbo == null) { tempFbo = new FrameBuffer(parent, glWidth, glHeight); } // This texture is the color (destination) buffer of the FBO. tempFbo.setColorBuffer(this); tempFbo.disableDepthTest(); // FBO copy: pg.pushFramebuffer(); pg.setFramebuffer(tempFbo); if (scale) { // Rendering tex into "this", and scaling the source rectangle // to cover the entire destination region. pgl.drawTexture(texTarget, texName, texWidth, texHeight, x, y, w, h, 0, 0, width, height); } else { // Rendering tex into "this" but without scaling so the contents // of the source texture fall in the corresponding texels of the // destination. pgl.drawTexture(texTarget, texName, texWidth, texHeight, x, y, w, h, x, y, w, h); } pg.popFramebuffer(); updateTexels(x, y, w, h); }
protected void createStencilBuffer() { if (screenFb) return; if (width == 0 || height == 0) { throw new RuntimeException("PFramebuffer: size undefined."); } pg.pushFramebuffer(); pg.setFramebuffer(this); glStencilBufferID = pg.createRenderBufferObject(); pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glStencilBufferID); int glConst = PGL.GL_STENCIL_INDEX1; if (stencilBits == 1) { glConst = PGL.GL_STENCIL_INDEX1; } else if (stencilBits == 4) { glConst = PGL.GL_STENCIL_INDEX4; } else if (stencilBits == 8) { glConst = PGL.GL_STENCIL_INDEX8; } if (multisample) { pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height); } else { pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height); } pgl.glFramebufferRenderbuffer( PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glStencilBufferID); pg.popFramebuffer(); }
public void clear() { pg.pushFramebuffer(); pg.setFramebuffer(this); pgl.glClearColor(0, 0, 0, 0); pgl.glClear(PGL.GL_COLOR_BUFFER_BIT | PGL.GL_DEPTH_BUFFER_BIT | PGL.GL_STENCIL_BUFFER_BIT); pg.popFramebuffer(); }
protected void createDepthBuffer() { if (screenFb) return; if (width == 0 || height == 0) { throw new RuntimeException("PFramebuffer: size undefined."); } pg.pushFramebuffer(); pg.setFramebuffer(this); glDepthBufferID = pg.createRenderBufferObject(); pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthBufferID); int glConst = PGL.GL_DEPTH_COMPONENT16; if (depthBits == 16) { glConst = PGL.GL_DEPTH_COMPONENT16; } else if (depthBits == 24) { glConst = PGL.GL_DEPTH_COMPONENT24; } else if (depthBits == 32) { glConst = PGL.GL_DEPTH_COMPONENT32; } if (multisample) { pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height); } else { pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height); } pgl.glFramebufferRenderbuffer( PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthBufferID); pg.popFramebuffer(); }
protected void allocate() { release(); // Just in the case this object is being re-allocated. context = pgl.getContext(); if (screenFb) { glFboID = 0; } else { glFboID = pg.createFrameBufferObject(); } // create the rest of the stuff... if (multisample) { createColorBufferMultisample(); } if (packedDepthStencil) { createPackedDepthStencilBuffer(); } else { if (0 < depthBits) { createDepthBuffer(); } if (0 < stencilBits) { createStencilBuffer(); } } }
protected void createColorBufferMultisample() { if (screenFb) return; pg.pushFramebuffer(); pg.setFramebuffer(this); glColorBufferMultisampleID = pg.createRenderBufferObject(); pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glColorBufferMultisampleID); pgl.glRenderbufferStorageMultisample( PGL.GL_RENDERBUFFER, nsamples, PGL.GL_RGBA8, width, height); pgl.glFramebufferRenderbuffer( PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0, PGL.GL_RENDERBUFFER, glColorBufferMultisampleID); pg.popFramebuffer(); }
public void finish() { if (noDepth) { // No need to clear depth buffer because depth testing was disabled. if (pg.hintEnabled(DISABLE_DEPTH_TEST)) { pgl.glDisable(PGL.GL_DEPTH_TEST); } else { pgl.glEnable(PGL.GL_DEPTH_TEST); } } }
@Override protected void finalize() throws Throwable { try { if (glName != 0) { pg.finalizeTextureObject(glName, context); } } finally { super.finalize(); } }
protected void finalize() throws Throwable { try { if (glFboID != 0) { pg.finalizeFrameBufferObject(glFboID); } if (glDepthBufferID != 0) { pg.finalizeRenderBufferObject(glDepthBufferID); } if (glStencilBufferID != 0) { pg.finalizeRenderBufferObject(glStencilBufferID); } if (glColorBufferMultisampleID != 0) { pg.finalizeRenderBufferObject(glColorBufferMultisampleID); } if (glDepthStencilBufferID != 0) { pg.finalizeRenderBufferObject(glDepthStencilBufferID); } } finally { super.finalize(); } }
protected void release() { if (glFboID != 0) { pg.finalizeFrameBufferObject(glFboID); glFboID = 0; } if (glDepthBufferID != 0) { pg.finalizeRenderBufferObject(glDepthBufferID); glDepthBufferID = 0; } if (glStencilBufferID != 0) { pg.finalizeRenderBufferObject(glStencilBufferID); glStencilBufferID = 0; } if (glColorBufferMultisampleID != 0) { pg.finalizeRenderBufferObject(glColorBufferMultisampleID); glColorBufferMultisampleID = 0; } if (glDepthStencilBufferID != 0) { pg.finalizeRenderBufferObject(glDepthStencilBufferID); glDepthStencilBufferID = 0; } }
protected boolean contextIsOutdated() { boolean outdated = !pgl.contextIsCurrent(context); if (outdated) { // Removing the texture object from the renderer's list so it // doesn't get deleted by OpenGL. The texture object was // automatically disposed when the old context was destroyed. pg.removeTextureObject(glName, context); // And then set the id to zero, so it doesn't try to be // deleted when the object's finalizer is invoked by the GC. glName = 0; } return outdated; }
/** Allocates the opengl texture object. */ protected void allocate() { release(); // Just in the case this object is being re-allocated. boolean enabledTex = false; if (!pgl.texturingIsEnabled(glTarget)) { pgl.enableTexturing(glTarget); enabledTex = true; } context = pgl.getCurrentContext(); glName = pg.createTextureObject(context); pgl.bindTexture(glTarget, glName); pgl.texParameteri(glTarget, PGL.TEXTURE_MIN_FILTER, glMinFilter); pgl.texParameteri(glTarget, PGL.TEXTURE_MAG_FILTER, glMagFilter); pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_S, glWrapS); pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_T, glWrapT); if (PGraphicsOpenGL.anisoSamplingSupported) { pgl.texParameterf(glTarget, PGL.TEXTURE_MAX_ANISOTROPY, PGraphicsOpenGL.maxAnisoAmount); } // First, we use glTexImage2D to set the full size of the texture (glW/glH // might be diff from w/h in the case that the GPU doesn't support NPOT // textures) pgl.texImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0, PGL.RGBA, PGL.UNSIGNED_BYTE, null); // Makes sure that the texture buffer in video memory doesn't contain // any garbage. pgl.initTexture(glTarget, PGL.RGBA, width, height); pgl.bindTexture(glTarget, 0); if (enabledTex) { pgl.disableTexturing(glTarget); } bound = false; }
/** Marks the texture object for deletion. */ protected void release() { if (glName != 0) { pg.finalizeTextureObject(glName, context); glName = 0; } }
public void set(PImage img, int x, int y, int w, int h) { Texture tex = (Texture) pg.getCache(img); set(tex, x, y, w, h); }
public void set(PImage img) { Texture tex = (Texture) pg.getCache(img); set(tex); }
// Copies source texture tex into this. protected void copyTexture(Texture tex, int x, int y, int w, int h, boolean scale) { if (tex == null) { throw new RuntimeException("Source texture is null"); } if (tempFbo == null) { tempFbo = new FrameBuffer(glWidth, glHeight); } // This texture is the color (destination) buffer of the FBO. tempFbo.setColorBuffer(this); tempFbo.disableDepthTest(); // FBO copy: PGraphicsOpenGL.pushFramebuffer(); PGraphicsOpenGL.setFramebuffer(tempFbo); // Clear the color buffer to make sure that the alpha channel is set to // full transparency pgl.clearColor(0, 0, 0, 0); pgl.clear(PGL.COLOR_BUFFER_BIT); if (scale) { // Rendering tex into "this", and scaling the source rectangle // to cover the entire destination region. pgl.drawTexture( tex.glTarget, tex.glName, tex.glWidth, tex.glHeight, tempFbo.width, tempFbo.height, x, y, w, h, 0, 0, width, height); } else { // Rendering tex into "this" but without scaling so the contents // of the source texture fall in the corresponding texels of the // destination. pgl.drawTexture( tex.glTarget, tex.glName, tex.glWidth, tex.glHeight, tempFbo.width, tempFbo.height, x, y, w, h, x, y, w, h); } PGraphicsOpenGL.popFramebuffer(); updateTexels(x, y, w, h); }
/** Marks the texture object for deletion. */ protected void dispose() { if (glName != 0) { PGraphicsOpenGL.finalizeTextureObject(glName, context); glName = 0; } }
@SuppressWarnings("deprecation") public SketchSurfaceViewGL( Context context, int wide, int high, Class<? extends PGraphicsOpenGL> clazz) { super(context); // Check if the system supports OpenGL ES 2.0. final ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE); final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo(); final boolean supportsGLES2 = configurationInfo.reqGlEsVersion >= 0x20000; if (!supportsGLES2) { throw new RuntimeException("OpenGL ES 2.0 is not supported by this device."); } surfaceHolder = getHolder(); // are these two needed? surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU); // The PGraphics object needs to be created here so the renderer is not // null. This is required because PApplet.onResume events (which call // this.onResume() and thus require a valid renderer) are triggered // before surfaceChanged() is ever called. if (clazz.equals(PGraphics2D.class)) { // P2D g3 = new PGraphics2D(); } else if (clazz.equals(PGraphics3D.class)) { // P3D g3 = new PGraphics3D(); } else { // something that extends P2D, P3D, or PGraphicsOpenGL try { Constructor<? extends PGraphicsOpenGL> constructor = clazz.getConstructor(); g3 = constructor.newInstance(); } catch (Exception exception) { throw new RuntimeException( "Error: Failed to initialize custom OpenGL renderer", exception); } } // set it up g3.setParent(sketch); g3.setPrimary(true); // Set semi-arbitrary size; will be set properly when surfaceChanged() called g3.setSize(wide, high); // Tells the default EGLContextFactory and EGLConfigChooser to create an GLES2 context. setEGLContextClientVersion(2); int quality = sketch.sketchQuality(); if (1 < quality) { setEGLConfigChooser(((PGLES) g3.pgl).getConfigChooser(quality)); } // The renderer can be set only once. setRenderer(((PGLES) g3.pgl).getRenderer()); setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); // assign this g to the PApplet sketch.g = g3; setFocusable(true); setFocusableInTouchMode(true); requestFocus(); }