GLKit,Opengl ES 3.0,使用 glReadPixels 获取深度
GLKit, Opengl ES 3.0, get depth with glReadPixels
如何在屏幕上获取距离点?
这是代码:
- (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
}
不适合我
除了你应该查看 depth
而不是 pixelColor
之外,你还需要注意时间,应该是在框架完成绘制之后和提交之前下一帧。
OpenGL ES 2.0 不支持从缓冲区读取 GL_DEPTH_COMPONENT
。更多信息在这里:
适用于 Opengl ES 3.0
在 ES 3.0 及更高版本中,支持深度纹理。使用它,您可以使用以下步骤获得深度。
- 将场景渲染到 FBO,使用纹理作为深度附件。
- 使用对深度进行采样的着色器渲染屏幕大小的四边形
上一步生成的纹理,并将值写入
颜色缓冲区。
- 在颜色缓冲区上使用 glReadPixels()。
如何在屏幕上获取距离点? 这是代码:
- (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
}
不适合我
除了你应该查看 depth
而不是 pixelColor
之外,你还需要注意时间,应该是在框架完成绘制之后和提交之前下一帧。
OpenGL ES 2.0 不支持从缓冲区读取 GL_DEPTH_COMPONENT
。更多信息在这里:
适用于 Opengl ES 3.0
在 ES 3.0 及更高版本中,支持深度纹理。使用它,您可以使用以下步骤获得深度。
- 将场景渲染到 FBO,使用纹理作为深度附件。
- 使用对深度进行采样的着色器渲染屏幕大小的四边形 上一步生成的纹理,并将值写入 颜色缓冲区。
- 在颜色缓冲区上使用 glReadPixels()。