From 5783c34cd77ae9de9bf2835fc0b21684da839c74 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Fri, 12 Nov 2010 13:54:20 +0000 Subject: [PATCH] Added wrapping modes to PTexture, PFont now uses PTexture objects to encapsulate the glyph textures --- android/core/src/processing/core/PApplet.java | 30 ++++ .../core/src/processing/core/PConstants.java | 4 + android/core/src/processing/core/PFont.java | 160 +++++++++--------- .../src/processing/core/PFramebuffer.java | 10 +- .../processing/core/PGraphicsAndroid3D.java | 62 ++++--- .../core/src/processing/core/PShape3D.java | 34 ++-- .../core/src/processing/core/PTexture.java | 159 +++++++++++------ 7 files changed, 275 insertions(+), 184 deletions(-) diff --git a/android/core/src/processing/core/PApplet.java b/android/core/src/processing/core/PApplet.java index fb043a340..f6a1d4c67 100644 --- a/android/core/src/processing/core/PApplet.java +++ b/android/core/src/processing/core/PApplet.java @@ -24,6 +24,36 @@ package processing.core; import java.io.InputStream; +import processing.xml.XMLElement; +import android.content.*; +import android.content.pm.ActivityInfo; +import android.content.res.AssetManager; +import android.content.res.Configuration; +import android.graphics.*; + +import java.io.*; +import java.lang.reflect.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.text.NumberFormat; +import java.util.*; +import java.util.regex.*; +import java.util.zip.*; + +import android.app.Activity; +import android.net.Uri; +import android.text.format.Time; +import android.util.*; +import android.view.SurfaceView; +import android.opengl.GLSurfaceView; +import android.view.WindowManager; +import android.os.Bundle; +import android.os.Handler; +//import android.os.Looper; +import android.view.*; +//import android.view.ViewGroup.LayoutParams; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; public class PApplet extends Activity implements PConstants, Runnable { diff --git a/android/core/src/processing/core/PConstants.java b/android/core/src/processing/core/PConstants.java index 833e1adb2..fdbd9791b 100644 --- a/android/core/src/processing/core/PConstants.java +++ b/android/core/src/processing/core/PConstants.java @@ -392,6 +392,10 @@ public interface PConstants { /** This constant identifies the linear/linear function to build mipmaps */ public static final int LINEAR_MIPMAP_LINEAR = 5; + /** This constant identifies the clamp-to-edge wrapping mode */ + public static final int CLAMP = 0; + /** This constant identifies the repeat wrapping mode */ + public static final int REPEAT = 1; // PShape3D diff --git a/android/core/src/processing/core/PFont.java b/android/core/src/processing/core/PFont.java index 0ac59d110..3e5614663 100644 --- a/android/core/src/processing/core/PFont.java +++ b/android/core/src/processing/core/PFont.java @@ -144,17 +144,22 @@ public class PFont implements PConstants { /** * Required for OpenGL-based font rendering. */ - protected PGraphicsAndroid3D a3d; - protected GL10 gl10; - protected int texWidth; - protected int texHeight; + protected PApplet parent; + protected int maxTexWidth; + protected int maxTexHeight; protected int offsetX; protected int offsetY; protected int lineHeight; + protected PTexture[] textures = null; + protected int currentTex; + protected int lastTex; + + /* protected int[] texIDList = null; - protected int currentTexID = -1; - protected int lastTexID = -1; - protected int recreateResourceIdx; + protected int[] texWidthList = null; + protected int[] texHeightList = null; + */ + public PFont() { } // for subclasses @@ -325,14 +330,6 @@ public class PFont implements PConstants { smooth = is.readBoolean(); } } - - protected void finalize() { - if (gl10 != null && texIDList != null) { - a3d.removeRecreateResourceMethod(recreateResourceIdx); - gl10.glDeleteTextures(texIDList.length, texIDList, 0); - texIDList = null; - } - } /** @@ -676,59 +673,57 @@ public class PFont implements PConstants { // OPENGL stuff - public void initTexture(GL10 gl, int w, int h) { - gl10 = gl; - texWidth = w; - texHeight = h; + public void initTexture(PApplet p, int w, int h) { + parent = p; + maxTexWidth = w; + maxTexHeight = h; - addTexture(gl); + currentTex = -1; + lastTex = -1; + + addTexture(); offsetX = 0; offsetY = 0; - lineHeight = 0; - - try { - Method meth = this.getClass().getMethod("recreateResource", new Class[] { PGraphicsAndroid3D.class }); - recreateResourceIdx = a3d.addRecreateResourceMethod(this, meth); - } catch (Exception e) { - recreateResourceIdx = -1; - } + lineHeight = 0; } - public int addTexture(GL10 gl) { - int[] textures = new int[1]; + public int addTexture() { + int w = maxTexWidth; + int h = maxTexHeight; - // We assume GL10.GL_TEXTURE_2D is enabled at this point (shoud be called by PGraphicsAndroid3D.textLineImpl()). - gl.glGenTextures(1, textures, 0); - gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); - - gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); - gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); - - gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); - gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); - - gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, texWidth, texHeight, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, null); - - if (texIDList == null) { - texIDList = new int[1]; - texIDList[0] = textures[0]; - } else { - int[] tmp = texIDList; - texIDList = new int[texIDList.length + 1]; - PApplet.arrayCopy(tmp, texIDList, tmp.length); - texIDList[tmp.length] = textures[0]; - } - currentTexID = textures[0]; + PTexture tex = new PTexture(parent, w, h, new PTexture.Parameters(ARGB, NEAREST)); - return currentTexID; + if (textures == null) { + textures = new PTexture[1]; + textures[0] = tex; + } else { + PTexture[] tmp = textures; + textures = new PTexture[textures.length + 1]; + PApplet.arrayCopy(tmp, textures, tmp.length); + textures[tmp.length] = tex; + } + currentTex = textures.length - 1; + return currentTex; + } + + public void setFirstTexture() { + setTexture(0); + } + + public void setTexture(int idx) { + if (0 <= idx && idx < textures.length) { + GL10 gl = ((PGraphicsAndroid3D)parent.g).gl; + gl.glBindTexture(textures[idx].glTarget, textures[idx].glID); + currentTex = idx; + } } // Add all the current glyphs to opengl texture. - public void addAllGlyphsToTexture(GL10 gl) { + public void addAllGlyphsToTexture() { // loop over current glyphs. for (int i = 0; i < glyphCount; i++) { - glyphs[i].addToTexture(gl); + glyphs[i].addToTexture(); } } @@ -901,8 +896,9 @@ public class PFont implements PConstants { } // Adds this glyph to the opengl texture in PFont. - protected void addToTexture(GL10 gl) { + protected void addToTexture() { // Converting the pixels array from the PImage into a valid RGBA array for OpenGL. + GL10 gl = ((PGraphicsAndroid3D)parent.g).gl; int[] rgba = new int[width * height]; int t = 0; @@ -922,16 +918,16 @@ public class PFont implements PConstants { } // Is there room for this glyph on the current line? - if (offsetX + width> texWidth) { + if (offsetX + width> textures[currentTex].glWidth) { // No room, go to the next line: offsetX = 0; offsetY += lineHeight; lineHeight = 0; } lineHeight = Math.max(lineHeight, height); - if (offsetY + lineHeight > texHeight) { + if (offsetY + lineHeight > textures[currentTex].glHeight) { // We run out of space in the current texture, we add a new texture: - lastTexID = addTexture(gl); + lastTex = addTexture(); // Reseting texture coordinates and line. offsetX = 0; @@ -939,40 +935,40 @@ public class PFont implements PConstants { lineHeight = 0; } - if (lastTexID == -1) { - lastTexID = texIDList[0]; + if (lastTex == -1) { + lastTex = 0; } // We assume GL10.GL_TEXTURE_2D is enabled at this point. - if (currentTexID != lastTexID) { - gl.glBindTexture(GL10.GL_TEXTURE_2D, lastTexID); - currentTexID = lastTexID; + if (currentTex != lastTex) { + setTexture(lastTex); } - gl.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, offsetX, offsetY, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, IntBuffer.wrap(rgba)); + gl.glTexSubImage2D(textures[currentTex].glTarget, 0, offsetX, offsetY, width, height, + GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, IntBuffer.wrap(rgba)); - texture = new TextureInfo(currentTexID, offsetX, offsetY + height, width, -height); + texture = new TextureInfo(currentTex, offsetX, offsetY + height, width, -height); offsetX += width; } public class TextureInfo { - public TextureInfo(int glid, int cropX, int cropY, int cropW, int cropH) { - this.glid = glid; - crop = new int[4]; - crop[0] = cropX; - crop[1] = cropY; - crop[2] = cropW; - crop[3] = cropH; - u0 = (float)cropX / (float)texWidth; - u1 = u0 + (float)cropW / (float)texWidth; - v0 = (float)(cropY + cropH) / (float)texHeight; - v1 = (float)cropY / (float)texHeight; - } + public TextureInfo(int n, int cropX, int cropY, int cropW, int cropH) { + tex = n; + crop = new int[4]; + crop[0] = cropX; + crop[1] = cropY; + crop[2] = cropW; + crop[3] = cropH; + u0 = (float)cropX / (float)textures[n].glWidth; + u1 = u0 + (float)cropW / (float)textures[n].glWidth; + v0 = (float)(cropY + cropH) / (float)textures[n].glHeight; + v1 = (float)cropY / (float)textures[n].glHeight; + } - public int glid; - public int[] crop; - public float u0, u1; - public float v0, v1; + public int tex; + public int[] crop; + public float u0, u1; + public float v0, v1; } } } diff --git a/android/core/src/processing/core/PFramebuffer.java b/android/core/src/processing/core/PFramebuffer.java index a127f5f52..f40c82081 100644 --- a/android/core/src/processing/core/PFramebuffer.java +++ b/android/core/src/processing/core/PFramebuffer.java @@ -89,6 +89,10 @@ public class PFramebuffer implements PConstants { initFramebuffer(w, h); if (!screenFb && !FboMode) { + // When FBOs are not available, rendering to texture is implemented by saving a portion of + // the screen, doing the "offscreen" rendering on this portion, copying the screen color + // 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)); pixelBuffer = IntBuffer.allocate(width * height); pixelBuffer.rewind(); @@ -136,7 +140,7 @@ public class PFramebuffer implements PConstants { for (int i = 0; i < numColorBuffers; i++) { colorBufferAttchPoints[i] = GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES + i; glColorBufferTargets[i] = textures[i].getGLTarget(); - glColorBufferIDs[i] = textures[i].getGLTextureID(); + glColorBufferIDs[i] = textures[i].getGLID(); gl11xp.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, colorBufferAttchPoints[i], glColorBufferTargets[i], glColorBufferIDs[i], 0); } @@ -153,7 +157,7 @@ public class PFramebuffer implements PConstants { glColorBufferIDs = new int[numColorBuffers]; for (int i = 0; i < numColorBuffers; i++) { glColorBufferTargets[i] = textures[i].getGLTarget(); - glColorBufferIDs[i] = textures[i].getGLTextureID(); + glColorBufferIDs[i] = textures[i].getGLID(); } } } @@ -277,7 +281,7 @@ public class PFramebuffer implements PConstants { // Saves content of the screen into the backup texture. public void backupScreen() { gl.glReadPixels(0, 0, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixelBuffer); - copyToTexture(pixelBuffer, backupTexture.getGLTextureID(), backupTexture.getGLTarget()); + copyToTexture(pixelBuffer, backupTexture.getGLID(), backupTexture.getGLTarget()); } // Draws the contents of the backup texture to the screen. diff --git a/android/core/src/processing/core/PGraphicsAndroid3D.java b/android/core/src/processing/core/PGraphicsAndroid3D.java index 679e78e62..20dc60abb 100644 --- a/android/core/src/processing/core/PGraphicsAndroid3D.java +++ b/android/core/src/processing/core/PGraphicsAndroid3D.java @@ -1885,7 +1885,7 @@ public class PGraphicsAndroid3D extends PGraphics { tex = faceTexture[j].getTexture(); if (tex != null) { gl.glEnable(tex.getGLTarget()); - gl.glBindTexture(tex.getGLTarget(), tex.getGLTextureID()); + gl.glBindTexture(tex.getGLTarget(), tex.getGLID()); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); texturing = true; } else { @@ -1928,8 +1928,8 @@ public class PGraphicsAndroid3D extends PGraphics { float cy = 0.0f; float sy = +1.0f; if (texturing) { - uscale *= tex.getMaxTextureCoordS(); - vscale *= tex.getMaxTextureCoordT(); + uscale *= tex.getMaxTexCoordU(); + vscale *= tex.getMaxTexCoordV(); if (tex.isFlippedX()) { cx = 1.0f; @@ -2588,15 +2588,14 @@ public class PGraphicsAndroid3D extends PGraphics { gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); } - if (textFont.texIDList == null) { - textFont.initTexture(gl, maxTextureSize, maxTextureSize); + if (textFont.textures == null) { + textFont.initTexture(parent, maxTextureSize, maxTextureSize); // Add all the current glyphs to the texture. - textFont.addAllGlyphsToTexture(gl); + textFont.addAllGlyphsToTexture(); } gl.glEnable(GL10.GL_TEXTURE_2D); - textFont.currentTexID = textFont.texIDList[0]; - gl.glBindTexture(GL10.GL_TEXTURE_2D, textFont.currentTexID); + textFont.setFirstTexture(); // Setting the current fill color as the font color. gl.glColor4f(fillR, fillG, fillB, fillA); @@ -2634,7 +2633,7 @@ public class PGraphicsAndroid3D extends PGraphics { if (glyph.texture == null) { // Adding new glyph to the font texture. - glyph.addToTexture(gl); + glyph.addToTexture(); } if (textMode == MODEL) { @@ -2662,17 +2661,16 @@ public class PGraphicsAndroid3D extends PGraphics { } } - protected void textCharModelImpl(Glyph.TextureInfo tex, float x1, float y1, + protected void textCharModelImpl(Glyph.TextureInfo info, float x1, float y1, float x2, float y2) { - if (textFont.currentTexID != tex.glid) { + if (textFont.currentTex != info.tex) { if (0 < textVertexCount) { // Current texture changes (the font is so large that needs more than one texture). // So rendering all we got until now, and reseting vertex counter. renderTextModel(); textVertexCount = 0; } - gl.glBindTexture(GL10.GL_TEXTURE_2D, tex.glid); - textFont.currentTexID = tex.glid; + textFont.setTexture(info.tex); } // Division by three needed because each int element in the buffer is used @@ -2685,53 +2683,52 @@ public class PGraphicsAndroid3D extends PGraphics { textVertexArray[3 * n + 0] = toFixed32(x1); textVertexArray[3 * n + 1] = toFixed32(y1); textVertexArray[3 * n + 2] = toFixed32(0); - textTexCoordArray[2 * n + 0] = toFixed32(tex.u0); - textTexCoordArray[2 * n + 1] = toFixed32(tex.v0); + textTexCoordArray[2 * n + 0] = toFixed32(info.u0); + textTexCoordArray[2 * n + 1] = toFixed32(info.v0); n++; textVertexArray[3 * n + 0] = toFixed32(x2); textVertexArray[3 * n + 1] = toFixed32(y2); textVertexArray[3 * n + 2] = toFixed32(0); - textTexCoordArray[2 * n + 0] = toFixed32(tex.u1); - textTexCoordArray[2 * n + 1] = toFixed32(tex.v1); + textTexCoordArray[2 * n + 0] = toFixed32(info.u1); + textTexCoordArray[2 * n + 1] = toFixed32(info.v1); n++; textVertexArray[3 * n + 0] = toFixed32(x1); textVertexArray[3 * n + 1] = toFixed32(y2); textVertexArray[3 * n + 2] = toFixed32(0); - textTexCoordArray[2 * n + 0] = toFixed32(tex.u0); - textTexCoordArray[2 * n + 1] = toFixed32(tex.v1); + textTexCoordArray[2 * n + 0] = toFixed32(info.u0); + textTexCoordArray[2 * n + 1] = toFixed32(info.v1); n++; textVertexArray[3 * n + 0] = toFixed32(x1); textVertexArray[3 * n + 1] = toFixed32(y1); textVertexArray[3 * n + 2] = toFixed32(0); - textTexCoordArray[2 * n + 0] = toFixed32(tex.u0); - textTexCoordArray[2 * n + 1] = toFixed32(tex.v0); + textTexCoordArray[2 * n + 0] = toFixed32(info.u0); + textTexCoordArray[2 * n + 1] = toFixed32(info.v0); n++; textVertexArray[3 * n + 0] = toFixed32(x2); textVertexArray[3 * n + 1] = toFixed32(y1); textVertexArray[3 * n + 2] = toFixed32(0); - textTexCoordArray[2 * n + 0] = toFixed32(tex.u1); - textTexCoordArray[2 * n + 1] = toFixed32(tex.v0); + textTexCoordArray[2 * n + 0] = toFixed32(info.u1); + textTexCoordArray[2 * n + 1] = toFixed32(info.v0); n++; textVertexArray[3 * n + 0] = toFixed32(x2); textVertexArray[3 * n + 1] = toFixed32(y2); textVertexArray[3 * n + 2] = toFixed32(0); - textTexCoordArray[2 * n + 0] = toFixed32(tex.u1); - textTexCoordArray[2 * n + 1] = toFixed32(tex.v1); + textTexCoordArray[2 * n + 0] = toFixed32(info.u1); + textTexCoordArray[2 * n + 1] = toFixed32(info.v1); n++; textVertexCount = n; } - protected void textCharScreenImpl(Glyph.TextureInfo tex, int xx, int yy, + protected void textCharScreenImpl(Glyph.TextureInfo info, int xx, int yy, int w0, int h0) { - if (textFont.currentTexID != tex.glid) { - gl.glBindTexture(GL10.GL_TEXTURE_2D, tex.glid); - textFont.currentTexID = tex.glid; + if (textFont.currentTex != info.tex) { + textFont.setTexture(info.tex); } // There is no need to setup orthographic projection or any related matrix set/restore @@ -2740,8 +2737,7 @@ public class PGraphicsAndroid3D extends PGraphics { // (except for mapping Z to the depth range), so there is no need for any // matrix setup/restore code." // (from https://www.khronos.org/message_boards/viewtopic.php?f=4&t=948&p=2553). - gl11.glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, - tex.crop, 0); + gl11.glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, info.crop, 0); gl11x.glDrawTexiOES(xx, height - yy, 0, w0, h0); } @@ -4940,7 +4936,7 @@ public class PGraphicsAndroid3D extends PGraphics { protected void drawTexture(PTexture tex, int[] crop, int x, int y, int w, int h) { gl.glEnable(tex.getGLTarget()); - gl.glBindTexture(tex.getGLTarget(), tex.getGLTextureID()); + gl.glBindTexture(tex.getGLTarget(), tex.getGLID()); gl.glDepthMask(false); gl.glDisable(GL10.GL_BLEND); @@ -4980,7 +4976,7 @@ public class PGraphicsAndroid3D extends PGraphics { // Utility function to copy buffer to texture protected void copyToTexture(PTexture tex, IntBuffer buffer, int x, int y, int w, int h) { gl.glEnable(tex.getGLTarget()); - gl.glBindTexture(tex.getGLTarget(), tex.getGLTextureID()); + gl.glBindTexture(tex.getGLTarget(), tex.getGLID()); gl.glTexSubImage2D(tex.getGLTarget(), 0, x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, buffer); gl.glDisable(tex.getGLTarget()); } diff --git a/android/core/src/processing/core/PShape3D.java b/android/core/src/processing/core/PShape3D.java index bdbafd49f..02195ba0d 100644 --- a/android/core/src/processing/core/PShape3D.java +++ b/android/core/src/processing/core/PShape3D.java @@ -775,8 +775,8 @@ public class PShape3D extends PShape implements PConstants { cy = 1.0f; sy = -1.0f; } - uscale *= tex.getMaxTextureCoordS(); - vscale *= tex.getMaxTextureCoordT(); + uscale *= tex.getMaxTexCoordU(); + vscale *= tex.getMaxTexCoordV(); // Inverting the texture coordinate transformation. u = (u / uscale - cx) / sx; @@ -844,8 +844,8 @@ public class PShape3D extends PShape implements PConstants { cy = 1.0f; sy = -1.0f; } - uscale *= tex.getMaxTextureCoordS(); - vscale *= tex.getMaxTextureCoordT(); + uscale *= tex.getMaxTexCoordU(); + vscale *= tex.getMaxTexCoordV(); w = vertGroup[i].texture.width; h = vertGroup[i].texture.height; @@ -920,8 +920,8 @@ public class PShape3D extends PShape implements PConstants { cy = 1.0f; sy = -1.0f; } - uscale *= tex.getMaxTextureCoordS(); - vscale *= tex.getMaxTextureCoordT(); + uscale *= tex.getMaxTexCoordU(); + vscale *= tex.getMaxTexCoordV(); // Texture coordinate transformation. u = (cx + sx * u) * uscale; @@ -1003,8 +1003,8 @@ public class PShape3D extends PShape implements PConstants { cy = 1.0f; sy = -1.0f; } - uscale *= tex.getMaxTextureCoordS(); - vscale *= tex.getMaxTextureCoordT(); + uscale *= tex.getMaxTexCoordU(); + vscale *= tex.getMaxTexCoordV(); img = vertGroup[i].texture; } @@ -1085,8 +1085,8 @@ public class PShape3D extends PShape implements PConstants { cy = 1.0f; sy = -1.0f; } - uscale *= tex.getMaxTextureCoordS(); - vscale *= tex.getMaxTextureCoordT(); + uscale *= tex.getMaxTexCoordU(); + vscale *= tex.getMaxTexCoordV(); img = vertGroup[i].texture; } @@ -1223,8 +1223,8 @@ public class PShape3D extends PShape implements PConstants { tex.height != group.texture.height || tex1.flippedX != tex0.flippedX || tex1.flippedY != tex0.flippedY || - tex1.maxTexCoordS != tex0.maxTexCoordS || - tex1.maxTexCoordT != tex0.maxTexCoordT; + tex1.maxTexCoordU != tex0.maxTexCoordU || + tex1.maxTexCoordV != tex0.maxTexCoordV; if (diff) { float uscale = 1.0f; @@ -1253,8 +1253,8 @@ public class PShape3D extends PShape implements PConstants { cy = 1.0f; sy = -1.0f; } - uscale *= tex0.getMaxTextureCoordS(); - vscale *= tex0.getMaxTextureCoordT(); + uscale *= tex0.getMaxTexCoordU(); + vscale *= tex0.getMaxTexCoordV(); u = (u / uscale - cx) / sx; v = (v / vscale - cy) / sy; @@ -1273,8 +1273,8 @@ public class PShape3D extends PShape implements PConstants { cy = 1.0f; sy = -1.0f; } - uscale *= tex1.getMaxTextureCoordS(); - vscale *= tex1.getMaxTextureCoordT(); + uscale *= tex1.getMaxTexCoordU(); + vscale *= tex1.getMaxTexCoordV(); u = (cx + sx * u) * uscale; v = (cy + sy * v) * vscale; @@ -1948,7 +1948,7 @@ public class PShape3D extends PShape implements PConstants { // Binding texture units. gl.glActiveTexture(GL11.GL_TEXTURE0); - gl.glBindTexture(texTarget, tex.getGLTextureID()); + gl.glBindTexture(texTarget, tex.getGLID()); if (pointSprites) { // Texturing with point sprites. diff --git a/android/core/src/processing/core/PTexture.java b/android/core/src/processing/core/PTexture.java index beedc1944..3b44405b4 100644 --- a/android/core/src/processing/core/PTexture.java +++ b/android/core/src/processing/core/PTexture.java @@ -47,18 +47,20 @@ public class PTexture implements PConstants { protected PGraphicsAndroid3D a3d; protected GL10 gl; - protected int glTextureID; + protected int glID; protected int glTarget; - protected int glInternalFormat; + protected int glFormat; protected int glMinFilter; protected int glMagFilter; - + protected int glWrapS; + protected int glWrapT; + protected int glWidth; protected int glHeight; protected boolean usingMipmaps; - protected float maxTexCoordS; - protected float maxTexCoordT; + protected float maxTexCoordU; + protected float maxTexCoordV; protected boolean flippedX; protected boolean flippedY; @@ -98,7 +100,7 @@ public class PTexture implements PConstants { a3d = (PGraphicsAndroid3D)parent.g; gl = a3d.gl; - glTextureID = 0; + glID = 0; setParameters(params); createTexture(width, height); @@ -134,7 +136,7 @@ public class PTexture implements PConstants { a3d = (PGraphicsAndroid3D)parent.g; gl = a3d.gl; - glTextureID = 0; + glID = 0; PImage img = parent.loadImage(filename); setParameters(params); @@ -201,7 +203,7 @@ public class PTexture implements PConstants { // Zeroing the texture id of tex, so the texture is not // deleted by OpenGL when the object is finalized by the GC. // "This" texture now wraps the one created in tex. - tex.glTextureID = 0; + tex.glID = 0; } @@ -210,7 +212,7 @@ public class PTexture implements PConstants { * @return boolean */ public boolean available() { - return 0 < glTextureID; + return 0 < glID; } @@ -252,7 +254,7 @@ public class PTexture implements PConstants { } - // Copies source texture to this by means of FBO. + // Copies source texture to this. public void set(PTexture tex, int x, int y, int w, int h) { if (tex == null) { throw new RuntimeException("PTexture: source texture is null"); @@ -297,7 +299,7 @@ public class PTexture implements PConstants { throw new RuntimeException("PTexture: wrong length of pixels array"); } - if (glTextureID == 0) { + if (glID == 0) { createTexture(width, height); } @@ -317,7 +319,7 @@ public class PTexture implements PConstants { */ gl.glEnable(glTarget); - gl.glBindTexture(glTarget, glTextureID); + gl.glBindTexture(glTarget, glID); if (usingMipmaps) { if (a3d.gl11 != null && PGraphicsAndroid3D.mipmapSupported) { @@ -457,8 +459,8 @@ public class PTexture implements PConstants { * Provides the ID of the OpenGL texture object. * @return int */ - protected int getGLTextureID() { - return glTextureID; + protected int getGLID() { + return glID; } @@ -475,8 +477,8 @@ public class PTexture implements PConstants { * Returns the texture internal format. * @return int */ - protected int getGLInternalFormat() { - return glInternalFormat; + protected int getGLFormat() { + return glFormat; } @@ -497,7 +499,22 @@ public class PTexture implements PConstants { return glMagFilter; } + /** + * Returns the texture wrapping mode for the S coordinate. + * @return int + */ + protected int getGLWrapS() { + return glWrapS; + } + /** + * Returns the texture wrapping mode for the T coordinate. + * @return int + */ + protected int getGLWrapT() { + return glWrapT; + } + /** * Returns true or false whether or not the texture is using mipmaps. * @return boolean @@ -508,20 +525,20 @@ public class PTexture implements PConstants { /** - * Returns the maximum possible value for the texture coordinate S. + * Returns the maximum possible value for the texture coordinate U (horizontal). * @return float */ - protected float getMaxTextureCoordS() { - return maxTexCoordS; + protected float getMaxTexCoordU() { + return maxTexCoordU; } /** - * Returns the maximum possible value for the texture coordinate T. + * Returns the maximum possible value for the texture coordinate V (vertical). * @return float */ - protected float getMaxTextureCoordT() { - return maxTexCoordT; + protected float getMaxTexCoordV() { + return maxTexCoordV; } @@ -803,7 +820,7 @@ public class PTexture implements PConstants { if (PGraphicsAndroid3D.npotTexSupported) { glWidth = w; - glHeight =h; + glHeight = h; } else { glWidth = nextPowerOfTwo(w); glHeight = nextPowerOfTwo(h); @@ -824,14 +841,14 @@ public class PTexture implements PConstants { gl.glEnable(glTarget); int[] tmp = new int[1]; gl.glGenTextures(1, tmp, 0); - glTextureID = tmp[0]; - gl.glBindTexture(glTarget, glTextureID); + glID = tmp[0]; + gl.glBindTexture(glTarget, glID); gl.glTexParameterf(glTarget, GL10.GL_TEXTURE_MIN_FILTER, glMinFilter); gl.glTexParameterf(glTarget, GL10.GL_TEXTURE_MAG_FILTER, glMagFilter); - gl.glTexParameterf(glTarget, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); - gl.glTexParameterf(glTarget, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); - - gl.glTexImage2D(glTarget, 0, glInternalFormat, glWidth, glHeight, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, null); + gl.glTexParameterf(glTarget, GL10.GL_TEXTURE_WRAP_S, glWrapS); + gl.glTexParameterf(glTarget, GL10.GL_TEXTURE_WRAP_T, glWrapT); + + gl.glTexImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, null); gl.glDisable(glTarget); flippedX = false; @@ -841,8 +858,8 @@ public class PTexture implements PConstants { // 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. - maxTexCoordS = (float)w / glWidth; - maxTexCoordT = (float)h / glHeight; + maxTexCoordU = (float)w / glWidth; + maxTexCoordV = (float)h / glHeight; } @@ -850,10 +867,10 @@ public class PTexture implements PConstants { * Deletes the opengl texture object. */ protected void deleteTexture() { - if (glTextureID != 0) { - int[] tmp = { glTextureID }; + if (glID != 0) { + int[] tmp = { glID }; gl.glDeleteTextures(1, tmp, 0); - glTextureID = 0; + glID = 0; } } @@ -874,9 +891,9 @@ public class PTexture implements PConstants { a3d = src.a3d; gl = src.gl; - glTextureID = src.glTextureID; + glID = src.glID; glTarget = src.glTarget; - glInternalFormat = src.glInternalFormat; + glFormat = src.glFormat; glMinFilter = src.glMinFilter; glMagFilter = src.glMagFilter; @@ -884,8 +901,8 @@ public class PTexture implements PConstants { glHeight = src.glHeight; usingMipmaps = src.usingMipmaps; - maxTexCoordS = src.maxTexCoordS; - maxTexCoordT = src.maxTexCoordT; + maxTexCoordU = src.maxTexCoordU; + maxTexCoordV = src.maxTexCoordV; flippedX = src.flippedX; flippedY = src.flippedY; @@ -905,11 +922,11 @@ public class PTexture implements PConstants { res.target = TEXTURE2D; } - if (glInternalFormat == GL10.GL_RGB) { + if (glFormat == GL10.GL_RGB) { res.format = RGB; - } else if (glInternalFormat == GL10.GL_RGBA) { + } else if (glFormat == GL10.GL_RGBA) { res.format = ARGB; - } else if (glInternalFormat == GL10.GL_ALPHA) { + } else if (glFormat == GL10.GL_ALPHA) { res.format = ALPHA; } @@ -929,9 +946,21 @@ public class PTexture implements PConstants { if (glMagFilter == GL10.GL_NEAREST) { res.magFilter = NEAREST; - } else if (glMagFilter == GL10.GL_LINEAR) { + } else if (glMagFilter == GL10.GL_LINEAR) { res.magFilter = LINEAR; } + + if (glWrapS == GL10.GL_CLAMP_TO_EDGE) { + res.wrapU = CLAMP; + } else if (glWrapS == GL10.GL_REPEAT) { + res.wrapU = REPEAT; + } + + if (glWrapT == GL10.GL_CLAMP_TO_EDGE) { + res.wrapV = CLAMP; + } else if (glWrapT == GL10.GL_REPEAT) { + res.wrapV = REPEAT; + } return res; } @@ -950,11 +979,11 @@ public class PTexture implements PConstants { } if (params.format == RGB) { - glInternalFormat = GL10.GL_RGB; + glFormat = GL10.GL_RGB; } else if (params.format == ARGB) { - glInternalFormat = GL10.GL_RGBA; + glFormat = GL10.GL_RGBA; } else if (params.format == ALPHA) { - glInternalFormat = GL10.GL_ALPHA; + glFormat = GL10.GL_ALPHA; } else { throw new RuntimeException("GTexture: Unknown texture format"); } @@ -975,13 +1004,29 @@ public class PTexture implements PConstants { throw new RuntimeException("GTexture: Unknown minimization filter"); } - if (params.magFilter == NEAREST) { + if (params.magFilter == NEAREST) { glMagFilter = GL10.GL_NEAREST; } else if (params.magFilter == LINEAR) { glMagFilter = GL10.GL_LINEAR; } else { throw new RuntimeException("GTexture: Unknown magnification filter"); } + + if (params.wrapU == CLAMP) { + glWrapS = GL10.GL_CLAMP_TO_EDGE; + } else if (params.wrapU == REPEAT) { + glWrapS = GL10.GL_REPEAT; + } else { + throw new RuntimeException("GTexture: Unknown wrapping mode"); + } + + if (params.wrapV == CLAMP) { + glWrapT = GL10.GL_CLAMP_TO_EDGE; + } else if (params.wrapV == REPEAT) { + glWrapT = GL10.GL_REPEAT; + } else { + throw new RuntimeException("GTexture: Unknown wrapping mode"); + } } @@ -1029,7 +1074,17 @@ public class PTexture implements PConstants { * Texture magnification filter. */ public int magFilter; - + + /** + * Wrapping mode along U. + */ + public int wrapU; + + /** + * Wrapping mode along V. + */ + public int wrapV; + /** * Creates an instance of GLTextureParameters, setting all the parameters to default values. */ @@ -1037,7 +1092,9 @@ public class PTexture implements PConstants { target = TEXTURE2D; format = ARGB; minFilter = LINEAR; - magFilter = LINEAR; + magFilter = LINEAR; + wrapU = CLAMP; + wrapV = CLAMP; } public Parameters(int format) { @@ -1045,13 +1102,17 @@ public class PTexture implements PConstants { this.format = format; minFilter = LINEAR; magFilter = LINEAR; + wrapU = CLAMP; + wrapV = CLAMP; } public Parameters(int format, int filter) { target = PTexture.TEXTURE2D; this.format = format; minFilter = filter; - magFilter = filter; + magFilter = filter; + wrapU = CLAMP; + wrapV = CLAMP; } } }