iOS将UIImage转为OpenGL texture

原文链接:http://blog.hdlx.tk/index.php/2019/08/16/ios%e5%b0%86uiimage%e8%bd%ac%e4%b8%baopengl-texture/

一、swift

创建一个extension类 UIImage+Texture.switf

import UIKit

import OpenGLES

extension UIImage {

 func createGLTexture() -> GLuint {

 let cgImageRef = self.cgImage

 let width = cgImageRef!.width

 let height = cgImageRef!.height

 let rect = CGRect(x: 0, y: 0, width: width, height: height)

 let imageData = malloc(width * height * 4)

 let context = CGContext(data: imageData, width: width, height: height, bitsPerComponent: 8, bytesPerRow: width * 4, space: cgImageRef!.colorSpace!, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Big.rawValue)

        context?.clear(rect)

        context?.draw(cgImageRef!, in: rect)        

 glEnable(GLenum(GL_TEXTURE_2D))

 /**

         *  GL_TEXTURE_2D表示操作2D纹理

* 创建纹理对象,

* 绑定纹理对象,

         */

 var textureID : GLuint = 0

 glGenTextures(1, &textureID)

 glBindTexture(GLenum(GL_TEXTURE_2D), textureID)

 /**

* 纹理过滤函数

* 图象从纹理图象空间映射到帧缓冲图象空间(映射需要重新构造纹理图像,这样就会造成应用到多边形上的图像失真),

* 这时就可用glTexParmeteri()函数来确定如何把纹理象素映射成像素.

* 如何把图像从纹理图像空间映射到帧缓冲图像空间(即如何把纹理像素映射成像素)

         */

 glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_CLAMP_TO_EDGE); // S方向上的贴图模式

 glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_CLAMP_TO_EDGE); // T方向上的贴图模式

 // 线性过滤:使用距离当前渲染像素中心最近的4个纹理像素加权平均值

 glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR);

 glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_LINEAR);

 /**

* 将图像数据传递给到GL_TEXTURE_2D中, 因其于textureID纹理对象已经绑定,所以即传递给了textureID纹理对象中。

         *  glTexImage2d会将图像数据从CPU内存通过PCIE上传到GPU内存。

* 不使用PBO时它是一个阻塞CPU的函数,数据量大会卡。

         */

 glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGBA, GLsizei(width), GLsizei(height), 0, GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), imageData);

 // 结束后要做清理

 glBindTexture(GLenum(GL_TEXTURE_2D), 0); //解绑

 free(imageData);

 return textureID

    }

}


二、objective-c

创建分类UIImage+Texture

@implementation UIImage(Texture)

/**

 * 加载image, 使用CoreGraphics将位图以RGBA格式存放. 将UIImage图像数据转化成OpenGL ES接受的数据.

 * 然后在GPU中将图像纹理传递给GL_TEXTURE_2D。

 * @return 返回的是纹理对象,该纹理对象暂时未跟GL_TEXTURE_2D绑定(要调用bind)。

 * 即GL_TEXTURE_2D中的图像数据都可从纹理对象中取出。

 */

– (GLuint)createOGLTexture {

 CGImageRef cgImageRef = [self CGImage];

 GLuint width = (GLuint)CGImageGetWidth(cgImageRef);

 GLuint height = (GLuint)CGImageGetHeight(cgImageRef);

 CGRect rect = CGRectMake(0, 0, width, height);    

 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

 void *imageData = malloc(width * height * 4);

 CGContextRef context = CGBitmapContextCreate(imageData, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

 CGContextTranslateCTM(context, 0, height);

 CGContextScaleCTM(context, 1.0f, –1.0f);

 CGColorSpaceRelease(colorSpace);

 CGContextClearRect(context, rect);

 CGContextDrawImage(context, rect, cgImageRef);

 glEnable(GL_TEXTURE_2D);

 /**

     * GL_TEXTURE_2D表示操作2D纹理

     * 创建纹理对象,

     * 绑定纹理对象,

     */

 GLuint textureID;

 glGenTextures(1, &textureID);

 glBindTexture(GL_TEXTURE_2D, textureID);

 /**

     * 纹理过滤函数

     * 图象从纹理图象空间映射到帧缓冲图象空间(映射需要重新构造纹理图像,这样就会造成应用到多边形上的图像失真),

     * 这时就可用glTexParmeteri()函数来确定如何把纹理象素映射成像素.

     * 如何把图像从纹理图像空间映射到帧缓冲图像空间(即如何把纹理像素映射成像素)

     */

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // S方向上的贴图模式

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // T方向上的贴图模式

 // 线性过滤:使用距离当前渲染像素中心最近的4个纹理像素加权平均值

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

 /**

     * 将图像数据传递给到GL_TEXTURE_2D中, 因其于textureID纹理对象已经绑定,所以即传递给了textureID纹理对象中。

     * glTexImage2d会将图像数据从CPU内存通过PCIE上传到GPU内存。

     * 不使用PBO时它是一个阻塞CPU的函数,数据量大会卡。

     */

 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

 NSLog(@”glTexImage2D error : %d” , glGetError());    

 // 结束后要做清理

 glBindTexture(GL_TEXTURE_2D, 0); //解绑

 CGContextRelease(context);

 free(imageData);

 return textureID;

}

@end

你可能感兴趣的:(iOS将UIImage转为OpenGL texture)