GLKit, Opengl ES 3.0, get depth with glReadPixels

532 Views Asked by At

Ho can I get distance point on screen? Here is code:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];

    if (!context || ![EAGLContext setCurrentContext:context]) {
        NSLog(@"Failed to create ES context");
    }

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

    glEnable(GL_DEPTH_TEST);

    shader = [[BaseEffect alloc] initWithVertexShader:@"Shader.vsh"
                                       fragmentShader:@"Shader.fsh"];

    // setup projection and model matrix
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepthf(1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


    [shader prepareToDraw];
    // draw point

    glBindVertexArray(vertexArray);
    glDrawArrays(GL_POINTS, 0, pointsCount);
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint tapLoc = [touch locationInView:self.view];

    GLfloat depth = 0;
    glReadPixels(tapLoc.x, tapLoc.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
    NSLog(@"Depth %f", depth);
}

All draws perfectly, but I can't get distance to drew points.

Edit:

I log depth, also experimenting with color. Color is reading only whith this arguments:

glReadPixels(p.x, p.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer);

When use GL_FLOAT, rgb can not be read. I also try get values after drawing:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    // preparing and drawing

    if (testDepthPoint.x != 0) {
        [self testDepth:testDepthPoint];
        testDepthPoint = CGPointZero;
    }
}

- (void)testDepth:(CGPoint)p {
    GLfloat depth = -99.0;
    glReadPixels(p.x, p.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
    NSLog(@"Depth %f", depth); // always log -99.0
}

Not worked for me

2

There are 2 best solutions below

0
Gralex On BEST ANSWER

OpenGL ES 2.0 not supported to read GL_DEPTH_COMPONENT from buffer. More info here:

https://stackoverflow.com/a/18805281/820795

It works for Opengl ES 3.0

In ES 3.0 and later,there is support for depth textures. Using this, you can get the depth using the following steps.

  • Render the scene to an FBO, using a texture as the depth attachment.
  • Render a screen sized quad with a shader that samples the depth texture generated in the previous step, and writes the value to the color buffer.
  • Use glReadPixels() on the color buffer.
6
IanSabine On

Besides the fact that you should be looking at depth instead of pixelColor, you also need to be aware of timing, which should be after the frame has completed drawing and before the submit of the next frame.