New OpenGL resource creation/deletion method in A3D. Takes care of issue 456

This commit is contained in:
codeanticode
2010-11-27 04:17:53 +00:00
parent d07eb4e954
commit 81ece7e4f1
7 changed files with 302 additions and 240 deletions
@@ -546,6 +546,7 @@ public class PApplet extends Activity implements PConstants, Runnable {
protected void onPause() {
super.onPause();
// TODO need to save all application state here!
// System.out.println("PApplet.onPause() called");
@@ -795,7 +796,6 @@ public class PApplet extends Activity implements PConstants, Runnable {
if (DEBUG) {
System.out.println("surfaceDestroyed()");
}
g3.dispose();
}
@@ -2500,7 +2500,7 @@ public class PApplet extends Activity implements PConstants, Runnable {
// don't run stop and disposers twice
if (thread == null) return;
thread = null;
// call to shut down renderer, in case it needs it (pdf does)
if (g != null) g.dispose();
disposeMethods.handle();
+8 -3
View File
@@ -330,6 +330,13 @@ public class PFont implements PConstants {
}
public void delete() {
for (int i = 0; i < textures.length; i++) {
textures[i].delete();
}
}
/**
* Write this PFont to an OutputStream.
* <p>
@@ -758,9 +765,7 @@ public class PFont implements PConstants {
}
}
protected void recreateResource(PGraphicsAndroid3D renderer) {
}
/////////////////////////////////////////////////////////////
@@ -22,7 +22,6 @@
package processing.core;
import java.lang.reflect.Method;
import java.nio.IntBuffer;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11ExtensionPack;
@@ -48,8 +47,6 @@ public class PFramebuffer implements PConstants {
protected int glStencilBufferID;
protected int width;
protected int height;
protected int recreateResourceIdx;
protected int numColorBuffers;
protected int[] colorBufferAttchPoints;
@@ -75,6 +72,9 @@ public class PFramebuffer implements PConstants {
this.parent = parent;
a3d = (PGraphicsAndroid3D)parent.g;
glFboID = 0;
glDepthBufferID = 0;
glStencilBufferID = 0;
screenFb = screen;
noDepth = false;
FboMode = PGraphicsAndroid3D.fboSupported;
@@ -88,7 +88,7 @@ public class PFramebuffer implements PConstants {
throw new RuntimeException("PFramebuffer: OpenGL ES 1.1 Extension Pack required");
}
initFramebuffer(w, h);
createFramebuffer(w, h);
pixelBuffer = IntBuffer.allocate(width * height);
pixelBuffer.rewind();
@@ -99,30 +99,22 @@ public class PFramebuffer implements PConstants {
// buffer to the texture bound as color buffer to this PFramebuffer object and then drawing
// the backup texture back on the screen.
backupTexture = new PTexture(parent, width, height, new PTexture.Parameters(ARGB, NEAREST));
}
try {
Method meth = this.getClass().getMethod("recreateResource", new Class[] { PGraphicsAndroid3D.class });
recreateResourceIdx = a3d.addRecreateResourceMethod(this, meth);
} catch (Exception e) {
recreateResourceIdx = -1;
}
}
}
protected void finalize() {
a3d.removeRecreateResourceMethod(recreateResourceIdx);
//deleteFramebuffer();
public void delete() {
deleteFramebuffer();
}
void setColorBuffer(PTexture tex) {
public void setColorBuffer(PTexture tex) {
setColorBuffers(new PTexture[] { tex }, 1);
}
void setColorBuffers(PTexture[] textures) {
public void setColorBuffers(PTexture[] textures) {
setColorBuffers(textures, textures.length);
}
void setColorBuffers(PTexture[] textures, int n) {
public void setColorBuffers(PTexture[] textures, int n) {
if (screenFb) return;
if (FboMode) {
@@ -176,10 +168,7 @@ public class PFramebuffer implements PConstants {
a3d.pushFramebuffer();
a3d.setFramebuffer(this);
int[] temp = new int[1];
gl11xp.glGenRenderbuffersOES(1, temp, 0);
glDepthBufferID = temp[0];
glDepthBufferID = a3d.createGLResource(PGraphicsAndroid3D.GL_RENDER_BUFFER);
gl11xp.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, glDepthBufferID);
int glConst = GL11ExtensionPack.GL_DEPTH_COMPONENT16;
@@ -211,10 +200,7 @@ public class PFramebuffer implements PConstants {
a3d.pushFramebuffer();
a3d.setFramebuffer(this);
int[] temp = new int[1];
gl11xp.glGenRenderbuffersOES(1, temp, 0);
glStencilBufferID = temp[0];
glStencilBufferID = a3d.createGLResource(PGraphicsAndroid3D.GL_RENDER_BUFFER);
gl11xp.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, glStencilBufferID);
int glConst = GL11ExtensionPack.GL_STENCIL_INDEX1_OES;
@@ -321,45 +307,38 @@ public class PFramebuffer implements PConstants {
gl.glDisable(gltarget);
}
protected void initFramebuffer(int w, int h) {
protected void createFramebuffer(int w, int h) {
deleteFramebuffer(); // Just in the case this object is being re-initialized.
width = w;
height = h;
if (screenFb) {
glFboID = 0;
} else if (FboMode) {
int[] temp = new int[1];
gl11xp.glGenFramebuffersOES(1, temp, 0);
glFboID = temp[0];
} else if (FboMode) {
glFboID = a3d.createGLResource(PGraphicsAndroid3D.GL_FRAME_BUFFER);
} else {
glFboID = 0;
}
}
protected void deleteFramebuffer() {
if (glFboID != 0) {
int[] temp = { glFboID };
gl11xp.glDeleteFramebuffersOES(1, temp, 0);
a3d.deleteGLResource(glFboID, PGraphicsAndroid3D.GL_FRAME_BUFFER);
glFboID = 0;
}
if (glDepthBufferID != 0) {
int[] temp = { glDepthBufferID };
gl11xp.glDeleteRenderbuffersOES(1, temp, 0);
if (glDepthBufferID != 0) {
a3d.deleteGLResource(glDepthBufferID, PGraphicsAndroid3D.GL_RENDER_BUFFER);
glDepthBufferID = 0;
}
}
if (glStencilBufferID != 0) {
int[] temp = { glStencilBufferID };
gl11xp.glDeleteRenderbuffersOES(1, temp, 0);
if (glStencilBufferID != 0) {
a3d.deleteGLResource(glStencilBufferID, PGraphicsAndroid3D.GL_RENDER_BUFFER);
glStencilBufferID = 0;
}
width = height = 0;
}
protected void recreateResource(PGraphicsAndroid3D renderer) {
// Recreate GL resources (buffers, etc).
width = height = 0;
}
public boolean validFbo() {
@@ -29,6 +29,8 @@ import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.Set;
import java.util.HashSet;
import java.util.Stack;
import android.opengl.GLU;
@@ -190,6 +192,8 @@ public class PGraphicsAndroid3D extends PGraphics {
// Used to detect changes in the current texture images.
protected PImage multitextureImages0[] = new PImage[MAX_TEXTURES];
protected PImage textureImage0;
// Current multitexture UV coordinates.
protected float[] multitextureU = new float[MAX_TEXTURES];
protected float[] multitextureV = new float[MAX_TEXTURES];
@@ -309,14 +313,17 @@ public class PGraphicsAndroid3D extends PGraphics {
// ........................................................
// This array contains the recreateResource methods of all the GL objects
// created in Processing. These methods are used to recreate the open GL
// data when there is a context change or surface creation in Android.
// TODO: Check the resource recreation method.
protected ArrayList<GLResource> recreateResourceMethods;
// This is only used by non primary surfaces.
protected int recreateResourceIdx;
// OpenGL resources
static protected final int GL_TEXTURE_OBJECT = 0;
static protected final int GL_VERTEX_BUFFER = 1;
static protected final int GL_FRAME_BUFFER = 2;
static protected final int GL_RENDER_BUFFER = 3;
Set<Integer> glTextureObjects;
Set<Integer> glVertexBuffers;
Set<Integer> glFrameBuffers;
Set<Integer> glRenderBuffers;
// ........................................................
@@ -404,7 +411,11 @@ public class PGraphicsAndroid3D extends PGraphics {
public PGraphicsAndroid3D() {
renderer = new A3DRenderer();
recreateResourceMethods = new ArrayList<GLResource>();
glTextureObjects = new HashSet<Integer>();
glVertexBuffers = new HashSet<Integer>();
glFrameBuffers = new HashSet<Integer>();
glRenderBuffers = new HashSet<Integer>();
}
// public void setParent(PApplet parent)
@@ -509,49 +520,99 @@ public class PGraphicsAndroid3D extends PGraphics {
}
}
public void dispose() {
public void dispose() {
// Releasing any remaining OpenGL resources.
if (!glTextureObjects.isEmpty()) {
Object[] glids = glTextureObjects.toArray();
for (int i = 0; i < glids.length; i++) {
int id = ((Integer)glids[i]).intValue();
int[] temp = { id };
gl.glDeleteTextures(1, temp, 0);
}
}
if (!glVertexBuffers.isEmpty()) {
Object[] glids = glVertexBuffers.toArray();
for (int i = 0; i < glids.length; i++) {
int id = ((Integer)glids[i]).intValue();
int[] temp = { id };
gl11.glDeleteBuffers(1, temp, 0);
}
}
if (!glFrameBuffers.isEmpty()) {
Object[] glids = glFrameBuffers.toArray();
for (int i = 0; i < glids.length; i++) {
int id = ((Integer)glids[i]).intValue();
int[] temp = { id };
gl11xp.glDeleteFramebuffersOES(1, temp, 0);
}
}
if (!glRenderBuffers.isEmpty()) {
Object[] glids = glRenderBuffers.toArray();
for (int i = 0; i < glids.length; i++) {
int id = ((Integer)glids[i]).intValue();
int[] temp = { id };
gl11xp.glDeleteRenderbuffersOES(1, temp, 0);
}
}
}
// TODO: finalize or dispose to clean up opengl resources?
protected void finalize() {
if (!primarySurface) {
PGraphicsAndroid3D a3d = (PGraphicsAndroid3D)parent.g;
if (a3d != null) {
a3d.removeRecreateResourceMethod(recreateResourceIdx);
protected int createGLResource(int type) {
int id = 0;
if (type == GL_TEXTURE_OBJECT) {
int[] temp = new int[1];
gl.glGenTextures(1, temp, 0);
id = temp[0];
glTextureObjects.add(id);
} else if (type == GL_VERTEX_BUFFER) {
int[] temp = new int[1];
gl11.glGenBuffers(1, temp, 0);
id = temp[0];
glVertexBuffers.add(id);
} else if (type == GL_FRAME_BUFFER) {
int[] temp = new int[1];
gl11xp.glGenFramebuffersOES(1, temp, 0);
id = temp[0];
glFrameBuffers.add(id);
} else if (type == GL_RENDER_BUFFER) {
int[] temp = new int[1];
gl11xp.glGenRenderbuffersOES(1, temp, 0);
id = temp[0];
glRenderBuffers.add(id);
}
return id;
}
protected void deleteGLResource(int id, int type) {
if (type == GL_TEXTURE_OBJECT) {
if (glTextureObjects.contains(id)) {
int[] temp = { id };
gl.glDeleteTextures(1, temp, 0);
glTextureObjects.remove(id);
}
}
}
public void recreateResources() {
// Recreate the openGL resources of the registered GL objects (PTexture,
// PShape3D, PFramebuffer, PFont)
for (int i = 0; i < recreateResourceMethods.size(); i++) {
GLResource resource = (GLResource) recreateResourceMethods.get(i);
try {
resource.method.invoke(resource.object, new Object[] { this });
} catch (Exception e) {
System.err.println("A3D: Error, opengl resources in " + resource.object
+ " cannot be recreated.");
e.printStackTrace();
} else if (type == GL_VERTEX_BUFFER) {
if (glVertexBuffers.contains(id)) {
int[] temp = { id };
gl11.glDeleteBuffers(1, temp, 0);
glVertexBuffers.remove(id);
}
} else if (type == GL_FRAME_BUFFER) {
if (glFrameBuffers.contains(id)) {
int[] temp = { id };
gl11xp.glDeleteFramebuffersOES(1, temp, 0);
glFrameBuffers.remove(id);
}
} else if (type == GL_RENDER_BUFFER) {
if (glRenderBuffers.contains(id)) {
int[] temp = { id };
gl11xp.glDeleteRenderbuffersOES(1, temp, 0);
glRenderBuffers.remove(id);
}
}
}
protected int addRecreateResourceMethod(Object obj, Method meth) {
recreateResourceMethods.add(new GLResource(obj, meth));
return recreateResourceMethods.size() - 1;
}
protected void removeRecreateResourceMethod(int idx) {
if (-1 < idx && idx < recreateResourceMethods.size()) {
recreateResourceMethods.remove(idx);
}
}
protected void recreateResource(PGraphicsAndroid3D renderer) {
}
// ////////////////////////////////////////////////////////////
@@ -847,6 +908,7 @@ public class PGraphicsAndroid3D extends PGraphics {
// Each frame starts with multitexturing disabled.
usingMultitexture = false;
textureImage0 = null;
clearMultitextures();
clearMultitextures0();
@@ -1097,16 +1159,6 @@ public class PGraphicsAndroid3D extends PGraphics {
// easiest for beginners
textureMode(IMAGE);
if (!primarySurface) {
PGraphicsAndroid3D a3d = (PGraphicsAndroid3D)parent.g;
try {
Method meth = this.getClass().getMethod("recreateResource", new Class[] { PGraphicsAndroid3D.class });
recreateResourceIdx = a3d.addRecreateResourceMethod(this, meth);
} catch (Exception e) {
recreateResourceIdx = -1;
}
}
}
// reapplySettings
@@ -1242,6 +1294,7 @@ public class PGraphicsAndroid3D extends PGraphics {
clearMultitextures();
clearMultitextures0();
textureImage0 = null;
}
// public void edge(boolean e)
@@ -1259,10 +1312,12 @@ public class PGraphicsAndroid3D extends PGraphics {
public void texture(PImage image) {
super.texture(image);
usingMultitexture = false;
multitextureImages[0] = image;
for (int t = 1; t < maxTextureUnits; t++) {
multitextureImages[t] = null;
}
}
public void texture(PImage image0, PImage image1) {
@@ -1276,7 +1331,7 @@ public class PGraphicsAndroid3D extends PGraphics {
}
for (int t = 2; t < maxTextureUnits; t++) {
multitextureImages[t] = null;
}
}
} else {
System.err.println("A3D: insufficient texture units.");
}
@@ -1307,6 +1362,9 @@ public class PGraphicsAndroid3D extends PGraphics {
usingMultitexture = true;
if (numTexBuffers < 4) {
addTexBuffers(4 - numTexBuffers);
}
for (int t = 4; t < maxTextureUnits; t++) {
multitextureImages[t] = null;
}
} else {
System.err.println("A3D: insufficient texture units.");
@@ -1320,7 +1378,10 @@ public class PGraphicsAndroid3D extends PGraphics {
usingMultitexture = true;
if (numTexBuffers < images.length) {
addTexBuffers(images.length - numTexBuffers);
}
}
for (int t = images.length; t < maxTextureUnits; t++) {
multitextureImages[t] = null;
}
} else {
System.err.println("A3D: insufficient texture units.");
}
@@ -1484,14 +1545,18 @@ public class PGraphicsAndroid3D extends PGraphics {
}
}
/*
public void vertex(float x, float y, float z, float u, float v) {
vertexTexture(u, v, 0);
vertex(x, y, z);
int n = vertexCount - 1;
vertexTex[n][0] = multitextureImages[0];
vertexU[n][0] = multitextureU[0];
vertexV[n][0] = multitextureV[0];
}
*/
public void vertex(float x, float y, float z, float u0, float v0, float u1, float v1) {
if (2 <= maxTextureUnits) {
@@ -2297,7 +2362,13 @@ public class PGraphicsAndroid3D extends PGraphics {
triangles[triangleCount][VERTEX2] = b;
triangles[triangleCount][VERTEX3] = c;
PImage[] images = vertexTex[a];
/*
PImage[] images;
if (usingMultitexture) {
images = vertexTex[a];
} else {
images = new PImage[] {textureImage};
}
boolean firstFace = triangleCount == 0;
if (diffFromMultitextures0(images) || firstFace) {
// A new face starts at the first triangle or when the texture changes.
@@ -2307,8 +2378,36 @@ public class PGraphicsAndroid3D extends PGraphics {
faceLength[faceCount - 1]++;
}
triangleCount++;
setMultitextures0(images);
*/
if (usingMultitexture) {
PImage[] images = vertexTex[a];
boolean firstFace = triangleCount == 0;
if (diffFromMultitextures0(images) || firstFace) {
// A new face starts at the first triangle or when the texture changes.
addNewFace(firstFace, images);
} else {
// mark this triangle as being part of the current face.
faceLength[faceCount - 1]++;
}
triangleCount++;
setMultitextures0(images);
} else {
PImage image = textureImage;
boolean firstFace = triangleCount == 0;
if (image != textureImage0 || firstFace) {
// A new face starts at the first triangle or when the texture changes.
addNewFace(firstFace, image);
} else {
// mark this triangle as being part of the current face.
faceLength[faceCount - 1]++;
}
triangleCount++;
textureImage0 = textureImage;
}
}
// New "face" starts. A face is just a range of consecutive triangles
@@ -2335,6 +2434,27 @@ public class PGraphicsAndroid3D extends PGraphics {
faceCount++;
}
protected void addNewFace(boolean firstFace, PImage image) {
if (faceCount == faceOffset.length) {
faceOffset = PApplet.expand(faceOffset);
faceLength = PApplet.expand(faceLength);
PImage tempi[][] = new PImage[faceCount << 1][MAX_TEXTURES];
System.arraycopy(faceTextures, 0, tempi, 0, faceCount);
faceTextures = tempi;
}
faceOffset[faceCount] = firstFace ? 0 : triangleCount;
faceLength[faceCount] = 1;
PImage p[] = faceTextures[faceCount];
p[0] = image;
faceCount++;
}
protected void renderTriangles(int start, int stop) {
report("render_triangles in");
@@ -2371,6 +2491,7 @@ public class PGraphicsAndroid3D extends PGraphics {
}
} else if (images[0] != null) {
PTexture tex = images[0].getTexture();
if (tex != null) {
gl.glEnable(tex.getGLTarget());
gl.glActiveTexture(GL10.GL_TEXTURE0);
@@ -2381,6 +2502,7 @@ public class PGraphicsAndroid3D extends PGraphics {
// Null PTexture field in A3D? no good!
throw new RuntimeException("A3D: missing image texture");
}
}
if (0 < numTextures) {
@@ -5909,8 +6031,7 @@ public class PGraphicsAndroid3D extends PGraphics {
gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_UNITS, temp, 0);
maxTextureUnits = PApplet.min(MAX_TEXTURES, temp[0]);
recreateResources();
gl = null;
gl11 = null;
gl11x = null;
@@ -139,6 +139,13 @@ public class PImage implements PConstants, Cloneable {
// this.cache = null;
}
public void delete() {
if (texture != null) {
texture.delete();
}
}
/**
* Check the alpha on an image, using a really primitive loop.
+68 -91
View File
@@ -30,7 +30,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.io.BufferedReader;
import java.lang.reflect.Method;
/**
* This class holds a 3D model composed of vertices, normals, colors (per vertex) and
@@ -52,11 +51,11 @@ public class PShape3D extends PShape implements PConstants {
protected int glUsage;
protected boolean pointSprites;
protected int[] glVertexBufferID = new int[1];
protected int[] glColorBufferID = new int[1];
protected int[] glNormalBufferID = new int[1];
protected int glVertexBufferID;
protected int glColorBufferID;
protected int glNormalBufferID;
protected int[] glTexCoordBufferID = new int[PGraphicsAndroid3D.MAX_TEXTURES];
protected FloatBuffer vertexBuffer;
protected FloatBuffer colorBuffer;
protected FloatBuffer normalBuffer;
@@ -77,8 +76,6 @@ public class PShape3D extends PShape implements PConstants {
protected boolean firstSetGroup;
protected int grIdx0;
protected int grIdx1;
protected int recreateResourceIdx;
protected float xmin, xmax;
protected float ymin, ymax;
@@ -91,8 +88,7 @@ public class PShape3D extends PShape implements PConstants {
protected int TEXTURESMAX;
protected static final int SIZEOF_FLOAT = Float.SIZE / 8;
protected static final int SIZEOF_FLOAT = Float.SIZE / 8;
////////////////////////////////////////////////////////////
@@ -101,15 +97,13 @@ public class PShape3D extends PShape implements PConstants {
public PShape3D(PApplet parent) {
this.parent = parent;
a3d = (PGraphicsAndroid3D)parent.g;
TEXTURESMAX = TEXTURES0 + PGraphicsAndroid3D.maxTextureUnits;
glVertexBufferID = 0;
glColorBufferID = 0;
glNormalBufferID = 0;
java.util.Arrays.fill(glTexCoordBufferID, 0);
try {
Method meth = this.getClass().getMethod("recreateResource", new Class[] { PGraphicsAndroid3D.class });
recreateResourceIdx = a3d.addRecreateResourceMethod(this, meth);
} catch (Exception e) {
recreateResourceIdx = -1;
}
TEXTURESMAX = TEXTURES0 + PGraphicsAndroid3D.maxTextureUnits;
}
public PShape3D(PApplet parent, int numVert) {
@@ -119,6 +113,11 @@ public class PShape3D extends PShape implements PConstants {
public PShape3D(PApplet parent, String filename, int mode) {
this.parent = parent;
a3d = (PGraphicsAndroid3D)parent.g;
glVertexBufferID = 0;
glColorBufferID = 0;
glNormalBufferID = 0;
java.util.Arrays.fill(glTexCoordBufferID, 0);
TEXTURESMAX = TEXTURES0 + PGraphicsAndroid3D.maxTextureUnits;
@@ -148,13 +147,6 @@ public class PShape3D extends PShape implements PConstants {
parseOBJ(reader, vertices, normals, textures, faces, materials);
recordOBJ(vertices, normals, textures, faces, materials);
centerAt(0, 0, 0);
try {
Method meth = this.getClass().getMethod("recreateResource", new Class[] { PGraphicsAndroid3D.class });
recreateResourceIdx = a3d.addRecreateResourceMethod(this, meth);
} catch (Exception e) {
recreateResourceIdx = -1;
}
}
@@ -162,22 +154,18 @@ public class PShape3D extends PShape implements PConstants {
this.parent = parent;
a3d = (PGraphicsAndroid3D)parent.g;
glVertexBufferID = 0;
glColorBufferID = 0;
glNormalBufferID = 0;
java.util.Arrays.fill(glTexCoordBufferID, 0);
TEXTURESMAX = TEXTURES0 + PGraphicsAndroid3D.maxTextureUnits;
initShape(numVert, params);
try {
Method meth = this.getClass().getMethod("recreateResource", new Class[] { PGraphicsAndroid3D.class });
recreateResourceIdx = a3d.addRecreateResourceMethod(this, meth);
} catch (Exception e) {
recreateResourceIdx = -1;
}
}
protected void finalize() {
a3d.removeRecreateResourceMethod(recreateResourceIdx);
public void delete() {
//deleteVertexBuffer();
//deleteColorBuffer();
//deleteTexCoordBuffer();
@@ -261,7 +249,7 @@ public class PShape3D extends PShape implements PConstants {
lastUpdateIdx = -1;
if (updateElement == VERTICES) {
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glVertexBufferID[0]);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glVertexBufferID);
int offset = first * 3;
int size = (last - first + 1) * 3;
@@ -273,7 +261,7 @@ public class PShape3D extends PShape implements PConstants {
creatingGroup = false;
firstSetGroup = true;
} else if (updateElement == COLORS) {
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glColorBufferID[0]);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glColorBufferID);
int offset = first * 4;
int size = (last - first + 1) * 4;
@@ -281,7 +269,7 @@ public class PShape3D extends PShape implements PConstants {
colorBuffer.rewind();
colorBuffer.get(colorArray, offset, size);
} else if (updateElement == NORMALS) {
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glNormalBufferID[0]);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glNormalBufferID);
int offset = first * 3;
int size = (last - first + 1) * 3;
@@ -1746,10 +1734,10 @@ public class PShape3D extends PShape implements PConstants {
protected void createVertexBuffer() {
deleteVertexBuffer(); // Just in case.
deleteVertexBuffer(); // Just in the case this object is being re-initialized.
gl.glGenBuffers(1, glVertexBufferID, 0);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glVertexBufferID[0]);
glVertexBufferID = a3d.createGLResource(PGraphicsAndroid3D.GL_VERTEX_BUFFER);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glVertexBufferID);
final int bufferSize = vertexBuffer.capacity() * SIZEOF_FLOAT;
gl.glBufferData(GL11.GL_ARRAY_BUFFER, bufferSize, vertexBuffer, glUsage);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
@@ -1772,10 +1760,10 @@ public class PShape3D extends PShape implements PConstants {
protected void createColorBuffer() {
deleteColorBuffer(); // Just in case.
deleteColorBuffer();
gl.glGenBuffers(1, glColorBufferID, 0);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glColorBufferID[0]);
glColorBufferID = a3d.createGLResource(PGraphicsAndroid3D.GL_VERTEX_BUFFER);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glColorBufferID);
final int bufferSize = colorBuffer.capacity() * SIZEOF_FLOAT;
gl.glBufferData(GL11.GL_ARRAY_BUFFER, bufferSize, colorBuffer, glUsage);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
@@ -1794,10 +1782,10 @@ public class PShape3D extends PShape implements PConstants {
protected void createNormalBuffer() {
deleteNormalBuffer(); // Just in case.
deleteNormalBuffer();
gl.glGenBuffers(1, glNormalBufferID, 0);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glNormalBufferID[0]);
glNormalBufferID = a3d.createGLResource(PGraphicsAndroid3D.GL_VERTEX_BUFFER);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glNormalBufferID);
final int bufferSize = normalBuffer.capacity() * SIZEOF_FLOAT;
gl.glBufferData(GL11.GL_ARRAY_BUFFER, bufferSize, normalBuffer, glUsage);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
@@ -1816,9 +1804,9 @@ public class PShape3D extends PShape implements PConstants {
protected void createTexCoordBuffer() {
deleteTexCoordBuffer(); // Just in case.
deleteTexCoordBuffer();
gl.glGenBuffers(1, glTexCoordBufferID, 0);
glTexCoordBufferID[0] = a3d.createGLResource(PGraphicsAndroid3D.GL_VERTEX_BUFFER);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glTexCoordBufferID[0]);
final int bufferSize = texCoordBuffer.capacity() * SIZEOF_FLOAT;
gl.glBufferData(GL11.GL_ARRAY_BUFFER, bufferSize, texCoordBuffer, glUsage);
@@ -1828,15 +1816,14 @@ public class PShape3D extends PShape implements PConstants {
protected void addTexBuffers(int more) {
for (int i = 0; i < more; i++) {
deleteTexCoordBuffer(numTexBuffers + i); // Just in case.
int t = numTexBuffers + i;
deleteTexCoordBuffer(t);
int[] temp = {0};
gl.glGenBuffers(1, temp, 0);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, temp[0]);
glTexCoordBufferID[t] = a3d.createGLResource(PGraphicsAndroid3D.GL_VERTEX_BUFFER);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glTexCoordBufferID[t]);
final int bufferSize = texCoordBuffer.capacity() * SIZEOF_FLOAT;
gl.glBufferData(GL11.GL_ARRAY_BUFFER, bufferSize, texCoordBuffer, glUsage);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
glTexCoordBufferID[numTexBuffers + i] = temp[0];
}
numTexBuffers += more;
@@ -1844,25 +1831,25 @@ public class PShape3D extends PShape implements PConstants {
protected void deleteVertexBuffer() {
if (glVertexBufferID[0] != 0) {
gl.glDeleteBuffers(1, glVertexBufferID, 0);
glVertexBufferID[0] = 0;
if (glVertexBufferID != 0) {
a3d.deleteGLResource(glVertexBufferID, PGraphicsAndroid3D.GL_VERTEX_BUFFER);
glVertexBufferID = 0;
}
}
protected void deleteColorBuffer() {
if (glColorBufferID[0] != 0) {
gl.glDeleteBuffers(1, glColorBufferID, 0);
glColorBufferID[0] = 0;
if (glColorBufferID != 0) {
a3d.deleteGLResource(glColorBufferID, PGraphicsAndroid3D.GL_VERTEX_BUFFER);
glColorBufferID = 0;
}
}
protected void deleteNormalBuffer() {
if (glNormalBufferID[0] != 0) {
gl.glDeleteBuffers(1, glNormalBufferID, 0);
glNormalBufferID[0] = 0;
if (glNormalBufferID != 0) {
a3d.deleteGLResource(glNormalBufferID, PGraphicsAndroid3D.GL_VERTEX_BUFFER);
glNormalBufferID = 0;
}
}
@@ -1875,26 +1862,16 @@ public class PShape3D extends PShape implements PConstants {
protected void deleteTexCoordBuffer(int idx) {
if (glTexCoordBufferID[idx] != 0) {
int[] temp = {glTexCoordBufferID[idx]};
gl.glDeleteBuffers(1, temp, 0);
if (glTexCoordBufferID[idx] != 0) {
a3d.deleteGLResource(glTexCoordBufferID[idx], PGraphicsAndroid3D.GL_VERTEX_BUFFER);
glTexCoordBufferID[idx] = 0;
}
}
protected void recreateResource(PGraphicsAndroid3D renderer) {
createVertexBuffer();
createColorBuffer();
createNormalBuffer();
createTexCoordBuffer();
}
///////////////////////////////////////////////////////////
// Reimplementing methods inherited from PShape.
// Re-implementing methods inherited from PShape.
public void translate(float tx, float ty) {
@@ -2070,7 +2047,7 @@ public class PShape3D extends PShape implements PConstants {
public void draw(PGraphics g, int gr0, int gr1) {
PImage[] imgs = null;
PImage[] images = null;
boolean textured = false;
float pointSize;
@@ -2086,17 +2063,17 @@ public class PShape3D extends PShape implements PConstants {
gl.glPointSize(pointSize);
gl.glEnableClientState(GL11.GL_NORMAL_ARRAY);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glNormalBufferID[0]);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glNormalBufferID);
gl.glNormalPointer(GL11.GL_FLOAT, 0, 0);
if (vertexColor) {
gl.glEnableClientState(GL11.GL_COLOR_ARRAY);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glColorBufferID[0]);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glColorBufferID);
gl.glColorPointer(4, GL11.GL_FLOAT, 0, 0);
}
gl.glEnableClientState(GL11.GL_VERTEX_ARRAY);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glVertexBufferID[0]);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glVertexBufferID);
gl.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);
VertexGroup group;
@@ -2106,13 +2083,13 @@ public class PShape3D extends PShape implements PConstants {
if (group.hasTexture()) {
textured = true;
// Binding texture units.
imgs = group.textures;
for (int n = 0; n < imgs.length; n++) {
if (imgs[n] != null && imgs[n].getTexture() != null) {
PTexture tex = imgs[n].getTexture();
images = group.textures;
for (int t = 0; t < images.length; t++) {
if (images[t] != null && images[t].getTexture() != null) {
PTexture tex = images[t].getTexture();
int texTarget = tex.getGLTarget();
gl.glEnable(texTarget);
gl.glActiveTexture(GL10.GL_TEXTURE0 + n);
gl.glActiveTexture(GL10.GL_TEXTURE0 + t);
gl.glBindTexture(texTarget, tex.getGLID());
}
}
@@ -2140,9 +2117,9 @@ public class PShape3D extends PShape implements PConstants {
} else {
// Regular texturing.
gl.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
for (int n = 0; n < numTexBuffers; n++) {
gl.glClientActiveTexture(GL11.GL_TEXTURE0 + n);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glTexCoordBufferID[n]);
for (int t = 0; t < numTexBuffers; t++) {
gl.glClientActiveTexture(GL11.GL_TEXTURE0 + t);
gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, glTexCoordBufferID[t]);
gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
}
}
@@ -2183,9 +2160,9 @@ public class PShape3D extends PShape implements PConstants {
gl.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
}
for (int n = 0; n < numTexBuffers; n++) {
if (imgs[n] != null && imgs[n].getTexture() != null) {
PTexture tex = imgs[n].getTexture();
for (int t = 0; t < numTexBuffers; t++) {
if (images[t] != null && images[t].getTexture() != null) {
PTexture tex = images[t].getTexture();
int texTarget = tex.getGLTarget();
gl.glDisable(texTarget);
}
+10 -37
View File
@@ -68,8 +68,6 @@ public class PTexture implements PConstants {
protected int[] tmpPixels = null;
protected PFramebuffer tmpFbo = null;
protected int recreateResourceIdx;
////////////////////////////////////////////////////////////
// Constructors.
@@ -106,14 +104,7 @@ public class PTexture implements PConstants {
glID = 0;
setParameters(params);
createTexture(width, height);
try {
Method meth = this.getClass().getMethod("recreateResource", new Class[] { PGraphicsAndroid3D.class });
recreateResourceIdx = a3d.addRecreateResourceMethod(this, meth);
} catch (Exception e) {
recreateResourceIdx = -1;
}
createTexture(width, height);
}
@@ -143,20 +134,12 @@ public class PTexture implements PConstants {
PImage img = parent.loadImage(filename);
setParameters(params);
set(img);
try {
Method meth = this.getClass().getMethod("recreateResource", new Class[] { PGraphicsAndroid3D.class });
recreateResourceIdx = a3d.addRecreateResourceMethod(this, meth);
} catch (Exception e) {
recreateResourceIdx = -1;
}
set(img);
}
protected void finalize() {
a3d.removeRecreateResourceMethod(recreateResourceIdx);
//deleteTexture();
public void delete() {
deleteTexture();
}
@@ -889,7 +872,7 @@ public class PTexture implements PConstants {
* @param h int
*/
protected void createTexture(int w, int h) {
deleteTexture();
deleteTexture(); // Just in the case this object is being re-initialized.
if (PGraphicsAndroid3D.npotTexSupported) {
glWidth = w;
@@ -912,9 +895,7 @@ public class PTexture implements PConstants {
(glMinFilter == GL10.GL_LINEAR_MIPMAP_LINEAR));
gl.glEnable(glTarget);
int[] tmp = new int[1];
gl.glGenTextures(1, tmp, 0);
glID = tmp[0];
glID = a3d.createGLResource(PGraphicsAndroid3D.GL_TEXTURE_OBJECT);
gl.glBindTexture(glTarget, glID);
gl.glTexParameterf(glTarget, GL10.GL_TEXTURE_MIN_FILTER, glMinFilter);
gl.glTexParameterf(glTarget, GL10.GL_TEXTURE_MAG_FILTER, glMagFilter);
@@ -941,18 +922,11 @@ public class PTexture implements PConstants {
*/
protected void deleteTexture() {
if (glID != 0) {
int[] tmp = { glID };
gl.glDeleteTextures(1, tmp, 0);
a3d.deleteGLResource(glID, PGraphicsAndroid3D.GL_TEXTURE_OBJECT);
glID = 0;
}
}
protected void recreateResource(PGraphicsAndroid3D renderer) {
createTexture(width, height);
}
// Copies source texture to this.
protected void copyTexels(PTexture tex, int x, int y, int w, int h, boolean scale) {
if (tex == null) {
@@ -991,8 +965,9 @@ public class PTexture implements PConstants {
}
protected void copyObject(PTexture src) {
a3d.removeRecreateResourceMethod(recreateResourceIdx);
deleteTexture();
// The OpenGL texture of this object is replaced with the one from the source object,
// so we delete the former to avoid resource wasting.
deleteTexture();
width = src.width;
height = src.height;
@@ -1016,8 +991,6 @@ public class PTexture implements PConstants {
flippedX = src.flippedX;
flippedY = src.flippedY;
recreateResourceIdx = src.recreateResourceIdx;
}
///////////////////////////////////////////////////////////