add filter(PShader) function

This commit is contained in:
codeanticode
2012-07-20 17:07:29 +00:00
parent 629e7a6dbb
commit 6aab3afd58
14 changed files with 519 additions and 204 deletions
@@ -1333,7 +1333,12 @@ public class PGraphics extends PImage implements PConstants {
return null;
}
public void filter(Object shader) {
showMissingWarning("filter");
}
//////////////////////////////////////////////////////////////
// CURVE/BEZIER VERTEX HANDLING
@@ -370,9 +370,7 @@ class PFontTexture implements PConstants {
void updateTex() {
textures[texIndex].bind();
textures[texIndex].setTexels(pixels, 0, crop[0] - 1, crop[1] + crop[3] - 1, crop[2] + 2, -crop[3] + 2);
textures[texIndex].unbind();
textures[texIndex].setNative(pixels, 0, crop[0] - 1, crop[1] + crop[3] - 1, crop[2] + 2, -crop[3] + 2);
}
}
}
+39 -7
View File
@@ -451,10 +451,10 @@ public class PGL {
GLES20.glGenTextures(2, colorTex, 0);
for (int i = 0; i < 2; i++) {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, colorTex[i]);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texWidth, texHeight, 0, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, null);
initTexture(GLES20.GL_TEXTURE_2D, PGL.GL_RGBA, texWidth, texHeight);
}
@@ -505,14 +505,41 @@ public class PGL {
}
public boolean usingPrimaryFBO() {
public boolean primaryIsFboBacked() {
return colorFBO[0] != 0;
}
public int getFboTexTarget() {
return GLES20.GL_TEXTURE_2D;
}
public int getFboTexName() {
return colorTex[0];
}
public int getFboWidth() {
return texWidth;
}
public int getFboHeight() {
return texHeight;
}
public void bindPrimaryColorFBO() {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, colorFBO[0]);
PGraphicsOpenGL.screenFramebuffer.glFbo = colorFBO[0];
// Make the color buffer opaque so it doesn't show
// the background when drawn on top of another surface.
GLES20.glColorMask(false, false, false, true);
GLES20.glClearColor(0, 0, 0, 1);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glColorMask(true, true, true, true);
}
@@ -741,11 +768,16 @@ public class PGL {
}
public void glTexParameterf(int target, int param, int value) {
GLES20.glTexParameterf(target, param, value);
public void glTexParameteri(int target, int param, int value) {
GLES20.glTexParameteri(target, param, value);
}
public void glGetTexParameteriv(int target, int param, int[] values, int offset) {
GLES20.glGetTexParameteriv(target, param, values, offset);
}
public void glGenerateMipmap(int target) {
GLES20.glGenerateMipmap(target);
}
@@ -146,6 +146,25 @@ public class PGraphics2D extends PGraphicsOpenGL {
}
//////////////////////////////////////////////////////////////
// MATRIX MORE!
protected void begin2D() {
pushProjection();
defaultPerspective();
pushMatrix();
defaultCamera();
}
protected void end2D() {
popMatrix();
popProjection();
}
//////////////////////////////////////////////////////////////
// SHAPE
@@ -67,6 +67,25 @@ public class PGraphics3D extends PGraphicsOpenGL {
protected void defaultCamera() {
camera();
}
//////////////////////////////////////////////////////////////
// MATRIX MORE!
protected void begin2D() {
pushProjection();
ortho(-width/2, +width/2, -height/2, +height/2, -1, +1);
pushMatrix();
camera(width/2, height/2);
}
protected void end2D() {
popMatrix();
popProjection();
}
//////////////////////////////////////////////////////////////
@@ -362,13 +362,17 @@ public class PGraphicsOpenGL extends PGraphics {
/** Used to create a temporary copy of the color buffer of this
* rendering surface when applying a filter */
protected Texture textureCopy;
protected PImage imageCopy;
/** IntBuffer wrapping the pixels array. */
protected IntBuffer pixelBuffer;
/** Array to store pixels in OpenGL format. */
protected int[] rgbaPixels;
protected int[] nativePixels;
/** IntBuffer wrapping the native pixels array. */
protected IntBuffer nativePixelBuffer;
/** Flag to indicate if the user is manipulating the
* pixels array through the set()/get() methods */
protected boolean setgetPixels;
@@ -1796,7 +1800,7 @@ public class PGraphicsOpenGL extends PGraphics {
pgl.glDrawBuffer(PGL.GL_BACK);
}
offscreenNotCurrent = false;
} else if (pgl.usingPrimaryFBO()) {
} else if (pgl.primaryIsFboBacked()) {
if (op == OP_READ) {
// We read from the color FBO, but the multisample FBO is currently bound, so:
offscreenNotCurrent = true;
@@ -3690,6 +3694,14 @@ public class PGraphicsOpenGL extends PGraphics {
n30, n31, n32, n33);
}
protected void begin2D() {
}
protected void end2D() {
}
//////////////////////////////////////////////////////////////
@@ -4078,8 +4090,8 @@ public class PGraphicsOpenGL extends PGraphics {
protected void defaultCamera() {
camera();
}
//////////////////////////////////////////////////////////////
// PROJECTION
@@ -4921,14 +4933,7 @@ public class PGraphicsOpenGL extends PGraphics {
allocatePixels();
if (!setgetPixels) {
readPixels();
if (primarySurface) {
// Copy pixels to the texture associated to the primary surface
// so both are in sync.
loadTextureImpl(POINT, false);
pixelsToTexture();
}
readPixels();
}
if (needEndDraw) {
@@ -4970,19 +4975,20 @@ public class PGraphicsOpenGL extends PGraphics {
int i0 = y * width + x;
int len = w * h;
if (rgbaPixels == null || rgbaPixels.length < len) {
rgbaPixels = new int[len];
if (nativePixels == null || nativePixels.length < len) {
nativePixels = new int[len];
nativePixelBuffer = IntBuffer.wrap(nativePixels);
}
PApplet.arrayCopy(pixels, i0, rgbaPixels, 0, len);
PGL.javaToNativeARGB(rgbaPixels, w, h);
PApplet.arrayCopy(pixels, i0, nativePixels, 0, len);
PGL.javaToNativeARGB(nativePixels, w, h);
// Copying pixel buffer to screen texture...
if (primarySurface) {
loadTextureImpl(POINT, false); // (first making sure that the screen texture is valid).
}
pgl.copyToTexture(texture.glTarget, texture.glFormat, texture.glName,
x, y, w, h, IntBuffer.wrap(rgbaPixels));
x, y, w, h, IntBuffer.wrap(nativePixels));
if (primarySurface || offscreenMultisample) {
// ...and drawing the texture to screen... but only
@@ -5004,7 +5010,7 @@ public class PGraphicsOpenGL extends PGraphics {
public int get(int x, int y) {
loadPixels();
loadPixels();
setgetPixels = true;
return super.get(x, y);
}
@@ -5040,14 +5046,78 @@ public class PGraphicsOpenGL extends PGraphics {
// Copies the contents of the color buffer into the pixels
// array, and then the pixels array into the screen texture.
public void loadTexture() {
boolean needEndDraw = false;
if (!drawing) {
beginDraw();
needEndDraw = true;
}
flush(); // To make sure the color buffer is updated.
if (primarySurface) {
loadTextureImpl(Texture.POINT, false);
loadPixels();
pixelsToTexture();
if (pgl.primaryIsFboBacked()) {
pgl.bindPrimaryColorFBO();
// Copy the contents of the FBO used by the primary surface into texture, this copy
// operation is very fast because it is resolved in the GPU.
texture.set(pgl.getFboTexTarget(), pgl.getFboTexName(), pgl.getFboWidth(), pgl.getFboHeight(), width, height);
pgl.bindPrimaryMultiFBO();
} else {
// Here we go the slow route: we first copy the contents of the color buffer into a pixels array (but we keep it
// in native format) and then copy this array into the texture.
if (nativePixels == null || nativePixels.length < width * height) {
nativePixels = new int[width * height];
nativePixelBuffer = IntBuffer.wrap(nativePixels);
}
beginPixelsOp(OP_READ);
pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, nativePixelBuffer);
endPixelsOp();
texture.setNative(nativePixels, 0, 0, width, height);
}
} else {
// We need to copy the contents of the multisampled buffer to the
// color buffer, so the later is up-to-date with the last drawing.
if (offscreenMultisample) {
offscreenFramebufferMultisample.copy(offscreenFramebuffer);
}
// Make the offscreen color buffer opaque so it doesn't show
// the background when drawn on the main surface.
if (offscreenMultisample) {
pushFramebuffer();
setFramebuffer(offscreenFramebuffer);
}
pgl.glColorMask(false, false, false, true);
pgl.glClearColor(0, 0, 0, 1);
pgl.glClear(PGL.GL_COLOR_BUFFER_BIT);
pgl.glColorMask(true, true, true, true);
if (offscreenMultisample) {
popFramebuffer();
}
}
if (needEndDraw) {
endDraw();
}
}
// Just marks the whole texture as updated
public void updateTexture() {
texture.updateTexels();
}
// Marks the specified rectanglular subregion in the texture as
// updated.
public void updateTexture(int x, int y, int w, int h) {
texture.updateTexels(x, y, w, h);
}
// Draws wherever it is in the screen texture right now to the display.
public void updateDisplay() {
flush();
@@ -5065,15 +5135,17 @@ public class PGraphicsOpenGL extends PGraphics {
}
if (texture == null || texture != img.getCache(pgPrimary)) {
Texture.Parameters params;
if (primarySurface) {
params = new Texture.Parameters(ARGB, Texture.POINT, false);
} else {
params = new Texture.Parameters(ARGB, Texture.BILINEAR, false);
}
texture = addTexture(img, params);
Texture tex = (Texture)img.getCache(pgPrimary);
Texture.Parameters params = tex != null ? tex.getParameters() : null;
if (tex == null || tex.contextIsOutdated() || !validSurfaceTex(tex)) {
if (primarySurface) {
params = new Texture.Parameters(ARGB, Texture.POINT, false);
} else {
params = new Texture.Parameters(ARGB, Texture.BILINEAR, false);
}
tex = addTexture(img, params);
}
texture = tex;
texture.setFlippedY(true);
this.setCache(pgPrimary, texture);
this.setParams(pgPrimary, params);
@@ -5111,18 +5183,18 @@ public class PGraphicsOpenGL extends PGraphics {
texture.glWidth, texture.glHeight,
x, y, x + w, y + h);
}
protected void pixelsToTexture() {
texture.set(pixels);
}
protected void textureToPixels() {
texture.get(pixels);
}
protected boolean validSurfaceTex(Texture tex) {
Texture.Parameters params = tex.getParameters();
if (primarySurface) {
return params.sampling == Texture.POINT && !params.mipmaps;
} else {
return params.sampling == Texture.BILINEAR && !params.mipmaps;
}
}
//////////////////////////////////////////////////////////////
// IMAGE CONVERSION
@@ -5206,48 +5278,58 @@ public class PGraphicsOpenGL extends PGraphics {
return;
}
PolyTexShader texShader = (PolyTexShader)shader;
// if (shader instanceof FilterShader) {
//
// }
if (primarySurface) {
} else {
if (textureCopy == null) {
Texture.Parameters params = new Texture.Parameters(ARGB, Texture.BILINEAR, false);
textureCopy = new Texture(parent, width, height, params);
textureCopy.setFlippedY(true);
}
flush();
// Disable writing to the depth buffer, so that after applying the filter we can
// still use the depth information to properly add geometry to the scene.
offscreenFramebuffer.setColorBuffer(textureCopy);
offscreenFramebuffer.clear();
// Disable depth test so the texture overwrites everything else.
beginPGL();
pgl.drawTexture(texture.glTarget, texture.glName,
texture.glWidth, texture.glHeight,
0, 0, width, height);
endPGL();
loadTexture();
offscreenFramebuffer.setColorBuffer(texture);
offscreenFramebuffer.clear();
beginPGL();
pgl.drawTextureCustom(textureCopy.glTarget, textureCopy.glName,
textureCopy.glWidth, textureCopy.glHeight,
0, 0, width, height, texShader.glProgram);
endPGL();
}
if (textureCopy == null || textureCopy.width != width || textureCopy.height != height) {
Texture.Parameters params = new Texture.Parameters(ARGB, Texture.POINT, false);
textureCopy = new Texture(parent, width, height, params);
textureCopy.setFlippedY(true);
imageCopy = wrapTexture(textureCopy);
}
textureCopy.set(texture.glTarget, texture.glName, texture.glWidth, texture.glHeight, width, height);
// Disable writing to the depth buffer, so that after applying the filter we can
// still use the depth information to keep adding geometry to the scene.
pgl.glDepthMask(false);
// Also disabling depth testing so the texture is drawn on top of everything that
// has been drawn before.
pgl.glDisable(PGL.GL_DEPTH_TEST);
PolyTexShader prevTexShader = polyTexShader;
polyTexShader = (PolyTexShader) shader;
boolean prevLights = lights;
lights = false;
int prevTextureMode = textureMode;
textureMode = NORMAL;
boolean prevStroke = stroke;
stroke = false;
// Drawing a textured quad in 2D, covering the entire screen,
// with the filter shader applied to it:
begin2D();
beginShape(QUADS);
texture(imageCopy);
vertex(0, 0, 0, 0);
vertex(width, 0, 1, 0);
vertex(width, height, 1, 1);
vertex(0, height, 0, 1);
endShape();
end2D();
// Restoring previous configuration.
stroke = prevStroke;
lights = prevLights;
textureMode = prevTextureMode;
polyTexShader = prevTexShader;
if (!hints[DISABLE_DEPTH_TEST]) {
pgl.glEnable(PGL.GL_DEPTH_TEST);
}
if (!hints[DISABLE_DEPTH_MASK]) {
pgl.glDepthMask(true);
}
}
+119 -48
View File
@@ -89,6 +89,7 @@ public class Texture implements PConstants {
protected boolean usingMipmaps;
protected float maxTexcoordU;
protected float maxTexcoordV;
protected boolean bound;
protected boolean flippedX;
protected boolean flippedY;
@@ -241,15 +242,25 @@ public class Texture implements PConstants {
public void set(Texture tex) {
copyTexels(tex, 0, 0, tex.width, tex.height, true);
copyTexture(tex, 0, 0, tex.width, tex.height, true);
}
public void set(Texture tex, int x, int y, int w, int h) {
copyTexels(tex, x, y, w, h, true);
copyTexture(tex, x, y, w, h, true);
}
public void set(int texTarget, int texName, int texWidth, int texHeight, int w, int h) {
copyTexture(texTarget, texName, texWidth, texHeight, 0, 0, w, h, true);
}
public void set(int texTarget, int texName, int texWidth, int texHeight, int target, int tex, int x, int y, int w, int h) {
copyTexture(texTarget, texName, texWidth, texHeight, x, y, w, h, true);
}
public void set(int[] pixels) {
set(pixels, 0, 0, width, height, ARGB);
}
@@ -276,15 +287,14 @@ public class Texture implements PConstants {
return;
}
pgl.enableTexturing(glTarget);
pgl.glBindTexture(glTarget, glName);
bind();
if (usingMipmaps) {
if (PGraphicsOpenGL.autoMipmapGenSupported) {
// Automatic mipmap generation.
int[] rgbaPixels = new int[w * h];
convertToRGBA(pixels, rgbaPixels, format, w, h);
setTexels(rgbaPixels, x, y, w, h);
setNative(rgbaPixels, x, y, w, h);
pgl.glGenerateMipmap(glTarget);
rgbaPixels = null;
} else {
@@ -344,23 +354,53 @@ public class Texture implements PConstants {
int[] rgbaPixels = new int[w * h];
convertToRGBA(pixels, rgbaPixels, format, w, h);
setTexels(rgbaPixels, x, y, w, h);
setNative(rgbaPixels, x, y, w, h);
rgbaPixels = null;
}
} else {
int[] rgbaPixels = new int[w * h];
convertToRGBA(pixels, rgbaPixels, format, w, h);
setTexels(rgbaPixels, x, y, w, h);
setNative(rgbaPixels, x, y, w, h);
rgbaPixels = null;
}
pgl.glBindTexture(glTarget, 0);
pgl.disableTexturing(glTarget);
unbind();
updateTexels(x, y, w, h);
}
////////////////////////////////////////////////////////////
// Native set methods
public void setNative(int[] pix, int x, int y, int w, int h) {
setNative(pix, 0, x, y, w, h);
}
public void setNative(int[] pix, int level, int x, int y, int w, int h) {
bind();
pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, IntBuffer.wrap(pix));
unbind();
updateTexels(x, y, w, h);
}
public void setNative(IntBuffer buffer, int x, int y, int w, int h) {
setNative(buffer, 0, x, y, w, h);
}
public void setNative(IntBuffer buffer, int level, int x, int y, int w, int h) {
bind();
pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer);
unbind();
updateTexels(x, y, w, h);
}
////////////////////////////////////////////////////////////
// Get methods
@@ -425,14 +465,24 @@ public class Texture implements PConstants {
public void put(Texture tex) {
copyTexels(tex, 0, 0, tex.width, tex.height, false);
copyTexture(tex, 0, 0, tex.width, tex.height, false);
}
public void put(Texture tex, int x, int y, int w, int h) {
copyTexels(tex, x, y, w, h, false);
copyTexture(tex, x, y, w, h, false);
}
public void put(int texTarget, int texName, int texWidth, int texHeight, int w, int h) {
copyTexture(texTarget, texName, texWidth, texHeight, 0, 0, w, h, false);
}
public void put(int texTarget, int texName, int texWidth, int texHeight, int target, int tex, int x, int y, int w, int h) {
copyTexture(texTarget, texName, texWidth, texHeight, x, y, w, h, false);
}
////////////////////////////////////////////////////////////
@@ -505,18 +555,29 @@ public class Texture implements PConstants {
// Bind/unbind
public void bind() {
pgl.enableTexturing(glTarget);
pgl.glBindTexture(glTarget, glName);
public void bind() {
if (!bound) {
pgl.enableTexturing(glTarget);
pgl.glBindTexture(glTarget, glName);
bound = true;
}
}
public void unbind() {
pgl.enableTexturing(glTarget);
pgl.glBindTexture(glTarget, 0);
if (bound) {
pgl.enableTexturing(glTarget);
pgl.glBindTexture(glTarget, 0);
bound = false;
}
}
public boolean bound() {
return bound;
}
//////////////////////////////////////////////////////////////
// Modified flag
@@ -636,7 +697,7 @@ public class Texture implements PConstants {
try {
data = bufferCache.remove(0);
} catch (NoSuchElementException ex) {
PGraphics.showWarning("PTexture: don't have pixel data to copy to texture");
PGraphics.showWarning("Don't have pixel data to copy to texture");
}
if (data != null) {
@@ -644,7 +705,7 @@ public class Texture implements PConstants {
init(data.w, data.h);
}
bind();
setTexels(data.rgbBuf, 0, 0, width, height);
setNative(data.rgbBuf, 0, 0, width, height);
unbind();
data.dispose();
@@ -661,7 +722,7 @@ public class Texture implements PConstants {
try {
data = bufferCache.remove(0);
} catch (NoSuchElementException ex) {
PGraphics.showWarning("PTexture: don't have pixel data to copy to texture");
PGraphics.showWarning("Don't have pixel data to copy to texture");
}
if (data != null) {
@@ -669,7 +730,7 @@ public class Texture implements PConstants {
init(data.w, data.h);
}
bind();
setTexels(data.rgbBuf, 0, 0, width, height);
setNative(data.rgbBuf, 0, 0, width, height);
unbind();
data.rgbBuf.get(pixels);
@@ -688,7 +749,7 @@ public class Texture implements PConstants {
try {
disposeBufferMethod = bufferSource.getClass().getMethod("disposeBuffer", new Class[] { Object.class });
} catch (Exception e) {
throw new RuntimeException("PTexture: provided source object doesn't have a disposeBuffer method.");
throw new RuntimeException("Provided source object doesn't have a disposeBuffer method.");
}
}
@@ -974,10 +1035,10 @@ public class Texture implements PConstants {
glName = pg.createTextureObject(context.code());
pgl.glBindTexture(glTarget, glName);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MIN_FILTER, glMinFilter);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MAG_FILTER, glMagFilter);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_S, glWrapS);
pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_T, glWrapT);
pgl.glTexParameteri(glTarget, PGL.GL_TEXTURE_MIN_FILTER, glMinFilter);
pgl.glTexParameteri(glTarget, PGL.GL_TEXTURE_MAG_FILTER, glMagFilter);
pgl.glTexParameteri(glTarget, PGL.GL_TEXTURE_WRAP_S, glWrapS);
pgl.glTexParameteri(glTarget, PGL.GL_TEXTURE_WRAP_T, glWrapT);
// First, we use glTexImage2D to set the full size of the texture (glW/glH might be diff
// from w/h in the case that the GPU doesn't support NPOT textures)
@@ -988,6 +1049,7 @@ public class Texture implements PConstants {
pgl.glBindTexture(glTarget, 0);
pgl.disableTexturing(glTarget);
bound = false;
}
@@ -1024,9 +1086,9 @@ public class Texture implements PConstants {
// Copies source texture tex into this.
protected void copyTexels(Texture tex, int x, int y, int w, int h, boolean scale) {
protected void copyTexture(Texture tex, int x, int y, int w, int h, boolean scale) {
if (tex == null) {
throw new RuntimeException("PTexture: source texture is null");
throw new RuntimeException("Source texture is null");
}
if (tempFbo == null) {
@@ -1044,39 +1106,48 @@ public class Texture implements PConstants {
// Rendering tex into "this", and scaling the source rectangle
// to cover the entire destination region.
pgl.drawTexture(tex.glTarget, tex.glName, tex.glWidth, tex.glHeight,
x, y, w, h, 0, 0, width, height);
x, y, w, h, 0, 0, width, height);
} else {
// Rendering tex into "this" but without scaling so the contents
// of the source texture fall in the corresponding texels of the
// destination.
pgl.drawTexture(tex.glTarget, tex.glName, tex.glWidth, tex.glHeight,
x, y, w, h, x, y, w, h);
x, y, w, h, x, y, w, h);
}
pg.popFramebuffer();
updateTexels(x, y, w, h);
}
protected void setTexels(int[] pix, int x, int y, int w, int h) {
setTexels(pix, 0, x, y, w, h);
}
protected void setTexels(int[] pix, int level, int x, int y, int w, int h) {
pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, IntBuffer.wrap(pix));
updateTexels(x, y, w, h);
}
protected void setTexels(IntBuffer buffer, int x, int y, int w, int h) {
setTexels(buffer, 0, x, y, w, h);
}
protected void setTexels(IntBuffer buffer, int level, int x, int y, int w, int h) {
pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer);
updateTexels(x, y, w, h);
// Copies source texture tex into this.
protected void copyTexture(int texTarget, int texName, int texWidth, int texHeight, int x, int y, int w, int h, boolean scale) {
if (tempFbo == null) {
tempFbo = new FrameBuffer(parent, glWidth, glHeight);
}
// This texture is the color (destination) buffer of the FBO.
tempFbo.setColorBuffer(this);
tempFbo.disableDepthTest();
// FBO copy:
pg.pushFramebuffer();
pg.setFramebuffer(tempFbo);
if (scale) {
// Rendering tex into "this", and scaling the source rectangle
// to cover the entire destination region.
pgl.drawTexture(texTarget, texName, texWidth, texHeight,
x, y, w, h, 0, 0, width, height);
} else {
// Rendering tex into "this" but without scaling so the contents
// of the source texture fall in the corresponding texels of the
// destination.
pgl.drawTexture(texTarget, texName, texWidth, texHeight,
x, y, w, h, x, y, w, h);
}
pg.popFramebuffer();
updateTexels(x, y, w, h);
}