【问题标题】:GLKit, Opengl ES 3.0, get depth with glReadPixelsGLKit,Opengl ES 3.0,使用 glReadPixels 获取深度
【发布时间】:2018-09-18 16:10:44
【问题描述】:

我可以在屏幕上获得距离点吗? 这是代码:

- (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);
}

一切都画得很完美,但我无法确定画点的距离。

编辑:

我记录深度,也尝试颜色。仅使用此参数读取颜色:

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

使用 GL_FLOAT 时,无法读取 rgb。 我也尝试在绘制后获取值:

- (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
}

不适合我

【问题讨论】:

    标签: ios opengl-es glkit


    【解决方案1】:

    除了您应该查看depth 而不是pixelColor这一事实之外,您还需要注意时间,这应该是在帧完成绘制之后和下一帧提交之前。

    【讨论】:

    • 不起作用 =( pixelColor 是实验,无论如何深度都没有读取
    • 如果 glReadPixels 成功,你会得到一个介于 0 和 1 之间的数字。此时你需要看看失败的原因。使用 glGetError 查看发生了什么。 khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetError.xml
    • 谢谢,seams OpenGL ES 3.0 不支持读取深度组件,只支持 GL_RGBA。
    • 我想知道这一点,但有足够的引用来实际读取我无法确定的深度缓冲区。不过也许有一种解决方法,因为您可以取消投影接触点并在世界空间中投影一条射线以进行碰撞(/深度)检测。
    • 只要你能绑定深度缓冲区,你仍然可以做一些恶作剧从RGBA值计算深度值。对于 16 位深度缓冲区,公式将类似于 R * (1/255*256) + G * (1/256)。
    【解决方案2】:

    OpenGL ES 2.0 不支持从缓冲区读取GL_DEPTH_COMPONENT。更多信息在这里:

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

    它适用于 Opengl ES 3.0

    在 ES 3.0 及更高版本中,支持深度纹理。使用它,您可以使用以下步骤获得深度。

    • 将场景渲染到 FBO,使用纹理作为深度附件。
    • 使用对深度进行采样的着色器渲染屏幕大小的四边形 上一步生成的纹理,并将值写入 颜色缓冲区。
    • 在颜色缓冲区上使用 glReadPixels()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-12
      • 2015-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多