将UIImage转换为纹理。

7
在我的OpenGL项目中,我需要将UIImage转换为纹理;有什么方法可以做到吗? 你能帮我吗?
3个回答

12

我还没有测试以下内容,但我将把转换分解为3个步骤:

  1. 提取图像信息:

    UIImage* image = [UIImage imageNamed:@"imageToApplyAsATexture.png"];
    CGImageRef imageRef = [image CGImage];
    int width = CGImageGetWidth(imageRef);
    int height = CGImageGetHeight(imageRef);
    
  2. 使用上述属性分配一个textureData

  3. GLubyte* textureData = (GLubyte *)malloc(width * height * 4); // if 4 components per pixel (RGBA)
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;  
    CGContextRef context = CGBitmapContextCreate(textureData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    
    CGColorSpaceRelease(colorSpace);
    
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);
    
  4. 设置你的纹理:

    GLuint textureID;    
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glGenTextures(1, &textureID);
    
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
    

编辑:

阅读这篇教程,其中讲解了如何在iOS环境中将一张图片转换为纹理并应用纹理。


我有两个问题:我的图像尺寸是1024x768,我应该在哪里设置这些值?最后,我的纹理是什么? - cyclingIsBetter
为什么context是一个未使用的变量?您能告诉我如何在glpaint中设置纹理和背景吗? - cyclingIsBetter
我不是OpenGL专家,你能帮我一下吗?告诉我如何在glPaint纹理中设置这个纹理? - cyclingIsBetter
我相信你现在可以使用这个链接了:http://blog.csdn.net/opengl_es/article/details/25240061 - tiguero
@tiguero,纹理ID始终为零,你能帮我吗? - a.masri
显示剩余5条评论

1
获取UIImage纹理的Swift版本如下:
func setupTexture(sourceImage: UIImage) -> GLuint {

guard let textureImage = sourceImage.cgImage else {
    print("Failed to load image")
    return 0
}

let width = textureImage.width
let height = textureImage.height

/*
 it will write one byte each for red, green, blue, and alpha – so 4 bytes in total.
 */

let textureData = calloc(width * height * 4, MemoryLayout<GLubyte>.size) //4 components per pixel (RGBA)
let spriteContext = CGContext(data: textureData,
                              width: width,
                              height: height,
                              bitsPerComponent: 8,
                              bytesPerRow: width * 4,
                              space: textureImage.colorSpace!,
                              bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)

spriteContext?.draw(textureImage, in: CGRect(x: 0, y: 0, width: width, height: height))

var textName = GLuint()
glGenTextures(1, &textName)
glBindTexture(GLenum(GL_TEXTURE_2D), textName)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_NEAREST)
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGBA, GLsizei(width),
             GLsizei(height), 0, GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), textureData)

return textName

}

注意:需要记住当我们加载图片时,Core Graphics会翻转它们。


textName为什么总是为零? - a.masri

0

使用GLKit框架的另一种方法:

//Path to image
NSString *path = [[NSBundle mainBundle] pathForResource:@"textureImage" ofType:@"png"];

//Set eaglContext
[EAGLContext setCurrentContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]];

//Create texture
NSError *theError;    
GLKTextureInfo *texture = [GLKTextureLoader textureWithContentsOfFile:filePath options:nil error:&theError];
glBindTexture(texture.target, texture.name);

texture.name 是 OpenGL 上下文对纹理的名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接