你的位置:首页 > 操作系统

[操作系统]GPUImage API文档之GLProgram类


  GLProgram是GPUImage中代表openGL ES 中的program,具有glprogram功能。

  属性

  @property(readwrite, nonatomic) BOOL initialized

   作用:该属性用于指示program的初始化工作是否成功,成功返回YES,反之返回NO 

 

    @property(readwrite, copy, nonatomic) NSString *vertexShaderLog

    作用:该属性用于设置或获取顶点着色器的日志。

 

    @property(readwrite, copy, nonatomic) NSString *fragmentShaderLog

    作用:该属性用于设置或获取片段着色器的日志。

 

    @property(readwrite, copy, nonatomic) NSString *programLog

    作用:该属性用于设置或获取program的日志。

 

  方法

    - (id)initWithVertexShaderString:(NSString *)vShaderString fragmentShaderString:(NSString *)fShaderString

    说明:使用一个顶点着色字符串和一个片段着色字符串创建一个GLProgram对象

    参数:顶点着色字符串,片段着色字符串

    返回:GLProgram对象

    相似方法:- (id)initWithVertexShaderString:(NSString *)vShaderString fragmentShaderFilename:(NSString *)fShaderFilename;
         - (id)initWithVertexShaderFilename:(NSString *)vShaderFilename fragmentShaderFilename:(NSString *)fShaderFilename(从文件中读取内容)

    实现

 

