我在生成带有深度数据的Float纹理时遇到问题。
由于我认为它更像是一个OpenGL ES(OES 2.0)问题而不是我正在使用的SDK,我试着在这里考虑OpenGL ES部分获得帮助。
我得到的错误只是我的应用程序崩溃,这就是为什么我认为错误是错误的纹理和/或错误使用浮动纹理。
关于我正在使用的数据的几个注释:
-The depthFrame I am getting is in Float
-With the use of depthInMillimeters, it is possible to get actual mm values in Float
-Since i am working on an iPhone 5 GL_HALF_FLOAT_OES should be available to use
-If someone wants to know, the data comes from the StructureSensor
这是我从流式深度数据生成纹理的功能。 我使用几乎相同的函数从图像生成RGB纹理,但使用其他数据输入和值。
-(GLuint) generateDepthTexture: (STDepthFrame*)depthFrame{
//data from depth in mm
NSData *data = [NSData dataWithBytes:depthFrame.depthInMillimeters length:depthFrame.width*depthFrame.height*4];
//data to texture
UIImage* depthImage = [[UIImage alloc] initWithData:data];
CGImageRef spriteImage = [depthImage CGImage];
if(!spriteImage){
NSLog(@"Failed to load image depth");
exit(1);
}
size_t width = CGImageGetWidth(spriteImage);
size_t height = CGImageGetHeight(spriteImage);
GLubyte * spriteData = (GLubyte *) calloc(width*height*4, sizeof(GLubyte)); // *4
CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4,
CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage);
CGContextRelease(spriteContext);
GLuint texName;
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_FLOAT, (GLsizei)width,(GLsizei)height, 0, GL_FLOAT, GL_HALF_FLOAT_OES, spriteData);
free(spriteData);
return texName;
}
这是我的渲染方法的重要部分:
//depth
//depthFrame is given every call
_depthTexture = [self generateDepthTexture:depthFrame];
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, _depthTexture);
glUniform1i(_depthUniform, 2);
我在着色器中使用它:
//texture
uniform sampler2D DepthTexture;
//usage of the Texture
mediump vec4 depthV = texture2D(DepthTexture,TexCoordsIn);
我不确定这里的正确使用方法,因为我宁愿在浮点数中获取值,而不是在vec4中。
同样,我想在考虑具有浮动纹理的OpenGL ES部分时获得一些帮助。如果完全正确,问题必须与我得到的数据有关。如果是这样的话,我会问使用传感器的人。
错误可能只是错误的纹理大小或内存。
我真的希望,有人对此有答案。
答案 0 :(得分:2)
OP似乎已经意识到了这一点,但为了清晰起见,只是提前发送:浮动纹理不标准的ES 2.0功能。仅当OES_texture_float and/or OES_texture_half_float扩展名存在时才支持它们。对于半浮点情况,这是相当明显的,因为扩展引入了GL_HALF_FLOAT_OES
值,但浮点大小写也需要扩展支持,即使扩展不引入新的枚举值。
您尝试使用此扩展程序存在许多问题:
glTexImage2D(GL_TEXTURE_2D, 0, GL_FLOAT, (GLsizei)width, (GLsizei)height, 0,
GL_FLOAT, GL_HALF_FLOAT_OES, spriteData);
您尝试将GL_FLOAT
/ GL_HALF_FLOAT
值传递给内部格式,格式和类型 glTexImage2D()
的论点。但扩展只为 type 参数引入了新值。因此,分配单分量浮动纹理的正确调用是:
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, (GLsizei)width, (GLsizei)height, 0,
GL_LUMINANCE, GL_FLOAT, spriteData);
请注意,与新版本的OpenGL不同,ES 2.0仍然使用GL_LUMINANCE
或GL_ALPHA
作为单组件的 internalformat 和 format 纹理。
对于半浮点纹理,调用是:
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, (GLsizei)width, (GLsizei)height, 0,
GL_LUMINANCE, GL_HALF_FLOAT_OES, spriteData);
对于这种半浮动情况,了解您需要将半浮点(每值16位)数据传递到调用中非常重要。如果您的原始数据是浮动格式,则您必须编写(或查找)将其转换为half-float format的代码。
这在ES 3.0及更高版本中看起来有所不同,其中引入了来自更现代的OpenGL版本的大小的内部格式。在那里,分配单组件浮动纹理的调用将是:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, (GLsizei)width, (GLsizei)height, 0,
GL_RED, GL_FLOAT, spriteData);