Protect State and Error(Error:before: glError1285)

Started by suheyb1991, February 05, 2015, 12:46:45 AM

Previous topic - Next topic

suheyb1991

I have 2 questions.
1. I have 3 main classes. These are extends from Renderer,GLSurfaceView and Activity.  I pause or stop Activity but when I want to resume
texture return to black. How can I fix it?

2. I am  getting error(Error:before: glError1285). I add-remove,replace some textures. I think this error about out of gpu memory. But how can I fix it?

Here is log...

Quote
02-04 22:44:43.254: I/jPCT-AE(1671): Creating buffers...
02-04 22:44:43.258: E/jPCT-AE(1671): [ 1423089883261 ] - ERROR: before: glError 1285
02-04 22:44:43.258: W/dalvikvm(1671): threadid=10: thread exiting with uncaught exception (group=0xa626c288)
02-04 22:44:43.266: E/AndroidRuntime(1671): FATAL EXCEPTION: GLThread 146
02-04 22:44:43.266: E/AndroidRuntime(1671): java.lang.RuntimeException: [ 1423089883261 ] - ERROR: before: glError 1285
02-04 22:44:43.266: E/AndroidRuntime(1671):    at com.threed.jpct.Logger.log(Logger.java:206)
02-04 22:44:43.266: E/AndroidRuntime(1671):    at com.threed.jpct.GL20.checkError(GL20.java:152)
02-04 22:44:43.266: E/AndroidRuntime(1671):    at com.threed.jpct.GL20.glGenBuffers(GL20.java:1362)
02-04 22:44:43.266: E/AndroidRuntime(1671):    at com.threed.jpct.CompiledInstance.compileToVBO(CompiledInstance.java:1475)
02-04 22:44:43.266: E/AndroidRuntime(1671):    at com.threed.jpct.CompiledInstance.render(CompiledInstance.java:604)
02-04 22:44:43.266: E/AndroidRuntime(1671):    at com.threed.jpct.GLRenderer.drawVertexArray(GLRenderer.java:2308)
02-04 22:44:43.266: E/AndroidRuntime(1671):    at com.threed.jpct.World.draw(World.java:1417)
02-04 22:44:43.266: E/AndroidRuntime(1671):    at com.threed.jpct.World.draw(World.java:1100)
02-04 22:44:43.266: E/AndroidRuntime(1671):    at com.example.jcptlib.MyRenderer.onDrawFrame(MyRenderer.java:338)
02-04 22:44:43.266: E/AndroidRuntime(1671):    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)
02-04 22:44:43.266: E/AndroidRuntime(1671):    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)

EgonOlsen

Hard to tell...just try smaller textures and see if that fixes the problem. Are you doing any exotic stuff like calling GL functions directly in your code or are you using this: http://www.jpct.net/jpct-ae/doc/com/threed/jpct/GLSLShader.html#compile(java.util.List)?
Or maybe your texture add/remove/replace code is faulty. If you, for example, assign a texture to an object that the TextureManager knows as "blah" and you remove "blah" from the manager just to add another texture with the same name, your object will still reference the old one. If you are doing something like that, then don't! Use replaceTexture instead.

suheyb1991

#2
I think problem at my Renderer class.

