glBindAttribLocation()和glGetAttribLocation()
glBindAttribLocation()-----随时指定属性变量名和通用属性索引之间的关联
glGetAttribLocation()----查询由program(glCreateProgram())指定的先前链接的程序对象,用于name指定的属性变量,并返回绑定到该属性变量的通用顶点属性的索引
使用上的区别:
glBindAttribLocation() --- 通俗地讲'就是要在'glLinkProgram(program)‘之前进行绑定
在调用glLinkProgram之前,属性绑定不会生效。 成功链接程序对象后,属性变量的索引值将保持固定,直到发生下一个链接命令
glGetAttribLocation() --- 直接获取
代码实例:
BLImageProgram.h
#import <Foundation/Foundation.h>
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
#define STRINGIZE(x) #x
#define STRINGIZE2(x) STRINGIZE(x)
#define SHADER_STRING(text) @ STRINGIZE2(text)
NS_ASSUME_NONNULL_BEGIN
@interface BLImageProgram : NSObject
- (void)use;
- (BOOL)link;
- (GLuint)uniformIndex:(NSString *)uniformName;
- (GLuint)attributeIndex:(NSString *)attributeName;
- (void)addAttribute:(NSString *)attributeName;
- (instancetype)initWithVertexShaderString:(NSString *)vShaderString
fragmentShaderString:(NSString *)fShaderString;
- (void)mat4f_LoadOrtho:(float)left
right:(float)right
bottom:(float)bottom
top:(float)top
near:(float)near
far:(float)far
mout:(float*)mout;
@end
NS_ASSUME_NONNULL_END
BLImageProgram.m
#import "BLImageProgram.h"
@implementation BLImageProgram {
NSMutableArray *attributes;
NSMutableArray *uniforms;
GLuint program;
GLuint vertShader;
GLuint fragShader;
}
- (instancetype)initWithVertexShaderString:(NSString *)vShaderString
fragmentShaderString:(NSString *)fShaderString {
self = [super init];
if (self) {
attributes = [NSMutableArray array];
uniforms = [NSMutableArray array];
program = glCreateProgram();
if (![self complileShader:&vertShader type:GL_VERTEX_SHADER string:vShaderString]) {
NSLog(@"Failed to compile vertex shader");
}
if (![self complileShader:&fragShader type:GL_FRAGMENT_SHADER string:fShaderString]) {
NSLog(@"Failed to compile fragment shader");
}
glAttachShader(program, vertShader);
glAttachShader(program, fragShader);
}
return self;
}
- (void)use {
glUseProgram(program);
}
- (BOOL)complileShader:(GLuint *)shader
type:(GLenum)type
string:(NSString *)shaderString {
GLint status;
const GLchar *source;
source = (GLchar *)[shaderString cStringUsingEncoding:NSUTF8StringEncoding];
if (!source) {
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)
{
NSLog(@" vertex Shader log is : %@", [NSString stringWithFormat:@"%s", log]);
}
else
{
NSLog(@" fragment Shader log is : %@", [NSString stringWithFormat:@"%s", log]);
}
free(log);
}
}
return status == GL_TRUE;
}
- (void)addAttribute:(NSString *)attributeName {
if (![attributes containsObject:attributeName]) {
[attributes addObject:attributeName];
glBindAttribLocation(program,
(GLuint)[attributes indexOfObject:attributeName],
[attributeName cStringUsingEncoding:NSUTF8StringEncoding]);
}
}
- (GLuint)attributeIndex:(NSString *)attributeName {
// return glGetAttribLocation(program, [attributeName cStringUsingEncoding:NSUTF8StringEncoding]);
return (GLuint)[attributes indexOfObject:attributeName];
}
- (GLuint)uniformIndex:(NSString *)uniformName {
return glGetUniformLocation(program, [uniformName cStringUsingEncoding:NSUTF8StringEncoding]);
}
- (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;
}
return YES;
}
- (BOOL)validateProgram:(GLuint)prog {
GLint status;
glValidateProgram(prog);
#ifdef DEBUG
GLint logLength;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetProgramInfoLog(prog, logLength, &logLength, log);
NSLog(@"Program validate log:\n%s", log);
free(log);
}
#endif
glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
if (status == GL_FALSE) {
NSLog(@"Failed to validate program %d", prog);
return NO;
}
return YES;
}
- (void)mat4f_LoadOrtho:(float)left right:(float)right bottom:(float)bottom top:(float)top near:(float)near far:(float)far mout:(float*)mout {
float r_l = right - left;
float t_b = top - bottom;
float f_n = far - near;
float tx = - (right + left) / (right - left);
float ty = - (top + bottom) / (top - bottom);
float tz = - (far + near) / (far - near);
mout[0] = 2.0f / r_l;
mout[1] = 0.0f;
mout[2] = 0.0f;
mout[3] = 0.0f;
mout[4] = 0.0f;
mout[5] = 2.0f / t_b;
mout[6] = 0.0f;
mout[7] = 0.0f;
mout[8] = 0.0f;
mout[9] = 0.0f;
mout[10] = -2.0f / f_n;
mout[11] = 0.0f;
mout[12] = tx;
mout[13] = ty;
mout[14] = tz;
mout[15] = 1.0f;
}
@end