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_SHADERstring:vShaderString])
{
NSLog(@"Failed to compile vertex shader");
}//Create and compile fragment shaderif(![self compileShader:&fragShader
type:GL_FRAGMENT_SHADERstring:fShaderString])
{
NSLog(@"Failed to compile fragment shader");
}
glAttachShader(program, vertShader);
glAttachShader(program, fragShader);
}returnself;
}
详解: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)returnNO;if(vertShader)
{
glDeleteShader(vertShader);
vertShader=0;
}if(fragShader)
{
glDeleteShader(fragShader);
fragShader=0;
}
self.initialized=YES;returnYES;
}
详解:glLinkProgram(program)函数link一个创建好的program对象,glGetProgramiv(program, GL_LINK_STATUS, &status)用来查询link结果。
- (void)use
说明:使用program
- (void)validate
说明:program对象是否有效
- (BOOL)compileShader:(GLuint *)shader type:(GLenum)typestring:(NSString *)shaderString
说明:编译着色器
参数:shader是着色器 type为着色器类型(顶点和片段) shaderString为着色器内容字符串。
实现
- (BOOL)compileShader:(GLuint *)shader
type:(GLenum)typestring:(NSString *)shaderString
{//CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();GLint status;constGLchar *source;
source=(GLchar*)[shaderString UTF8String];if(!source)
{
NSLog(@"Failed to load vertex shader");returnNO;
}*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);returnstatus ==GL_TRUE;
}
#import <Foundation/Foundation.h>#ifTARGET_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#pragmamark Function Pointer Definitionstypedefvoid(*GLInfoFunction)(GLuint program, GLenum pname, GLint*params);
typedefvoid(*GLLogFunction) (GLuint program, GLsizei bufsize, GLsizei* length, GLchar*infolog);//END:typedefs#pragmamark -#pragmamark Private Extension Method Declaration//START:extension@interface GLProgram()- (BOOL)compileShader:(GLuint *)shader
type:(GLenum)typestring:(NSString *)shaderString;
@end//END:extension#pragmamark -@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_SHADERstring:vShaderString])
{
NSLog(@"Failed to compile vertex shader");
}//Create and compile fragment shaderif(![self compileShader:&fragShader
type:GL_FRAGMENT_SHADERstring:fShaderString])
{
NSLog(@"Failed to compile fragment shader");
}
glAttachShader(program, vertShader);
glAttachShader(program, fragShader);
}returnself;
}- (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]))
{
}returnself;
}- (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]))
{
}returnself;
}//END:init//START:compile- (BOOL)compileShader:(GLuint *)shader
type:(GLenum)typestring:(NSString *)shaderString
{//CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();GLint status;constGLchar *source;
source=(GLchar*)[shaderString UTF8String];if(!source)
{
NSLog(@"Failed to load vertex shader");returnNO;
}*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);returnstatus ==GL_TRUE;
}//END:compile#pragmamark -//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
{returnglGetUniformLocation(program, [uniformName UTF8String]);
}//END:indexmethods#pragmamark -//START:link-(BOOL)link
{//CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();GLint status;
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS,&status);if(status ==GL_FALSE)returnNO;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);returnYES;
}//END:link//START:use- (void)use
{
glUseProgram(program);
}//END:use#pragmamark -
- (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);
}
}#pragmamark -//START:dealloc- (void)dealloc
{if(vertShader)
glDeleteShader(vertShader);if(fragShader)
glDeleteShader(fragShader);if(program)
glDeleteProgram(program);
}//END:dealloc@end