Android OpenGL sync

This commit is contained in:
codeanticode
2012-12-05 23:06:26 +00:00
parent 55c777bfe9
commit 5c64f3f178
9 changed files with 2564 additions and 2482 deletions
@@ -159,14 +159,14 @@ class FontTexture implements PConstants {
currentTex = textures.length - 1;
PImage[] tempImg = images;
images = new PImage[textures.length + 1];
images = new PImage[textures.length];
PApplet.arrayCopy(tempImg, images, tempImg.length);
images[tempImg.length] = pg.wrapTexture(tex);
}
lastTex = currentTex;
// Make sure that the current texture is bound.
//tex.bind();
tex.bind();
return resize;
}
@@ -324,14 +324,6 @@ class FontTexture implements PConstants {
}
}
if (lastTex == -1) {
lastTex = 0;
}
if (currentTex != lastTex || resized) {
currentTex = idx;
}
TextureInfo tinfo = new TextureInfo(currentTex, offsetX, offsetY,
w, h, rgba);
offsetX += w;
@@ -183,12 +183,14 @@ public class FrameBuffer implements PConstants {
pg.popFramebuffer();
}
public void copy(FrameBuffer dest) {
public void copy(FrameBuffer dest, FrameBuffer current) {
pgl.bindFramebuffer(PGL.READ_FRAMEBUFFER, this.glFbo);
pgl.bindFramebuffer(PGL.DRAW_FRAMEBUFFER, dest.glFbo);
pgl.blitFramebuffer(0, 0, this.width, this.height,
0, 0, dest.width, dest.height,
PGL.COLOR_BUFFER_BIT, PGL.NEAREST);
pgl.bindFramebuffer(PGL.READ_FRAMEBUFFER, current.glFbo);
pgl.bindFramebuffer(PGL.DRAW_FRAMEBUFFER, current.glFbo);
}
public void bind() {
@@ -311,6 +313,24 @@ public class FrameBuffer implements PConstants {
}
public int getDefaultReadBuffer() {
if (screenFb) {
return pgl.getDefaultReadBuffer();
} else {
return PGL.COLOR_ATTACHMENT0;
}
}
public int getDefaultDrawBuffer() {
if (screenFb) {
return pgl.getDefaultDrawBuffer();
} else {
return PGL.COLOR_ATTACHMENT0;
}
}
///////////////////////////////////////////////////////////
// Allocate/release framebuffer.
+163 -120
View File
@@ -316,13 +316,13 @@ public class PGL {
protected static final int EGL_OPENGL_ES2_BIT = 0x0004;
/** Basic GLES 1.0 interface */
public GL10 gl;
public static GL10 gl;
/** GLU interface **/
public PGLU glu;
public static PGLU glu;
/** The current opengl context */
static public EGLContext context;
public static EGLContext context;
/** The PGraphics object using this interface */
protected PGraphicsOpenGL pg;
@@ -342,14 +342,13 @@ public class PGL {
///////////////////////////////////////////////////////////
// FBO for incremental drawing
// FBO layer
protected static final boolean FORCE_SCREEN_FBO = false;
protected boolean firstOnscreenFrame = true;
protected boolean usingFBOlayer = false;
protected int[] glColorFbo = { 0 };
protected int[] glColorTex = { 0, 0 };
protected int fboWidth, fboHeight;
protected int backTex, frontTex;
protected int[] glColorTex = { 0, 0 };
protected int[] glColorFbo = { 0 };
///////////////////////////////////////////////////////////
@@ -405,7 +404,9 @@ public class PGL {
public PGL(PGraphicsOpenGL pg) {
this.pg = pg;
renderer = new AndroidRenderer();
glu = new PGLU();
if (glu == null) {
glu = new PGLU();
}
initialized = false;
}
@@ -414,7 +415,7 @@ public class PGL {
}
protected void initPrimarySurface(int antialias) {
protected void initSurface(int antialias) {
// We do the initialization in updatePrimary() because
// at the moment initPrimarySurface() gets called we
// cannot rely on the GL surface being actually
@@ -422,12 +423,7 @@ public class PGL {
}
protected void initOffscreenSurface(PGL primary) {
initialized = true;
}
protected void updatePrimary() {
protected void update() {
if (!initialized) {
String ext = GLES20.glGetString(GLES20.GL_EXTENSIONS);
if (-1 < ext.indexOf("texture_non_power_of_two")) {
@@ -520,87 +516,139 @@ public class PGL {
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
PGraphicsOpenGL.screenFramebuffer.glFbo = 0;
PGraphicsOpenGL.drawFramebuffer.glFbo = 0;
// Use this instead for the new code to be implemented later...
// PGraphicsOpenGL.screenFramebuffer.glFbo = glColorFbo[0];
backTex = 1;
frontTex = 0;
backTex = 0;
frontTex = 1;
initialized = true;
}
}
protected void updateOffscreen(PGL primary) {
gl = primary.gl;
}
protected int primaryDrawBuffer() {
if (PGraphicsOpenGL.screenFramebuffer.glFbo != 0) {
return GLES20.GL_BACK;
protected int getReadFramebuffer() {
if (usingFBOlayer) {
return glColorFbo[0];
} else {
return GLES20.GL_COLOR_ATTACHMENT0;
return 0;
}
}
/*
protected boolean primaryIsDoubleBuffered() {
return PGraphicsOpenGL.screenFramebuffer.glFbo != 0;
}
*/
protected boolean primaryIsFboBacked() {
return PGraphicsOpenGL.screenFramebuffer.glFbo != 0;
protected int getDrawFramebuffer() {
if (usingFBOlayer) {
return glColorFbo[0];
} else {
return 0;
}
}
protected int getFboTexTarget() {
return GLES20.GL_TEXTURE_2D;
}
protected int getFboTexName() {
return glColorTex[0];
}
protected int getFboWidth() {
return fboWidth;
protected int getDefaultDrawBuffer() {
if (usingFBOlayer) {
return GLES20.GL_COLOR_ATTACHMENT0;
} else {
return GLES20.GL_BACK;
}
}
protected int getFboHeight() {
return fboHeight;
}
protected void bindPrimaryColorFBO() {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, glColorFbo[0]);
PGraphicsOpenGL.screenFramebuffer.glFbo = glColorFbo[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);
protected int getDefaultReadBuffer() {
if (usingFBOlayer) {
return GLES20.GL_COLOR_ATTACHMENT0;
} else {
return GLES20.GL_FRONT;
}
}
protected void bindPrimaryMultiFBO() {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, glColorFbo[0]);
PGraphicsOpenGL.screenFramebuffer.glFbo = glColorFbo[0];
protected boolean isFBOBacked() {
return usingFBOlayer;
}
protected void bindBackBufferTex() {
protected boolean isMultisampled() {
return false;
}
protected void unbindBackBufferTex() {
protected int getDepthBits() {
int[] temp = {0};
GLES20.glGetIntegerv(GLES20.GL_DEPTH_BITS, temp, 0);
return temp[0];
}
protected int getStencilBits() {
int[] temp = {0};
GLES20.glGetIntegerv(GLES20.GL_STENCIL_BITS, temp, 0);
return temp[0];
}
protected Texture wrapBackTexture() {
Texture tex = new Texture(pg.parent);
tex.init(glColorTex[backTex],
GLES20.GL_TEXTURE_2D, GLES20.GL_RGBA,
fboWidth, fboHeight,
GLES20.GL_NEAREST, GLES20.GL_NEAREST,
GLES20.GL_CLAMP_TO_EDGE, GLES20.GL_CLAMP_TO_EDGE);
tex.invertedY(true);
tex.colorBufferOf(pg);
pg.setCache(pg, tex);
return tex;
}
protected Texture wrapFrontTexture() {
Texture tex = new Texture(pg.parent);
tex.init(glColorTex[frontTex],
GLES20.GL_TEXTURE_2D, GLES20.GL_RGBA,
fboWidth, fboHeight,
GLES20.GL_NEAREST, GLES20.GL_NEAREST,
GLES20.GL_CLAMP_TO_EDGE, GLES20.GL_CLAMP_TO_EDGE);
tex.invertedY(true);
tex.colorBufferOf(pg);
return tex;
}
int getBackTextureName() {
return glColorTex[backTex];
}
int getFrontTextureName() {
return glColorTex[frontTex];
}
protected void bindFrontTexture() {
if (!texturingIsEnabled(GLES20.GL_TEXTURE_2D)) {
enableTexturing(GLES20.GL_TEXTURE_2D);
}
gl.glBindTexture(GLES20.GL_TEXTURE_2D, glColorTex[frontTex]);
}
protected void unbindFrontTexture() {
if (textureIsBound(GLES20.GL_TEXTURE_2D, glColorTex[frontTex])) {
// We don't want to unbind another texture
// that might be bound instead of this one.
if (!texturingIsEnabled(GLES20.GL_TEXTURE_2D)) {
enableTexturing(GLES20.GL_TEXTURE_2D);
gl.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
disableTexturing(GLES20.GL_TEXTURE_2D);
} else {
gl.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
}
}
}
protected void syncBackTexture() {
// Nothing to do because there is no MSAA in GLES20
}
@@ -609,27 +657,29 @@ public class PGL {
// Frame rendering
protected void beginOnscreenDraw(boolean clear) {
// TODO: enable this implementation later (solves the flickering problem):
/*
if (glColorFbo[0] != 0) {
protected void beginDraw(boolean clear0) {
if (!clear0 && glColorFbo[0] != 0) {
// Bind the FBO and use the back texture to draw to.
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, glColorFbo[0]);
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D,
glColorTex[frontTex], 0);
PGraphicsOpenGL.screenFramebuffer.glFbo = glColorFbo[0];
glColorTex[backTex], 0);
usingFBOlayer = true;
} else {
usingFBOlayer = false;
}
*/
/*
if (clear && !FORCE_SCREEN_FBO) {
// Simplest scenario: clear mode means we clear both the color and depth
// buffers. No need for saving front color buffer, etc.
GLES20.glClearColor(0, 0, 0, 0);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
PGraphicsOpenGL.screenFramebuffer.glFbo = 0;
PGraphicsOpenGL.drawFramebuffer.glFbo = 0;
} else {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, glColorFbo[0]);
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
@@ -651,69 +701,69 @@ public class PGL {
fboWidth, fboHeight, 0, 0, pg.width, pg.height,
0, 0, pg.width, pg.height);
}
PGraphicsOpenGL.screenFramebuffer.glFbo = glColorFbo[0];
PGraphicsOpenGL.drawFramebuffer.glFbo = glColorFbo[0];
}
if (firstOnscreenFrame) {
firstOnscreenFrame = false;
}
*/
}
protected void endOnscreenDraw(boolean clear0) {
/*
// TODO: enable this implementation later (solves the flickering problem):
if (glColorFbo[0] != 0) {
// We are in the primary surface, and no clear mode, this means that the
// current contents of the front buffer needs to be used in the next frame
// as the background.
protected void endDraw(boolean clear) {
if (usingFBOlayer) {
// Draw the contents of the back texture to the main framebuffer.
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLES20.glClearDepthf(1);
GLES20.glClearColor(0, 0, 0, 0);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Render current front texture to screen, without blending.
// Render current back texture to screen, without blending.
GLES20.glDisable(GLES20.GL_BLEND);
drawTexture(GLES20.GL_TEXTURE_2D, glColorTex[frontTex],
drawTexture(GLES20.GL_TEXTURE_2D, glColorTex[backTex],
fboWidth, fboHeight,
0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, glColorFbo[0]);
// Blitting the front texture into the back texture.
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D,
glColorTex[backTex], 0);
drawTexture(GLES20.GL_TEXTURE_2D, glColorTex[frontTex],
fboWidth, fboHeight,
0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height);
if (!clear) {
// Draw the back texture into the front texture, which will be used as
// back texture in the next frame. Otherwise flickering will occur if
// the sketch uses "incremental drawing" (background() not called).
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D,
glColorTex[frontTex], 0);
drawTexture(GLES20.GL_TEXTURE_2D, glColorTex[backTex],
fboWidth, fboHeight,
0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height);
// Leave the front texture as current
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D,
glColorTex[frontTex], 0);
// Leave the back texture as current
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D,
glColorTex[backTex], 0);
}
// int temp = frontTex;
// frontTex = backTex;
// backTex = temp;
// Swap textures.
int temp = frontTex;
frontTex = backTex;
backTex = temp;
// This is the trick to avoid tre flickering: don't leave the FBO bound!
// This is the trick to avoid the flickering: don't leave the FBO bound!
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
PGraphicsOpenGL.screenFramebuffer.glFbo = 0;
}
*/
/*
if (!clear0 || FORCE_SCREEN_FBO) {
// We are in the primary surface, and no clear mode, this means that the
// current contents of the front buffer needs to be used in the next frame
// as the background.
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
PGraphicsOpenGL.screenFramebuffer.glFbo = 0;
PGraphicsOpenGL.drawFramebuffer.glFbo = 0;
GLES20.glClearDepthf(1);
GLES20.glClearColor(0, 0, 0, 0);
@@ -730,14 +780,7 @@ public class PGL {
frontTex = backTex;
backTex = temp;
}
}
protected void beginOffscreenDraw(boolean clear) {
}
protected void endOffscreenDraw(boolean clear0) {
*/
}
@@ -120,7 +120,7 @@ public class PGraphics2D extends PGraphicsOpenGL {
@Override
protected void defaultPerspective() {
super.ortho(-width/2, +width/2, -height/2, +height/2, -1, +1);
super.ortho(0, width, 0, height, -1, +1);
}
@@ -85,7 +85,7 @@ public class PGraphics3D extends PGraphicsOpenGL {
@Override
protected void begin2D() {
pushProjection();
ortho(-width/2, +width/2, -height/2, +height/2, -1, +1);
ortho(0, width, 0, height, -1, +1);
pushMatrix();
camera(width/2, height/2);
}
File diff suppressed because it is too large Load Diff
+39 -13
View File
@@ -34,6 +34,8 @@ import java.util.HashMap;
* and a fragment shader. Based on the GLSLShader class from GLGraphics, which
* in turn was originally based in the code by JohnG:
* http://processing.org/discourse/beta/num_1159494801.html
*
* @webref rendering:shaders
*/
public class PShader {
// shaders constants
@@ -113,9 +115,9 @@ public class PShader {
* Creates a shader program using the specified vertex and fragment
* shaders.
*
* @param parent PApplet
* @param vertexFN String
* @param fragmentFN String
* @param parent the parent program
* @param vertFilename name of the vertex shader
* @param fragFilename name of the fragment shader
*/
public PShader(PApplet parent, String vertFilename, String fragFilename) {
this.parent = parent;
@@ -132,7 +134,10 @@ public class PShader {
glFragment = 0;
}
/**
* @param vertURL network location of the vertex shader
* @param fragURL network location of the fragment shader
*/
public PShader(PApplet parent, URL vertURL, URL fragURL) {
this.parent = parent;
pgMain = (PGraphicsOpenGL) parent.g;
@@ -216,22 +221,33 @@ public class PShader {
return bound;
}
/**
* @webref rendering:shaders
* @brief Sets a variable within the shader
* @param name the name of the uniform variable to modify
* @param x first component of the variable to modify
*/
public void set(String name, int x) {
setUniformImpl(name, UniformValue.INT1, new int[] { x });
}
/**
* @param y second component of the variable to modify. The variable has to be declared with an array/vector type in the shader (i.e.: int[2], vec2)
*/
public void set(String name, int x, int y) {
setUniformImpl(name, UniformValue.INT2, new int[] { x, y });
}
/**
* @param z third component of the variable to modify. The variable has to be declared with an array/vector type in the shader (i.e.: int[3], vec3)
*/
public void set(String name, int x, int y, int z) {
setUniformImpl(name, UniformValue.INT3, new int[] { x, y, z });
}
/**
* @param w fourth component of the variable to modify. The variable has to be declared with an array/vector type in the shader (i.e.: int[4], vec4)
*/
public void set(String name, int x, int y, int z, int w) {
setUniformImpl(name, UniformValue.INT4, new int[] { x, y, z });
}
@@ -256,7 +272,9 @@ public class PShader {
setUniformImpl(name, UniformValue.FLOAT4, new float[] { x, y, z, w });
}
/**
* @param vec modifies all the components of an array/vector uniform variable. PVector can only be used if the type of the variable is vec3.
*/
public void set(String name, PVector vec) {
setUniformImpl(name, UniformValue.FLOAT3,
new float[] { vec.x, vec.y, vec.z });
@@ -267,7 +285,9 @@ public class PShader {
set(name, vec, 1);
}
/**
* @param ncoords number of coordinates per element, max 4
*/
public void set(String name, int[] vec, int ncoords) {
if (ncoords == 1) {
setUniformImpl(name, UniformValue.INT1VEC, vec);
@@ -308,7 +328,9 @@ public class PShader {
}
}
/**
* @param mat matrix of values
*/
public void set(String name, PMatrix2D mat) {
float[] matv = { mat.m00, mat.m01,
mat.m10, mat.m11 };
@@ -320,7 +342,9 @@ public class PShader {
set(name, mat, false);
}
/**
* @param use3x3 enforces the matrix is 3 x 3
*/
public void set(String name, PMatrix3D mat, boolean use3x3) {
if (use3x3) {
float[] matv = { mat.m00, mat.m01, mat.m02,
@@ -336,7 +360,9 @@ public class PShader {
}
}
/**
* @param tex sets the sampler uniform variable to read from this image texture
*/
public void set(String name, PImage tex) {
setUniformImpl(name, UniformValue.SAMPLER2D, tex);
}
@@ -33,7 +33,7 @@ import processing.core.PShape;
import processing.core.PVector;
import processing.opengl.PGraphicsOpenGL.LineShader;
import processing.opengl.PGraphicsOpenGL.PointShader;
import processing.opengl.PGraphicsOpenGL.PolyShader;
import processing.opengl.PGraphicsOpenGL.BaseShader;
import processing.opengl.PGraphicsOpenGL.IndexCache;
import processing.opengl.PGraphicsOpenGL.InGeometry;
import processing.opengl.PGraphicsOpenGL.TessGeometry;
@@ -350,6 +350,10 @@ public class PShapeOpenGL extends PShape {
normalMode = NORMAL_MODE_AUTO;
// To make sure that the first vertex is marked as a break.
// Same behavior as in the immediate mode.
breakShape = true;
if (family == GROUP) {
// GROUP shapes are always marked as ended.
shapeEnded = true;
@@ -895,6 +899,7 @@ public class PShapeOpenGL extends PShape {
return;
}
openContour = true;
breakShape = true;
}
@@ -910,7 +915,6 @@ public class PShapeOpenGL extends PShape {
return;
}
openContour = false;
breakShape = true;
}
@@ -4306,7 +4310,7 @@ public class PShapeOpenGL extends PShape {
}
boolean renderingFill = false, renderingStroke = false;
PolyShader shader = null;
BaseShader shader = null;
IndexCache cache = tessGeo.polyIndexCache;
for (int n = firstPolyIndexCache; n <= lastPolyIndexCache; n++) {
if (is3D() || (tex != null && (firstLineIndexCache == -1 ||
File diff suppressed because it is too large Load Diff