some cleaning up, handle edges

This commit is contained in:
codeanticode
2015-05-30 13:45:40 -04:00
parent 8d0ae882f2
commit aed0224154

View File

@@ -24,9 +24,11 @@ package processing.opengl;
import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PGraphics;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.NoSuchElementException;
@@ -100,6 +102,10 @@ public class Texture implements PConstants {
protected int[] rgbaPixels = null;
protected IntBuffer pixelBuffer = null;
protected int[] edgePixels = null;
protected IntBuffer edgeBuffer = null;
protected FrameBuffer tempFbo = null;
protected int pixBufUpdateCount = 0;
protected int rgbaPixUpdateCount = 0;
@@ -340,82 +346,20 @@ public class Texture implements PConstants {
}
pgl.bindTexture(glTarget, glName);
loadPixels(w * h);
convertToRGBA(pixels, format, w, h);
updatePixelBuffer(rgbaPixels);
pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
pixelBuffer);
fillEdges(x, y, w, h);
if (usingMipmaps) {
if (PGraphicsOpenGL.autoMipmapGenSupported) {
// Automatic mipmap generation.
loadPixels(w * h);
convertToRGBA(pixels, format, w, h);
updatePixelBuffer(rgbaPixels);
pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
pixelBuffer);
pgl.generateMipmap(glTarget);
} else {
// TODO: finish manual mipmap generation, replacing Bitmap with AWT's BufferedImage,
// making it work in npot textures (embed npot tex into larger pot tex?), subregions,
// and moving GLUtils.texImage2D (originally from Android SDK) into PGL.
// Actually, this whole code should go into PGL, so the Android implementation can
// use Bitmap, and desktop use BufferedImage.
/*
if (w != width || h != height) {
System.err.println("Sorry but I don't know how to generate mipmaps for a subregion.");
return;
}
// Code by Mike Miller obtained from here:
// http://insanitydesign.com/wp/2009/08/01/android-opengl-es-mipmaps/
int w0 = glWidth;
int h0 = glHeight;
int[] argbPixels = new int[w0 * h0];
convertToARGB(pixels, argbPixels, format);
int level = 0;
int denom = 1;
// We create a Bitmap because then we use its built-in filtered downsampling
// functionality.
Bitmap bitmap = Bitmap.createBitmap(w0, h0, Config.ARGB_8888);
bitmap.setPixels(argbPixels, 0, w0, 0, 0, w0, h0);
while (w0 >= 1 || h0 >= 1) {
//First of all, generate the texture from our bitmap and set it to the according level
GLUtils.texImage2D(glTarget, level, bitmap, 0);
// We are done.
if (w0 == 1 && h0 == 1) {
break;
}
// Increase the mipmap level
level++;
denom *= 2;
// Downsampling bitmap. We must eventually arrive to the 1x1 level,
// and if the width and height are different, there will be a few 1D
// texture levels just before.
// This update formula also allows for NPOT resolutions.
w0 = PApplet.max(1, PApplet.floor((float)glWidth / denom));
h0 = PApplet.max(1, PApplet.floor((float)glHeight / denom));
// (see getScaledInstance in AWT Image)
Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, w0, h0, true);
// Clean up
bitmap.recycle();
bitmap = bitmap2;
}
*/
loadPixels(w * h);
convertToRGBA(pixels, format, w, h);
updatePixelBuffer(rgbaPixels);
pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
pixelBuffer);
// TODO: finish manual mipmap generation,
// https://github.com/processing/processing/issues/3335
}
} else {
loadPixels(w * h);
convertToRGBA(pixels, format, w, h);
updatePixelBuffer(rgbaPixels);
pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
pixelBuffer);
}
pgl.bindTexture(glTarget, 0);
@@ -472,20 +416,18 @@ public class Texture implements PConstants {
}
pgl.bindTexture(glTarget, glName);
pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
pixBuf);
fillEdges(x, y, w, h);
if (usingMipmaps) {
if (PGraphicsOpenGL.autoMipmapGenSupported) {
pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
pixBuf);
pgl.generateMipmap(glTarget);
} else {
pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
pixBuf);
// TODO: finish manual mipmap generation,
// https://github.com/processing/processing/issues/3335
}
} else {
pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
pixBuf);
}
pgl.bindTexture(glTarget, 0);
if (enabledTex) {
pgl.disableTexturing(glTarget);
@@ -1504,6 +1446,44 @@ public class Texture implements PConstants {
}
protected void fillEdges(int x, int y, int w, int h) {
if ((width < glWidth || height < glHeight) && (x + w == width || y + h == height)) {
if (x + w == width) {
int ew = glWidth - width;
edgePixels = new int[h * ew];
for (int i = 0; i < h; i++) {
int c = rgbaPixels[i * w + (w - 1)];
Arrays.fill(edgePixels, i * ew, (i + 1) * ew, c);
}
edgeBuffer = PGL.updateIntBuffer(edgeBuffer, edgePixels, true);
pgl.texSubImage2D(glTarget, 0, width, y, ew, h, PGL.RGBA,
PGL.UNSIGNED_BYTE, edgeBuffer);
}
if (y + h == height) {
int eh = glHeight - height;
edgePixels = new int[eh * w];
for (int i = 0; i < eh; i++) {
System.arraycopy(rgbaPixels, (h - 1) * w, edgePixels, i * w, w);
}
edgeBuffer = PGL.updateIntBuffer(edgeBuffer, edgePixels, true);
pgl.texSubImage2D(glTarget, 0, x, height, w, eh, PGL.RGBA,
PGL.UNSIGNED_BYTE, edgeBuffer);
}
if (x + w == width && y + h == height) {
int ew = glWidth - width;
int eh = glHeight - height;
int c = rgbaPixels[w * h - 1];
edgePixels = new int[eh * ew];
Arrays.fill(edgePixels, 0, eh * ew, c);
edgeBuffer = PGL.updateIntBuffer(edgeBuffer, edgePixels, true);
pgl.texSubImage2D(glTarget, 0, width, height, ew, eh, PGL.RGBA,
PGL.UNSIGNED_BYTE, edgeBuffer);
}
}
}
///////////////////////////////////////////////////////////////////////////
// Parameters object