First of all, thanks a lot for posting that new tutorial (Here is the link) - it came exactly when I started looking for something like that and it was almost perfect for me. However while reading it and making use of the examples, I bumped into a few questions I hoped some of you could help me with.
In the example the GUI Gamestate is started up in the OpenGL thread. I understand why it is probably necessary - OpenGL calls that are made must be executed in the correct thread. However does this mean that all my other gamestates that include geometry etc must also be started up in OpenGL thread or is this just a special advice for FengGUI?
In the example, input was handled via FengJMEInputHandler. However so far I have tried implementing controls through the GameControlManager. Is that still possible in some simple way or would you advise I change the way I handle input? I am still 1-2 days away from trying it myself, but thought I migh as well ask
I would like to put different elements of my GUI in different gamestates. Is that still possible by using FengGUI or does it mess up the system when I have several FengGUI displays and/or windows in my game?
I have more questions about gamestates but they can wait I guess
I have run into another problem with FengGUI and Standardgame… I have asked about it on the FengGUI forum and that did help a bit, but the main problem still eludes me. However I think the fault is with my general game structure and no particular code line. Perhaps someone could advise me on what I am doing wrong. The basic setup:
Main
getSettings
start Standardgame
init gamestate_1 (main thread in standard way)
init gamestate_2 (main thread in standard way)
init FengGUIGamestate (OpenGL thread)
init skyBox & add to gamestate_2 (textures loaded in main thread)
gamestate_1
init
loadTexture
position box and put texture on it
camera positioning
gamestate_2
init
add some controllers
loadTexture
position box and put texture on it
FengGUIGamestate
buildUI
disp = new LWJGLBinding
add some container
load texture and put it on container
disp.layout
render
straight from tutorial
The weird thing happening:
- When I load all gamestates but do NOT init skybox, all works fine
- When I load skybox and all gamestates except gamestate_1, all works fine
- When I load skybox and all gamestates except gamestate_2, all works fine
- However when I load all gamestates AND skybox, all textures turn completely white (most of them being briefly visible during loading process)
Is the problem thread related? Where do I have to load textures... Do I have to put the load command into OpenGL thread? Confused about that. Or perhaps some reason I am missing completely? Please advise :?
to be honest im not really sure where the problem is. it seems that this could be thread problem.
1.it seems like gamestate1 and 2 should be in one game state. imo, a game state represents a certain stage of the game. such as an entry scene, a mission scene and an ending scene.
2.this is more of a suggestion. i had alot of weird problems with standard game when i was using it coz i thought it is natrual to use it with game states. however, alot of the problems are just so weird (most related to threading) that its not worth the time to solve them. then i switched to base game + game states. and now everything works perfectly fine. so maybe u should switch to base game too, if u dont wanna deal with all these weird problems.
I agree completely. In fact they are - gamestate_1 is my main menu background and gamestate_2 is my actual in-game state. I just activated them both here to demonstrate in a simple way how the problematic situation arises. In fact there are more gamestates (that actually suit together in the game in a logical way) that cause the problem, but I did not want to complicate the picture here.
Well, yeah, I will keep this option open for sure. I might go for the game that allowed setting my own render passes… so that FengGUI elements are sure to be drawn last. The current system works fine in that respect, but I do not know if BaseGame would. I am still a noob when it comes to jME
I find myself writing the basic game framework over and over and over again, trying to come up with one that would not cause me problems later on. And I am still to tackle the server side, model loading etc. It is hard to find an example out there that includes all these elements in a way that is worth emulating. If you know a good one with available source, please do share
actually, base game wont have any problems with render passes since simeplePassGame is actually using baseSimpleGame which is very similar to base game. so if u do choose to change to base game implementation, that should be ur last concern.
im afraid i dont know such example. the game frame work is entirely up to the software engineer and most of the work are copy right to some company or team. so im sry i cant provide anything helpful here.
but one suggestion which u may already be very familiar with is seperation of data(art assets) and logic. make sure u have a clear art pipeline for ur game and that will for sure save u alot of troubles in the future. i remember once i found an article from google on this topic, u might wanna read it.
You know, you can lose any "weirdness" due to multi-threaded operation by not using StandardGame in multiple threads…either create a gamestate that does the loading at some point within the update or render method, or interject the instantiation and adding to the GameStateManager into a GameTask. Then you'll never have to deal with the complexities of multi-threading. There's nothing ultra complex about StandardGame, it simply opens up more potential to do things in multiple threads and standardizes the base of your game, but you are never required to use more than one thread.
I finally got the weird behavior to stop (for now), but I never figured out what exactly had caused it. Could have been the fact that I built the same gamestates several times during initialization or the fact that they used the same texture in a few places (seems unlikely to me though). It was certainly related to threading as the problem occurred always when I started the app. for the first time after restarting Eclipse, but only occasionally after that - I guess something was already loaded in the memory and someone else won the race.
Another indication is the fact that the FengGUI textures were fine, but the jME ones not - and FengGUI loading was done entirely in the OpenGL thread.
darkfrog said:
You know, you can lose any "weirdness" due to multi-threaded operation by not using StandardGame in multiple threads...either create a gamestate that does the loading at some point within the update or render method, or interject the instantiation and adding to the GameStateManager into a GameTask. Then you'll never have to deal with the complexities of multi-threading. There's nothing ultra complex about StandardGame, it simply opens up more potential to do things in multiple threads and standardizes the base of your game, but you are never required to use more than one thread.
The thing that confuses me about StandardGame is that in all the examples texture loading and update methods that are done in the constructor or init methods, are done just there - in the constructor etc. They are not added as tasks to the OpenGL queue. And appearantly that IS the correct use as this is also the way it is done in the MonkeyMahhjong code. However that leaves me a question - what MUST be put in the OpenGL thread during GameState initialization?
I am still concerned as it is quite possible my problem is still present - I just cleaned up the code enough so that the race always goes one way. Also, I will need to make use of threads later on anyways, so I'd really prefer understanding that part top to bottom. While investigating the StandardGame I also put together a small FAQ for myself, so if anyone has questions about StandardGame, there are also some answers listed on this webpage.
However that leaves me a question - what MUST be put in the OpenGL thread during GameState initialization?
I believe there's a wiki entry that discusses this.
I am still concerned as it is quite possible my problem is still present - I just cleaned up the code enough so that the race always goes one way. Also, I will need to make use of threads later on anyways, so I'd really prefer understanding that part top to bottom. While investigating the StandardGame I also put together a small FAQ for myself, so if anyone has questions about StandardGame, there are also some answers listed on this webpage.
Nice work, but if you don't mind, it would be more accessible if you would put that in a wiki entry for jME. Anyone can create wiki entries for jME and they're always appreciated. :)
Nice work, but if you don't mind, it would be more accessible if you would put that in a wiki entry for jME. Anyone can create wiki entries for jME and they're always appreciated. :)
Sure, I will create a WiKi entry. Actually I wanted to do this from the start, but was not sure what the policy is.
However the OpenGL call listing says that the com.jme.util.TextureManager loadTexture(…) call should be made from withing OpenGL thread. This I find confusing when I examine the code in the MonkeyMahjongg game code (to become a tutorial at some point):
GameState is started up in main, not in OpenGL:
standardGame = new StandardGame("Monkey Mahjongg", StandardGame.GameType.GRAPHICAL, gameSettings);
standardGame.start();
mahjonggGameState = new MahjonggGameState();
GameStateManager.getInstance().attachChild(mahjonggGameState);
mahjonggGameState.setActive(true); // Called when start button is pressed
And in the GameState:
public class MahjonggGameState extends BasicGameState {
public MahjonggGameState() {
super("mahjongg");
}
public void setActive(boolean active) {
super.setActive(active);
if (active) {
init(Main.getLevel());
} else {
// etc..
}
}
Loop and conditions{
int tileId = level.getTile(x, y, z);
SharedMesh tile = new SharedMesh("tile", box);
tile.setUserData(TILE_USER_DATA, new TileData(x, y, z, tileId));
setState(tile, tileId);
rootNode.attachChild(tile);
// ... Sets translation and bound
tile.updateRenderState();
}
rootNode.updateRenderState();
}
Here TextureManager.loadTexture is used, but I cannot understand how it is done in the correct thread. I added logging to the setState method and it is executing in the main thread. Actually I am yet to see an example that adds a GameTask in a GameState init method or constructor to the OpenGL thread. Perhaps just another example is necessary?
loadTexture used to require the OpenGL thread because it used to force the actual loading of the texture data on the card and texture id creation, but it no longer does. (now the texture either loads on first application, or if you call preloadCache(Renderer), both of which need to happen in the OpenGL thread)
loadTexture used to require the OpenGL thread because it used to force the actual loading of the texture data on the card and texture id creation, but it no longer does. (now the texture either loads on first application, or if you call preloadCache(Renderer), both of which need to happen in the OpenGL thread)
I read that like "you can now load textures from GameState constructors without injecting the command into OpenGL thread." :)
Thank you for this information. I do not dare to touch the OpenGL call list Wiki entry myself, but I guess someone needs to update that.... or alternatively wait till jME 2.0. Hmm... I wonder when that is coming