0

I'm trying to create game loop which runs in separate thread. I decided to use NSThread object instead of CADisplayLink and NSTimer.
To test if OpenGLES is working correctly I'm clearing the screen by solid color.
The problem here is that all is working fine with no loops, single render call from initWithFrame. But when I put my render code inside game loop, or just simply create new thread and call render code from new thread there is nothing happens in the screen.
Here is my initWithFrame function which is called from AppDelegate's didFinishLaunchingWithOptions:

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
    [self setupLayer];
    [self setupContext];
    [self setScaleFactor];      
    [self initGame];
    [NSThread detachNewThreadSelector:@selector(render) toTarget:self withObject:nil];
}
return self;
}

And this is render function:

- (void)render
{
    glClearColor(1.0f, 0.0f, 1.0f, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    [context presentRenderbuffer:GL_RENDERBUFFER];
}

If I put render call instead of creating thread inside initWithFrame, all works fine. But with current implementation I get black screen, despite render function is called. I also tried using

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(render) object:nil];
[thread start];

It does not make pink screen to appear either.
Appreciate any advices how can I use threads to get OpenGl ES rendered to the screen.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
user1687498
  • 61
  • 1
  • 7

2 Answers2

0

Try this:

@interface GameObject
{
  BOOL hasStoppedRendering;
}

@end

@implementation GameObject

- (id)initWithFrame:(CGRect)frame
{
   self = [super initWithFrame:frame];
   if (self)
   {
    [self setupLayer];
    [self setupContext];
    [self setScaleFactor];      
    [self initGame];
    [NSThread detachNewThreadSelector:@selector(render) toTarget:self withObject:nil];
   }
  return self;
}

- (void)render
{
    while(!hasStoppedRendering)
    {
      /*BEGIN RENDERING CODE*/
          glClearColor(1.0f, 0.0f, 1.0f, 1.0);
          glClear(GL_COLOR_BUFFER_BIT);
      /*END RENDERING CODE*/

     [self performSelector:@selector(presentRenderBuffer) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES]; 
    }

}

- (void)presentRenderBuffer
{
  [context presentRenderbuffer:GL_RENDERBUFFER];
}


@end
CodenameLambda1
  • 1,299
  • 7
  • 17
  • As @borrrden said, context object must be used in the same thread where it was created. Otherwise render code would not work. Now I get it working with creating and using context in the same thread, but I still have to solve why I can't use loop inside thread function. I have terrible performance now, 1-3fps. Probably it's connected with presenting render buffer. – user1687498 Aug 19 '13 at 10:59
-1

add [EaglContext setCurrentContext:eaglobject];

MathieuF
  • 3,130
  • 5
  • 31
  • 34