Improved context recreation mechanism

This commit is contained in:
codeanticode
2011-12-12 03:55:17 +00:00
parent c1762fbaee
commit 05bc179a61
6 changed files with 350 additions and 235 deletions
@@ -25,6 +25,9 @@
package processing.opengl;
import java.util.HashMap;
import javax.media.opengl.GLContext;
import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PFont;
@@ -50,6 +53,7 @@ import processing.core.PImage;
class PFontTexture implements PConstants {
protected PApplet parent;
protected PGraphicsOpenGL ogl;
protected GLContext context;
protected PFont font;
protected int maxTexWidth;
@@ -68,38 +72,11 @@ class PFontTexture implements PConstants {
this.parent = parent;
this.font = font;
ogl = (PGraphicsOpenGL)parent.g;
context = ogl.getContext();
initTexture(maxw, maxh);
}
/*
public void delete() {
for (int i = 0; i < textures.length; i++) {
textures[i].delete();
}
ogl.unregisterPGLObject(this);
}
public void backup() {
// Nothing to do here: the font textures will backup
// themselves.
}
public void restore() {
// Restoration we have to do explicitly because the font
// textures don't have a backing PImage object, so the
// updateTex() method is in charge of updating each appropriate
// section of the font textures.
for (int i = 0; i < PApplet.min(font.getGlyphCount(), glyphTexinfos.length); i++) {
TextureInfo tinfo = glyphTexinfos[i];
textures[tinfo.texIndex].bind();
tinfo.updateTex();
textures[tinfo.texIndex].unbind();
}
}
*/
protected void allocate() {
// Nothing to do here: the font textures will allocate
@@ -147,7 +124,7 @@ class PFontTexture implements PConstants {
textures = new PTexture[1];
textures[0] = tex;
images = new PImage[1];
images[0] = PTexture.wrap(ogl, tex);
images[0] = ogl.wrapTexture(tex);
currentTex = 0;
} else if (resize) {
// Replacing old smaller texture with larger one.
@@ -171,7 +148,7 @@ class PFontTexture implements PConstants {
PImage[] tempImg = images;
images = new PImage[textures.length + 1];
PApplet.arrayCopy(tempImg, images, tempImg.length);
images[tempImg.length] = PTexture.wrap(ogl, tex);
images[tempImg.length] = ogl.wrapTexture(tex);
}
lastTex = currentTex;
@@ -151,42 +151,22 @@ public class PFramebuffer implements PConstants {
backupTexture = new PTexture(parent, width, height, new PTexture.Parameters(ARGB, POINT));
}
}
/*
public void delete() {
release();
for (int i = 0; i < numColorBuffers; i++) {
colorBufferTex[i] = null;
}
ogl.unregisterPGLObject(this);
}
public void backup() {
}
public void restore() {
setColorBuffers(colorBufferTex.clone(), colorBufferTex.length);
}
*/
protected void finalize() throws Throwable {
try {
if (glFboID != 0) {
ogl.finalizeFrameBufferObject(glFboID);
}
}
if (glDepthBufferID != 0) {
ogl.finalizeRenderBufferObject(glDepthBufferID);
}
}
if (glStencilBufferID != 0) {
ogl.finalizeRenderBufferObject(glStencilBufferID);
}
if (glColorBufferMultisampleID != 0) {
ogl.finalizeRenderBufferObject(glColorBufferMultisampleID);
}
if (glDepthStencilBufferID != 0) {
ogl.finalizeRenderBufferObject(glDepthStencilBufferID);
}
@@ -670,21 +670,37 @@ public class PGraphicsOpenGL extends PGraphics {
int[] temp = new int[1];
gl.glGenTextures(1, temp, 0);
int idx = temp[0];
int id = temp[0];
if (glTextureObjects.containsKey(idx)) {
if (glTextureObjects.containsKey(id)) {
showWarning("Adding same texture twice");
} else {
glTextureObjects.put(idx, false);
glTextureObjects.put(id, false);
}
return idx;
return id;
}
protected void deleteTextureObject(int id) {
if (glTextureObjects.containsKey(id)) {
int[] temp = { id };
gl.glDeleteTextures(1, temp, 0);
glTextureObjects.remove(id);
}
}
protected void deleteAllTextureObjects() {
for (Integer id : glTextureObjects.keySet()) {
int[] temp = { id.intValue() };
gl.glDeleteTextures(1, temp, 0);
}
glTextureObjects.clear();
}
// This is synchronized because it is called from the GC thread.
synchronized protected void finalizeTextureObject(int idx) {
if (glTextureObjects.containsKey(idx)) {
glTextureObjects.put(idx, true);
synchronized protected void finalizeTextureObject(int id) {
if (glTextureObjects.containsKey(id)) {
glTextureObjects.put(id, true);
} else {
showWarning("Trying to finalize non-existing texture");
}
@@ -693,17 +709,16 @@ public class PGraphicsOpenGL extends PGraphics {
protected void deleteFinalizedTextureObjects() {
Set<Integer> finalized = new HashSet<Integer>();
for (Integer idx : glTextureObjects.keySet()) {
if (glTextureObjects.get(idx)) {
finalized.add(idx);
int id = idx.intValue();
int[] temp = { id };
for (Integer id : glTextureObjects.keySet()) {
if (glTextureObjects.get(id)) {
finalized.add(id);
int[] temp = { id.intValue() };
gl.glDeleteTextures(1, temp, 0);
}
}
for (Integer idx : finalized) {
glTextureObjects.remove(idx);
for (Integer id : finalized) {
glTextureObjects.remove(id);
}
}
@@ -733,6 +748,14 @@ public class PGraphicsOpenGL extends PGraphics {
}
}
protected void deleteAllVertexBufferObjects() {
for (Integer id : glVertexBuffers.keySet()) {
int[] temp = { id.intValue() };
gl.glDeleteBuffers(1, temp, 0);
}
glVertexBuffers.clear();
}
// This is synchronized because it is called from the GC thread.
synchronized protected void finalizeVertexBufferObject(int id) {
if (glVertexBuffers.containsKey(id)) {
@@ -765,21 +788,37 @@ public class PGraphicsOpenGL extends PGraphics {
int[] temp = new int[1];
gl.glGenFramebuffers(1, temp, 0);
int idx = temp[0];
int id = temp[0];
if (glFrameBuffers.containsKey(idx)) {
if (glFrameBuffers.containsKey(id)) {
showWarning("Adding same FBO twice");
} else {
glFrameBuffers.put(idx, false);
glFrameBuffers.put(id, false);
}
return idx;
return id;
}
protected void deleteFrameBufferObject(int id) {
if (glFrameBuffers.containsKey(id)) {
int[] temp = { id };
gl.glDeleteFramebuffers(1, temp, 0);
glFrameBuffers.remove(id);
}
}
protected void deleteAllFrameBufferObjects() {
for (Integer id : glFrameBuffers.keySet()) {
int[] temp = { id.intValue() };
gl.glDeleteFramebuffers(1, temp, 0);
}
glFrameBuffers.clear();
}
// This is synchronized because it is called from the GC thread.
synchronized protected void finalizeFrameBufferObject(int idx) {
if (glFrameBuffers.containsKey(idx)) {
glFrameBuffers.put(idx, true);
synchronized protected void finalizeFrameBufferObject(int id) {
if (glFrameBuffers.containsKey(id)) {
glFrameBuffers.put(id, true);
} else {
showWarning("Trying to finalize non-existing FBO");
}
@@ -788,17 +827,16 @@ public class PGraphicsOpenGL extends PGraphics {
protected void deleteFinalizedFrameBufferObjects() {
Set<Integer> finalized = new HashSet<Integer>();
for (Integer idx : glFrameBuffers.keySet()) {
if (glFrameBuffers.get(idx)) {
finalized.add(idx);
int id = idx.intValue();
int[] temp = { id };
for (Integer id : glFrameBuffers.keySet()) {
if (glFrameBuffers.get(id)) {
finalized.add(id);
int[] temp = { id.intValue() };
gl.glDeleteFramebuffers(1, temp, 0);
}
}
for (Integer idx : finalized) {
glFrameBuffers.remove(idx);
for (Integer id : finalized) {
glFrameBuffers.remove(id);
}
}
@@ -809,21 +847,37 @@ public class PGraphicsOpenGL extends PGraphics {
int[] temp = new int[1];
gl.glGenRenderbuffers(1, temp, 0);
int idx = temp[0];
int id = temp[0];
if (glRenderBuffers.containsKey(idx)) {
if (glRenderBuffers.containsKey(id)) {
showWarning("Adding same renderbuffer twice");
} else {
glRenderBuffers.put(idx, false);
glRenderBuffers.put(id, false);
}
return idx;
return id;
}
protected void deleteRenderBufferObject(int id) {
if (glRenderBuffers.containsKey(id)) {
int[] temp = { id };
gl.glDeleteRenderbuffers(1, temp, 0);
glRenderBuffers.remove(id);
}
}
protected void deleteAllRenderBufferObjects() {
for (Integer id : glRenderBuffers.keySet()) {
int[] temp = { id.intValue() };
gl.glDeleteRenderbuffers(1, temp, 0);
}
glRenderBuffers.clear();
}
// This is synchronized because it is called from the GC thread.
synchronized protected void finalizeRenderBufferObject(int idx) {
if (glRenderBuffers.containsKey(idx)) {
glRenderBuffers.put(idx, true);
synchronized protected void finalizeRenderBufferObject(int id) {
if (glRenderBuffers.containsKey(id)) {
glRenderBuffers.put(id, true);
} else {
showWarning("Trying to finalize non-existing renderbuffer");
}
@@ -832,17 +886,16 @@ public class PGraphicsOpenGL extends PGraphics {
protected void deleteFinalizedRenderBufferObjects() {
Set<Integer> finalized = new HashSet<Integer>();
for (Integer idx : glRenderBuffers.keySet()) {
if (glRenderBuffers.get(idx)) {
finalized.add(idx);
int id = idx.intValue();
int[] temp = { id };
for (Integer id : glRenderBuffers.keySet()) {
if (glRenderBuffers.get(id)) {
finalized.add(id);
int[] temp = { id.intValue() };
gl.glDeleteRenderbuffers(1, temp, 0);
}
}
for (Integer idx : finalized) {
glRenderBuffers.remove(idx);
for (Integer id : finalized) {
glRenderBuffers.remove(id);
}
}
@@ -853,21 +906,35 @@ public class PGraphicsOpenGL extends PGraphics {
ogl.report("before delete");
deleteFinalizedGLSLProgramObjects();
int idx = gl2x.glCreateProgram();
int id = gl2x.glCreateProgram();
if (glslPrograms.containsKey(idx)) {
if (glslPrograms.containsKey(id)) {
showWarning("Adding same glsl program twice");
} else {
glslPrograms.put(idx, false);
glslPrograms.put(id, false);
}
return idx;
return id;
}
protected void deleteGLSLProgramObject(int id) {
if (glslPrograms.containsKey(id)) {
gl2x.glDeleteProgram(id);
glslPrograms.remove(id);
}
}
protected void deleteAllGLSLProgramObjects() {
for (Integer id : glslPrograms.keySet()) {
gl2x.glDeleteProgram(id);
}
glslPrograms.clear();
}
// This is synchronized because it is called from the GC thread.
synchronized protected void finalizeGLSLProgramObject(int idx) {
if (glslPrograms.containsKey(idx)) {
glslPrograms.put(idx, true);
synchronized protected void finalizeGLSLProgramObject(int id) {
if (glslPrograms.containsKey(id)) {
glslPrograms.put(id, true);
} else {
showWarning("Trying to finalize non-existing glsl program");
}
@@ -876,16 +943,15 @@ public class PGraphicsOpenGL extends PGraphics {
protected void deleteFinalizedGLSLProgramObjects() {
Set<Integer> finalized = new HashSet<Integer>();
for (Integer idx : glslPrograms.keySet()) {
if (glslPrograms.get(idx)) {
finalized.add(idx);
int id = idx.intValue();
gl2x.glDeleteProgram(id);
for (Integer id : glslPrograms.keySet()) {
if (glslPrograms.get(id)) {
finalized.add(id);
gl2x.glDeleteProgram(id.intValue());
}
}
for (Integer idx : finalized) {
glslPrograms.remove(idx);
for (Integer id : finalized) {
glslPrograms.remove(id);
}
}
@@ -894,21 +960,35 @@ public class PGraphicsOpenGL extends PGraphics {
protected int createGLSLVertShaderObject() {
deleteFinalizedGLSLVertShaderObjects();
int idx = gl2x.glCreateShader(GL2.GL_VERTEX_SHADER);
int id = gl2x.glCreateShader(GL2.GL_VERTEX_SHADER);
if (glslVertexShaders.containsKey(idx)) {
if (glslVertexShaders.containsKey(id)) {
showWarning("Adding same glsl vertex shader twice");
} else {
glslVertexShaders.put(idx, false);
glslVertexShaders.put(id, false);
}
return idx;
return id;
}
protected void deleteGLSLVertShaderObject(int id) {
if (glslVertexShaders.containsKey(id)) {
gl2x.glDeleteShader(id);
glslVertexShaders.remove(id);
}
}
protected void deleteAllGLSLVertShaderObjects() {
for (Integer id : glslVertexShaders.keySet()) {
gl2x.glDeleteShader(id);
}
glslVertexShaders.clear();
}
// This is synchronized because it is called from the GC thread.
synchronized protected void finalizeGLSLVertShaderObject(int idx) {
if (glslVertexShaders.containsKey(idx)) {
glslVertexShaders.put(idx, true);
synchronized protected void finalizeGLSLVertShaderObject(int id) {
if (glslVertexShaders.containsKey(id)) {
glslVertexShaders.put(id, true);
} else {
showWarning("Trying to finalize non-existing glsl vertex shader");
}
@@ -917,16 +997,15 @@ public class PGraphicsOpenGL extends PGraphics {
protected void deleteFinalizedGLSLVertShaderObjects() {
Set<Integer> finalized = new HashSet<Integer>();
for (Integer idx : glslVertexShaders.keySet()) {
if (glslVertexShaders.get(idx)) {
finalized.add(idx);
int id = idx.intValue();
gl2x.glDeleteShader(id);
for (Integer id : glslVertexShaders.keySet()) {
if (glslVertexShaders.get(id)) {
finalized.add(id);
gl2x.glDeleteShader(id.intValue());
}
}
for (Integer idx : finalized) {
glslVertexShaders.remove(idx);
for (Integer id : finalized) {
glslVertexShaders.remove(id);
}
}
@@ -936,21 +1015,35 @@ public class PGraphicsOpenGL extends PGraphics {
protected int createGLSLFragShaderObject() {
deleteFinalizedGLSLFragShaderObjects();
int idx = gl2x.glCreateShader(GL2.GL_FRAGMENT_SHADER);
int id = gl2x.glCreateShader(GL2.GL_FRAGMENT_SHADER);
if (glslFragmentShaders.containsKey(idx)) {
if (glslFragmentShaders.containsKey(id)) {
showWarning("Adding same glsl fragment shader twice");
} else {
glslFragmentShaders.put(idx, false);
glslFragmentShaders.put(id, false);
}
return idx;
return id;
}
protected void deleteGLSLFragShaderObject(int id) {
if (glslFragmentShaders.containsKey(id)) {
gl2x.glDeleteShader(id);
glslFragmentShaders.remove(id);
}
}
protected void deleteAllGLSLFragShaderObjects() {
for (Integer id : glslFragmentShaders.keySet()) {
gl2x.glDeleteShader(id);
}
glslFragmentShaders.clear();
}
// This is synchronized because it is called from the GC thread.
synchronized protected void finalizeGLSLFragShaderObject(int idx) {
if (glslFragmentShaders.containsKey(idx)) {
glslFragmentShaders.put(idx, true);
synchronized protected void finalizeGLSLFragShaderObject(int id) {
if (glslFragmentShaders.containsKey(id)) {
glslFragmentShaders.put(id, true);
} else {
showWarning("Trying to finalize non-existing glsl fragment shader");
}
@@ -959,16 +1052,15 @@ public class PGraphicsOpenGL extends PGraphics {
protected void deleteFinalizedGLSLFragShaderObjects() {
Set<Integer> finalized = new HashSet<Integer>();
for (Integer idx : glslFragmentShaders.keySet()) {
if (glslFragmentShaders.get(idx)) {
finalized.add(idx);
int id = idx.intValue();
gl2x.glDeleteShader(id);
for (Integer id : glslFragmentShaders.keySet()) {
if (glslFragmentShaders.get(id)) {
finalized.add(id);
gl2x.glDeleteShader(id.intValue());
}
}
for (Integer idx : finalized) {
glslFragmentShaders.remove(idx);
for (Integer id : finalized) {
glslFragmentShaders.remove(id);
}
}
@@ -983,6 +1075,15 @@ public class PGraphicsOpenGL extends PGraphics {
deleteFinalizedGLSLFragShaderObjects();
}
protected void deleteAllGLResources() {
deleteAllTextureObjects();
deleteAllVertexBufferObjects();
deleteAllFrameBufferObjects();
deleteAllRenderBufferObjects();
deleteAllGLSLProgramObjects();
deleteAllGLSLVertShaderObjects();
deleteAllGLSLFragShaderObjects();
}
//////////////////////////////////////////////////////////////
@@ -1059,6 +1160,8 @@ public class PGraphicsOpenGL extends PGraphics {
}
protected void releaseResources() {
// First, releasing the resources used by
// renderer itself.
if (texture != null) {
texture.release();
texture = null;
@@ -1085,7 +1188,11 @@ public class PGraphicsOpenGL extends PGraphics {
if (pointVBOsCreated) {
releasePointBuffers();
pointVBOsCreated = false;
}
}
// Now, releasing the remaining resources
// (from user's objects).
deleteAllGLResources();
}
@@ -1102,14 +1209,8 @@ public class PGraphicsOpenGL extends PGraphics {
* the current OpenGL objects remain valid afterward.
*/
public void restartContext() {
//backupPGLObjects();
// This releases the objects holding OpenGL resources
// that are used by this renderer, so they are recreated
// later... but what TODO with the objects such as PImages
// or PShapes that might have been created by the user?
releaseResources();
deleteFinalizedGLResources();
releaseResources();
//deleteFinalizedGLResources();
releaseContext();
context.destroy();
@@ -1118,9 +1219,6 @@ public class PGraphicsOpenGL extends PGraphics {
detainContext();
updateGLInterfaces();
// allocatePGLObjects();
// clearPGLFramebuffers();
// restorePGLObjects();
}
protected void createFillBuffers() {
@@ -1440,8 +1538,6 @@ public class PGraphicsOpenGL extends PGraphics {
drawing = false;
//deleteFinalizedGLResources();
report("bot endDraw()");
}
@@ -1459,26 +1555,9 @@ public class PGraphicsOpenGL extends PGraphics {
public void endGL() {
restoreGLState();
}
/*
public void allocateGL() {
allocatePGLObjects();
}
public void backupGL() {
backupPGLObjects();
}
public void restoreGL() {
clearPGLFramebuffers();
restorePGLObjects();
}
*/
public void updateGLInterfaces() {
gl = context.getGL();
@@ -3100,7 +3179,16 @@ public class PGraphicsOpenGL extends PGraphics {
if (textTex == null) {
textTex = new PFontTexture(parent, textFont, maxTextureSize, maxTextureSize);
textFont.setCache(this, textTex);
}
} else {
if (context.hashCode() != textTex.context.hashCode()) {
for (int i = 0; i < textTex.textures.length; i++) {
textTex.textures[i].glID = 0; // To avoid finalization (texture objects were already deleted when context changed).
textTex.textures[i] = null;
}
textTex = new PFontTexture(parent, textFont, maxTextureSize, maxTextureSize);
textFont.setCache(this, textTex);
}
}
textTex.setFirstTexture();
// Saving style parameters modified by text rendering.
@@ -5274,7 +5362,6 @@ public class PGraphicsOpenGL extends PGraphics {
texture.setFlippedY(true);
this.setCache(ogl, texture);
this.setParams(ogl, params);
texture.setImage(this);
texCrop = new int[4];
texCrop[0] = 0;
@@ -5713,11 +5800,26 @@ public class PGraphicsOpenGL extends PGraphics {
PTexture tex = (PTexture)img.getCache(ogl);
if (tex == null) {
tex = addTexture(img);
} else if (img.isModified()) {
if (img.width != tex.width || img.height != tex.height) {
tex.init(img.width, img.height);
} else {
if (context.hashCode() != tex.context.hashCode()) {
// The texture was created with a different context. We need
// to recreate it. First, we make sure that the old GL id
// is not used to delete the texture object (it was already
// deleted when the context changed).
tex.glID = 0;
tex = addTexture(img);
// TODO: apply this mechanism to all the Processing objects using
// GL resources (PShape, PShader, PFramebuffer). They will probably
// need the cache thingy as well.
}
updateTexture(img, tex);
if (img.isModified()) {
if (img.width != tex.width || img.height != tex.height) {
tex.init(img.width, img.height);
}
updateTexture(img, tex);
}
}
return tex;
}
@@ -5735,12 +5837,24 @@ public class PGraphicsOpenGL extends PGraphics {
}
PTexture tex = new PTexture(img.parent, img.width, img.height, params);
img.loadPixels();
tex.set(img.pixels);
if (img.pixels != null) tex.set(img.pixels);
img.setCache(ogl, tex);
tex.setImage(img); // The parent image so the texture can regenerate itself upon re-allocation.
return tex;
}
protected PImage wrapTexture(PTexture tex) {
// We don't use the PImage(int width, int height, int mode) constructor to
// avoid initializing the pixels array.
PImage img = new PImage();
img.parent = parent;
img.width = tex.width;
img.height = tex.height;
img.format = ARGB;
img.setCache(ogl, tex);
return img;
}
protected void updateTexture(PImage img, PTexture tex) {
if (tex != null) {
@@ -86,7 +86,15 @@ public class PShader {
protected void finalize() throws Throwable {
try {
release();
if (vertexShader != 0) {
ogl.finalizeGLSLVertShaderObject(vertexShader);
}
if (fragmentShader != 0) {
ogl.finalizeGLSLFragShaderObject(fragmentShader);
}
if (programObject != 0) {
ogl.finalizeGLSLProgramObject(programObject);
}
} finally {
super.finalize();
}
@@ -492,15 +500,15 @@ public class PShader {
protected void release() {
if (vertexShader != 0) {
ogl.finalizeGLSLVertShaderObject(vertexShader);
ogl.deleteGLSLVertShaderObject(vertexShader);
vertexShader = 0;
}
if (fragmentShader != 0) {
ogl.finalizeGLSLFragShaderObject(fragmentShader);
ogl.deleteGLSLFragShaderObject(fragmentShader);
fragmentShader = 0;
}
if (programObject != 0) {
ogl.finalizeGLSLProgramObject(programObject);
ogl.deleteGLSLProgramObject(programObject);
programObject = 0;
}
}
@@ -297,13 +297,80 @@ public class PShape3D extends PShape {
protected void finalize() throws Throwable {
try {
release();
finalizeFillBuffers();
finalizeLineBuffers();
finalizePointBuffers();
} finally {
super.finalize();
}
}
protected void finalizeFillBuffers() {
if (glFillVertexBufferID != 0) {
ogl.finalizeVertexBufferObject(glFillVertexBufferID);
}
if (glFillColorBufferID != 0) {
ogl.finalizeVertexBufferObject(glFillColorBufferID);
}
if (glFillNormalBufferID != 0) {
ogl.finalizeVertexBufferObject(glFillNormalBufferID);
}
if (glFillTexCoordBufferID != 0) {
ogl.finalizeVertexBufferObject(glFillTexCoordBufferID);
}
if (glFillIndexBufferID != 0) {
ogl.finalizeVertexBufferObject(glFillIndexBufferID);
}
}
protected void finalizeLineBuffers() {
if (glLineVertexBufferID != 0) {
ogl.finalizeVertexBufferObject(glLineVertexBufferID);
}
if (glLineColorBufferID != 0) {
ogl.finalizeVertexBufferObject(glLineColorBufferID);
}
if (glLineNormalBufferID != 0) {
ogl.finalizeVertexBufferObject(glLineNormalBufferID);
}
if (glLineAttribBufferID != 0) {
ogl.finalizeVertexBufferObject(glLineAttribBufferID);
}
if (glLineIndexBufferID != 0) {
ogl.finalizeVertexBufferObject(glLineIndexBufferID);
}
}
protected void finalizePointBuffers() {
if (glPointVertexBufferID != 0) {
ogl.finalizeVertexBufferObject(glPointVertexBufferID);
}
if (glPointColorBufferID != 0) {
ogl.finalizeVertexBufferObject(glPointColorBufferID);
}
if (glPointNormalBufferID != 0) {
ogl.finalizeVertexBufferObject(glPointNormalBufferID);
}
if (glPointAttribBufferID != 0) {
ogl.finalizeVertexBufferObject(glPointAttribBufferID);
}
if (glPointIndexBufferID != 0) {
ogl.finalizeVertexBufferObject(glPointIndexBufferID);
}
}
///////////////////////////////////////////////////////////
//
@@ -1622,81 +1689,81 @@ public class PShape3D extends PShape {
protected void deleteFillBuffers() {
if (glFillVertexBufferID != 0) {
ogl.finalizeVertexBufferObject(glFillVertexBufferID);
ogl.deleteVertexBufferObject(glFillVertexBufferID);
glFillVertexBufferID = 0;
}
if (glFillColorBufferID != 0) {
ogl.finalizeVertexBufferObject(glFillColorBufferID);
ogl.deleteVertexBufferObject(glFillColorBufferID);
glFillColorBufferID = 0;
}
if (glFillNormalBufferID != 0) {
ogl.finalizeVertexBufferObject(glFillNormalBufferID);
ogl.deleteVertexBufferObject(glFillNormalBufferID);
glFillNormalBufferID = 0;
}
if (glFillTexCoordBufferID != 0) {
ogl.finalizeVertexBufferObject(glFillTexCoordBufferID);
ogl.deleteVertexBufferObject(glFillTexCoordBufferID);
glFillTexCoordBufferID = 0;
}
if (glFillIndexBufferID != 0) {
ogl.finalizeVertexBufferObject(glFillIndexBufferID);
ogl.deleteVertexBufferObject(glFillIndexBufferID);
glFillIndexBufferID = 0;
}
}
protected void deleteLineBuffers() {
if (glLineVertexBufferID != 0) {
ogl.finalizeVertexBufferObject(glLineVertexBufferID);
ogl.deleteVertexBufferObject(glLineVertexBufferID);
glLineVertexBufferID = 0;
}
if (glLineColorBufferID != 0) {
ogl.finalizeVertexBufferObject(glLineColorBufferID);
ogl.deleteVertexBufferObject(glLineColorBufferID);
glLineColorBufferID = 0;
}
if (glLineNormalBufferID != 0) {
ogl.finalizeVertexBufferObject(glLineNormalBufferID);
ogl.deleteVertexBufferObject(glLineNormalBufferID);
glLineNormalBufferID = 0;
}
if (glLineAttribBufferID != 0) {
ogl.finalizeVertexBufferObject(glLineAttribBufferID);
ogl.deleteVertexBufferObject(glLineAttribBufferID);
glLineAttribBufferID = 0;
}
if (glLineIndexBufferID != 0) {
ogl.finalizeVertexBufferObject(glLineIndexBufferID);
ogl.deleteVertexBufferObject(glLineIndexBufferID);
glLineIndexBufferID = 0;
}
}
protected void deletePointBuffers() {
if (glPointVertexBufferID != 0) {
ogl.finalizeVertexBufferObject(glPointVertexBufferID);
ogl.deleteVertexBufferObject(glPointVertexBufferID);
glPointVertexBufferID = 0;
}
if (glPointColorBufferID != 0) {
ogl.finalizeVertexBufferObject(glPointColorBufferID);
ogl.deleteVertexBufferObject(glPointColorBufferID);
glPointColorBufferID = 0;
}
if (glPointNormalBufferID != 0) {
ogl.finalizeVertexBufferObject(glPointNormalBufferID);
ogl.deleteVertexBufferObject(glPointNormalBufferID);
glPointNormalBufferID = 0;
}
if (glPointAttribBufferID != 0) {
ogl.finalizeVertexBufferObject(glPointAttribBufferID);
ogl.deleteVertexBufferObject(glPointAttribBufferID);
glPointAttribBufferID = 0;
}
if (glPointIndexBufferID != 0) {
ogl.finalizeVertexBufferObject(glPointIndexBufferID);
ogl.deleteVertexBufferObject(glPointIndexBufferID);
glPointIndexBufferID = 0;
}
}
@@ -24,6 +24,8 @@ package processing.opengl;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLContext;
import java.nio.*;
import processing.core.PApplet;
import processing.core.PConstants;
@@ -37,11 +39,11 @@ import processing.core.PImage;
*/
public class PTexture implements PConstants {
public int width, height;
protected PApplet parent; // The Processing applet
protected PGraphicsOpenGL ogl; // The main renderer
protected PImage img; // The parent image
protected GLContext context; // The context that created this texture.
// These are public but use at your own risk!
public int glID;
public int glTarget;
@@ -92,6 +94,7 @@ public class PTexture implements PConstants {
this.parent = parent;
ogl = (PGraphicsOpenGL)parent.g;
context = ogl.getContext();
glID = 0;
@@ -99,17 +102,6 @@ public class PTexture implements PConstants {
}
static public PImage wrap(PGraphicsOpenGL ogl, PTexture tex) {
// We don't use the PImage(int width, int height, int mode) constructor to
// avoid initializing the pixels array.
PImage img = new PImage();
img.width = tex.width;
img.height = tex.height;
img.format = ARGB;
img.setCache(ogl, tex);
return img;
}
protected void finalize() throws Throwable {
try {
if (glID != 0) {
@@ -119,28 +111,8 @@ public class PTexture implements PConstants {
super.finalize();
}
}
/*
public void backup() {
if (img != null) {
img.loadPixels();
if (img.pixels != null && (img instanceof PGraphicsOpenGL)) {
// When img is an offscreen renderer, the loadPixels() call above
// already takes care of copying the contents of the color buffer
// to the pixels array.
get(img.pixels);
}
}
}
public void restore() {
if (img != null && img.pixels != null) {
set(img.pixels);
}
}
*/
////////////////////////////////////////////////////////////
@@ -257,6 +229,7 @@ public class PTexture implements PConstants {
public void set(int[] pixels, int x, int y, int w, int h, int format) {
if (pixels == null) {
pixels = null;
PGraphics.showWarning("The pixels array is null.");
return;
}
@@ -938,11 +911,7 @@ public class PTexture implements PConstants {
///////////////////////////////////////////////////////////////////////////
// Utilities
protected void setImage(PImage img) {
this.img = img;
}
protected GL getGl() {
return ogl.gl;
}