From ae2ff779c2aee17607e87f6b7b21e9f031eba932 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Sat, 2 Jul 2011 08:32:53 +0000 Subject: [PATCH] Fixed some issues in the reallocation/refreshing mechanism --- .../src/processing/opengl/PFontTexture.java | 2 +- .../src/processing/opengl/PFramebuffer.java | 131 +++++++-------- .../processing/opengl/PGraphicsOpenGL.java | 153 +++++++++++++----- .../src/processing/opengl/PShape3D.java | 30 ++-- .../src/processing/opengl/PTexture.java | 94 ++++++----- 5 files changed, 235 insertions(+), 175 deletions(-) diff --git a/java/libraries/opengl/src/processing/opengl/PFontTexture.java b/java/libraries/opengl/src/processing/opengl/PFontTexture.java index 0f50ddc28..f4955ff33 100644 --- a/java/libraries/opengl/src/processing/opengl/PFontTexture.java +++ b/java/libraries/opengl/src/processing/opengl/PFontTexture.java @@ -86,7 +86,7 @@ class PFontTexture implements PConstants { public void refresh() { // loop over current glyphs. - for (int i = 0; i < font.getGlyphCount(); i++) { + for (int i = 0; i < PApplet.min(font.getGlyphCount(), glyphTexinfos.length); i++) { TextureInfo tinfo = glyphTexinfos[i]; textures[tinfo.texIndex].bind(); tinfo.updateTex(); diff --git a/java/libraries/opengl/src/processing/opengl/PFramebuffer.java b/java/libraries/opengl/src/processing/opengl/PFramebuffer.java index 2c200fc5c..c85e0265b 100644 --- a/java/libraries/opengl/src/processing/opengl/PFramebuffer.java +++ b/java/libraries/opengl/src/processing/opengl/PFramebuffer.java @@ -60,8 +60,6 @@ public class PFramebuffer implements PConstants { protected int numColorBuffers; protected int[] colorBufferAttchPoints; - protected int[] glColorBufferTargets; // should remove this? - protected int[] glColorBufferIDs; // should remove this? protected PTexture[] colorBufferTex; protected boolean screenFb; @@ -94,8 +92,46 @@ public class PFramebuffer implements PConstants { fboMode = PGraphicsOpenGL.fboSupported; - allocate(w, h, samples, colorBuffers, depthBits, stencilBits, - combinedDepthStencil, screen); + width = w; + height = h; + + if (1 < samples) { + multisample = true; + nsamples = samples; + } else { + multisample = false; + nsamples = 1; + } + + numColorBuffers = colorBuffers; + colorBufferAttchPoints = new int[numColorBuffers]; + colorBufferTex = new PTexture[numColorBuffers]; + for (int i = 0; i < numColorBuffers; i++) { + colorBufferAttchPoints[i] = GL.GL_COLOR_ATTACHMENT0 + i; + colorBufferTex[i] = null; + } + + if (depthBits < 1 && stencilBits < 1) { + this.depthBits = 0; + this.stencilBits = 0; + this.combinedDepthStencil = false; + } else { + if (combinedDepthStencil) { + // When combined depth/stencil format is required, the depth and stencil bits + // are overriden and the 24/8 combination for a 32 bits surface is used. + this.depthBits = 24; + this.stencilBits = 8; + this.combinedDepthStencil = true; + } else { + this.depthBits = depthBits; + this.stencilBits = stencilBits; + this.combinedDepthStencil = false; + } + } + + screenFb = screen; + + allocate(); noDepth = false; pixelBuffer = null; @@ -149,7 +185,7 @@ public class PFramebuffer implements PConstants { if (0 < numColorBuffers) { // Drawing the current contents of the first color buffer to emulate // front-back buffer swap. - ogl.drawTexture(glColorBufferTargets[0], glColorBufferIDs[0], width, height, 0, 0, width, height, 0, 0, width, height); + ogl.drawTexture(colorBufferTex[0].glTarget, colorBufferTex[0].glID, width, height, 0, 0, width, height, 0, 0, width, height); } if (noDepth) { @@ -206,7 +242,7 @@ public class PFramebuffer implements PConstants { if (pixelBuffer == null) createPixelBuffer(); getGl().glReadPixels(0, 0, width, height, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixelBuffer); for (int i = 0; i < numColorBuffers; i++) { - copyToTexture(pixelBuffer, glColorBufferIDs[i], glColorBufferTargets[i]); + copyToTexture(pixelBuffer, colorBufferTex[i].glID, colorBufferTex[i].glTarget); } } @@ -248,11 +284,15 @@ public class PFramebuffer implements PConstants { 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]; + } + if (fboMode) { ogl.pushFramebuffer(); ogl.setFramebuffer(this); @@ -264,11 +304,8 @@ public class PFramebuffer implements PConstants { } for (int i = 0; i < numColorBuffers; i++) { - this.colorBufferTex[i] = textures[i]; - glColorBufferTargets[i] = textures[i].glTarget; - glColorBufferIDs[i] = textures[i].glID; getGl().glFramebufferTexture2D(GL.GL_FRAMEBUFFER, colorBufferAttchPoints[i], - glColorBufferTargets[i], glColorBufferIDs[i], 0); + colorBufferTex[i].glTarget, colorBufferTex[i].glID, 0); } if (validFbo() && textures != null && 0 < textures.length) { @@ -277,11 +314,6 @@ public class PFramebuffer implements PConstants { } ogl.popFramebuffer(); - } else { - for (int i = 0; i < numColorBuffers; i++) { - glColorBufferTargets[i] = textures[i].glTarget; - glColorBufferIDs[i] = textures[i].glID; - } } } @@ -290,52 +322,8 @@ public class PFramebuffer implements PConstants { // Allocate/release framebuffer. - protected void allocate(int w, int h, int samples, int colorBuffers, - int depthBits, int stencilBits, boolean combinedDepthStencil, - boolean screen) { - release(); // Just in the case this object is being re-allocated. - - width = w; - height = h; - - if (1 < samples) { - multisample = true; - nsamples = samples; - } else { - multisample = false; - nsamples = 1; - } - - numColorBuffers = colorBuffers; - colorBufferAttchPoints = new int[numColorBuffers]; - glColorBufferTargets = new int[numColorBuffers]; - glColorBufferIDs = new int[numColorBuffers]; - colorBufferTex = new PTexture[numColorBuffers]; - for (int i = 0; i < numColorBuffers; i++) { - colorBufferAttchPoints[i] = GL.GL_COLOR_ATTACHMENT0 + i; - glColorBufferIDs[i] = 0; - colorBufferTex[i] = null; - } - - if (depthBits < 1 && stencilBits < 1) { - this.depthBits = 0; - this.stencilBits = 0; - this.combinedDepthStencil = false; - } else { - if (combinedDepthStencil) { - // When combined depth/stencil format is required, the depth and stencil bits - // are overriden and the 24/8 combination for a 32 bits surface is used. - this.depthBits = 24; - this.stencilBits = 8; - this.combinedDepthStencil = true; - } else { - this.depthBits = depthBits; - this.stencilBits = stencilBits; - this.combinedDepthStencil = false; - } - } - - screenFb = screen; + protected void allocate() { + release(); // Just in the case this object is being re-allocated. if (screenFb) { glFboID = 0; @@ -359,23 +347,16 @@ public class PFramebuffer implements PConstants { if (0 < stencilBits) { createStencilBuffer(); } - } - + } } - protected void reallocate() { - allocate(width, height, nsamples, numColorBuffers, - depthBits, stencilBits, combinedDepthStencil, - screenFb); - } protected void release() { deleteFbo(); deleteDepthBuffer(); deleteStencilBuffer(); deleteCombinedDepthStencilBuffer(); - deleteColorBufferMultisample(); - width = height = 0; + deleteColorBufferMultisample(); } @@ -426,15 +407,11 @@ public class PFramebuffer implements PConstants { ogl.pushFramebuffer(); ogl.setFramebuffer(this); - numColorBuffers = 1; - colorBufferAttchPoints = new int[numColorBuffers]; - colorBufferAttchPoints[0] = GL.GL_COLOR_ATTACHMENT0; - glColorBufferMultisampleID = ogl.createGLResource(PGraphicsOpenGL.GL_RENDER_BUFFER); getGl().glBindRenderbuffer(GL.GL_RENDERBUFFER, glColorBufferMultisampleID); getGl2().glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, nsamples, GL.GL_RGBA8, width, height); - getGl().glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, colorBufferAttchPoints[0], + getGl().glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_COLOR_ATTACHMENT0, GL.GL_RENDERBUFFER, glColorBufferMultisampleID); ogl.popFramebuffer(); diff --git a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java index 43fdb5075..e043aa001 100644 --- a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java @@ -680,7 +680,7 @@ public class PGraphicsOpenGL extends PGraphics { // that the context has been recreated, so we need to re-allocate them in // order to be able to keep using them. This step doesn't refresh their data, this // is, they are empty after re-allocation. - reallocateGLObjects(); + allocateGLObjects(); } else { reapplySettings(); } @@ -719,16 +719,16 @@ public class PGraphicsOpenGL extends PGraphics { // RESOURCE HANDLING - protected void reallocateGLObjects() { + protected void allocateGLObjects() { if (!glObjects.isEmpty()) { Object[] globjs = glObjects.toArray(); for (int i = 0; i < globjs.length; i++) { if (globjs[i] instanceof PTexture) { - ((PTexture)globjs[i]).reallocate(); + ((PTexture)globjs[i]).allocate(); } else if (globjs[i] instanceof PShape3D) { - ((PShape3D)globjs[i]).reallocate(); + ((PShape3D)globjs[i]).allocate(); } else if (globjs[i] instanceof PFramebuffer) { - ((PFramebuffer)globjs[i]).reallocate(); + ((PFramebuffer)globjs[i]).allocate(); } else if (globjs[i] instanceof PFontTexture) { // No need to do reallocation for a PFontTexture, since its // textures will reallocate themselves. @@ -737,6 +737,40 @@ public class PGraphicsOpenGL extends PGraphics { } } + protected void updateGLObjects() { + if (!glObjects.isEmpty()) { + Object[] globjs = glObjects.toArray(); + for (int i = 0; i < globjs.length; i++) { + if (globjs[i] instanceof PTexture) { + ((PTexture)globjs[i]).update(); + } else if (globjs[i] instanceof PShape3D) { + //((PShape3D)globjs[i]).refresh(); + } else if (globjs[i] instanceof PFramebuffer) { + //((PFramebuffer)globjs[i]).refresh(); + } else if (globjs[i] instanceof PFontTexture) { + //((PFontTexture)globjs[i]).refresh(); + } + } + } + } + + protected void refreshGLObjects() { + if (!glObjects.isEmpty()) { + Object[] globjs = glObjects.toArray(); + for (int i = 0; i < globjs.length; i++) { + if (globjs[i] instanceof PTexture) { + ((PTexture)globjs[i]).refresh(); + } else if (globjs[i] instanceof PShape3D) { + ((PShape3D)globjs[i]).refresh(); + } else if (globjs[i] instanceof PFramebuffer) { + ((PFramebuffer)globjs[i]).refresh(); + } else if (globjs[i] instanceof PFontTexture) { + ((PFontTexture)globjs[i]).refresh(); + } + } + } + } + protected void registerGLObject(Object obj) { glObjects.add(obj); } @@ -1126,26 +1160,16 @@ public class PGraphicsOpenGL extends PGraphics { } - public void reallocateGL() { - reallocateGLObjects(); + public void allocateGL() { + allocateGLObjects(); } + public void updateGL() { + updateGLObjects(); + } public void refreshGL() { - if (!glObjects.isEmpty()) { - Object[] globjs = glObjects.toArray(); - for (int i = 0; i < globjs.length; i++) { - if (globjs[i] instanceof PTexture) { - ((PTexture)globjs[i]).refresh(); - } else if (globjs[i] instanceof PShape3D) { - ((PShape3D)globjs[i]).refresh(); - } else if (globjs[i] instanceof PFramebuffer) { - ((PFramebuffer)globjs[i]).refresh(); - } else if (globjs[i] instanceof PFontTexture) { - ((PFontTexture)globjs[i]).refresh(); - } - } - } + refreshGLObjects(); } protected void saveGLState() { @@ -5724,7 +5748,18 @@ return width * (1 + ox) / 2.0f; pixelBuffer.rewind(); } + boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; + if (notCurrent) { + pushFramebuffer(); + setFramebuffer(offscreenFramebuffer); + } + gl.glReadPixels(0, 0, width, height, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixelBuffer); + + if (notCurrent) { + popFramebuffer(); + } + pixelBuffer.get(pixels); pixelBuffer.rewind(); @@ -6004,8 +6039,24 @@ return width * (1 + ox) / 2.0f; // Copying pixel buffer to screen texture... copyToTexture(pixelBuffer); + // ...and drawing the texture to screen. - drawTexture(texture, texCrop, 0, 0, width, height); + + boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; + if (notCurrent) { + // If this is an offscreen surface that is not current, then the offscreen framebuffer + // is bound so the texture is drawn to it instead to the main surface. Even if the + // surface in antialiased we don't need to bind the multisample framebuffer, we + // just draw to the regular offscreen framebuffer. + pushFramebuffer(); + setFramebuffer(offscreenFramebuffer); + } + + drawTexture(texture, texCrop, 0, 0, width, height); + + if (notCurrent) { + popFramebuffer(); + } } ////////////////////////////////////////////////////////////// @@ -6028,6 +6079,7 @@ return width * (1 + ox) / 2.0f; texture.setFlippedY(true); this.setCache(ogl, texture); this.setParams(ogl, params); + texture.setImage(this); texCrop = new int[4]; texCrop[0] = 0; @@ -6039,7 +6091,17 @@ return width * (1 + ox) / 2.0f; // Draws wherever it is in the screen texture right now to the screen. public void updateTexture() { + boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; + if (notCurrent) { + pushFramebuffer(); + setFramebuffer(offscreenFramebuffer); + } + drawTexture(); + + if (notCurrent) { + popFramebuffer(); + } } protected void drawTexture() { @@ -6083,8 +6145,8 @@ return width * (1 + ox) / 2.0f; getsetBuffer.rewind(); } - boolean nonCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; - if (nonCurrent) { + boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; + if (notCurrent) { // If the surface is not primary and multisampling is on, then the framebuffer // will be switched momentarily from offscreenFramebufferMultisample to offscreenFramebuffer. // This is in fact correct, because the glReadPixels() function doesn't work with @@ -6095,7 +6157,7 @@ return width * (1 + ox) / 2.0f; gl.glReadPixels(x, height - y - 1, 1, 1, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, getsetBuffer); - if (nonCurrent) { + if (notCurrent) { popFramebuffer(); } @@ -6118,21 +6180,21 @@ return width * (1 + ox) / 2.0f; IntBuffer newbieBuffer = IntBuffer.allocate(w * h); - boolean nonCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; - if (nonCurrent) { + boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; + if (notCurrent) { pushFramebuffer(); setFramebuffer(offscreenFramebuffer); } gl.glReadPixels(x, height - y - h, w, h, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, newbieBuffer); - if (nonCurrent) { + if (notCurrent) { popFramebuffer(); } copyToTexture(newbieTex, newbieBuffer, 0, 0, w, h); newbie.loadPixels(); - newbieTex.flippedY = true; + newbieTex.setFlippedY(true); newbieTex.get(newbie.pixels); return newbie; @@ -6166,8 +6228,19 @@ return width * (1 + ox) / 2.0f; getsetTexture = new PTexture(parent, 1, 1, new PTexture.Parameters(ARGB, POINT)); } - copyToTexture(getsetTexture, getsetBuffer, 0, 0, 1, 1); + copyToTexture(getsetTexture, getsetBuffer, 0, 0, 1, 1); + + boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; + if (notCurrent) { + pushFramebuffer(); + setFramebuffer(offscreenFramebuffer); + } + drawTexture(getsetTexture, 0, 0, 1, 1, x, height - y, 1, 1); + + if (notCurrent) { + popFramebuffer(); + } } /** @@ -6180,9 +6253,21 @@ return width * (1 + ox) / 2.0f; if (tex != null) { int w = source.width; int h = source.height; + + boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; + if (notCurrent) { + pushFramebuffer(); + setFramebuffer(offscreenFramebuffer); + } + + // The crop region and draw rectangle are given like this to take into account // inverted y-axis in Processin with respect to OpenGL. drawTexture(tex, 0, h, w, -h, x, height - y, w, h); + + if (notCurrent) { + popFramebuffer(); + } } } @@ -7046,14 +7131,6 @@ return width * (1 + ox) / 2.0f; offscreenFramebufferMultisample = new PFramebuffer(parent, texture.glWidth, texture.glHeight, nsamples, 0, offscreenDepthBits, offscreenStencilBits, offscreenDepthBits == 24 && offscreenStencilBits == 8, false); - /* - try { - offscreenFramebufferMultisample.addColorBufferMultisample(nsamples); - offscreenMultisample = true; - } catch (GLException e) { - PGraphics.showWarning("Unable to create antialised offscreen surface."); - } - */ offscreenFramebufferMultisample.clear(); offscreenMultisample = true; diff --git a/java/libraries/opengl/src/processing/opengl/PShape3D.java b/java/libraries/opengl/src/processing/opengl/PShape3D.java index f9ada1f40..e010e2a41 100644 --- a/java/libraries/opengl/src/processing/opengl/PShape3D.java +++ b/java/libraries/opengl/src/processing/opengl/PShape3D.java @@ -2154,7 +2154,9 @@ public class PShape3D extends PShape { } setParameters(params); - allocate(numVert); + setSize(numVert); + allocate(); + initChildrenData(); updateElement = -1; resetBounds(); @@ -2200,15 +2202,17 @@ public class PShape3D extends PShape { // Allocate/release shape. - - protected void allocate(int numVert) { - release(); // Just in the case this object is being re-allocated. - + protected void setSize(int numVert) { vertexCount = numVert; numTexBuffers = 1; - firstVertex = 0; - lastVertex = numVert - 1; + firstVertex = 0; + lastVertex = numVert - 1; + } + + protected void allocate() { + release(); // Just in the case this object is being re-allocated. + initVertexData(); createVertexBuffer(); initColorData(); @@ -2217,12 +2221,6 @@ public class PShape3D extends PShape { createNormalBuffer(); initTexCoordData(); createTexCoordBuffer(); - - initChildrenData(); - } - - protected void reallocate() { - allocate(vertexCount); } protected void release() { @@ -2382,7 +2380,7 @@ public class PShape3D extends PShape { protected void deleteTexCoordBuffer() { - for (int i = 0; i < numTexBuffers; i++) { + for (int i = 0; i < glTexCoordBufferID.length; i++) { deleteTexCoordBuffer(i); } } @@ -3087,7 +3085,9 @@ public class PShape3D extends PShape { } // Allocate space for the geometry that the triangulator has generated from the OBJ model. - allocate(ogl.recordedVertices.size()); + setSize(ogl.recordedVertices.size()); + allocate(); + initChildrenData(); updateElement = -1; width = height = depth = 0; diff --git a/java/libraries/opengl/src/processing/opengl/PTexture.java b/java/libraries/opengl/src/processing/opengl/PTexture.java index 40a83df6d..7f6907aff 100644 --- a/java/libraries/opengl/src/processing/opengl/PTexture.java +++ b/java/libraries/opengl/src/processing/opengl/PTexture.java @@ -89,16 +89,13 @@ public class PTexture implements PConstants { */ public PTexture(PApplet parent, int width, int height, Object params) { this.parent = parent; - this.width = width; - this.height = height; ogl = (PGraphicsOpenGL)parent.g; ogl.registerGLObject(this); glID = 0; - setParameters((Parameters)params); - allocate(width, height); + init(width, height, (Parameters)params); } @@ -107,17 +104,19 @@ public class PTexture implements PConstants { * @param parent PApplet * @param filename String */ + /* public PTexture(PApplet parent, String filename) { this(parent, filename, new Parameters()); } - +*/ /** * Creates an instance of PTexture using image file filename as source and the specified texture parameters. * @param parent PApplet * @param filename String * @param params Parameters - */ + */ + /* public PTexture(PApplet parent, String filename, Object params) { this.parent = parent; @@ -128,9 +127,9 @@ public class PTexture implements PConstants { PImage img = parent.loadImage(filename); setParameters((Parameters)params); - set(img); + set(img); } - +*/ public void delete() { release(); @@ -138,6 +137,18 @@ public class PTexture implements PConstants { ogl.unregisterGLObject(this); } + + public void update() { + if (img != null) { + //if (img.pixels == null) { + img.loadPixels(); + // } + //get(img.pixels); + //img.updatePixels(); + } + } + + public void refresh() { if (img != null && img.pixels != null) { set(img.pixels); @@ -179,10 +190,9 @@ public class PTexture implements PConstants { * @param params GLTextureParameters */ public void init(int width, int height, Parameters params) { - this.width = width; - this.height = height; setParameters(params); - allocate(width, height); + setSize(width, height); + allocate(); } @@ -266,10 +276,6 @@ public class PTexture implements PConstants { throw new RuntimeException("PTexture: wrong length of pixels array"); } - if (glID == 0) { - allocate(width, height); - } - getGl().glEnable(glTarget); getGl().glBindTexture(glTarget, glID); @@ -695,15 +701,10 @@ public class PTexture implements PConstants { // Allocate/release texture. + protected void setSize(int w, int h) { + width = w; + height = h; - /** - * Allocates the opengl texture object. - * @param w int - * @param h int - */ - protected void allocate(int w, int h) { - release(); // Just in the case this object is being re-allocated. - if (PGraphicsOpenGL.npotTexSupported) { glWidth = w; glHeight = h; @@ -717,9 +718,23 @@ public class PTexture implements PConstants { throw new RuntimeException("Image width and height cannot be" + " larger than " + PGraphicsOpenGL.maxTextureSize + " with this graphics card."); - } + } - usingMipmaps = glMinFilter == GL.GL_LINEAR_MIPMAP_LINEAR; + // If non-power-of-two textures are not supported, and the specified width or height + // is non-power-of-two, then glWidth (glHeight) will be greater than w (h) because it + // is chosen to be the next power of two, and this quotient will give the appropriate + // maximum texture coordinate value given this situation. + maxTexCoordU = (float)width / glWidth; + maxTexCoordV = (float)height / glHeight; + } + + /** + * Allocates the opengl texture object. + * @param w int + * @param h int + */ + protected void allocate() { + release(); // Just in the case this object is being re-allocated. getGl().glEnable(glTarget); glID = ogl.createGLResource(PGraphicsOpenGL.GL_TEXTURE_OBJECT); @@ -735,28 +750,14 @@ public class PTexture implements PConstants { GL.GL_UNSIGNED_BYTE, null); // Once OpenGL knows the size of the new texture, we make sure it doesn't - // contain any garbage in the region of interest (0, 0, w, h): - int[] texels = new int[w * h]; - java.util.Arrays.fill(texels, 0, w * h, 0x00000000); - setTexels(0, 0, w, h, texels); + // contain any garbage in the region of interest (0, 0, width, height): + int[] texels = new int[width * height]; + java.util.Arrays.fill(texels, 0, width * height, 0x00000000); + setTexels(0, 0, width, height, texels); texels = null; getGl().glBindTexture(glTarget, 0); - getGl().glDisable(glTarget); - - flippedX = false; - flippedY = false; - - // If non-power-of-two textures are not supported, and the specified width or height - // is non-power-of-two, then glWidth (glHeight) will be greater than w (h) because it - // is chosen to be the next power of two, and this quotient will give the appropriate - // maximum texture coordinate value given this situation. - maxTexCoordU = (float)w / glWidth; - maxTexCoordV = (float)h / glHeight; - } - - protected void reallocate() { - allocate(width, height); + getGl().glDisable(glTarget); } /** @@ -934,6 +935,11 @@ public class PTexture implements PConstants { } else { throw new RuntimeException("OPENGL2: Unknown wrapping mode"); } + + usingMipmaps = glMinFilter == GL.GL_LINEAR_MIPMAP_LINEAR; + + flippedX = false; + flippedY = false; } ///////////////////////////////////////////////////////////////////////////