GPUImage源码解读(二)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

这篇文章主要是阅读GPUImage框架中的 GLProgram、GPUImageContext 两个重要类的源码。这两个类是 GPUImage 框架的基础,里面涉及的知识也有 OpenGL ES 基础 和 多线程 基础。以下是源码内容:

GLProgram

一 GLProgram

GLProgram专门处理OpenGL ES程序的创建等相关工作。

  • 初始化方法,可以根据需要传入顶点着色器的路径或字符串以及片源着色器的路径及字符串进行初始化。
- (id)initWithVertexShaderString:(NSString *)vShaderString
            fragmentShaderString:(NSString *)fShaderString;
- (id)initWithVertexShaderString:(NSString *)vShaderString
          fragmentShaderFilename:(NSString *)fShaderFilename;
- (id)initWithVertexShaderFilename:(NSString *)vShaderFilename
            fragmentShaderFilename:(NSString *)fShaderFilename;

初始化的过程包含了顶点片源着色器的创建、编译,着色器程序的创建,顶点片源着色器附着到着色器程序等过程。以文件初始化方式最后都会调用 initWithVertexShaderString:fragmentShaderString: 字符串的初始化方式,

- (id)initWithVertexShaderString:(NSString *)vShaderString
            fragmentShaderString:(NSString *)fShaderString;
{
    if ((self = [super init]))
    {
        _initialized = NO;

        // 初始化属性数组
        attributes = [[NSMutableArray alloc] init];
        // 初始化uniform属性数组
        uniforms = [[NSMutableArray alloc] init];

        // 创建着色器程序
        program = glCreateProgram();

        // 编译顶点着色器
        if (![self compileShader:&vertShader
                            type:GL_VERTEX_SHADER
                          string:vShaderString])
        {
            NSLog(@"Failed to compile vertex shader");
        }

        // 编译片源着色器
        // Create and compile fragment shader
        if (![self compileShader:&fragShader
                            type:GL_FRAGMENT_SHADER
                          string:fShaderString])
        {
            NSLog(@"Failed to compile fragment shader");
        }

        // 将顶点片源着色器附着到着色器程序
        glAttachShader(program, vertShader);
        glAttachShader(program, fragShader);
    }

    return self;
}
  • 在给着色器传值的时候,我们需要获取相关属性的位置。GLProgram也提供了相关接口,方便我们获取变量的位置。.h 中定义如下:
//着色器变量的保存和读取
- (void)addAttribute:(NSString *)attributeName;
- (GLuint)attributeIndex:(NSString *)attributeName;
- (GLuint)uniformIndex:(NSString *)uniformName;

具体实现:

- (void)addAttribute:(NSString *)attributeName
{
    // 先判断当前的属性是否已存在
    if (![attributes containsObject:attributeName])
    {
        // 如果不存在先加入属性数组,然后绑定该属性的位置为在属性数组中的位置
        [attributes addObject:attributeName];
        glBindAttribLocation(program,
                             (GLuint)[attributes indexOfObject:attributeName],
                             [attributeName UTF8String]);
    }
}
// END:addattribute
// START:indexmethods
- (GLuint)attributeIndex:(NSString *)attributeName
{
    // 获取着色器属性变量的位置,即在数组的位置(根据之前的绑定关系)
    return (GLuint)[attributes indexOfObject:attributeName];
}
- (GLuint)uniformIndex:(NSString *)uniformName
{
    // 获取Uniform变量的位置
    return glGetUniformLocation(program, [uniformName UTF8String]);
}

  • 链接程序,和编译型语言一样,OpenGL程序也需要链接。
//连接 program
- (BOOL)link;
- (BOOL)link
{
//    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();

    GLint status;
    // 链接着色器程序
    glLinkProgram(program);

     // 获取链接状态
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (status == GL_FALSE)
        return NO;

    if (vertShader)
    {
        glDeleteShader(vertShader);
        vertShader = 0;
    }
    if (fragShader)
    {
        glDeleteShader(fragShader);
        fragShader = 0;
    }
    // 设置初始化成功标识
    self.initialized = YES;

//    CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime);
//    NSLog(@"Linked in %f ms", linkTime * 1000.0);

    return YES;
}
  • 使用着色器程序
//使用 program
- (void)use;
- (void)use
{
    glUseProgram(program);
}
  • log 信息 都会调用内部方法 logForOpenGLObject, 在连接阶段使用glGetProgramInfoLog获取连接错误
//取到log string
- (NSString *)vertexShaderLog;
- (NSString *)fragmentShaderLog;
- (NSString *)programLog;
// START:privatelog 打印 LOG
- (NSString *)logForOpenGLObject:(GLuint)object
                    infoCallback:(GLInfoFunction)infoFunc
                         logFunc:(GLLogFunction)logFunc
{
    GLint logLength = 0, charsWritten = 0;

    infoFunc(object, GL_INFO_LOG_LENGTH, &logLength);    
    if (logLength < 1)
        return nil;

    char *logBytes = malloc(logLength);
    logFunc(object, logLength, &charsWritten, logBytes);
    NSString *log = [[NSString alloc] initWithBytes:logBytes
                                              length:logLength
                                            encoding:NSUTF8StringEncoding];
    free(logBytes);
    return log;
}
  • 释放资源。在析构的时候,将着色器等相关资源清理。
