Author Topic: How to clean after changing Rooms/Scenes? [Solved]  (Read 2915 times)

Offline efaj

  • byte
  • *
  • Posts: 32
    • View Profile
How to clean after changing Rooms/Scenes? [Solved]
« on: January 05, 2012, 10:54:36 am »
So, on my original attempt to do so, I got
Code: [Select]
[ Thu Jan 05 03:46:05 CST 2012 ] - WARNING: There's a problem with the object list not being consistent during rendering. This is often caused by concurrent modification of jPCT objects on a thread different from the rendering thread!
[ Thu Jan 05 03:46:05 CST 2012 ] - ERROR: null
But, only with the OpenGL renderer and if it's the second time I go into the Game room. (the only other room is a title screen that only blits 2d stuff with raft's openglFont and texturePack)

I guess it's related to the way cleaning must be done in between rooms. Is there any example on it?

So far what I do is call world.dispose(); and textureManager.removeandUnload() for every texture I can keep track of after rendering and before creating a new Room object over the previous.
« Last Edit: January 05, 2012, 04:45:06 pm by efaj »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: How to clean after changing Rooms/Scenes?
« Reply #1 on: January 05, 2012, 11:23:43 am »
That highly depends on what exactly you want to do. I suggest to keep the world-instance if possible and also keep the textures in the manager unless your textures vary greatly from room to room and you are running out of GPU memory, but that's rather unlikely. In Robombs, i simply do world.removeAllObjects() and world.removeAllLights(). Then i'm adding the new objects and lights to the same world instance.

Offline efaj

  • byte
  • *
  • Posts: 32
    • View Profile
Re: How to clean after changing Rooms/Scenes?
« Reply #2 on: January 05, 2012, 04:44:43 pm »
Alright, thanks!
I changed my code accordingly using just world.removeAll(). Also, found out that the error was being caused by textureManager.removeandUnload(), so I'll just use remove() when there are textures I'll have to remove (because yes, there will be some rooms that have objects with very unique textures, and several of those)

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: How to clean after changing Rooms/Scenes? [Solved]
« Reply #3 on: January 05, 2012, 08:19:38 pm »
removeAndUnload can only cause that if you are still rendering objects that use these textures. Keep in mind that all this has to happen in the render thread or otherwise, you'll run into trouble because jPCT isn't thread-safe. Using remove() only isn't a good idea, because it leaves the texture data in the GPU's memory and it never gets freed. Isn't it an option to simply leave the textures in the manager even if they are not in use?

Offline efaj

  • byte
  • *
  • Posts: 32
    • View Profile
Re: How to clean after changing Rooms/Scenes? [Solved]
« Reply #4 on: January 05, 2012, 09:13:54 pm »
As far as I know, I'm not using concurrency (at least not explicitly), so I guess I'm in the render thread. And damn, didn't know I was leaving those textures like that.... thanks.
And for this project, leaving the textures I don't think is an option, because I want the game to run in any video card from Pentium 4 integrated and up, and I'm making a Pokemon-like MMO... which means there will be around 100 different creatures with different textures in different fights, so if the client were to be left open for extended gameplay, those and the player (which will be customizable, increasing the amount of textures) and terrain textures will build up.

Quote
removeAndUnload can only cause that if you are still rendering objects that use these textures.
What do I have to do then? Inside my loop I have:

Code: [Select]
display();
changeRoom();
removeTextures();
Thread.yield();

private void changeRoom(){
 if(nextRoom!=null){
room.dispose();
world.removeAll();
sky.removeAll();
switch (nextRoom) {
case TITLE:
room=new Title(this);
break;
case GAME:
room=new Game(this);
break;
default:
break;
}
nextRoom=null;
}

private void removeTextures(){
for (String name : texturesForRemoval) {
TextureManager.getInstance().removeTexture(name); //This is the line that will become removeAndUnload()
}
texturesForRemoval.clear();
}

So, I thought since the objects are removed before the textures unloaded they should have already be "Not rendered".

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: How to clean after changing Rooms/Scenes? [Solved]
« Reply #5 on: January 05, 2012, 09:38:03 pm »
I'm not sure what's going on there, but if the removeAndUnload() causes the problem, i don't see why this should happen except if you render something that uses that texture. Keep in mind that if you remove a texture and add the same texture with the same name, an old object using this texture will still refer to the old one. Maybe that causes the problem?

Offline efaj

  • byte
  • *
  • Posts: 32
    • View Profile
Re: How to clean after changing Rooms/Scenes? [Solved]
« Reply #6 on: January 05, 2012, 10:21:10 pm »
It's a mix of removeAndUnload and my attempt at cleaning the resources raft's GLFont uses. With what you've told me, I should be able to fix it now (since I already did some changes to texturePack for disposal) -or since it's a font, I might as well leave it-
All the rest remove and unload their textures correctly without triggering that error.

EdIT:
Quote
Keep in mind that if you remove a texture and add the same texture with the same name, an old object using this texture will still refer to the old one. Maybe that causes the problem?
And yes, this was the case... I hadn't seen GLFont kept a cache.
« Last Edit: January 05, 2012, 11:43:45 pm by efaj »