我尝试使用Open GL ES 从 OpenCv Mat渲染图像。但是,我得到一个绿屏,没有别的。
我遵循了这条管道: cv :: Mat - > CVPixelBufferRef - > CVOpenGLESTextureCacheCreateTextureFromImage - > glbindTexture。
// OpenGL Texture reference for y images.
CVOpenGLESTextureRef lumaTexture;
// OpenGL Texture reference for color images.
CVOpenGLESTextureRef chromaTexture;
// OpenGL Texture cache for the color camera.
CVOpenGLESTextureCacheRef videoTextureCache;
- (void) uploadGLColorTextureFromMat:(cv::Mat)image{
if(image.empty()){
NSLog(@"image empty.");
}else{
// Clear the previous color texture.
if (lumaTexture)
{
CFRelease (lumaTexture);
lumaTexture = NULL;
}
// Clear the previous color texture
if (chromaTexture)
{
CFRelease (chromaTexture);
chromaTexture = NULL;
}
// Displaying image with width over 1280 is an overkill. Downsample it to save bandwidth.
while( image.cols > 2560 )
cv::resize(image, image, cv::Size(image.cols/2,image.rows/2));
// Allow the texture cache to do internal cleanup.
CVOpenGLESTextureCacheFlush(_display.videoTextureCache, 0);
int height = image.rows;
int width = image.cols;
// set pixel buffer attributes so we get an iosurface
NSDictionary *pixelBufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[NSDictionary dictionary], kCVPixelBufferIOSurfacePropertiesKey,
nil];
// create planar pixel buffer
CVPixelBufferRef pixelBuffer = nil;
CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
(__bridge CFDictionaryRef)pixelBufferAttributes, &pixelBuffer);
// lock pixel buffer
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
// get image details
size_t widthB = CVPixelBufferGetWidth(pixelBuffer);
size_t heightB = CVPixelBufferGetHeight(pixelBuffer);
NSLog(@"%@",(pixelBuffer));
OSType pixelFormat = CVPixelBufferGetPixelFormatType (pixelBuffer);
NSAssert(pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, @"YCbCr is expected!");
// Activate the default texture unit.
glActiveTexture (GL_TEXTURE0);
CVReturn err;
// Create an new Y texture from the video texture cache.
err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,videoTextureCache,
pixelBuffer,
NULL,
GL_TEXTURE_2D,
GL_RED_EXT,
(int)widthB,
(int)heightB,
GL_RED_EXT,
GL_UNSIGNED_BYTE,
0,
lumaTexture);
if (err) {
NSLog(@"CVOpenGLESTextureCacheCreateTextureFromImage failed (error: %d)", err);
CVPixelBufferRelease(pixelBuffer);
return;
}
// Set good rendering properties for the new texture.
glBindTexture(CVOpenGLESTextureGetTarget(lumaTexture), CVOpenGLESTextureGetName(lumaTexture));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Activate the default texture unit.
glActiveTexture (GL_TEXTURE1);
// Create an new CbCr texture from the video texture cache.
err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
videoTextureCache,
pixelBuffer,
NULL,
GL_TEXTURE_2D,
GL_RG_EXT,
(int)widthB/2,
(int)heightB/2,
GL_RG_EXT,
GL_UNSIGNED_BYTE,
1,
&chromaTexture);
if (err)
{
NSLog(@"Error with CVOpenGLESTextureCacheCreateTextureFromImage: %d", err);
return;
}
// Set rendering properties for the new texture.
glBindTexture(CVOpenGLESTextureGetTarget(chromaTexture), CVOpenGLESTextureGetName(_display.chromaTexture));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
要渲染的功能:
- (void)renderCameraImage
{
if (_useColorCamera)
{
if (!lumaTexture || !chromaTexture)
return;
glActiveTexture(GL_TEXTURE0);
glBindTexture(CVOpenGLESTextureGetTarget(lumaTexture),
CVOpenGLESTextureGetName(lumaTexture));
glActiveTexture(GL_TEXTURE1);
glBindTexture(CVOpenGLESTextureGetTarget(chromaTexture),
CVOpenGLESTextureGetName(chromaTexture));
glDisable(GL_BLEND);
[yCbCrTextureShader useShaderProgram];
[yCbCrTextureShader renderWithLumaTexture:GL_TEXTURE0 chromaTexture:GL_TEXTURE1];
}
else
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _display.depthAsRgbaTexture);
[rgbaTextureShader useShaderProgram];
[rgbaTextureShader renderTexture:GL_TEXTURE0];
}
glUseProgram (0);
}
我没有任何错误。刚拿到绿屏,我没弄明白如何解决这个问题。 作为pixelBuffer的输出,我得到(第一行):
<CVPixelBuffer 0x13e6cd0b0 width=968 height=1296 pixelFormat=420f iosurface=0x140500a28 planes=2>
<Plane 0 width=968 height=1296 bytesPerRow=976>
<Plane 1 width=484 height=648 bytesPerRow=976>
我已经在this post,this one和其他帖子上了,但它对我没有帮助。
你能帮忙弄明白如何解决这个问题吗?