- (void)dealloc
{
    if (vertShader)
        glDeleteShader(vertShader);

    if (fragShader)
        glDeleteShader(fragShader);

    if (program)
        glDeleteProgram(program);

}
CUDA编程之GPU图像数据结构的设计 实现GPU上的图像数据结构,且可以同时使用nvcc和c++编译器进行编译,或者说c++代码链接cu代码 阅读详情

相关推荐

iOS-GPUImage框架:实现多样图像处理与滤镜效果

GPUImage是一个功能强大的图像和视频处理库,它让开发者可以在iOS和Android平台上快速应用复杂的滤镜和图像处理算法。利用GPU加速计算,GPUImage不仅可以实时处理视频流,还能轻松集成到各种图像和视频相关的应用中。GPUImgDemo 是一个展示 GPUImage 框架实际应用的示例项目,它不仅包含了多种滤镜效果的实现,还演示了如何将 GPUImage 集成到真实的应用程序中。项目整体结构清晰,旨在帮助开发者快速理解 GPUImage 的使用方法,并在自己的应用中实现类似的功能。

weixin_33610780的博客 1417

iOS GPUImage 的使用

GPUImage是现在做滤镜最主流的开源框架,没有之一。作者BradLarson基于openGL对图片处理单元进行封装,提供出GPUImageFilter基类,配合shader,常用滤镜都拿下不是问题。一、安装(1):首先下载GPUImagehttps://github.com/BradLarson/GPUImage(2):解压后,在framework 目录下,打开 GPUImage.xcodep

vvqlql的博客 740

GPUImage源码解读()

GPUImageFramebuffer类用于管理帧缓冲对象,负责帧缓冲对象的创建和销毁,读取帧缓冲内容,其中纹理附件涉及到了相关的纹理选项。因此,它提供的属性也是和帧缓存、纹理附件、纹理选项等相关。 ###### 属性 // 帧缓存大小 @property(readonly) CGSize size; // 纹理选项 @property(readonly) GPUTextureOpti...

Philm_iOS的博客 518

GPUImage框架使用

它是GPUImage框架的帧缓存管理器,可以创建、存储和管理多个帧缓存对象,并且可以在需要时快速地获取和释放帧缓存。它是所有输出对象的基类,定义了输出源应该具有的基本方法,例如获取处理后的纹理、获取处理后的图片、获取处理后的视频等。它是所有帧缓存对象的基类,保存了一个纹理对象和一些其他的数据,可以在需要时输出到屏幕或其他帧缓存中。它是所有输入对象的基类,定义了输入源应该具有的基本方法,例如需要处理的图像、需要处理的纹理等。它是所有滤镜对象的基类,定义了滤镜应该具有的基本方法,例如设置输入纹理、处理纹理等。

woaimx_1314的博客 772

GPUImage 源码分析

GPUImage源码解读 介绍 GitHub - cats-oss/android-gpuimage: Android filters based on OpenGL (idea from GPUImage for iOS) 做图片或者视频滤镜渲染,离不开 OpenGL,而在移动平台上最令人熟知的就是 GitHub - BradLarson/GPUImage2: GPUImage 2 is ...

crazy_jack 2149

iOS GPUImage研究总结

关于GPUImage 这里直接引用官方描述:GPUImage是使用GPU处理图像的、他可以对图片、实时画面、视频进行处理。他允许你自定义滤镜、支持iOS4.0。然而,目前缺乏核心形象的一些更高级的功能,比如面部检测。

Quinn's blog ! I'm glad to be here! 1万+

iOS GPUImage源码解读

前言 GPUImage是iOS上一个基于OpenGL进行图像处理的开源框架,内置大量滤镜,架构灵活,可以在其基础上很轻松地实现各种图像处理功能。本文主要向大家分享一下项目的核心架构、源码解读及使用心得。 GPUImage有哪些特性 丰富的输入组件 摄像头、图片、视频、OpenGL纹理、进制数据、UIElement(UIView, CALayer) 大量现成的内置滤镜(4大类) 1). 颜...

majiakun1的专栏 3610

iOS开发——GPUImage源码解析

一、基本概念 GPUImage:一个开源的、基于openGL的图片或视频的处理框架,其本身内置了多达120多种常见的滤镜效果,并且支持照相机和摄像机的实时滤镜,并且能够自定义图像滤镜。同时也很方便在原有基础上加入自己的滤镜Filter,所有滤镜是基于opengl shader(着色器)实现的,所以滤镜效果图像处理是在GPU上实现的,处理效率比较高,在iPhone6及其以上手机,可以做到实时流...

weixin_30240349的博客 376

GPUImage源码分析与使用()

