I didn’t see anything specific to OpenGL, so if I missed it then let me know.
That aside here are my thoughts on your predicament.
One Way of Doing This
I think the best way to do it is to split it up into 3 different classes or rather 2 classes and the all your sub classes who extend the abstract class.
Basically you have a handler class who is responsible for handling the basic graphics, like initializing any OpenGL and LWJGL Display settings.
It would also handle the transitioning between your stages.
For the stages themselves, they would contain all the objects you need to load, unload and how you want to draw stuff for that stage.
But let’s take a look at the code first. It should make a bit more sense. Though do keep in mind I’m sure there’s more ways to do this and I make no claims to being a pinnacle of proper programming practices.
Here’s the stage Handler
public class StageHandler{
public static final int STAGE1 =1;
public static final int STAGE2 =2;
public static final int STAGE3 =3;
public static final int OPTIONS =4;
public Map<Integer, AbstractStage> stage = null; //A map of all your abstract stages
public boolean running = false; //If the rendering of the engine is running
private AbstractStage currentstage= null; //The current stage you want to draw
private boolean change = false; //If you need to change the stage
private int newstage = 0; //The id value for a stage you want to change to
public void StageHandlder(){
this.stage = new HashMap<Integer, AbstractStage>();
this.stage.put(StageHandler.STAGE1, new Stage_One(this));
this.stage.put(StageHandler.STAGE1, new Stage_Two(this));
this.stage.put(StageHandler.STAGE1, new Stage_Three(this));
this.stage.put(StageHandler.STAGE1, new Stage_Options(this));
}
public void startRender(){ //Start the render loop
this.running = true;
this.changeStage(StageHandler.Stage1);
while(running){ //Your drawing loop
if(change){
this.changeStage(this.newstage); //Change the stage
}
this.currentstage.draw(); //Draw all the stuff in your stage
}
}
public void postStageChange(int stageid){ //Prep for a stage change
this.change = true;
this.newstage = stageid;
}
private void changeStage(int stageid){ //Change to a new stage
if(this.currentstage!= null){ //Avoid the start up null
this.currentstage.unload(); //Unload the stage you are transitioning from
}
this.currentstage = stage.get(stageid); //Get the stage you are transitioning to
this.currentstage.load(); //Load all the stuff for the stage
this.change = false;
}
}
And here’s the Abstract class
public abstract class AbstractStage{
private StageHandler stagehandler = null; //Used as a reference back to the handler
public AbstractStage(StageHandler stagehandler){
this.stagehandler = stagehandler;
)
//Load, unload and drawing stuff
public abstract void load();
public abstract void unload();
public abstract void draw();
void changeStage(int stageid){
this.stagehandler.postStageChange(stageid);
}
}
Now in order to change stages, all you have to do from your extended abstract sub is call the stage you want to change to (let’s use Stage3 as an example):
this.changeStage(StageHandler.STAGE3);
This setup does leave the door open for calling out a stage and rendering it from within anywhere; the catch being it needs to already be loaded. For example, you would need load the Options stage when the options are entered and then unload them after they’re exited. (I’m not a big fan of this, see below).
To do that, all you need to do this from wthin a stage:
this.stagehandler.stage.get(StageHandler.OPTIONS).draw();
Some Things to Keep in Mind
I’m not really sure you would want to draw 2 stages at the same time. Particularly with the options menu. That seems like something which should be taken care of with a class which handles the drawing of windows. Trying to combine window logic with stage logic could get messy.
This is only the tip of inter-class communication. If you’re running a multi-threaded application, you’ll need to take care when passing messages back and forth.