OpenGL set up

Tutorials concerning the OpenGL® ES cross-platform API for full-function 2D and 3D graphics on the Google-Android platform.

OpenGL set up

Postby TimV » Fri Oct 02, 2009 12:43 am

Hi,

So I have the LunarLander sample. So I made my own opengl rendering activity (but its hacked together, and doesn't allow for a "game loop", unless I put it into the per/frame drawing code).

How do I set up an OpenGL renderer, with a proper "game loop", using GLSurfaceView? This stuff confuses me to no limit.

Thank you very much.

Sincerely,
Tim
TimV
Freshman
Freshman
 
Posts: 7
Joined: Fri Oct 02, 2009 12:34 am

Top

Postby Shaka » Fri Oct 02, 2009 7:21 am

Hiya!

To set up an OpenGL rendering loop you need to use GLSurfaceView or create a class that extends GLSurfaceView, you then create another class that implements the Renderer interface. The latter is where you implement your render logic. GLSurfaceView creates a new rendering thread for you.

Example:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. class GameActivity extends Activity
  2.  
  3. {
  4.  
  5.         protected onCreate(Context context){
  6.  
  7.                 super(context);
  8.  
  9.                 GLSurfaceView surfaceView = new GLSurfaceView(this);
  10.  
  11.                 surfaceView.setRenderer(new GameRenderer());   
  12.  
  13.                 setContentView(surfaceView);   
  14.  
  15.         }
  16.  
  17.  
  18.  
  19. }
  20.  
  21.  
  22.  
  23. class GameRenderer implements GLSurfaceView.Renderer{
  24.  
  25.         public void onSurfaceCreated(GL10 gl, EGLConfig config){
  26.  
  27.                 //Do OpenGL init stuff.
  28.  
  29.         }
  30.  
  31.  
  32.  
  33.         public void onDrawFrame(GL10 gl){
  34.  
  35.                 //Do rendering.
  36.  
  37.         }
  38.  
  39.  
  40.  
  41.         public void onSurfaceChanged(GL10 gl, int w, int h){
  42.  
  43.                 gl.glViewport(0, 0, w, h);
  44.  
  45.         }
  46.  
  47.  
  48.  
  49. }
Parsed in 0.032 seconds, using GeSHi 1.0.8.4
Shaka
Developer
Developer
 
Posts: 44
Joined: Fri Aug 28, 2009 3:01 pm

Postby TimV » Fri Oct 02, 2009 2:47 pm

Excellent answer! Thank you Shaka.
Unfortunately, I've gone this far, and now I am facing an issue of where the main game logic thread would be?
As in, the main loop (but not for rendering, and I wish to abstract logic from drawing code).

Now, I also feel that I should set the GLSurfaceView.Render implementation to render on request (I have that stuff set) so I would request rendering from inside the main loop.

Its just that I developed many engines in C/C++, but never in Java, and especially never on Android, so this API is a little confusing for me. And threaded programming is also the kind of stuff I never seriously messed with :)

So if you/someone could help me out with this, I would greatly appreciate it. I saw the main loop in LunarLander, but it uses a different rendering interface, and all the "synchronized" calls confuse me.

Thank you in advance!

Sincerely,
Tim
TimV
Freshman
Freshman
 
Posts: 7
Joined: Fri Oct 02, 2009 12:34 am

Postby TimV » Fri Oct 02, 2009 3:19 pm

Excuse me, but also - I see the SurfaceHolder object all over the place, how does it tie together with GLSurfaceView?

I see it used in a lot of demos, but I can't get its function and relationship/use with GLSurfaceView. Could someone please explain?

Thank you!
TimV
Freshman
Freshman
 
Posts: 7
Joined: Fri Oct 02, 2009 12:34 am

Postby Shaka » Fri Oct 02, 2009 3:56 pm

TimV wrote:Excuse me, but also - I see the SurfaceHolder object all over the place, how does it tie together with GLSurfaceView?

I see it used in a lot of demos, but I can't get its function and relationship/use with GLSurfaceView. Could someone please explain?

Thank you!


Well, the SurfaceHolder is basically the surface of the GLSurfaceView (or any view for that matter).

