That's what i was wondering. It makes of course a lot of sense to use
the CPU idle time while the GPU is doing the heavy lifting. However,
but having to put a synch around the access to the logic data in the
rendering thread and the logic thread you explicitely starve one of
the threads, depending on which one is faster. So while the logic
thread can do it's work in parallel to the rendering thread blocking
on eglSwapBuffers you effectively take away CPU from the logic thread
while the rendering thread is setting everything up so that
eglSwapBuffer can do it's magic, thus essentially serializing the
logic and rendering thread again. As some poster noted earlier the
design will only increase performance if your scene drawing minus the
swap is extremely fast, e.g. very little GL calls or routines that
generate geometry on the fly. This essentially means that your
rendering pipeline must be rather simple.

But as stated earlier, implementing it one or the other way isn't
really a huge biggie as you have explicit synchronization in the
critical regions anyways.

On 9 Apr., 21:24, Robert Green <rbgrn....@gmail.com> wrote:
> Eddie,
>
> Yes, that'll do the trick.
>
> As far as the multiple threads goes, sure you can drive your logic off
> of the call to onDrawFrame but there is a situation in which having a
> separate thread makes sense:
>
> After onDrawFrame, the rendering thread is finishing/swapping.  That
> can actually take a decent amount of time to do in certain cases and
> most of it is happening on the GPU, especially on a device like the
> Droid which has a discrete CPU/GPU.  During that time, the CPU is
> available and can be used on the logic thread.  Properly implemented,
> in a heavy scene you can get some or all of the logic processed before
> the rendering thread is ready again, which is why I favor it.
>
> My question is:  onDrawFrame is only called once the GPU is ready for
> another draw.  Why waste those precious GPU idle moments just doing
> CPU stuff like physics and collisions?  You can maximize with another
> thread.
>
> Also - 2 (game and UI) or 3 threads (game logic, rendering and UI)
> does make sense because you never want to block the UI thread in
> Android.  Get out of its way as fast as possible!  :)
>
> On Apr 9, 1:58 pm, Eddie Ringle <ed...@eringle.net> wrote:
>
> > Is it as simple as:
>
> > In GameView.java (my custom GLSurfaceView class):
> > World _world = new World();
>
> > GameRenderer _renderer = new GameRenderer(_world);
>
> > In GameRenderer.java:
> > public World _world;
>
> > public GameRenderer(World world)
> > {
> >     _world = world;
>
> > }
>
> > In GameRenderer.java, _world would now have the address of world,
> > which is the address of GameView.java's _world, right?
>
> > On Apr 9, 2:49 pm, Eddie Ringle <ed...@eringle.net> wrote:
>
> > > One more thing question and I think I will be set. Coming from a C/C++
> > > background, I enjoyed the use of references. I know that there is a
> > > way to pass the reference by value in Java, but am not quite clear on
> > > how. Could I, for example, create my World object, then pass that
> > > object to the renderer and logic objects when I create them? I did a
> > > small bit of reading on this topic, but still am not quite sure.
>
> > > On Apr 9, 1:55 pm, Robert Green <rbgrn....@gmail.com> wrote:
>
> > > > Yeah, you're going to want to model your game like you would model the
> > > > real world:
>
> > > > class World {
> > > >   public Player player;
> > > >   public Enemy[] enemies;
> > > >   public int timeLeft;
> > > >   public int level;
> > > >   //etc..
>
> > > > }
>
> > > > Then you update the world (usually by calls to player.update,
> > > > enemy.update, etc) from your logic thread.
>
> > > > Then what I like to do is separate the rendering stuff from the
> > > > simulation so that I have renderers for specific things:
>
> > > > class PlayerRenderer extends BaseRenderer {
> > > >   // knows about player geometry, knows how to draw the player and
> > > > anything player-related..
>
> > > > }
>
> > > > Then in my main Renderer, I just call out to the individual component
> > > > renderers:
>
> > > > class WorldRenderer implements Renderer {
> > > >   onDrawFrame(GL gl) {
> > > >     // clear, set up projection, etc
> > > >     playerRenderer.draw(gl, world.player);
> > > >     enemyRenderer.draw(gl, world.enemies);
> > > >     // etc..
> > > >   }
>
> > > > }
>
> > > > And that's how I do it.  I have just a little bit of initialization
> > > > communication from the Renderer side to the game logic so that we can
> > > > set up positioning of touchable UI components but otherwise it's
> > > > always GameThread updates World, WorldRenderer draws World, repeat.
>
> > > > On Apr 9, 11:25 am, Eddie Ringle <ed...@eringle.net> wrote:
>
> > > > > Where do you store all your attributes, like player position?
> > > > > Currently I just have a "GLQuad" class that I use to create new quads,
> > > > > texture them, and manage position and velocity. Do you store them in
> > > > > World, and then each side can access them from the world object?
> > > > > Also, threading is new to me, so I really have no clue what a lock is.
>
> > > > > On Apr 9, 12:03 pm, Robert Green <rbgrn....@gmail.com> wrote:
>
> > > > > > It's pretty easy to do this:
>
> > > > > > I use a World to write to and read from for the two "sides."  Makes
> > > > > > networking nice too.  My World has a simple lock.  Only one thing 
> > > > > > can
> > > > > > write to it or read from it at a time.
>
> > > > > > in GameLogicThread:
>
> > > > > > run() {
> > > > > >  while (!done) {
> > > > > >   // wait for renderer
> > > > > >   world.getLock(); // blocks
> > > > > >   update()
> > > > > >   world.releaseLock();
> > > > > >  }
>
> > > > > > }
>
> > > > > > in Renderer:
>
> > > > > > onDrawFrame() {
> > > > > >   world.getLock(); // blocks
> > > > > >   draw()
> > > > > >   world.releaseLock();
>
> > > > > > }
>
> > > > > > On Apr 9, 3:27 am, Clankrieger <tob...@googlemail.com> wrote:
>
> > > > > > > Hi,
>
> > > > > > > I had a lot of difficulties getting the threading and app 
> > > > > > > lifecycle
> > > > > > > issues done, too. For my part, this was much more confusing than
> > > > > > > getting the actual game done. ;)
>
> > > > > > > The good thing is: you do not have to do too much for the render- 
> > > > > > > and
> > > > > > > logic-thread separation because most of the rendering time is 
> > > > > > > getting
> > > > > > > spent "outside" of your renderer's onDraw method. This is how I 
> > > > > > > got
> > > > > > > this done: The "Game" itself is owned by the glSurfaceView 
> > > > > > > renderer
> > > > > > > instance. the when the game starts (at onResume), I start an
> > > > > > > updatethread that is very simple an does something like
>
> > > > > > > while(bKeeprunning) {
> > > > > > >   synchronized(Game.sInstance) {
> > > > > > >     Game.sInstance.update();
> > > > > > >   }
> > > > > > >   Thread.sleep(50);
>
> > > > > > > }
>
> > > > > > > I have to add that my game logic is doing only this: logic. The 
> > > > > > > world
> > > > > > > gets simulated. This is done less than 10 times per second - this 
> > > > > > > is
> > > > > > > why I can have it sleep for 50 ms. sleeping is important here to 
> > > > > > > give
> > > > > > > the render thread time to do this (I don't remember the full 
> > > > > > > method
> > > > > > > signature, but I think you know what I mean):
>
> > > > > > > onDrawGlFrame() {
> > > > > > >   synchronized(Game.sInstance) {
> > > > > > >     Game.sInstance.render();
> > > > > > >   }
> > > > > > >   Thread.sleep(5);
>
> > > > > > > }
>
> > > > > > > I defined the updatethread as class inside of the Renderer 
> > > > > > > because it
> > > > > > > is so small. This gave me a huge performance boost. Handling the 
> > > > > > > app
> > > > > > > lifecycle is less easy (at least for me).
>
> > > > > > > On Apr 9, 3:09 am, Eddie Ringle <ed...@eringle.net> wrote:
>
> > > > > > > > Surprisingly, I don't seem to have issues with the OpenGL side 
> > > > > > > > of
> > > > > > > > things (which is very unusual), but my problems stem from 
> > > > > > > > getting a
> > > > > > > > clear idea for app architecture and a few other problems.
> > > > > > > > Right now, most tutorials on the net just describe the render 
> > > > > > > > portion.
> > > > > > > > I know that when I create a GLSurfaceView and hook a Renderer 
> > > > > > > > into it,
> > > > > > > > it uses it's own thread for rendering.
>
> > > > > > > > I want to do logic operations and other gameplay stuff (like 
> > > > > > > > moving
> > > > > > > > characters and whatnot) in it's own thread as well. Can anyone 
> > > > > > > > explain
> > > > > > > > a good approach to this? I'm guessing the two threads will have 
> > > > > > > > to be
> > > > > > > > synchronized (do logic, render, repeat), and limited based on 
> > > > > > > > time so
> > > > > > > > that it performs smoothly across different devices.

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to