Properly initializing GLES2 context.

This commit is contained in:
codeanticode
2012-02-01 20:38:41 +00:00
parent 937a8f5eb9
commit 0465b58c06
2 changed files with 80 additions and 59 deletions
+10 -10
View File
@@ -790,13 +790,12 @@ public class PApplet extends Activity implements PConstants, Runnable {
// Check if the system supports OpenGL ES 2.0.
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;
final boolean supportsGLES2 = configurationInfo.reqGlEsVersion >= 0x20000;
if (!supportsEs2) {
throw new RuntimeException("GLES2 NOT SUPPORTED!!!");
if (!supportsGLES2) {
throw new RuntimeException("P3D: OpenGL ES 2.0 is not supported by this device.");
}
surfaceHolder = getHolder();
// are these two needed?
surfaceHolder.addCallback(this);
@@ -812,11 +811,6 @@ public class PApplet extends Activity implements PConstants, Runnable {
// Set semi-arbitrary size; will be set properly when surfaceChanged() called
g3.setSize(wide, high);
// Set context factory. This make possible to have 2.x contexts.
// We don't need this for the time being since we are using GLES 1.1.
// setEGLContextFactory(g3.getContextFactory());
String depth = sketchColordepth();
if (!depth.equals(DEFAULT_COLOR_DEPTH)) {
// Setting user specified color depth. Otherwise, we let the
@@ -842,8 +836,14 @@ public class PApplet extends Activity implements PConstants, Runnable {
// Getting stencil bits.
val[5] = parseInt(list[5]);
}
// We use our own context factory and config chooser to set the desired RGBA and depth+stencil
// bits.
setEGLContextFactory(g3.pgl.getContextFactory());
setEGLConfigChooser(g3.pgl.getConfigChooser(val[0], val[1], val[2], val[3], val[4], val[5]));
} else {
// Tells the default EGLContextFactory and EGLConfigChooser to create an GLES2 context.
setEGLContextClientVersion(2);
}
// The renderer can be set only once.
+70 -49
View File
@@ -30,7 +30,9 @@ import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.*;
@@ -140,7 +142,11 @@ public class PGL {
public static final int TESS_WINDING_NONZERO = -1;
public static final int TESS_WINDING_ODD = -1;
// Rendering pipeline modes
// Some EGL constants needed to initialize an GLES2 context.
public static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public static final int EGL_OPENGL_ES2_BIT = 0x0004;
// Rendering pipeline modes
public static final int FIXED = 0;
public static final int PROG_GL2 = 1;
public static final int PROG_GL3 = 2;
@@ -1441,9 +1447,12 @@ public class PGL {
return renderer;
}
public AndroidContextFactory getContextFactory() {
return new AndroidContextFactory();
}
public AndroidConfigChooser getConfigChooser(int r, int g, int b, int a, int d, int s) {
AndroidConfigChooser configChooser = new AndroidConfigChooser(r, g, b, a, d, s);
return configChooser;
return new AndroidConfigChooser(r, g, b, a, d, s);
}
public class AndroidRenderer implements Renderer {
@@ -1527,6 +1536,20 @@ public class PGL {
*/
}
}
public class AndroidContextFactory implements GLSurfaceView.EGLContextFactory {
public EGLContext createContext(EGL10 egl, EGLDisplay display,
EGLConfig eglConfig) {
int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2,
EGL10.EGL_NONE };
EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
return context;
}
public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
egl.eglDestroyContext(display, context);
}
}
public class AndroidConfigChooser implements EGLConfigChooser {
// Desired size (in bits) for the rgba color, depth and stencil buffers.
@@ -1545,20 +1568,15 @@ public class PGL {
public int depthBits;
public int stencilBits;
public int[] tempValue = new int[1];
/*
* This EGL config specification is used to specify 2.0 rendering. We use a
* minimum size of 4 bits for red/green/blue, but will perform actual
* matching in chooseConfig() below.
*/
// private int EGL_OPENGL_ES_BIT = 0x01; // EGL 1.x attribute value for
// GL_RENDERABLE_TYPE.
private int EGL_OPENGL_ES2_BIT = 0x04; // EGL 2.x attribute value for
// GL_RENDERABLE_TYPE.
private int[] configAttribsGL = { EGL10.EGL_RED_SIZE, 4,
EGL10.EGL_GREEN_SIZE, 4, EGL10.EGL_BLUE_SIZE, 4,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE };
// The attributes we want in the frame buffer configuration for Processing.
// For more details on other attributes, see:
// http://www.khronos.org/opengles/documentation/opengles1_0/html/eglChooseConfig.html
protected int[] configAttribsGL = { EGL10.EGL_RED_SIZE, 4,
EGL10.EGL_GREEN_SIZE, 4,
EGL10.EGL_BLUE_SIZE, 4,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE };
public AndroidConfigChooser(int r, int g, int b, int a, int d, int s) {
redTarget = r;
@@ -1588,7 +1606,7 @@ public class PGL {
if (PApplet.DEBUG) {
for (EGLConfig config : configs) {
String configStr = "A3D - selected EGL config : "
String configStr = "P3D - selected EGL config : "
+ printConfig(egl, display, config);
System.out.println(configStr);
}
@@ -1603,43 +1621,46 @@ public class PGL {
float bestScore = 1000;
for (EGLConfig config : configs) {
int d = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, 0);
int gl = findConfigAttrib(egl, display, config, EGL10.EGL_RENDERABLE_TYPE, 0);
if (gl == EGL_OPENGL_ES2_BIT) {
int d = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, 0);
int r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0);
int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
float score = 0.20f * PApplet.abs(r - redTarget) +
0.20f * PApplet.abs(g - greenTarget) +
0.20f * PApplet.abs(b - blueTarget) +
0.15f * PApplet.abs(a - blueTarget) +
0.15f * PApplet.abs(d - depthTarget) +
0.10f * PApplet.abs(s - stencilTarget);
if (score < bestScore) {
// We look for the config closest to the target config.
// Closeness is measured by the score function defined above:
// we give more weight to the RGB components, followed by the
// alpha, depth and finally stencil bits.
bestConfig = config;
bestScore = score;
redBits = r;
greenBits = g;
blueBits = b;
alphaBits = a;
depthBits = d;
stencilBits = s;
int r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0);
int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
pg.offscreenDepthBits = d;
pg.offscreenStencilBits = s;
float score = 0.20f * PApplet.abs(r - redTarget) +
0.20f * PApplet.abs(g - greenTarget) +
0.20f * PApplet.abs(b - blueTarget) +
0.15f * PApplet.abs(a - blueTarget) +
0.15f * PApplet.abs(d - depthTarget) +
0.10f * PApplet.abs(s - stencilTarget);
if (score < bestScore) {
// We look for the config closest to the target config.
// Closeness is measured by the score function defined above:
// we give more weight to the RGB components, followed by the
// alpha, depth and finally stencil bits.
bestConfig = config;
bestScore = score;
redBits = r;
greenBits = g;
blueBits = b;
alphaBits = a;
depthBits = d;
stencilBits = s;
pg.offscreenDepthBits = d;
pg.offscreenStencilBits = s;
}
}
}
if (PApplet.DEBUG) {
String configStr = "A3D - selected EGL config : "
String configStr = "P3D - selected EGL config : "
+ printConfig(egl, display, bestConfig);
System.out.println(configStr);
}