有丰富的输入组件,可以处理图片、纹理、视频、进制数据、UIElement(UIView、CALayer),可以使用GPUImage拍照、处理纹理图片、给视频或拍摄中的视频添加滤镜、添加水印可以使用UIElement。支持对大图进行处理,GPU的纹理限制是4096*4096,对于超出限制的图片,GPUImage会压缩处理导致损失图片质量,CoreImage会把图片拆解成小图处理。可以传入字符串类型,也可以传入文件类型,比如以.vsh/.fsh/.glsl等为后缀等命名的文件。

程序猿老樊的博客 1117

GPUImage源码解读()

导读: 系列文章会从结构到使用,细化到每一个变量, 使用方法全有对应 DEMO.也会有相对应的技术点扩展如(AVFoundation,OpenGL shader,CAEAGLLayer)等,目前是 Objective-C 版本的,后面会有Swift版本. GPUImage-Objective-C 官方源码 GPUImage-Swift 官方源码 GPUImage-Objective-C 添...

Philm_iOS的博客 798

c语言freeimage库文件,GPUImage源码解读之GLProgram

简述GLProgram是GPUImage中代表openGL ES 中的program,具有glprogram功能。其实是作者对OpenGL ES program的面向对象封装初始化- (id)initWithVertexShaderString:(NSString *)vShaderStringfragmentShaderString:(NSString *)fShaderString;- (id...

weixin_36176188的博客 303

android 滤镜开源,Android_GPUImage 支持实时摄像头滤镜的GPUImage是iOS下一个开源的基于GPU的图像处理库 - 下载 - 搜珍网...

Android例子源码支持实时摄像头滤镜的GPUImage/Android例子源码支持实时摄像头滤镜的GPUImage/.gitignoreAndroid例子源码支持实时摄像头滤镜的GPUImage/library/Android例子源码支持实时摄像头滤镜的GPUImage/library/.classpathAndroid例子源码支持实时摄像头滤镜的GPUImage/library/.gitig...

weixin_36397146的博客 184

GPUImage源码解读之GLProgram

简述 GLProgram是GPUImage中代表openGL ES 中的program,具有glprogram功能。其实是作者对OpenGL ES program的面向对象封装 初始化 - (id)initWithVertexShaderString:(NSString *)vShaderString fragmentShaderString:(NSString *)fS...

weixin_30346033的博客 168

GPUImage源码解读(十四)

GPUImageLookupFilter GPUImageLookupFilter 是GPUImage中的颜色查找滤镜,在一般的相机应用中使用得最广泛,它的作用是通过颜色变换从而产生出新风格的图片,在philm项目中也有大量使用 LUT (Lookup Tables)即查找表 。LUT是个非常简单的数值转换表,不同的色彩输入数值“映射”到一套输出数值,用来改变图像的色彩。例如:红色在LUT中可...

Philm_iOS的博客 740

GPUImage源码解读()

GPUImageView 从名称就可以知道GPUImageView是GPUImage框架中显示图片相关的类。GPUImageView实现了GPUImageInput协议,从而可以知道它能够接受GPUImageFramebuffer的输入。因此,常常作为响应链的终端节点,用于显示处理后的帧缓存。 - 重写静态方法 返回 CAEAGLLayer GPUImageView 是UIView的子类...

Philm_iOS的博客 500

GPUImage源码解读(十三)

GPUImageFilter GPUImageFilter 是GPUImage中很重要、很基础的类,它可以处理帧缓存对象的输入输出,但是对纹理并不添加任何特效,也就是说只是简单的让纹理通过。它更多的是作为其它滤镜的基类,一些具体的滤镜由它的子类去完成。同时它也只能处理单个帧缓存对象的输入,处理多个帧缓存对象的输入也是由它的子类去完成 向量定义 //在 GPUImage 中主要用到了3...

Philm_iOS的博客 485

GPUImage源码解读(十五)

#GPUImageView 结构说明 . ├── GPUImage.xcodeproj │&amp;nbsp;&amp;nbsp; ├── project.pbxproj │&amp;nbsp;&amp;nbsp; ├── project.xcworkspace ├── GPUImageMac.xcodeproj │&amp;nbsp;&amp;nbsp; ├── project.pbxproj │&amp;nbsp;&amp;nbsp;

Philm_iOS的博客 458

GPUImage源码解读()

GPUImagePicture 从名称就可以知道GPUImagePicture是GPUImage框架中处理与图片相关的类,它的主要作用是将UIImage或CGImage转化为纹理对象。GPUImagePicture继承自GPUImageOutput,从而可以知道它能够作为输出,由于它没有实现GPUImageInput协议,不能处理输入。因此,常常作为响应链源。 初始化方法 ,所有初始化方法...

Philm_iOS的博客 472

GPUImage源码解读()

介绍GPUImage框架中的GPUImageInput协议以及GPUImageOutput类 GPUImageInput GPUImageInput 在GPUImageContext.h中定义, 协议提供了方法列表,细节由实现的对象实现。GPUImage中实现GPUImageInput的协议的类比较多,常见的有 GPUImageFilter、GPUImageView、GPUImageRa...

Philm_iOS的博客 535
上一篇: iOS 启动优化
下一篇: 函数响应式编程
Philm_iOS
博客等级 码龄8年 74粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值