gpt4 book ai didi

objective-c - 将 CVOpenGLESTextureCacheCreateTextureFromImage 移植到普通的 OpenGL ES 方法

转载 作者:行者123 更新时间:2023-11-29 11:09:52 24 4
gpt4 key购买 nike

我正在开发一个应用程序,它将来自相机的视频帧输入到 OpenGL ES 纹理中以创建一些效果。该应用程序使用 Core Video 及其许多便捷方法来创建 OpenGL 纹理和缓存。

现在我想使用静态图像而不是视频缓冲区,我正在寻找标准的 OpenGL 方法来代替 Core Video 可用的方法。

例如:

  • CVOpenGLESTextureRef;
  • CVOpenGLESTextureCacheRef;
  • CVOpenGLESTextureCacheCreateTextureFromImage();
  • CVOpenGLESTextureGetTarget();
  • CVOpenGLESTextureGetName();
  • CVOpenGLESTextureCacheFlush();

我可以使用哪些标准 OpenGL 类型和方法来代替上面的代码,从普通图像加载和创建纹理?

谢谢

*编辑*

根据 Brad 的建议,我取得了一些进展……但仍然无法正常工作。我认为问题在于着色器期望两个单独的纹理能够正常工作。一个用于 Y 平面,一个用于 UV 平面。

这是用于设置它们的代码

// Y-plane
glActiveTexture(GL_TEXTURE0);
err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RED_EXT, _textureWidth, _textureHeight, GL_RED_EXT, GL_UNSIGNED_BYTE, 0, &_lumaTexture);
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);

// UV-plane
glActiveTexture(GL_TEXTURE1);
err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RG_EXT, _textureWidth/2, _textureHeight/2, GL_RG_EXT, GL_UNSIGNED_BYTE, 1, &_chromaTexture);
glBindTexture(CVOpenGLESTextureGetTarget(_chromaTexture), CVOpenGLESTextureGetName(_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);

所以我改成这样:

这是设置

glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &_lumaImageTexture);
glBindTexture(GL_TEXTURE_2D, _lumaImageTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &_chromaImageTexture);
glBindTexture(GL_TEXTURE_2D, _chromaImageTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

下面是我如何创建它们

// Y-plane
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _lumaImageTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _textureWidth, _textureHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, imageData);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// UV-plane
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _chromaImageTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _textureWidth, _textureHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, imageData);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

我猜问题出在 glTexImage2D 函数的参数之一。我尝试了具有不同结果的不同组合...但从来没有正确的组合:)

最佳答案

所有这些方法所做的就是为您提供对应于 CVPixelBuffer 的 OpenGL ES 纹理。在 iOS 5.0 中引入这些之前,我们必须手动从 CVPixelBuffer 中获取像素数据并将其上传到纹理。对于从另一个来源提取的静态图像,您可以使用相同的过程(除非您想使用一些 GLKit 便利类)。

以下是我用来上传静态图片的代码。首先,您需要将图像放入 BGRA 字节数组中:

if (shouldRedrawUsingCoreGraphics)
{
// For resized image, redraw
imageData = (GLubyte *) calloc(1, (int)pixelSizeToUseForTexture.width * (int)pixelSizeToUseForTexture.height * 4);

CGColorSpaceRef genericRGBColorspace = CGColorSpaceCreateDeviceRGB();
CGContextRef imageContext = CGBitmapContextCreate(imageData, (int)pixelSizeToUseForTexture.width, (int)pixelSizeToUseForTexture.height, 8, (int)pixelSizeToUseForTexture.width * 4, genericRGBColorspace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(imageContext, CGRectMake(0.0, 0.0, pixelSizeToUseForTexture.width, pixelSizeToUseForTexture.height), newImageSource);
CGContextRelease(imageContext);
CGColorSpaceRelease(genericRGBColorspace);
}
else
{
// Access the raw image bytes directly
dataFromImageDataProvider = CGDataProviderCopyData(CGImageGetDataProvider(newImageSource));
imageData = (GLubyte *)CFDataGetBytePtr(dataFromImageDataProvider);
}

在上面的代码中,newImageSource 是一个 CGImageRef。这显示了提取位图数据的两种不同路径,在我运行的每个基准测试中,第一种路径出人意料地更快。

一旦你有了它,你只需要将它上传到你的 OpenGL ES 纹理:

    glBindTexture(GL_TEXTURE_2D, outputTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)pixelSizeToUseForTexture.width, (int)pixelSizeToUseForTexture.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, imageData);

这假设您已经使用如下内容创建了 outputTexture:

    glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &outputTexture);
glBindTexture(GL_TEXTURE_2D, outputTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// This is necessary for non-power-of-two textures
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

并且使用 +setCurrentContext: 将正确的 EAGLContext 关联到当前线程。

如果我可以提出建议,为什么不看看 my open source framework为您处理所有这些以便完成图像处理任务?这可能会为您节省一些精力。

关于objective-c - 将 CVOpenGLESTextureCacheCreateTextureFromImage 移植到普通的 OpenGL ES 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12039429/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com