public class MyRenderer implements Renderer {

public static String IMAGE_PATH = "http://212.156.127.250:7080/panaromik/";
public static String BACK_END_PATH = "";
public static String CURRENT_IMAGE_SIZE = "/512x256/";
public static JSONDatas CURRENT_JSON_DATA;
private SimpleVector sphereTR;
public Camera cam;
public String filePath;

private FrameBuffer fb;
private World world;
private static Object3D mainSphere;
private static AssetManager assets;
private ArrowManager arrowMan;
private static Object3D arrowSample;
Texture texture1;
static InputStream insP = null;
HashSet<String> textures = TextureManager.getInstance().getNames();
Object3D tempObject3d = null;
ArrayList<Integer> idList = new ArrayList<Integer>();
Enumeration<Object3D> objects;
public int objectDelete = 0;
SurfaceChangeListener surfaceChangeListener = null;
private static boolean loadCntrl = true;

private MainRendererEvent.PrepareEvent preEvent;

private Vector<IUpdateable> updateables = new Vector<IUpdateable>();

public World getWorld() {
return world;
}

public FrameBuffer getBuffer() {
return fb;
}

public void setSurfaceListener(SurfaceChangeListener listener) {
surfaceChangeListener = listener;
Log.d("myrenderer", "surface");
}

public MyRenderer(Resources resources, AssetManager assets,
MainRendererEvent.PrepareEvent preEvent) {
this(resources, assets);
this.preEvent = preEvent;
}

@SuppressWarnings("static-access")
public MyRenderer(Resources resources, AssetManager assets) {
this.assets = assets;
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {

if(loadCntrl)
Load3ds();
if (fb != null) {
fb.dispose();
}

fb = new FrameBuffer(width, height); // OpenGL ES 2.0 constructor

if (world == null) {
world = new World();
LoadObjects();

} else {
world.dispose();
world = new World();
LoadObjects();
}

Log.d("Onsurfachanged", "deyim");
if (surfaceChangeListener != null)
surfaceChangeListener.onSurfaceChanged();
}

public static void Load3ds() {
try {
insP = assets.open("Suheyb.3ds");
mainSphere = loadModel(insP, 1.0f)[0];

insP = assets.open("ok.3ds");
arrowSample = loadModel(insP, 0.1f)[0];

insP = assets.open("label.3ds");
Label.labelSample = loadModel(insP, 0.3f)[0];

} catch (IOException e) {
e.printStackTrace();
}
loadCntrl = false;
}

public void LoadObjects() {

world.setAmbientLight(255, 255, 255);

cam = world.getCamera();

if (!textures.contains("texture1")) {
initializeAssets();
Texture.defaultToMipmapping(true);
Texture.defaultToKeepPixels(false);
createRotatingObject();

if (preEvent != null) {
preEvent.OnInitialized();
}

} else {
initializeAssets();
createRotatingObject();
}

}

public void changeTexture(int arrowGid) {

for (int i = 0; i < GetJSON.jsonDatas.size(); i++) {
if (GetJSON.jsonDatas.get(i).getGid() == arrowGid) {
new GetJSON(GetJSON.jsonDatas.get(i).getLat(),
GetJSON.jsonDatas.get(i).getLon(),
new JSonTouchEvent.JSONEvent() {
@Override
public void onComplete(ArrayList<JSONDatas> jsonData) {
setCurrentJSONData(jsonData);
}
});
}
}
}

private void loadSphere() {
Log.d("loadSphere", "deyim");

mainSphere.setTexture("texture1");
mainSphere.setCulling(true);
mainSphere.setShadingMode(Object3D.LIGHTING_NO_LIGHTS);
mainSphere.build();
Log.d("tempSphere", mainSphere.getName());

sphereTR = new SimpleVector();
sphereTR.x = 0.1f;
sphereTR.y = 0;
sphereTR.z = 0;

mainSphere.translate(sphereTR);

cam.lookAt(mainSphere.getTransformedCenter());
cam.setFOVLimits(0.4f, 2.1f);
MemoryHelper.compact();
Log.i("mainSphere", "loaded");

world.addObject(mainSphere);
arrowMan.addArrows(GetJSON.jsonDatas);
}

private void initializeAssets() {
textures = TextureManager.getInstance().getNames();
if (!textures.contains("arrow")) {
try {
insP = assets.open("ok.png");
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(insP);
Texture arrowTex = new Texture(bm);
arrowTex.setMipmap(false);
TextureManager.getInstance().addTexture("arrow", arrowTex);
bm.recycle();
}

}

private Object3DTransformer cubeTransformer;

private void createRotatingObject() {
arrowMan = new ArrowManager(null, world, arrowSample);
world.addObject(arrowMan);

cubeTransformer = new Object3DTransformer(arrowMan);
updateables.add(cubeTransformer);
updateables.add(arrowMan);
}

public int setPickingScreenCoordinates(int x, int y) {
SimpleVector dir = Interact2D.reproject2D3DWS(cam, fb, x, y)
.normalize();
Object[] res = world.calcMinDistanceAndObject3D(world.getCamera()
.getPosition(), dir, 10000 /* or whatever */);

for (int i = 0; i < res.length; i++) {

if (res[i] instanceof Arrow) {
Arrow tempArrow = (Arrow) res[i];

for (int j = 1; j < GetJSON.jsonDatas.size(); j++) {
if (tempArrow.getName().equals(
GetJSON.jsonDatas.get(j).getArrowName())) {
return GetJSON.jsonDatas.get(j).getGid();
}
}
}
}
return -1;
}

@SuppressWarnings("unused")
private float radTest = 0;

@Override
public void onDrawFrame(GL10 gl) {

if (objectDelete == 1) {
objectDelete = 0;
objects = world.getObjects();
idList.clear();
while (objects.hasMoreElements()) {
tempObject3d = objects.nextElement();
Log.d("listObject", tempObject3d.getName());
if (tempObject3d.getName().contains("arrow")) {
idList.add(tempObject3d.getID());
}
}

for (int i = 0; i < idList.size(); i++) {
world.removeObject(idList.get(i));
}
Label.removeAllTextures();
}
if (cubeTransformer != null) {

float camY = MyGlSurface.globalRotY;
double camyRad = camY + (Math.PI / 2);// / 180 * Math.PI;

float xpos = (float) (300 * Math.cos(camyRad));
float zpos = (float) (300 * Math.sin(camyRad));

cubeTransformer.setX(xpos);
cubeTransformer.setZ(zpos);
cubeTransformer.setY(100);
}

for (int i = 0; i < updateables.size(); i++) {
updateables.get(i).update();
}

fb.clear(0x000000);
world.renderScene(fb);
world.draw(fb);
fb.display();

}

private static Object3D[] loadModel(InputStream filename, float scale) {

Object3D[] model = Loader.load3DS(filename, scale);
Object3D[] modMod = new Object3D[model.length];
Object3D temp = null;
for (int i = 0; i < model.length; i++) {
temp = model[i];
temp.setCenter(SimpleVector.ORIGIN);
temp.rotateX((float) (-.5 * Math.PI));
temp.rotateMesh();
temp.setRotationMatrix(new Matrix());
temp.build();
modMod[i] = temp;
}
return modMod;
}

public void onUp(int x, int y) {
}

public void onMove(int x, int y) {

}

public void onDown(int x, int y) {
}

public void setCurrentPanaromicData(JSONDatas jdt) {

CURRENT_JSON_DATA = jdt;
String gungor = null;
String dirname = null;
try {
gungor = URLEncoder.encode("GÜNGÖREN_JPG", "utf-8");
dirname = URLEncoder.encode(jdt.getDirname(), "utf-8");
dirname = dirname.replace("+", "%20");

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String path = IMAGE_PATH + gungor + "//" + dirname + CURRENT_IMAGE_SIZE
+ jdt.getImg();
setTextureByPath(path);

}

private void setTextureByPath(String path) {

try {

AsynImageDownloader asynIma = new AsynImageDownloader();
asynIma.execute(path, new AsynImageEvent.ImageEvent() {
@Override
public void onComplete(Bitmap arrayBitmap) {

if (arrayBitmap != null) {
HashSet<String> textures = TextureManager.getInstance()
.getNames();

if (!textures.contains("texture1")) {
texture1 = new Texture(arrayBitmap);
texture1.setMipmap(false);
TextureManager.getInstance().addTexture("texture1",
texture1);
//arrayBitmap.recycle();
loadSphere();
} else {

texture1 = new Texture(arrayBitmap);
texture1.setMipmap(false);
TextureManager.getInstance().replaceTexture(
"texture1", texture1);
//arrayBitmap.recycle();
arrowMan.addArrows(GetJSON.jsonDatas);

}

} else {
Log.d("BİTMAP NULL Mı?", "NULL");
}

}
});

} catch (Exception e) {
Log.d("Hata!", "var");
e.printStackTrace();
}

}

public void disposeWorld() {
world.dispose();
}

public void setCurrentJSONData(ArrayList<JSONDatas> jsonData) {
setCurrentPanaromicData(jsonData.get(0));

}

public void listObjects() {

objectDelete = 1;
}
}

EgonOlsen

I can't be bothered to read the whole thing, but this part looks suspicious to me:

Quote...AsynImageDownloader...

An AsynImageDownloader looks quite...async? And if it is, it's not a good idea to replace a texture from outside the rendering thread.
You can load the textures async, but add or replace them inside the rendering thread or you might run into trouble. Just queue these operations and execute them inside the rendering thread.
Apart from that, you are doing quite a lot of unnecessary operations in the onSurfaceChanged-method. All you have to do is to create a new FrameBuffer. You don't have to recreate world and object instances if they still exist.