Question

I hope to create an offScreen FBO, and use glReadPixels() to get the value of RGBA in this offScreen FBO. unfortunately, I got the error: GL_ERROR:0x0502

#import "ViewController.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))

@interface ViewController ()
{
  GLuint backFBO;
  GLuint defaultFBO;
  int fbo_width;
  int fbo_height;

  //
  GLuint _vertexArray;
  GLuint _vertexBuffer;
  GLuint _texCoordBuffer;
  GLuint depthBuffer;

  //
  GLKMatrix4 _modelViewProjectionMatrix;
  GLKMatrix3 _normalMatrix;
  float _rotation;

}

@property (nonatomic, strong) GLKBaseEffect *baseEffect;
@property (nonatomic, strong) EAGLContext *context;

- (void)setupGL;
- (void)tearDownGL;
- (void)setupFBO;
@end

the vertex data and normal data of object in onScreen FBO

GLfloat gVertexData[] =
{
  0.5f, 0.5f, 0.0f,    0.0f, 0.0f, 1.0f,
  -0.5f, 0.5f, 0.0f,    0.0f, 0.0f, 1.0f,
  0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,
  -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f
};

@implementation ViewController

- (void)viewDidLoad
{
  [super viewDidLoad];

  //1. setup context
  self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2
                ];
  if (!self.context) {
    NSLog(@"Failed to create GLES Context");
}

  GLKView *view = (GLKView *)self.view;
  view.context = self.context;
  view.drawableDepthFormat = GLKViewDrawableDepthFormat24;

  [self setupGL];

}

- (void)viewDidUnload
{
    [super viewDidUnload];

    [self tearDownGL];

   if ([EAGLContext currentContext] == self.context) {
    [EAGLContext setCurrentContext:nil];
  }
self.context = nil;
}

- (void) setupGL
{
  [EAGLContext setCurrentContext:self.context];

  self.baseEffect = [[GLKBaseEffect alloc] init];

  glEnable(GL_DEPTH_TEST);
  glGenVertexArraysOES(1, &_vertexArray);
  glBindVertexArrayOES(_vertexArray);

  glGenBuffers(1, &_vertexBuffer);
  glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
  glBufferData(GL_ARRAY_BUFFER, sizeof(gVertexData), gVertexData, GL_STATIC_DRAW);

  glEnableVertexAttribArray(GLKVertexAttribPosition);
  glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
  glEnableVertexAttribArray(GLKVertexAttribNormal);
  glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

  glBindBuffer(GL_ARRAY_BUFFER, 0);
  glBindVertexArrayOES(0);

// initialize FBO
[self setupFBO];


}
- (void) tearDownGL
{
  [EAGLContext setCurrentContext:self.context];
  glDeleteBuffers(1, &_vertexBuffer);
}


- (void)update
{
  float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
  GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);

  self.baseEffect.transform.projectionMatrix = projectionMatrix;

  // Compute the model view matrix for the object rendered with ES2
  GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -2.0f);
  modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);

  self.baseEffect.transform.modelviewMatrix = modelViewMatrix;

  _rotation += self.timeSinceLastUpdate * 0.5f;
}

 - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
  // render FBO tex
  [self renderFBO];

  // reset to main framebuffer
  [((GLKView *) self.view) bindDrawable];

  glViewport(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
  // render main
  glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glBindVertexArrayOES(_vertexArray);
  [self.baseEffect prepareToDraw];
  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

#pragma mark - FBO

// intialize FBO
- (void)setupFBO
{
  fbo_width = 512;
  fbo_height = 512;

  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
  NSLog(@"default FBO: %d", defaultFBO);


  glGenFramebuffers(1, &backFBO);
  glGenRenderbuffers(1, &depthBuffer);

  glBindFramebuffer(GL_FRAMEBUFFER, backFBO);

  glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, fbo_width, fbo_height);

  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);

  // FBO status check
  GLenum status;
  status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  switch(status) {
    case GL_FRAMEBUFFER_COMPLETE:
        NSLog(@"fbo complete");
        break;

    case GL_FRAMEBUFFER_UNSUPPORTED:
        NSLog(@"fbo unsupported");
        break;

    default:
        /* programming error; will fail on all hardware */
        NSLog(@"Framebuffer Error");
        break;
  }

  glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
}

 // render FBO
- (void)renderFBO
{
  glBindFramebuffer(GL_FRAMEBUFFER, backFBO);
  glViewport(0,0, fbo_width, fbo_height);
  glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  **//in here, I hope to get the value of RGBA in offScreen FBO**
  Byte pixelColor[4] = {0,};
  glReadPixels(50, 50, fbo_width, fbo_height, GL_RGBA, GL_UNSIGNED_BYTE, pixelColor);

  glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
}

when I comment glReadPixels(), it's works well. Any help or advice would be much appreciated.

Was it helpful?

Solution

in your offScreen FBO, you should bind a GL_RENDERBUFFER, so you should add below code:

//create a new FBO
glBindFramebuffer(GL_FRAMEBUFFER, backFBO);


// add
GLuint  _colorBuffer;
glGenRenderbuffers(1, &_colorBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _colorBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, fbo_width      , fbo_height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER,  _colorBuffer);

I hope this will fix your error. good luck !!!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top