save/restore onscreen surface

This commit is contained in:
codeanticode
2012-04-23 20:14:40 +00:00
parent 9afac62a0b
commit f8922cf5d8
2 changed files with 99 additions and 49 deletions
@@ -343,6 +343,7 @@ public class PGL {
protected int texShaderProgram;
protected int texVertShader;
protected int texFragShader;
protected GLContext texShaderContext;
protected int texVertLoc;
protected int texTCoordLoc;
@@ -379,6 +380,7 @@ public class PGL {
protected int rectShaderProgram;
protected int rectVertShader;
protected int rectFragShader;
protected GLContext rectShaderContext;
protected int rectVertLoc;
protected int rectColorLoc;
@@ -1288,7 +1290,7 @@ public class PGL {
public void drawTexture(int target, int id, int width, int height,
int texX0, int texY0, int texX1, int texY1,
int scrX0, int scrY0, int scrX1, int scrY1) {
if (!loadedTexShader) {
if (!loadedTexShader || texShaderContext.hashCode() != context.hashCode()) {
texVertShader = createShader(GL_VERTEX_SHADER, texVertShaderSource);
texFragShader = createShader(GL_FRAGMENT_SHADER, texFragShaderSource);
if (0 < texVertShader && 0 < texFragShader) {
@@ -1300,8 +1302,9 @@ public class PGL {
}
texData = ByteBuffer.allocateDirect(texCoords.length * SIZEOF_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
loadedTexShader = true;
texShaderContext = context;
}
if (0 < texShaderProgram) {
// When drawing the texture we don't write to the
// depth mask, so the texture remains in the background
@@ -1311,9 +1314,9 @@ public class PGL {
glGetBooleanv(GL_DEPTH_WRITEMASK, val, 0);
boolean writeMask = val[0];
glDepthMask(false);
glUseProgram(texShaderProgram);
glEnableVertexAttribArray(texVertLoc);
glEnableVertexAttribArray(texTCoordLoc);
@@ -1346,18 +1349,18 @@ public class PGL {
texData.rewind();
texData.put(texCoords);
enableTexturing(target);
glActiveTexture(GL_TEXTURE0);
glBindTexture(target, id);
texData.position(0);
glVertexAttribPointer(texVertLoc, 2, GL_FLOAT, false, 4 * SIZEOF_FLOAT, texData);
texData.position(2);
glVertexAttribPointer(texTCoordLoc, 2, GL_FLOAT, false, 4 * SIZEOF_FLOAT, texData);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindTexture(target, 0);
disableTexturing(target);
@@ -1373,7 +1376,7 @@ public class PGL {
public void drawRectangle(float r, float g, float b, float a,
int scrX0, int scrY0, int scrX1, int scrY1) {
if (!loadedRectShader) {
if (!loadedRectShader || rectShaderContext.hashCode() != context.hashCode()) {
rectVertShader = createShader(GL_VERTEX_SHADER, rectVertShaderSource);
rectFragShader = createShader(GL_FRAGMENT_SHADER, rectFragShaderSource);
if (0 < rectVertShader && 0 < rectFragShader) {
@@ -1385,6 +1388,7 @@ public class PGL {
}
rectData = ByteBuffer.allocateDirect(rectCoords.length * SIZEOF_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
loadedRectShader = true;
rectShaderContext = context;
}
if (0 < rectShaderProgram) {
@@ -41,8 +41,6 @@ import java.util.Set;
import java.util.Stack;
// TODO:
// 0) Make sure to delete finalized resources.
// 1) fix get/set pixels, doesn't seem to work.
// 2) non-interactive mode problem?
/**
@@ -88,21 +86,21 @@ public class PGraphicsOpenGL extends PGraphics {
public int glFillEmissiveBufferID;
public int glFillShininessBufferID;
public int glFillIndexBufferID;
protected boolean fillVBOsCreated = false;
protected boolean fillBuffersCreated = false;
protected PGL.Context fillBuffersContext;
public int glLineVertexBufferID;
public int glLineColorBufferID;
public int glLineDirWidthBufferID;
public int glLineIndexBufferID;
protected boolean lineVBOsCreated = false;
protected boolean lineBuffersCreated = false;
protected PGL.Context lineBuffersContext;
public int glPointVertexBufferID;
public int glPointColorBufferID;
public int glPointSizeBufferID;
public int glPointIndexBufferID;
protected boolean pointVBOsCreated = false;
protected boolean pointBuffersCreated = false;
protected PGL.Context pointBuffersContext;
// ........................................................
@@ -350,6 +348,9 @@ public class PGraphicsOpenGL extends PGraphics {
/** True if we are inside a beginDraw()/endDraw() block. */
protected boolean drawing = false;
/** Used to indicate an OpenGL surface recreation */
protected boolean restoreSurface = false;
/** Type of pixels operation. */
static protected final int OP_NONE = 0;
static protected final int OP_READ = 1;
@@ -1026,7 +1027,7 @@ public class PGraphicsOpenGL extends PGraphics {
protected void createFillBuffers() {
if (!fillVBOsCreated || fillBuffersContextIsOutdated()) {
if (!fillBuffersCreated || fillBuffersContextIsOutdated()) {
fillBuffersContext = pgl.getContext();
int sizef = PGL.MAX_TESS_VERTICES * PGL.SIZEOF_FLOAT;
@@ -1073,7 +1074,7 @@ public class PGraphicsOpenGL extends PGraphics {
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0);
fillVBOsCreated = true;
fillBuffersCreated = true;
}
}
@@ -1132,7 +1133,7 @@ public class PGraphicsOpenGL extends PGraphics {
protected void deleteFillBuffers() {
if (fillVBOsCreated) {
if (fillBuffersCreated) {
deleteVertexBufferObject(glFillVertexBufferID);
glFillVertexBufferID = 0;
@@ -1160,13 +1161,13 @@ public class PGraphicsOpenGL extends PGraphics {
deleteVertexBufferObject(glFillIndexBufferID);
glFillIndexBufferID = 0;
fillVBOsCreated = false;
fillBuffersCreated = false;
}
}
protected void createLineBuffers() {
if (!lineVBOsCreated || lineBufferContextIsOutdated()) {
if (!lineBuffersCreated || lineBufferContextIsOutdated()) {
lineBuffersContext = pgl.getContext();
int sizef = PGL.MAX_TESS_VERTICES * PGL.SIZEOF_FLOAT;
@@ -1194,7 +1195,7 @@ public class PGraphicsOpenGL extends PGraphics {
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0);
lineVBOsCreated = true;
lineBuffersCreated = true;
}
}
@@ -1233,7 +1234,7 @@ public class PGraphicsOpenGL extends PGraphics {
protected void deleteLineBuffers() {
if (lineVBOsCreated) {
if (lineBuffersCreated) {
deleteVertexBufferObject(glLineVertexBufferID);
glLineVertexBufferID = 0;
@@ -1246,13 +1247,13 @@ public class PGraphicsOpenGL extends PGraphics {
deleteVertexBufferObject(glLineIndexBufferID);
glLineIndexBufferID = 0;
lineVBOsCreated = false;
lineBuffersCreated = false;
}
}
protected void createPointBuffers() {
if (!pointVBOsCreated || pointBuffersContextIsOutdated()) {
if (!pointBuffersCreated || pointBuffersContextIsOutdated()) {
pointBuffersContext = pgl.getContext();
int sizef = PGL.MAX_TESS_VERTICES * PGL.SIZEOF_FLOAT;
@@ -1279,7 +1280,7 @@ public class PGraphicsOpenGL extends PGraphics {
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0);
pointVBOsCreated = true;
pointBuffersCreated = true;
}
}
@@ -1318,7 +1319,7 @@ public class PGraphicsOpenGL extends PGraphics {
protected void deletePointBuffers() {
if (pointVBOsCreated) {
if (pointBuffersCreated) {
deleteVertexBufferObject(glPointVertexBufferID);
glPointVertexBufferID = 0;
@@ -1331,7 +1332,7 @@ public class PGraphicsOpenGL extends PGraphics {
deleteVertexBufferObject(glPointIndexBufferID);
glPointIndexBufferID = 0;
pointVBOsCreated = false;
pointBuffersCreated = false;
}
}
@@ -1509,6 +1510,11 @@ public class PGraphicsOpenGL extends PGraphics {
if (primarySurface) {
pgl.beginOnscreenDraw(clearColorBuffer);
if (restoreSurface) {
restoreSurfaceFromPixels();
restoreSurface = false;
}
} else {
pgl.beginOffscreenDraw(pg.clearColorBuffer);
@@ -1534,7 +1540,7 @@ public class PGraphicsOpenGL extends PGraphics {
report("bot beginDraw()");
}
public void endDraw() {
report("top endDraw()");
@@ -1555,6 +1561,15 @@ public class PGraphicsOpenGL extends PGraphics {
if (primarySurface) {
pgl.endOnscreenDraw(clearColorBuffer0);
if (!pgl.initialized) {
// Smooth was called at some point during drawing. We save
// the current contents of the back buffer (because the
// buffers haven't been swapped yet) to the pixels array.
saveSurfaceToPixels();
restoreSurface = true;
}
pgl.glFlush();
} else {
if (offscreenMultisample) {
@@ -1627,8 +1642,10 @@ public class PGraphicsOpenGL extends PGraphics {
protected void beginPixelsOp(int op) {
if (primarySurface) {
// We read or write from the back buffer, where all the
// drawing in the current frame is taking place.
if (op == OP_READ) {
pgl.glReadBuffer(PGL.GL_FRONT);
pgl.glReadBuffer(PGL.GL_BACK);
} else {
pgl.glDrawBuffer(PGL.GL_BACK);
}
@@ -2418,6 +2435,8 @@ public class PGraphicsOpenGL extends PGraphics {
endPixelsOp();
}
report("here");
modified = false;
}
@@ -2495,9 +2514,9 @@ public class PGraphicsOpenGL extends PGraphics {
// Utility function to render current tessellated geometry, under the assumption that
// the texture is already bound.
protected void renderTexFill(PTexture tex) {
if (!fillVBOsCreated) {
if (!fillBuffersCreated) {
createFillBuffers();
fillVBOsCreated = true;
fillBuffersCreated = true;
}
updateFillBuffers(lights, true);
@@ -2846,8 +2865,6 @@ public class PGraphicsOpenGL extends PGraphics {
// requestDraw() is called.
pgl.initialized = false;
}
PApplet.println("setting smooth at " + level);
}
@@ -4475,18 +4492,10 @@ public class PGraphicsOpenGL extends PGraphics {
flush();
}
if ((pixels == null) || (pixels.length != width * height)) {
pixels = new int[width * height];
pixelBuffer = IntBuffer.wrap(pixels);
}
allocatePixels();
if (!setgetPixels) {
beginPixelsOp(OP_READ);
pixelBuffer.rewind();
pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
endPixelsOp();
PGL.nativeToJavaARGB(pixels, width, height);
readPixels();
if (primarySurface) {
loadTextureImpl(POINT);
@@ -4589,8 +4598,45 @@ public class PGraphicsOpenGL extends PGraphics {
protected void textureToPixels() {
texture.get(pixels);
}
protected void saveSurfaceToPixels() {
if (primarySurface) {
allocatePixels();
readPixels();
}
}
protected void restoreSurfaceFromPixels() {
if (primarySurface) {
loadTextureImpl(POINT);
pixelsToTexture();
beginPixelsOp(OP_WRITE);
drawTexture();
endPixelsOp();
}
}
protected void allocatePixels() {
if ((pixels == null) || (pixels.length != width * height)) {
pixels = new int[width * height];
pixelBuffer = IntBuffer.wrap(pixels);
}
}
protected void readPixels() {
beginPixelsOp(OP_READ);
pixelBuffer.rewind();
pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
endPixelsOp();
PGL.nativeToJavaARGB(pixels, width, height);
}
//////////////////////////////////////////////////////////////
// IMAGE CONVERSION
@@ -5153,7 +5199,7 @@ public class PGraphicsOpenGL extends PGraphics {
if (defFillShaderFull == null || defFillShaderFull.contextIsOutdated()) {
defFillShaderFull = new FillShaderFull(parent, defFillShaderVertFullURL, defFillShaderFragTexURL);
}
if (fillShaderFull == null) {
if (fillShaderFull == null || fillShaderFull.contextIsOutdated()) {
fillShaderFull = defFillShaderFull;
}
shader = fillShaderFull;
@@ -5161,7 +5207,7 @@ public class PGraphicsOpenGL extends PGraphics {
if (defFillShaderLit == null || defFillShaderLit.contextIsOutdated()) {
defFillShaderLit = new FillShaderLit(parent, defFillShaderVertLitURL, defFillShaderFragNoTexURL);
}
if (fillShaderLit == null) {
if (fillShaderLit == null || fillShaderLit.contextIsOutdated()) {
fillShaderLit = defFillShaderLit;
}
shader = fillShaderLit;
@@ -5171,7 +5217,7 @@ public class PGraphicsOpenGL extends PGraphics {
if (defFillShaderTex == null || defFillShaderTex.contextIsOutdated()) {
defFillShaderTex = new FillShaderTex(parent, defFillShaderVertTexURL, defFillShaderFragTexURL);
}
if (fillShaderTex == null) {
if (fillShaderTex == null || fillShaderTex.contextIsOutdated()) {
fillShaderTex = defFillShaderTex;
}
shader = fillShaderTex;
@@ -5179,7 +5225,7 @@ public class PGraphicsOpenGL extends PGraphics {
if (defFillShaderSimple == null || defFillShaderSimple.contextIsOutdated()) {
defFillShaderSimple = new FillShaderSimple(parent, defFillShaderVertSimpleURL, defFillShaderFragNoTexURL);
}
if (fillShaderSimple == null) {
if (fillShaderSimple == null || fillShaderSimple.contextIsOutdated()) {
fillShaderSimple = defFillShaderSimple;
}
shader = fillShaderSimple;
@@ -5196,7 +5242,7 @@ public class PGraphicsOpenGL extends PGraphics {
if (defLineShader == null || defLineShader.contextIsOutdated()) {
defLineShader = new LineShader(parent, defLineShaderVertURL, defLineShaderFragURL);
}
if (lineShader == null) {
if (lineShader == null || lineShader.contextIsOutdated()) {
lineShader = defLineShader;
}
lineShader.setRenderer(this);
@@ -5210,7 +5256,7 @@ public class PGraphicsOpenGL extends PGraphics {
if (defPointShader == null || defPointShader.contextIsOutdated()) {
defPointShader = new PointShader(parent, defPointShaderVertURL, defPointShaderFragURL);
}
if (pointShader == null) {
if (pointShader == null || pointShader.contextIsOutdated()) {
pointShader = defPointShader;
}
pointShader.setRenderer(this);