here is the synchronized version of test case. just to be sure, every jPCT related thing is aggresively synchronized. result is the same. setting texture id's to -1 fixes the exception
package tmp;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;
import raft.jumpy.JConfig;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Object3D;
import com.threed.jpct.RGBColor;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.MemoryHelper;
/**
*
* @author hakan eryargi (r a f t)
*/
public class Test2Activity extends Activity {
private static final float HALF_SIDE = 0.35f;
private static final float HEIGHT = 4f;
private static final Object lock = new Object();
private static final Object3D MAGNET_PLANE_MASTER;
static {
synchronized (lock) {
TextureManager.getInstance().addTexture("white", new Texture(64, 64, RGBColor.WHITE));
TextureManager.getInstance().addTexture("blue", new Texture(64, 64, RGBColor.BLUE));
MAGNET_PLANE_MASTER = new Object3D(10);
int shiftTextureId = TextureManager.getInstance().getTextureID("blue");
int topTextureId = TextureManager.getInstance().getTextureID("white");
// uncomment these lines
// shiftTextureId = -1;
// topTextureId = -1;
// front side (looking from front)
MAGNET_PLANE_MASTER.addTriangle(
new SimpleVector(-HALF_SIDE, 0, -HALF_SIDE), 0, 0, // lower left
new SimpleVector(HALF_SIDE, 0, -HALF_SIDE), 1, 0, // lower right
new SimpleVector(-HALF_SIDE, -HEIGHT, -HALF_SIDE), 0, 0.5f, // upper left
shiftTextureId);
MAGNET_PLANE_MASTER.addTriangle(
new SimpleVector(HALF_SIDE, 0, -HALF_SIDE), 1, 0, // lower right
new SimpleVector(HALF_SIDE, -HEIGHT, -HALF_SIDE), 1, 0.5f, // upper right
new SimpleVector(-HALF_SIDE, -HEIGHT, -HALF_SIDE), 0, 0.5f, // upper left
shiftTextureId);
// back side (looking from front)
MAGNET_PLANE_MASTER.addTriangle(
new SimpleVector(HALF_SIDE, 0, HALF_SIDE), 1, 0, // lower right
new SimpleVector(-HALF_SIDE, 0, HALF_SIDE), 0, 0, // lower left
new SimpleVector(HALF_SIDE, -HEIGHT, HALF_SIDE), 1, 0.5f, // upper right
shiftTextureId);
MAGNET_PLANE_MASTER.addTriangle(
new SimpleVector(-HALF_SIDE, 0, HALF_SIDE), 0, 0, // lower left
new SimpleVector(-HALF_SIDE, -HEIGHT, HALF_SIDE), 0, 0.5f, // upper left
new SimpleVector(HALF_SIDE, -HEIGHT, HALF_SIDE), 1, 0.5f, // upper right
shiftTextureId);
// right side (looking from right)
MAGNET_PLANE_MASTER.addTriangle(
new SimpleVector(HALF_SIDE, 0, -HALF_SIDE), 0, 0, // lower left
new SimpleVector(HALF_SIDE, 0, HALF_SIDE), 1, 0, // lower right
new SimpleVector(HALF_SIDE, -HEIGHT, -HALF_SIDE), 0, 0.5f, // upper left
shiftTextureId);
MAGNET_PLANE_MASTER.addTriangle(
new SimpleVector(HALF_SIDE, 0, HALF_SIDE), 1, 0, // lower right
new SimpleVector(HALF_SIDE, -HEIGHT, HALF_SIDE), 1, 0.5f, // upper right
new SimpleVector(HALF_SIDE, -HEIGHT, -HALF_SIDE), 0, 0.5f, // upper left
shiftTextureId);
// left side (looking from left)
MAGNET_PLANE_MASTER.addTriangle(
new SimpleVector(-HALF_SIDE, 0, HALF_SIDE), 0, 0, // lower left
new SimpleVector(-HALF_SIDE, 0, -HALF_SIDE), 1, 0, // lower right
new SimpleVector(-HALF_SIDE, -HEIGHT, HALF_SIDE), 0, 0.5f, // upper left
shiftTextureId);
MAGNET_PLANE_MASTER.addTriangle(
new SimpleVector(-HALF_SIDE, 0, -HALF_SIDE), 1, 0, // lower right
new SimpleVector(-HALF_SIDE, -HEIGHT, -HALF_SIDE), 1, 0.5f, // upper right
new SimpleVector(-HALF_SIDE, -HEIGHT, HALF_SIDE), 0, 0.5f, // upper left
shiftTextureId);
// top side (looking from top)
MAGNET_PLANE_MASTER.addTriangle(
new SimpleVector(-HALF_SIDE, -HEIGHT, -HALF_SIDE), 0, 0, // lower left
new SimpleVector(HALF_SIDE, -HEIGHT, HALF_SIDE), 1, 0.5f, // upper right
new SimpleVector(-HALF_SIDE, -HEIGHT, HALF_SIDE), 0, 0.5f, // upper left
topTextureId);
MAGNET_PLANE_MASTER.addTriangle(
new SimpleVector(HALF_SIDE, -HEIGHT, -HALF_SIDE), 1, 0, // lower right
new SimpleVector(HALF_SIDE, -HEIGHT, HALF_SIDE), 1, 0.5f, // upper right
new SimpleVector(-HALF_SIDE, -HEIGHT, -HALF_SIDE), 0, 0, // lower left
topTextureId);
//MAGNET_PLANE_MASTER.translate(0, -0.5f, 0);
MAGNET_PLANE_MASTER.translateMesh();
MAGNET_PLANE_MASTER.getTranslationMatrix().setIdentity();
//MAGNET_PLANE_MASTER.setTexture("tile_MAGNET_PLANE");
MAGNET_PLANE_MASTER.getMesh().compress();
//MAGNET_PLANE_MASTER.setBillboarding(Object3D.BILLBOARDING_ENABLED);
MAGNET_PLANE_MASTER.setTransparency((int)(JConfig.transparencyRange / 1.5f));
//MAGNET_PLANE_MASTER.setTransparencyMode(Object3D.TRANSPARENCY_MODE_ADD);
MAGNET_PLANE_MASTER.setLighting(Object3D.LIGHTING_NO_LIGHTS);
MAGNET_PLANE_MASTER.setAdditionalColor(RGBColor.WHITE);
MAGNET_PLANE_MASTER.compile();
}
}
private GLSurfaceView mGLView;
private final MyRenderer renderer = new MyRenderer();
private World world;
private boolean compileAll;
@Override
protected void onCreate(Bundle savedInstanceState) {
synchronized (lock) {
super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(getApplication());
setContentView(mGLView);
mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
// Ensure that we get a 16bit framebuffer. Otherwise, we'll fall
// back to Pixelflinger on some device (read: Samsung I7500)
int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
EGLConfig[] configs = new EGLConfig[1];
int[] result = new int[1];
egl.eglChooseConfig(display, attributes, configs, 1, result);
return configs[0];
}
});
mGLView.setRenderer(renderer);
world = new World();
world.getCamera().moveCamera(Camera.CAMERA_MOVEOUT, 2);
Object3D magnetBox = MAGNET_PLANE_MASTER.cloneObject();
magnetBox.shareCompiledData(MAGNET_PLANE_MASTER);
world.addObject(magnetBox);
compileAll = true;
}
}
@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}
@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}
class MyRenderer implements GLSurfaceView.Renderer {
private FrameBuffer buffer = null;
public MyRenderer() {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
synchronized (lock) {
if (buffer != null) {
buffer.dispose();
}
buffer = new FrameBuffer(gl, width, height);
MemoryHelper.compact();
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
@Override
public void onDrawFrame(GL10 gl) {
synchronized (lock) {
if (buffer == null)
return;
buffer.clear();
if (compileAll) {
world.compileAllObjects(buffer);
compileAll = false;
}
world.renderScene(buffer);
world.draw(buffer);
buffer.display();
Thread.yield();
}
}
}
}