Some cleanup

This commit is contained in:
codeanticode
2012-03-20 21:15:20 +00:00
parent aff8f10446
commit eea9814d03
5 changed files with 108 additions and 206 deletions
@@ -21,8 +21,6 @@
uniform sampler2D textureSampler;
uniform vec2 texcoordOffset;
varying vec4 vertColor;
varying vec4 vertTexcoord;
@@ -64,10 +64,8 @@ public class PFramebuffer implements PConstants {
protected PTexture[] colorBufferTex;
protected boolean screenFb;
protected boolean noDepth;
protected boolean fboMode;
protected boolean noDepth;
protected PTexture backupTexture;
protected IntBuffer pixelBuffer;
PFramebuffer(PApplet parent, int w, int h) {
@@ -90,8 +88,6 @@ public class PFramebuffer implements PConstants {
glStencilBufferID = 0;
glDepthStencilBufferID = 0;
glColorBufferMultisampleID = 0;
fboMode = PGraphicsOpenGL.fboSupported;
if (screen) {
// If this framebuffer is used to represent a on-screen buffer,
@@ -141,14 +137,6 @@ public class PFramebuffer implements PConstants {
noDepth = false;
pixelBuffer = null;
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, POINT));
}
}
@@ -191,27 +179,10 @@ public class PFramebuffer implements PConstants {
}
public void bind() {
// if context is outdated ??
if (screenFb) {
if (PGraphicsOpenGL.fboSupported) {
pgl.glBindFramebuffer(PGL.GL_FRAMEBUFFER, 0);
}
} else if (fboMode) {
pgl.glBindFramebuffer(PGL.GL_FRAMEBUFFER, glFboID);
} else {
backupScreen();
if (0 < numColorBuffers) {
// Drawing the current contents of the first color buffer to emulate
// front-back buffer swap.
pg.drawTexture(colorBufferTex[0].glTarget, colorBufferTex[0].glID, width, height, 0, 0, width, height, 0, 0, width, height);
}
if (noDepth) {
pgl.glDisable(PGL.GL_DEPTH_TEST);
}
pgl.glBindFramebuffer(PGL.GL_FRAMEBUFFER, glFboID);
}
}
@@ -228,46 +199,7 @@ public class PFramebuffer implements PConstants {
pgl.glEnable(PGL.GL_DEPTH_TEST);
}
}
if (!screenFb && !fboMode) {
copyToColorBuffers();
restoreBackup();
if (!noDepth) {
// Reading the contents of the depth buffer is not possible in OpenGL ES:
// http://www.idevgames.com/forum/archive/index.php?t-15828.html
// so if this framebuffer uses depth and is offscreen with no FBOs, then
// the depth buffer is cleared to avoid artifacts when rendering more stuff
// after this offscreen render.
// A consequence of this behavior is that all the offscreen rendering when
// no FBOs are available should be done before any onscreen drawing.
pgl.glClearColor(0, 0, 0, 0);
pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT);
}
}
}
// Saves content of the screen into the backup texture.
public void backupScreen() {
if (pixelBuffer == null) createPixelBuffer();
pixelBuffer.rewind();
pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
copyToTexture(pixelBuffer, backupTexture.glID, backupTexture.glTarget);
}
// Draws the contents of the backup texture to the screen.
public void restoreBackup() {
pg.drawTexture(backupTexture, 0, 0, width, height, 0, 0, width, height);
}
// Copies current content of screen to color buffers.
public void copyToColorBuffers() {
if (pixelBuffer == null) createPixelBuffer();
pixelBuffer.rewind();
pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
for (int i = 0; i < numColorBuffers; i++) {
copyToTexture(pixelBuffer, colorBufferTex[i].glID, colorBufferTex[i].glTarget);
}
}
public void readPixels() {
if (pixelBuffer == null) createPixelBuffer();
@@ -320,23 +252,21 @@ public class PFramebuffer implements PConstants {
colorBufferTex[i] = textures[i];
}
if (fboMode) {
pg.pushFramebuffer();
pg.setFramebuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(this);
// Making sure nothing is attached.
for (int i = 0; i < numColorBuffers; i++) {
pgl.glFramebufferTexture2D(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, PGL.GL_TEXTURE_2D, 0, 0);
}
for (int i = 0; i < numColorBuffers; i++) {
pgl.glFramebufferTexture2D(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, colorBufferTex[i].glTarget, colorBufferTex[i].glID, 0);
}
validateFbo();
pg.popFramebuffer();
// Making sure nothing is attached.
for (int i = 0; i < numColorBuffers; i++) {
pgl.glFramebufferTexture2D(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, PGL.GL_TEXTURE_2D, 0, 0);
}
for (int i = 0; i < numColorBuffers; i++) {
pgl.glFramebufferTexture2D(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, colorBufferTex[i].glTarget, colorBufferTex[i].glID, 0);
}
validateFbo();
pg.popFramebuffer();
}
@@ -352,10 +282,8 @@ public class PFramebuffer implements PConstants {
if (screenFb) {
glFboID = 0;
} else if (fboMode) {
} else {
glFboID = pg.createFrameBufferObject();
} else {
glFboID = 0;
}
// create the rest of the stuff...
@@ -412,8 +340,6 @@ public class PFramebuffer implements PConstants {
for (int i = 0; i < numColorBuffers; i++) {
colorBufferTex[i] = null;
}
backupTexture = null;
}
return outdated;
}
@@ -422,17 +348,15 @@ public class PFramebuffer implements PConstants {
protected void createColorBufferMultisample() {
if (screenFb) return;
if (fboMode) {
pg.pushFramebuffer();
pg.setFramebuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(this);
glColorBufferMultisampleID = pg.createRenderBufferObject();
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glColorBufferMultisampleID);
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, PGL.GL_RGBA8, width, height);
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0, PGL.GL_RENDERBUFFER, glColorBufferMultisampleID);
pg.popFramebuffer();
}
glColorBufferMultisampleID = pg.createRenderBufferObject();
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glColorBufferMultisampleID);
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, PGL.GL_RGBA8, width, height);
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0, PGL.GL_RENDERBUFFER, glColorBufferMultisampleID);
pg.popFramebuffer();
}
@@ -443,24 +367,22 @@ public class PFramebuffer implements PConstants {
throw new RuntimeException("PFramebuffer: size undefined.");
}
if (fboMode) {
pg.pushFramebuffer();
pg.setFramebuffer(this);
glDepthStencilBufferID = pg.createRenderBufferObject();
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthStencilBufferID);
if (multisample) {
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, PGL.GL_DEPTH24_STENCIL8, width, height);
} else {
pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, PGL.GL_DEPTH24_STENCIL8, width, height);
}
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID);
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID);
pg.popFramebuffer();
}
pg.pushFramebuffer();
pg.setFramebuffer(this);
glDepthStencilBufferID = pg.createRenderBufferObject();
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthStencilBufferID);
if (multisample) {
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, PGL.GL_DEPTH24_STENCIL8, width, height);
} else {
pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, PGL.GL_DEPTH24_STENCIL8, width, height);
}
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID);
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID);
pg.popFramebuffer();
}
@@ -471,32 +393,30 @@ public class PFramebuffer implements PConstants {
throw new RuntimeException("PFramebuffer: size undefined.");
}
if (fboMode) {
pg.pushFramebuffer();
pg.setFramebuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(this);
glDepthBufferID = pg.createRenderBufferObject();
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthBufferID);
glDepthBufferID = pg.createRenderBufferObject();
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthBufferID);
int glConst = PGL.GL_DEPTH_COMPONENT16;
if (depthBits == 16) {
glConst = PGL.GL_DEPTH_COMPONENT16;
} else if (depthBits == 24) {
glConst = PGL.GL_DEPTH_COMPONENT24;
} else if (depthBits == 32) {
glConst = PGL.GL_DEPTH_COMPONENT32;
}
if (multisample) {
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height);
} else {
pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height);
}
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthBufferID);
pg.popFramebuffer();
int glConst = PGL.GL_DEPTH_COMPONENT16;
if (depthBits == 16) {
glConst = PGL.GL_DEPTH_COMPONENT16;
} else if (depthBits == 24) {
glConst = PGL.GL_DEPTH_COMPONENT24;
} else if (depthBits == 32) {
glConst = PGL.GL_DEPTH_COMPONENT32;
}
if (multisample) {
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height);
} else {
pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height);
}
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthBufferID);
pg.popFramebuffer();
}
@@ -507,31 +427,29 @@ public class PFramebuffer implements PConstants {
throw new RuntimeException("PFramebuffer: size undefined.");
}
if (fboMode) {
pg.pushFramebuffer();
pg.setFramebuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(this);
glStencilBufferID = pg.createRenderBufferObject();
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glStencilBufferID);
glStencilBufferID = pg.createRenderBufferObject();
pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glStencilBufferID);
int glConst = PGL.GL_STENCIL_INDEX1;
if (stencilBits == 1) {
glConst = PGL.GL_STENCIL_INDEX1;
} else if (stencilBits == 4) {
glConst = PGL.GL_STENCIL_INDEX4;
} else if (stencilBits == 8) {
glConst = PGL.GL_STENCIL_INDEX8;
}
if (multisample) {
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height);
} else {
pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height);
}
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glStencilBufferID);
pg.popFramebuffer();
int glConst = PGL.GL_STENCIL_INDEX1;
if (stencilBits == 1) {
glConst = PGL.GL_STENCIL_INDEX1;
} else if (stencilBits == 4) {
glConst = PGL.GL_STENCIL_INDEX4;
} else if (stencilBits == 8) {
glConst = PGL.GL_STENCIL_INDEX8;
}
if (multisample) {
pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height);
} else {
pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height);
}
pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glStencilBufferID);
pg.popFramebuffer();
}
@@ -98,6 +98,9 @@ public class PGL {
/** Maximum dimension of a texture used to hold font data. **/
public static final int MAX_FONT_TEX_SIZE = 256;
public static int DEFAULT_DEPTH_BITS = 24;
public static int DEFAULT_STENCIL_BITS = 8;
///////////////////////////////////////////////////////////////////////////////////
// OpenGL constants
@@ -1042,6 +1045,16 @@ public class PGL {
}
// bit shifting this might be more efficient
static public int nextPowerOfTwo(int val) {
int ret = 1;
while (ret < val) {
ret <<= 1;
}
return ret;
}
public String getShaderLog(int id) {
IntBuffer val = IntBuffer.allocate(1);
gl2.glGetObjectParameterivARB(id, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, val);
@@ -89,8 +89,6 @@ public class PGraphicsOpenGL extends PGraphics {
/** Extensions used by Processing */
static public boolean npotTexSupported;
static public boolean mipmapGeneration;
static public boolean vboSupported;
static public boolean fboSupported;
static public boolean fboMultisampleSupported;
static public boolean blendEqSupported;
@@ -297,10 +295,6 @@ public class PGraphicsOpenGL extends PGraphics {
protected PFramebuffer offscreenFramebufferMultisample;
protected boolean offscreenMultisample;
/** These are public so they can be changed by advanced users. */
public int offscreenDepthBits = 24;
public int offscreenStencilBits = 8;
// ........................................................
// Utility variables:
@@ -5608,8 +5602,8 @@ public class PGraphicsOpenGL extends PGraphics {
// function used in multisampled (antialiased) offscreen rendering.
if (PGraphicsOpenGL.fboMultisampleSupported && 1 < antialias) {
offscreenFramebufferMultisample = new PFramebuffer(parent, texture.glWidth, texture.glHeight, antialias, 0,
offscreenDepthBits, offscreenStencilBits,
offscreenDepthBits == 24 && offscreenStencilBits == 8, false);
PGL.DEFAULT_DEPTH_BITS, PGL.DEFAULT_STENCIL_BITS,
PGL.DEFAULT_DEPTH_BITS == 24 && PGL.DEFAULT_STENCIL_BITS == 8, false);
offscreenFramebufferMultisample.clear();
offscreenMultisample = true;
@@ -5623,8 +5617,8 @@ public class PGraphicsOpenGL extends PGraphics {
} else {
antialias = 0;
offscreenFramebuffer = new PFramebuffer(parent, texture.glWidth, texture.glHeight, 1, 1,
offscreenDepthBits, offscreenStencilBits,
offscreenDepthBits == 24 && offscreenStencilBits == 8, false);
PGL.DEFAULT_DEPTH_BITS, PGL.DEFAULT_STENCIL_BITS,
PGL.DEFAULT_DEPTH_BITS == 24 && PGL.DEFAULT_STENCIL_BITS == 8, false);
offscreenMultisample = false;
}
@@ -5641,8 +5635,6 @@ public class PGraphicsOpenGL extends PGraphics {
npotTexSupported = -1 < OPENGL_EXTENSIONS.indexOf("texture_non_power_of_two");
mipmapGeneration = -1 < OPENGL_EXTENSIONS.indexOf("generate_mipmap");
vboSupported = -1 < OPENGL_EXTENSIONS.indexOf("vertex_buffer_object");
fboSupported = -1 < OPENGL_EXTENSIONS.indexOf("framebuffer_object");
fboMultisampleSupported = -1 < OPENGL_EXTENSIONS.indexOf("framebuffer_multisample");
try {
@@ -293,23 +293,13 @@ public class PTexture implements PConstants {
tempFbo = new PFramebuffer(parent, glWidth, glHeight);
}
if (PGraphicsOpenGL.fboSupported) {
// Attaching the texture to the color buffer of a FBO, binding the FBO and reading the pixels
// from the current draw buffer (which is the color buffer of the FBO).
tempFbo.setColorBuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(tempFbo);
tempFbo.readPixels();
pg.popFramebuffer();
} else {
// Here we don't have FBOs, so the method above is of no use. What we do instead is
// to draw the texture to the screen framebuffer, and then grab the pixels from there.
pg.pushFramebuffer();
pg.setFramebuffer(tempFbo);
pg.drawTexture(this, 0, 0, glWidth, glHeight, 0, 0, glWidth, glHeight);
tempFbo.readPixels();
pg.popFramebuffer();
}
// Attaching the texture to the color buffer of a FBO, binding the FBO and reading the pixels
// from the current draw buffer (which is the color buffer of the FBO).
tempFbo.setColorBuffer(this);
pg.pushFramebuffer();
pg.setFramebuffer(tempFbo);
tempFbo.readPixels();
pg.popFramebuffer();
if (tempPixels == null) {
tempPixels = new int[size];
@@ -488,16 +478,7 @@ public class PTexture implements PConstants {
////////////////////////////////////////////////////////////
// Utilities
// bit shifting this might be more efficient
protected int nextPowerOfTwo(int val) {
int ret = 1;
while (ret < val) {
ret <<= 1;
}
return ret;
}
/**
* Flips intArray along the X axis.
@@ -745,8 +726,8 @@ public class PTexture implements PConstants {
glWidth = w;
glHeight = h;
} else {
glWidth = nextPowerOfTwo(w);
glHeight = nextPowerOfTwo(h);
glWidth = PGL.nextPowerOfTwo(w);
glHeight = PGL.nextPowerOfTwo(h);
}
if ((glWidth > PGraphicsOpenGL.maxTextureSize) || (glHeight > PGraphicsOpenGL.maxTextureSize)) {