About where the logic should go I'm not sure what the standard way of doing this is (if there is one) :P
I'm currently developing a framework that wraps the view and thread creation into a class. The user can then supply a callback class that will receive update calls from the thread at every rendering iteration, so the main loop is in the thread but the logic is handled in the callback class.

I also come from C++/C# development and I'm still experimenting with the platform, so I can't tell you it's the right way to do it but it works well for me (so far) :)
Shaka
Developer
Developer
 
Posts: 44
Joined: Fri Aug 28, 2009 3:01 pm

Postby TimV » Fri Oct 02, 2009 4:18 pm

I'm experimenting right now in the same way, and I see that some people have View classes create a thread with the Runnable object as a parameter, which in turn I assume could act as the main loop (needs some yielding/blocking). Is that correct?

There is a Rokon framework available on these forums, and I downloaded the alpha version to take a look at whats going on, it makes sense but I still don't see a main loop anywhere, and there are too many allocations in real time so the GC goes nuts all the time, have you looked at that code?

I will need to go home and look over some of this stuff when it comes to SurfaceHolder :)

Thank you for being so responsive Shaka!
TimV
Freshman
Freshman
 
Posts: 7
Joined: Fri Oct 02, 2009 12:34 am

Top

Postby Shaka » Sun Oct 04, 2009 7:16 am

TimV wrote:I'm experimenting right now in the same way, and I see that some people have View classes create a thread with the Runnable object as a parameter, which in turn I assume could act as the main loop (needs some yielding/blocking). Is that correct?

There is a Rokon framework available on these forums, and I downloaded the alpha version to take a look at whats going on, it makes sense but I still don't see a main loop anywhere, and there are too many allocations in real time so the GC goes nuts all the time, have you looked at that code?

I will need to go home and look over some of this stuff when it comes to SurfaceHolder :)

Thank you for being so responsive Shaka!


Hi!

Moving from C/C++ and opengl or directx to Android can be a bit confusing. In the case of OpenGL, the main loop is in the Renderer, in the onDrawFrame method, so you never explicitly tell the renderer when to draw as in opposed to for example Windows programming.

I haven't had a look at the Rokon framework though from the videos it looks pretty nifty, will have to check it out later. :)
Last edited by Shaka on Sun Oct 04, 2009 7:35 am, edited 1 time in total.
Shaka
Developer
Developer
 
Posts: 44
Joined: Fri Aug 28, 2009 3:01 pm

Postby TimV » Sun Oct 04, 2009 7:26 am

Hi Shaka,

The Rokon framework looked like a good example for an ideal setup, but as I keep looking over it, it seems to be much, much less than perfect.

I'm hearing a lot of good stuff, but I think my main problem is code wise, how would I set up a thread for my game logic, parallel to the GLSurfaceView thread, and then in turn how would I make them communicate among each other.

So far I kind of gave up on that idea, and I'm running all my logic from the GLSurfaceView.Render per-frame update method, but I feel incredibly iffy running my logic from a rendering loop. Linear execution on android seems like a bad idea (especially knowing that I have an ARM processor, which is ideal for multi-threading).

Do you think you could help me out a little bit, in terms of how to set up a thread parallel to the one created by GLSurfaceView? And some pointers on per-thread communication would be the frosting on top of the cake :)

Thank you so much for your help Shaka.

Sincerely,
Tim
TimV
Freshman
Freshman
 
Posts: 7
Joined: Fri Oct 02, 2009 12:34 am

Postby Shaka » Mon Oct 05, 2009 1:40 pm

Hiya!

Since I'm currently running my game logic at every render through the callback I haven't tried running it in a separate thread (but I think I will sooner or later).