- (id)initWithVertexShaderString:(NSString *)vShaderString       fragmentShaderString:(NSString *)fShaderString;{  if ((self = [super init]))   {    _initialized = NO;        attributes = [[NSMutableArray alloc] init];    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;}

    详解:1.使用glCreateProgram()函数创建一个program

       2.编译着色器

       3.附加着色器。glAttachShader(program, fragShader)

 

    - (void)addAttribute:(NSString *)attributeName

    说明:该方法用于向一个program对象中添加属性

    参数:需要添加的属性名称

    返回:void

    实现:

 

- (void)addAttribute:(NSString *)attributeName{  if (![attributes containsObject:attributeName])  {    [attributes addObject:attributeName];    glBindAttribLocation(program,               (GLuint)[attributes indexOfObject:attributeName],               [attributeName UTF8String]);  }}

    详解:void glBindAttribLocation( GLuint program, GLuint index,const GLchar *name)函数用来将属性绑定到具体位置。program是使用的program对象,index是位置索引,*name是需要绑定的属性名

 

    - (GLuint)attributeIndex:(NSString *)attributeName

    说明:返回具体属性名的索引

    参数:指定的属性名

    返回:指定属性名的索引

 

    - (GLuint)uniformIndex:(NSString *)uniformName

    说明:返回Uniform的索引

    参数:指定的Uniform名

    返回:指定Uniform的索引

 

    - (BOOL)link

    说明:判断program是否link成功

    返回:YES说明link成功,反之失败

    实现:

    

- (BOOL)link{  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;  return YES;}

 

    详解:glLinkProgram(program)函数link一个创建好的program对象,glGetProgramiv(program, GL_LINK_STATUS, &status)用来查询link结果。

 

    - (void)use

    说明:使用program

 

    
    - (void)validate

    说明:program对象是否有效

 

    - (BOOL)compileShader:(GLuint *)shader type:(GLenum)type string:(NSString *)shaderString

    说明:编译着色器

    参数:shader是着色器   type为着色器类型(顶点和片段)  shaderString为着色器内容字符串。

    实现

    

- (BOOL)compileShader:(GLuint *)shader         type:(GLenum)type        string:(NSString *)shaderString{//  CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();  GLint status;  const GLchar *source;    source =    (GLchar *)[shaderString UTF8String];  if (!source)  {    NSLog(@"Failed to load vertex shader");    return NO;  }    *shader = glCreateShader(type);  glShaderSource(*shader, 1, &source, NULL);  glCompileShader(*shader);    glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);  if (status != GL_TRUE)  {    GLint logLength;    glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);    if (logLength > 0)    {      GLchar *log = (GLchar *)malloc(logLength);      glGetShaderInfoLog(*shader, logLength, &logLength, log);      if (shader == &vertShader)      {        self.vertexShaderLog = [NSString stringWithFormat:@"%s", log];      }      else      {        self.fragmentShaderLog = [NSString stringWithFormat:@"%s", log];      }      free(log);    }  }    //  CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime);//  NSLog(@"Compiled in %f ms", linkTime * 1000.0);  return status == GL_TRUE;}

#import <Foundation/Foundation.h>#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE#import <OpenGLES/ES2/gl.h>#import <OpenGLES/ES2/glext.h>#else#import <OpenGL/OpenGL.h>#import <OpenGL/gl.h>#endif@interface GLProgram : NSObject {  NSMutableArray *attributes;  NSMutableArray *uniforms;  GLuint     program,  vertShader,   fragShader;  }@property(readwrite, nonatomic) BOOL initialized;@property(readwrite, copy, nonatomic) NSString *vertexShaderLog;@property(readwrite, copy, nonatomic) NSString *fragmentShaderLog;@property(readwrite, copy, nonatomic) NSString *programLog;- (id)initWithVertexShaderString:(NSString *)vShaderString       fragmentShaderString:(NSString *)fShaderString;- (id)initWithVertexShaderString:(NSString *)vShaderString      fragmentShaderFilename:(NSString *)fShaderFilename;- (id)initWithVertexShaderFilename:(NSString *)vShaderFilename       fragmentShaderFilename:(NSString *)fShaderFilename;- (void)addAttribute:(NSString *)attributeName;- (GLuint)attributeIndex:(NSString *)attributeName;- (GLuint)uniformIndex:(NSString *)uniformName;- (BOOL)link;- (void)use;- (void)validate;@end

 

#import "GLProgram.h"// START:typedefs#pragma mark Function Pointer Definitionstypedef void (*GLInfoFunction)(GLuint program, GLenum pname, GLint* params);typedef void (*GLLogFunction) (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);// END:typedefs#pragma mark -#pragma mark Private Extension Method Declaration// START:extension@interface GLProgram()- (BOOL)compileShader:(GLuint *)shader         type:(GLenum)type        string:(NSString *)shaderString;@end// END:extension#pragma mark -@implementation GLProgram// START:init@synthesize initialized = _initialized;- (id)initWithVertexShaderString:(NSString *)vShaderString       fragmentShaderString:(NSString *)fShaderString;{  if ((self = [super init]))   {    _initialized = NO;        attributes = [[NSMutableArray alloc] init];    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;}- (id)initWithVertexShaderString:(NSString *)vShaderString      fragmentShaderFilename:(NSString *)fShaderFilename;{  NSString *fragShaderPathname = [[NSBundle mainBundle] pathForResource:fShaderFilename ofType:@"fsh"];  NSString *fragmentShaderString = [NSString stringWithContentsOfFile:fragShaderPathname encoding:NSUTF8StringEncoding error:nil];    if ((self = [self initWithVertexShaderString:vShaderString fragmentShaderString:fragmentShaderString]))   {  }    return self;}- (id)initWithVertexShaderFilename:(NSString *)vShaderFilename       fragmentShaderFilename:(NSString *)fShaderFilename;{  NSString *vertShaderPathname = [[NSBundle mainBundle] pathForResource:vShaderFilename ofType:@"vsh"];  NSString *vertexShaderString = [NSString stringWithContentsOfFile:vertShaderPathname encoding:NSUTF8StringEncoding error:nil];  NSString *fragShaderPathname = [[NSBundle mainBundle] pathForResource:fShaderFilename ofType:@"fsh"];  NSString *fragmentShaderString = [NSString stringWithContentsOfFile:fragShaderPathname encoding:NSUTF8StringEncoding error:nil];    if ((self = [self initWithVertexShaderString:vertexShaderString fragmentShaderString:fragmentShaderString]))   {  }    return self;}// END:init// START:compile- (BOOL)compileShader:(GLuint *)shader         type:(GLenum)type        string:(NSString *)shaderString{//  CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();  GLint status;  const GLchar *source;    source =    (GLchar *)[shaderString UTF8String];  if (!source)  {    NSLog(@"Failed to load vertex shader");    return NO;  }    *shader = glCreateShader(type);  glShaderSource(*shader, 1, &source, NULL);  glCompileShader(*shader);    glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);  if (status != GL_TRUE)  {    GLint logLength;    glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);    if (logLength > 0)    {      GLchar *log = (GLchar *)malloc(logLength);      glGetShaderInfoLog(*shader, logLength, &logLength, log);      if (shader == &vertShader)      {        self.vertexShaderLog = [NSString stringWithFormat:@"%s", log];      }      else      {        self.fragmentShaderLog = [NSString stringWithFormat:@"%s", log];      }      free(log);    }  }    //  CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime);//  NSLog(@"Compiled in %f ms", linkTime * 1000.0);  return status == GL_TRUE;}// END:compile#pragma mark -// START:addattribute- (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{  return glGetUniformLocation(program, [uniformName UTF8String]);}// END:indexmethods#pragma mark -// START: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;}// END:link// START:use- (void)use{  glUseProgram(program);}// END:use#pragma mark -- (void)validate;{  GLint logLength;    glValidateProgram(program);  glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);  if (logLength > 0)  {    GLchar *log = (GLchar *)malloc(logLength);    glGetProgramInfoLog(program, logLength, &logLength, log);    self.programLog = [NSString stringWithFormat:@"%s", log];    free(log);  }  }#pragma mark -// START:dealloc- (void)dealloc{  if (vertShader)    glDeleteShader(vertShader);      if (fragShader)    glDeleteShader(fragShader);    if (program)    glDeleteProgram(program);    }// END:dealloc@end