1
\$\begingroup\$

I am creating a small platformer-like game for Android using OpenGL. The game has 3 main screens/states:

  1. Main menu screen
  2. Level selection screen
  3. The game screen

Currently I use a GLSurfaceView.Renderer to render all three screens and just run different parts of the render code depending on which screen I am on. Now my code is getting really messy because the render(), update() and onTouchEvent() methods of the renderer all have code for all three states in big if statements.

My question is now: Is it possible to have multiple GLSurfaceView.Renderer's (one for each screen/game state) and how can I implement the switching between them?

\$\endgroup\$
1
\$\begingroup\$

It's probably better to use one surface view. Each GLSurfaceView appears to get its own OpenGL context unless you jump through a bunch of hoops to manually create the context and customize the way each surface creates its context.

The practical upshot is that you cannot easily share resources between each view, so you will need to reload textures and geometry or keep two copies of them in memory at all times. This will have a negative impact on performance, memory use, or both depending on precisely how you implement it.

Using a single view avoids these problems. To alleviate your messy code issues, consider instead building a more robust state management system.

A very classical, straightforward approach to doing so is creating a GameState base class with virtual update, render and handleTouch calls. Then create three child classes, one for each of your current game states, and isolate your rendering and logic for each state to each state's appropriate overridden methods. Your primary view simply holds a reference to the active state and calls that state's render/update/whatever calls as needed. When you transition between states you just switch out what this reference points to.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the answer! I didn't want to create multiple GLSurfaceView's, but rather use multiple Renderers (GLSurfaceView.Renderer) and just switch between them (if that is even possible). But now I think it would probably be better to use multiple game states like you said.. What do you think is better? \$\endgroup\$ – Dominik Schmidt May 26 '16 at 15:40
  • \$\begingroup\$ Probably multiple game states. I'm not terribly familiar with the guts of GLSurfaceView but I think that having different renderers will still create the multiple-context problem... and in any event I don't really see how it would solve your "messy code" issues better than states would, since you also have update and input code you want to factor out, not just rendering. \$\endgroup\$ – Josh May 26 '16 at 15:42
  • \$\begingroup\$ Ok, I will go with game states then. Thanks for the help! \$\endgroup\$ – Dominik Schmidt May 26 '16 at 15:47
0
\$\begingroup\$

The docs for setRenderer() say:

This method should be called once and only once in the life-cycle of a GLSurfaceView.

If you look at the source code, you'll find that they actually meant "must" rather than "should". The setRenderer() method checks to see if a render thread is running. If not, it creates one and starts it. If the thread already exists, the call fails.

So you can't change out your GLSurfaceView.Renderer object. Switching based on game current state is the preferred approach.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.