mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
Finishing implementation of PFramebuffer
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
package processing.core;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -143,6 +144,7 @@ public class PFont implements PConstants {
|
||||
/**
|
||||
* Required for OpenGL-based font rendering.
|
||||
*/
|
||||
protected PGraphicsAndroid3D a3d;
|
||||
protected GL10 gl10;
|
||||
protected int texWidth;
|
||||
protected int texHeight;
|
||||
@@ -152,6 +154,7 @@ public class PFont implements PConstants {
|
||||
protected int[] texIDList = null;
|
||||
protected int currentTexID = -1;
|
||||
protected int lastTexID = -1;
|
||||
protected int recreateResourceIdx;
|
||||
|
||||
public PFont() { } // for subclasses
|
||||
|
||||
@@ -325,6 +328,7 @@ public class PFont implements PConstants {
|
||||
|
||||
protected void finalize() {
|
||||
if (gl10 != null && texIDList != null) {
|
||||
a3d.removeRecreateResourceMethod(recreateResourceIdx);
|
||||
gl10.glDeleteTextures(texIDList.length, texIDList, 0);
|
||||
texIDList = null;
|
||||
}
|
||||
@@ -682,6 +686,13 @@ public class PFont implements PConstants {
|
||||
offsetX = 0;
|
||||
offsetY = 0;
|
||||
lineHeight = 0;
|
||||
|
||||
try {
|
||||
Method meth = this.getClass().getMethod("recreateResource", new Class[] { PGraphicsAndroid3D.class });
|
||||
recreateResourceIdx = a3d.addRecreateResourceMethod(this, meth);
|
||||
} catch (Exception e) {
|
||||
recreateResourceIdx = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int addTexture(GL10 gl) {
|
||||
@@ -726,6 +737,9 @@ public class PFont implements PConstants {
|
||||
}
|
||||
}
|
||||
|
||||
protected void recreateResource(PGraphicsAndroid3D renderer) {
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,15 +22,10 @@
|
||||
|
||||
package processing.core;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.*;
|
||||
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
import javax.microedition.khronos.opengles.GL11ExtensionPack;
|
||||
|
||||
|
||||
/**
|
||||
* Encapsulates a Frame Buffer Object for offscreen rendering.
|
||||
* When created with onscreen == true, it represents the normal
|
||||
@@ -41,23 +36,33 @@ import javax.microedition.khronos.opengles.GL11ExtensionPack;
|
||||
*/
|
||||
public class PFramebuffer {
|
||||
|
||||
protected PApplet parent;
|
||||
protected GL11ExtensionPack gl;
|
||||
protected PApplet parent;
|
||||
protected PGraphicsAndroid3D a3d;
|
||||
protected GL11ExtensionPack gl;
|
||||
protected int glFboID;
|
||||
protected int glDepthBufferID;
|
||||
protected int glStencilBufferID;
|
||||
protected int width;
|
||||
protected int height;
|
||||
|
||||
protected int recreateResourceIdx;
|
||||
|
||||
protected int numColorBuffers;
|
||||
int[] colorBufferAttchPoints;
|
||||
int[] glColorBufferTargets;
|
||||
int[] glColorBufferIDs;
|
||||
|
||||
PFramebuffer(PApplet parent) {
|
||||
this(parent, 0, 0, false);
|
||||
}
|
||||
|
||||
protected int numDrawBuffersInUse;
|
||||
int[] colorDrawBuffers;
|
||||
int[] textureIDs;
|
||||
int[] textureTargets;
|
||||
PFramebuffer(PApplet parent, int w, int h) {
|
||||
this(parent, w, h, false);
|
||||
}
|
||||
|
||||
PFramebuffer(PApplet parent, int w, int h, boolean onscreen) {
|
||||
this.parent = parent;
|
||||
a3d = (PGraphicsAndroid3D)parent.g;
|
||||
|
||||
// Checking we have what we need:
|
||||
gl = a3d.gl11xp;
|
||||
@@ -67,156 +72,140 @@ public class PFramebuffer {
|
||||
if (!a3d.fboSupported) {
|
||||
throw new RuntimeException("PFramebuffer: Frame Buffer Objects are not available");
|
||||
}
|
||||
|
||||
int[] tmp = new int[1];
|
||||
gl.glGenFramebuffersOES(1, tmp, 0);
|
||||
glFboID = tmp[0];
|
||||
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
initFramebuffer(w, h, onscreen);
|
||||
|
||||
try {
|
||||
Method meth = this.getClass().getMethod("recreateResource", new Class[] { PGraphicsAndroid3D.class });
|
||||
recreateResourceIdx = a3d.addRecreateResourceMethod(this, meth);
|
||||
} catch (Exception e) {
|
||||
recreateResourceIdx = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void finalize() {
|
||||
//a3d.removeRecreateResourceMethod(recreateResourceIdx);
|
||||
a3d.removeRecreateResourceMethod(recreateResourceIdx);
|
||||
deleteFramebuffer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void createDepthBuffer(int bits) {
|
||||
if (width == 0 || height == 0) {
|
||||
// Throw error: size undefined.
|
||||
}
|
||||
|
||||
a3d.pushFramebuffer();
|
||||
a3d.setFramebuffer(this);
|
||||
|
||||
// Depth buffer config and attachment.
|
||||
int[] tmp = new int[1];
|
||||
gl.glGenRenderbuffersOES(1, tmp, 0);
|
||||
glDepthBufferID = tmp[0];
|
||||
|
||||
gl.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, glDepthBufferID);
|
||||
gl.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES,
|
||||
GL11ExtensionPack.GL_DEPTH_COMPONENT16, width, height);
|
||||
//GL11ExtensionPack.GL_DEPTH_COMPONENT24 for 24 bits depth buffer
|
||||
//GL11ExtensionPack.GL_DEPTH_COMPONENT32 for 32 bits depth buffer
|
||||
gl.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,
|
||||
GL11ExtensionPack.GL_DEPTH_ATTACHMENT_OES,
|
||||
GL11ExtensionPack.GL_RENDERBUFFER_OES, glDepthBufferID);
|
||||
|
||||
a3d.popFramebuffer();
|
||||
}
|
||||
|
||||
|
||||
public void createStencilBuffer(int bits) {
|
||||
|
||||
a3d.pushFramebuffer();
|
||||
a3d.setFramebuffer(this);
|
||||
|
||||
// Stencil buffer config and attachment.
|
||||
int[] tmp = new int[1];
|
||||
gl.glGenRenderbuffersOES(1, tmp, 0);
|
||||
glStencilBufferID = tmp[0];
|
||||
|
||||
gl.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, glStencilBufferID);
|
||||
|
||||
int glConst = GL11ExtensionPack.GL_STENCIL_INDEX1_OES;
|
||||
if (bits == 1) {
|
||||
glConst = GL11ExtensionPack.GL_STENCIL_INDEX1_OES;
|
||||
} else if (bits == 4) {
|
||||
glConst = GL11ExtensionPack.GL_STENCIL_INDEX4_OES;
|
||||
} else if (bits == 8) {
|
||||
glConst = GL11ExtensionPack.GL_STENCIL_INDEX8_OES;
|
||||
}
|
||||
gl.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, glConst, width, height);
|
||||
|
||||
//_OES for 1 bit stencil
|
||||
//GL11ExtensionPack.GL_STENCIL_INDEX4_OES for 4 bit stencil
|
||||
gl.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,
|
||||
GL11ExtensionPack.GL_STENCIL_ATTACHMENT_OES,
|
||||
GL11ExtensionPack.GL_RENDERBUFFER_OES, glStencilBufferID);
|
||||
|
||||
a3d.popFramebuffer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void setColorBuffer(PTexture tex) {
|
||||
setColorBuffers(new PTexture[] { tex }, 1);
|
||||
void addColorBuffer(PTexture tex) {
|
||||
addColorBuffers(new PTexture[] { tex }, 1);
|
||||
}
|
||||
|
||||
void setDrawBuffers(PTexture[] textures) {
|
||||
setColorBuffers(textures, textures.length);
|
||||
void addDrawBuffers(PTexture[] textures) {
|
||||
addColorBuffers(textures, textures.length);
|
||||
}
|
||||
|
||||
void setColorBuffers(PTexture[] textures, int n) {
|
||||
|
||||
void addColorBuffers(PTexture[] textures, int n) {
|
||||
a3d.pushFramebuffer();
|
||||
a3d.setFramebuffer(this);
|
||||
|
||||
for (int i = 0; i < numDrawBuffersInUse; i++) {
|
||||
// Making sure nothing is attached.
|
||||
for (int i = 0; i < numColorBuffers; i++) {
|
||||
gl.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,
|
||||
GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL10.GL_TEXTURE_2D, 0, 0);
|
||||
GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES + i, GL10.GL_TEXTURE_2D, 0, 0);
|
||||
}
|
||||
|
||||
numDrawBuffersInUse = PApplet.min(n, textures.length);
|
||||
numColorBuffers = PApplet.min(n, textures.length);
|
||||
colorBufferAttchPoints = new int[numColorBuffers];
|
||||
glColorBufferTargets = new int[numColorBuffers];
|
||||
glColorBufferIDs = new int[numColorBuffers];
|
||||
|
||||
for (int i = 0; i < numDrawBuffersInUse; i++) {
|
||||
colorDrawBuffers[i] = GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES + i;
|
||||
textureTargets[i] = textures[i].getGLTarget();
|
||||
textureIDs[i] = textures[i].getGLTextureID();
|
||||
|
||||
gl.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, colorDrawBuffers[i],
|
||||
textureTargets[i], textureIDs[i], 0);
|
||||
for (int i = 0; i < numColorBuffers; i++) {
|
||||
colorBufferAttchPoints[i] = GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES + i;
|
||||
glColorBufferTargets[i] = textures[i].getGLTarget();
|
||||
glColorBufferIDs[i] = textures[i].getGLTextureID();
|
||||
gl.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, colorBufferAttchPoints[i],
|
||||
glColorBufferTargets[i], glColorBufferIDs[i], 0);
|
||||
}
|
||||
|
||||
|
||||
checkFBO();
|
||||
|
||||
/*
|
||||
|
||||
|
||||
// Color buffer (texture) attachment.
|
||||
int glTextureID = 0;
|
||||
|
||||
|
||||
gl.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
|
||||
|
||||
|
||||
|
||||
numDrawBuffersInUse = PApplet.min(n, drawTextures.length);
|
||||
|
||||
colorDrawBuffers = new int[numDrawBuffersInUse];
|
||||
textureIDs = new int[numDrawBuffersInUse];
|
||||
textureTargets = new int[numDrawBuffersInUse];
|
||||
|
||||
for (int i = 0; i < numDrawBuffersInUse; i++) {
|
||||
colorDrawBuffers[i] = GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES + i;
|
||||
textureTargets[i] = drawTextures[i].getTextureTarget();
|
||||
textureIDs[i] = drawTextures[i].getTextureID();
|
||||
|
||||
gl.glFramebufferTexture2DEXT(GL11ExtensionPack.GL_FRAMEBUFFER_OES, colorDrawBuffers[i],
|
||||
textureTargets[i], textureIDs[i], 0);
|
||||
if (validFbo() && textures != null && 0 < textures.length) {
|
||||
width = textures[0].getGLWidth();
|
||||
height = textures[0].getGLHeight();
|
||||
}
|
||||
|
||||
checkFBO();
|
||||
*/
|
||||
|
||||
a3d.popFramebuffer();
|
||||
}
|
||||
|
||||
public void addDepthBuffer(int bits) {
|
||||
if (width == 0 || height == 0) {
|
||||
throw new RuntimeException("PFramebuffer: size undefined.");
|
||||
}
|
||||
|
||||
a3d.pushFramebuffer();
|
||||
a3d.setFramebuffer(this);
|
||||
|
||||
int[] tmp = new int[1];
|
||||
gl.glGenRenderbuffersOES(1, tmp, 0);
|
||||
glDepthBufferID = tmp[0];
|
||||
|
||||
gl.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, glDepthBufferID);
|
||||
|
||||
int glConst = GL11ExtensionPack.GL_DEPTH_COMPONENT16;
|
||||
if (bits == 16) {
|
||||
glConst = GL11ExtensionPack.GL_DEPTH_COMPONENT16;
|
||||
} else if (bits == 24) {
|
||||
glConst = GL11ExtensionPack.GL_DEPTH_COMPONENT24;
|
||||
} else if (bits == 32) {
|
||||
glConst = GL11ExtensionPack.GL_DEPTH_COMPONENT32;
|
||||
}
|
||||
gl.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, glConst, width, height);
|
||||
|
||||
gl.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,
|
||||
GL11ExtensionPack.GL_DEPTH_ATTACHMENT_OES,
|
||||
GL11ExtensionPack.GL_RENDERBUFFER_OES, glDepthBufferID);
|
||||
|
||||
a3d.popFramebuffer();
|
||||
}
|
||||
|
||||
public void addStencilBuffer(int bits) {
|
||||
if (width == 0 || height == 0) {
|
||||
throw new RuntimeException("PFramebuffer: size undefined.");
|
||||
}
|
||||
|
||||
a3d.pushFramebuffer();
|
||||
a3d.setFramebuffer(this);
|
||||
|
||||
int[] tmp = new int[1];
|
||||
gl.glGenRenderbuffersOES(1, tmp, 0);
|
||||
glStencilBufferID = tmp[0];
|
||||
|
||||
gl.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, glStencilBufferID);
|
||||
|
||||
int glConst = GL11ExtensionPack.GL_STENCIL_INDEX1_OES;
|
||||
if (bits == 1) {
|
||||
glConst = GL11ExtensionPack.GL_STENCIL_INDEX1_OES;
|
||||
} else if (bits == 4) {
|
||||
glConst = GL11ExtensionPack.GL_STENCIL_INDEX4_OES;
|
||||
} else if (bits == 8) {
|
||||
glConst = GL11ExtensionPack.GL_STENCIL_INDEX8_OES;
|
||||
}
|
||||
gl.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, glConst, width, height);
|
||||
|
||||
gl.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,
|
||||
GL11ExtensionPack.GL_STENCIL_ATTACHMENT_OES,
|
||||
GL11ExtensionPack.GL_RENDERBUFFER_OES, glStencilBufferID);
|
||||
|
||||
a3d.popFramebuffer();
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
gl.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, glFboID);
|
||||
}
|
||||
|
||||
|
||||
protected void initFramebuffer(int w, int h, boolean onscreen) {
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
if (!onscreen) {
|
||||
// On-screen buffer has no associated FBO.
|
||||
glFboID = 0;
|
||||
} else {
|
||||
int[] tmp = new int[1];
|
||||
gl.glGenFramebuffersOES(1, tmp, 0);
|
||||
glFboID = tmp[0];
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteFramebuffer() {
|
||||
if (glFboID != 0) {
|
||||
@@ -240,282 +229,30 @@ public class PFramebuffer {
|
||||
width = height = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void checkFBO() {
|
||||
|
||||
int status = gl.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
|
||||
if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES) {
|
||||
throw new RuntimeException("Framebuffer is not complete: " +
|
||||
Integer.toHexString(status));
|
||||
}
|
||||
|
||||
|
||||
if (status == GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES)
|
||||
return;
|
||||
else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES) {
|
||||
System.err
|
||||
.println("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES)");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES) {
|
||||
System.err
|
||||
.println("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES)");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES) {
|
||||
System.err
|
||||
.println("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES)");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES) {
|
||||
System.err
|
||||
.println("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT)");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES) {
|
||||
System.err
|
||||
.println("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES)");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES) {
|
||||
System.err
|
||||
.println("Frame buffer is incomplete (GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES)");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_UNSUPPORTED_OES) {
|
||||
System.err
|
||||
.println("Frame buffer is incomplete (GL_FRAMEBUFFER_UNSUPPORTED_OES)");
|
||||
} else {
|
||||
System.err.println("Frame buffer is incomplete (unknown error code)");
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void recreateResource(PGraphicsAndroid3D renderer) {
|
||||
// Recreate GL resources (buffers, etc).
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
private GLSurfaceView mGLSurfaceView;
|
||||
|
||||
private class Renderer implements GLSurfaceView.Renderer {
|
||||
private boolean mContextSupportsFrameBufferObject;
|
||||
private int mTargetTexture;
|
||||
private int mFramebuffer;
|
||||
private int mFramebufferWidth = 256;
|
||||
private int mFramebufferHeight = 256;
|
||||
private int mSurfaceWidth;
|
||||
private int mSurfaceHeight;
|
||||
|
||||
private Triangle mTriangle;
|
||||
private Cube mCube;
|
||||
private float mAngle;
|
||||
private static final boolean DEBUG_RENDER_OFFSCREEN_ONSCREEN = false;
|
||||
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
checkGLError(gl);
|
||||
if (mContextSupportsFrameBufferObject) {
|
||||
GL11ExtensionPack gl11ep = (GL11ExtensionPack) gl;
|
||||
if (DEBUG_RENDER_OFFSCREEN_ONSCREEN) {
|
||||
drawOffscreenImage(gl, mSurfaceWidth, mSurfaceHeight);
|
||||
} else {
|
||||
gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, mFramebuffer);
|
||||
drawOffscreenImage(gl, mFramebufferWidth, mFramebufferHeight);
|
||||
gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
|
||||
drawOnscreen(gl, mSurfaceWidth, mSurfaceHeight);
|
||||
}
|
||||
} else {
|
||||
// Current context doesn't support frame buffer objects.
|
||||
// Indicate this by drawing a red background.
|
||||
gl.glClearColor(1,0,0,0);
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
||||
checkGLError(gl);
|
||||
mSurfaceWidth = width;
|
||||
mSurfaceHeight = height;
|
||||
gl.glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
mContextSupportsFrameBufferObject = checkIfContextSupportsFrameBufferObject(gl);
|
||||
if (mContextSupportsFrameBufferObject) {
|
||||
mTargetTexture = createTargetTexture(gl, mFramebufferWidth, mFramebufferHeight);
|
||||
mFramebuffer = createFrameBuffer(gl, mFramebufferWidth, mFramebufferHeight, mTargetTexture);
|
||||
|
||||
mCube = new Cube();
|
||||
mTriangle = new Triangle();
|
||||
}
|
||||
}
|
||||
|
||||
private void drawOnscreen(GL10 gl, int width, int height) {
|
||||
gl.glViewport(0, 0, width, height);
|
||||
float ratio = (float) width / height;
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
|
||||
|
||||
gl.glClearColor(0,0,1,0);
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTargetTexture);
|
||||
|
||||
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
|
||||
GL10.GL_REPLACE);
|
||||
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
|
||||
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
|
||||
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
gl.glActiveTexture(GL10.GL_TEXTURE0);
|
||||
|
||||
long time = SystemClock.uptimeMillis() % 4000L;
|
||||
float angle = 0.090f * ((int) time);
|
||||
|
||||
gl.glRotatef(angle, 0, 0, 1.0f);
|
||||
|
||||
mTriangle.draw(gl);
|
||||
|
||||
// Restore default state so the other renderer is not affected.
|
||||
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
|
||||
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
private void drawOffscreenImage(GL10 gl, int width, int height) {
|
||||
gl.glViewport(0, 0, width, height);
|
||||
float ratio = (float) width / height;
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
|
||||
|
||||
gl.glEnable(GL10.GL_CULL_FACE);
|
||||
gl.glEnable(GL10.GL_DEPTH_TEST);
|
||||
|
||||
gl.glClearColor(0,0.5f,1,0);
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
gl.glTranslatef(0, 0, -3.0f);
|
||||
gl.glRotatef(mAngle, 0, 1, 0);
|
||||
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
|
||||
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
|
||||
|
||||
mCube.draw(gl);
|
||||
|
||||
gl.glRotatef(mAngle*2.0f, 0, 1, 1);
|
||||
gl.glTranslatef(0.5f, 0.5f, 0.5f);
|
||||
|
||||
mCube.draw(gl);
|
||||
|
||||
mAngle += 1.2f;
|
||||
|
||||
// Restore default state so the other renderer is not affected.
|
||||
|
||||
gl.glDisable(GL10.GL_CULL_FACE);
|
||||
gl.glDisable(GL10.GL_DEPTH_TEST);
|
||||
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
private int createTargetTexture(GL10 gl, int width, int height) {
|
||||
int texture;
|
||||
int[] textures = new int[1];
|
||||
gl.glGenTextures(1, textures, 0);
|
||||
texture = textures[0];
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
|
||||
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, width, height, 0,
|
||||
GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, null);
|
||||
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
|
||||
GL10.GL_NEAREST);
|
||||
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
|
||||
GL10.GL_TEXTURE_MAG_FILTER,
|
||||
GL10.GL_LINEAR);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
|
||||
GL10.GL_REPEAT);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
|
||||
GL10.GL_REPEAT);
|
||||
return texture;
|
||||
}
|
||||
|
||||
private int createFrameBuffer(GL10 gl, int width, int height, int targetTextureId) {
|
||||
GL11ExtensionPack gl11ep = (GL11ExtensionPack) gl;
|
||||
int framebuffer;
|
||||
int[] framebuffers = new int[1];
|
||||
gl11ep.glGenFramebuffersOES(1, framebuffers, 0);
|
||||
framebuffer = framebuffers[0];
|
||||
gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, framebuffer);
|
||||
|
||||
int depthbuffer;
|
||||
int[] renderbuffers = new int[1];
|
||||
gl11ep.glGenRenderbuffersOES(1, renderbuffers, 0);
|
||||
depthbuffer = renderbuffers[0];
|
||||
|
||||
gl11ep.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, depthbuffer);
|
||||
gl11ep.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES,
|
||||
GL11ExtensionPack.GL_DEPTH_COMPONENT16, width, height);
|
||||
gl11ep.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,
|
||||
GL11ExtensionPack.GL_DEPTH_ATTACHMENT_OES,
|
||||
GL11ExtensionPack.GL_RENDERBUFFER_OES, depthbuffer);
|
||||
|
||||
gl11ep.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,
|
||||
GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL10.GL_TEXTURE_2D,
|
||||
targetTextureId, 0);
|
||||
int status = gl11ep.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
|
||||
if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES) {
|
||||
throw new RuntimeException("Framebuffer is not complete: " +
|
||||
Integer.toHexString(status));
|
||||
}
|
||||
gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
|
||||
return framebuffer;
|
||||
|
||||
}
|
||||
|
||||
private boolean checkIfContextSupportsFrameBufferObject(GL10 gl) {
|
||||
return checkIfContextSupportsExtension(gl, "GL_OES_framebuffer_object");
|
||||
}
|
||||
|
||||
|
||||
// This is not the fastest way to check for an extension, but fine if
|
||||
// we are only checking for a few extensions each time a context is created.
|
||||
private boolean checkIfContextSupportsExtension(GL10 gl, String extension) {
|
||||
String extensions = " " + gl.glGetString(GL10.GL_EXTENSIONS) + " ";
|
||||
// The extensions string is padded with spaces between extensions, but not
|
||||
// necessarily at the beginning or end. For simplicity, add spaces at the
|
||||
// beginning and end of the extensions string and the extension string.
|
||||
// This means we can avoid special-case checks for the first or last
|
||||
// extension, as well as avoid special-case checks when an extension name
|
||||
// is the same as the first part of another extension name.
|
||||
return extensions.indexOf(" " + extension + " ") >= 0;
|
||||
}
|
||||
public boolean validFbo() {
|
||||
int status = gl.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
|
||||
if (status == GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES) {
|
||||
return true;
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES) {
|
||||
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES (" + Integer.toHexString(status) + ")");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES) {
|
||||
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES (" + Integer.toHexString(status) + ")");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES) {
|
||||
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES (" + Integer.toHexString(status) + ")");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES) {
|
||||
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES (" + Integer.toHexString(status) + ")");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES) {
|
||||
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES (" + Integer.toHexString(status) + ")");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES) {
|
||||
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES (" + Integer.toHexString(status) + ")");
|
||||
} else if (status == GL11ExtensionPack.GL_FRAMEBUFFER_UNSUPPORTED_OES) {
|
||||
throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_UNSUPPORTED_OES" + Integer.toHexString(status));
|
||||
} else {
|
||||
throw new RuntimeException("PFramebuffer: unknown framebuffer error (" + Integer.toHexString(status) + ")");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Create our surface view and set it as the content of our
|
||||
// Activity
|
||||
mGLSurfaceView = new GLSurfaceView(this);
|
||||
mGLSurfaceView.setRenderer(new Renderer());
|
||||
setContentView(mGLSurfaceView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onResume();
|
||||
mGLSurfaceView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
// Ideally a game should implement onResume() and onPause()
|
||||
// to take appropriate action when the activity looses focus
|
||||
super.onPause();
|
||||
mGLSurfaceView.onPause();
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ import processing.core.PShape3D.VertexGroup;
|
||||
* Android 3D renderer implemented with pure OpenGL ES 1.0/1.1
|
||||
* By Andres Colubri
|
||||
*
|
||||
* TODO: Comment A3D, PShape3D and PTexture,
|
||||
* TODO: Comment A3D, PShape3D, PTexture, PFramebuffer,
|
||||
* TODO: Check lighting and materials.
|
||||
* TODO: Revise triangulator (issues are particularly apparent when tesselating SVG shapes).
|
||||
*/
|
||||
@@ -277,6 +277,7 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
// This array contains the recreateResource methods of all the GL objects
|
||||
// created in Processing. These methods are used to recreate the open GL
|
||||
// data when there is a context change or surface creation in Android.
|
||||
// TODO: Check the resource recreation method.
|
||||
protected ArrayList<GLResource> recreateResourceMethods;
|
||||
|
||||
// ........................................................
|
||||
@@ -308,7 +309,7 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
|
||||
// .......................................................
|
||||
|
||||
protected Stack<PFramebuffer> fboStack;
|
||||
protected Stack<PFramebuffer> fbStack;
|
||||
protected PFramebuffer currentFramebuffer;
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
@@ -524,7 +525,7 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
|
||||
|
||||
public void pushFramebuffer() {
|
||||
fboStack.push(currentFramebuffer);
|
||||
fbStack.push(currentFramebuffer);
|
||||
}
|
||||
|
||||
public void setFramebuffer(PFramebuffer fbo) {
|
||||
@@ -534,10 +535,10 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
|
||||
public void popFramebuffer() {
|
||||
try {
|
||||
currentFramebuffer = fboStack.pop();
|
||||
currentFramebuffer = fbStack.pop();
|
||||
currentFramebuffer.bind();
|
||||
} catch (EmptyStackException e) {
|
||||
System.out.println("Empty framebuffer stack");
|
||||
PGraphics.showWarning("A3D: Empty framebuffer stack");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3853,12 +3854,12 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
public void report(String where) {
|
||||
if (!hints[DISABLE_OPENGL_ERROR_REPORT]) {
|
||||
int err = gl.glGetError();
|
||||
if (err != 0) {
|
||||
if (err != GL10.GL_NO_ERROR) {
|
||||
String errString = GLU.gluErrorString(err);
|
||||
String msg = "OpenGL error " + err + " at " + where + ": " + errString;
|
||||
PGraphics.showWarning(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
@@ -4796,15 +4797,6 @@ public class PGraphicsAndroid3D extends PGraphics {
|
||||
egl.eglDestroyContext(display, context);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: finish gl error handling.
|
||||
static void checkGLError(GL gl) {
|
||||
int error = ((GL10) gl).glGetError();
|
||||
if (error != GL10.GL_NO_ERROR) {
|
||||
throw new RuntimeException("GLError 0x" + Integer.toHexString(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Reference in New Issue
Block a user