What you could do is create a game logic class that implements Thread and run it in parallell with your rendering in GLSurfaceView.Render.
Though you'd probably want some kind of model and or sprite object you can reference from both threads. Like for example, in my framework i have a Sprite class that contains the image (bitmap when canvas rendering) and position information etc. I update the position for the sprite in the game logic code whilst the render thread takes care of rendering it.
Similar to Rokon I do something like this.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public GameActivity extends Activity
  2.  
  3. {
  4.  
  5.  
  6.  
  7. protected void onCreate(){
  8.  
  9. Trident2D trident2D = new Trident2D(this, RenderMode.Canvas); //name of my 2D renderer, starts a rendering thread
  10.  
  11. trident2D.AddSprite(SpriteFactory.CreateStaticSprite(getResources(), R.drawable.sprite);
  12.  
  13. }
  14.  
  15.  
  16.  
  17. }
  18.  
  19.  
  20.  
  21. here you could extend it to:
  22.  
  23.  
  24.  
  25. public GameActivity extends Activity
  26.  
  27. {
  28.  
  29.  
  30.  
  31. protected void onCreate(){
  32.  
  33. Trident2D trident2D = new Trident2D(this, RenderMode.Canvas); //name of my 2D renderer, starts a rendering thread
  34.  
  35. trident2D.AddSprite(SpriteFactory.CreateStaticSprite(getResources(), R.drawable.sprite); //Adds a sprite and starts rendering it directly.
  36.  
  37.  
  38.  
  39. GameLogic gameLogic = new GameLogic();
  40.  
  41. gameLogic.start();
  42.  
  43. gameLogicThread.AddSprite(sprite);
  44.  
  45. }
  46.  
  47.  
  48.  
  49. }
  50.  
  51.  
  52.  
  53.  
  54.  
  55. GameLogic extends Thread{
  56.  
  57.  
  58.  
  59. public void run(){
  60.  
  61.  
  62.  
  63. while(running){
  64.  
  65. for(int i = 0; i < _spriteList.size(); i++){
  66.  
  67.  
  68.  
  69. Sprite currentSprite = _spriteList.get(i);
  70.  
  71.  
  72.  
  73. //Lock down the sprite to this thread and modify it
  74.  
  75. synchronized(currentSprite){
  76.  
  77. _spriteList.get(i).Move(10,10);
  78.  
  79. }
  80.  
  81. }
  82.  
  83.  
  84.  
  85. public void AddSprite(Sprite sprite){
  86.  
  87. _spriteList.add(sprite);
  88.  
  89. }
  90.  
  91.  
  92.  
  93. }
Parsed in 0.034 seconds, using GeSHi 1.0.8.4


Now this code is just of the top of my head so it'll probably contain alot of syntax errors :), but I believe something similar could work for you.
Shaka
Developer
Developer
 
Posts: 44
Joined: Fri Aug 28, 2009 3:01 pm

Postby TimV » Mon Oct 05, 2009 3:12 pm

Ah! Good stuff Shaka!

One (hopefully for now, last) question:
"synchronized(" - this keyword is used on any pointer to lock it down (for thread safety), while the thread is editing it, is that correct? So if I have a series of sprites, I lock them down in my game thread, edit them, and then the render thread locks them down, and renders them? (theoretically in parallel?)

In other words, any shared data need their pointers locked down in each thread that is using them at that particular point in time?

I will do my research, but I just want to abuse the fact that you're so helpful ;)

Thank you once more Shaka, you are indeed a great help!

Sincerely,
Tim Vasko
TimV
Freshman
Freshman
 
Posts: 7
Joined: Fri Oct 02, 2009 12:34 am

Postby TimV » Mon Oct 05, 2009 3:45 pm

Hey Shaka,

I looked up the Java reference in this matter, no need to answer the above question.

Once again, you have been incredibly helpful, thank you and best wishes!

Sincerely,
Tim
TimV
Freshman
Freshman
 
Posts: 7
Joined: Fri Oct 02, 2009 12:34 am

Postby Shaka » Mon Oct 05, 2009 3:55 pm

Hi Tim!

You're correct about the synch part :)

Glad I could help, and please do post about any progress you make, I'm still in the learning phase myself so any good solutions to different kinds of problems are always of an interest :)

Regards /Shaka
Shaka
Developer
Developer
 
Posts: 44
Joined: Fri Aug 28, 2009 3:01 pm

Top

Return to Android 2D/3D Graphics - OpenGL Tutorials

Who is online

Users browsing this forum: No registered users and 2 guests