| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- //
- // GLESUtils.m
- // Tutorial02
- //
- // Created by kesalin@gmail.com on 12-11-25.
- // Copyright (c) 2012年 http://blog.csdn.net/kesalin/. All rights reserved.
- //
- #import "GLESUtils.h"
- #define LogInfo printf
- #define LogError printf
- @implementation GLESUtils
- +(GLuint)loadShader:(GLenum)type withFilepath:(NSString *)shaderFilepath
- {
- NSError* error;
- NSString* shaderString = [NSString stringWithContentsOfFile:shaderFilepath
- encoding:NSUTF8StringEncoding
- error:&error];
- if (!shaderString) {
- NSLog(@"Error: loading shader file: %@ %@", shaderFilepath, error.localizedDescription);
- return 0;
- }
-
- return [self loadShader:type withString:shaderString];
- }
- +(GLuint)loadShader:(GLenum)type withString:(NSString *)shaderString
- {
- // Create the shader object
- GLuint shader = glCreateShader(type);
- if (shader == 0) {
- NSLog(@"Error: failed to create shader.");
- return 0;
- }
-
- // Load the shader source
- const char * shaderStringUTF8 = [shaderString UTF8String];
- glShaderSource(shader, 1, &shaderStringUTF8, NULL);
-
- // Compile the shader
- glCompileShader(shader);
-
- // Check the compile status
- GLint compiled = 0;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
-
- if (!compiled) {
- GLint infoLen = 0;
- glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
-
- if (infoLen > 1) {
- char * infoLog = malloc(sizeof(char) * infoLen);
- glGetShaderInfoLog (shader, infoLen, NULL, infoLog);
- NSLog(@"Error compiling shader:\n%s\n", infoLog );
-
- free(infoLog);
- }
-
- glDeleteShader(shader);
- return 0;
- }
- return shader;
- }
- +(GLuint)loadProgram:(NSString *)vertexShaderFilepath withFragmentShaderFilepath:(NSString *)fragmentShaderFilepath
- {
- // Load the vertex/fragment shaders
- GLuint vertexShader = [self loadShader:GL_VERTEX_SHADER
- withFilepath:vertexShaderFilepath];
- if (vertexShader == 0)
- return 0;
-
- GLuint fragmentShader = [self loadShader:GL_FRAGMENT_SHADER
- withFilepath:fragmentShaderFilepath];
- if (fragmentShader == 0) {
- glDeleteShader(vertexShader);
- return 0;
- }
-
- // Create the program object
- GLuint programHandle = glCreateProgram();
- if (programHandle == 0)
- return 0;
-
- glAttachShader(programHandle, vertexShader);
- glAttachShader(programHandle, fragmentShader);
-
- // Link the program
- glLinkProgram(programHandle);
-
- // Check the link status
- GLint linked;
- glGetProgramiv(programHandle, GL_LINK_STATUS, &linked);
-
- if (!linked) {
- GLint infoLen = 0;
- glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &infoLen);
-
- if (infoLen > 1){
- char * infoLog = malloc(sizeof(char) * infoLen);
- glGetProgramInfoLog(programHandle, infoLen, NULL, infoLog);
- NSLog(@"Error linking program:\n%s\n", infoLog);
-
- free(infoLog);
- }
-
- glDeleteProgram(programHandle );
- return 0;
- }
-
- // Free up no longer needed shader resources
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
-
- return programHandle;
- }
- + (const GLchar *)readFile:(NSString *)name
- {
- NSString *path;
- const GLchar *source;
-
- path = [[NSBundle mainBundle] pathForResource:name ofType: nil];
- source = (GLchar *)[[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil] UTF8String];
- return source;
- }
- #pragma mark -
- /* Compile a shader from the provided source(s) */
- GLint glueCompileShader(GLenum target, GLsizei count, const GLchar **sources, GLuint *shader)
- {
- GLint status;
-
- *shader = glCreateShader(target);
- glShaderSource(*shader, count, sources, NULL);
- glCompileShader(*shader);
-
- #if defined(DEBUG)
- GLint logLength = 0;
- glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
- if (logLength > 0)
- {
- GLchar *log = (GLchar *)malloc(logLength);
- glGetShaderInfoLog(*shader, logLength, &logLength, log);
- LogInfo("Shader compile log:\n%s", log);
- free(log);
- }
- #endif
-
- glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
- if (status == 0)
- {
- int i;
-
- LogError("Failed to compile shader:\n");
- for (i = 0; i < count; i++)
- LogInfo("%s", sources[i]);
- }
-
- return status;
- }
- /* Link a program with all currently attached shaders */
- GLint glueLinkProgram(GLuint program)
- {
- GLint status;
-
- glLinkProgram(program);
-
- #if defined(DEBUG)
- GLint logLength = 0;
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
- if (logLength > 0)
- {
- GLchar *log = (GLchar *)malloc(logLength);
- glGetProgramInfoLog(program, logLength, &logLength, log);
- LogInfo("Program link log:\n%s", log);
- free(log);
- }
- #endif
-
- glGetProgramiv(program, GL_LINK_STATUS, &status);
- if (status == 0)
- LogError("Failed to link program %d", program);
-
- return status;
- }
- /* Validate a program (for i.e. inconsistent samplers) */
- GLint glueValidateProgram(GLuint program)
- {
- GLint status;
-
- glValidateProgram(program);
-
- #if defined(DEBUG)
- GLint logLength = 0;
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
- if (logLength > 0)
- {
- GLchar *log = (GLchar *)malloc(logLength);
- glGetProgramInfoLog(program, logLength, &logLength, log);
- LogInfo("Program validate log:\n%s", log);
- free(log);
- }
- #endif
-
- glGetProgramiv(program, GL_VALIDATE_STATUS, &status);
- if (status == 0)
- LogError("Failed to validate program %d", program);
-
- return status;
- }
- /* Return named uniform location after linking */
- GLint glueGetUniformLocation(GLuint program, const GLchar *uniformName)
- {
- GLint loc;
-
- loc = glGetUniformLocation(program, uniformName);
-
- return loc;
- }
- /* Convenience wrapper that compiles, links, enumerates uniforms and attribs */
- GLint glueCreateProgram(const GLchar *vertSource, const GLchar *fragSource,
- GLsizei attribNameCt, const GLchar **attribNames,
- const GLint *attribLocations,
- GLsizei uniformNameCt, const GLchar **uniformNames,
- GLint *uniformLocations,
- GLuint *program)
- {
- GLuint vertShader = 0, fragShader = 0, prog = 0, status = 1, i;
-
- // Create shader program
- prog = glCreateProgram();
-
- // Create and compile vertex shader
- status *= glueCompileShader(GL_VERTEX_SHADER, 1, &vertSource, &vertShader);
-
- // Create and compile fragment shader
- status *= glueCompileShader(GL_FRAGMENT_SHADER, 1, &fragSource, &fragShader);
-
- // Attach vertex shader to program
- glAttachShader(prog, vertShader);
-
- // Attach fragment shader to program
- glAttachShader(prog, fragShader);
-
- // Bind attribute locations
- // This needs to be done prior to linking
- for (i = 0; i < attribNameCt; i++)
- {
- if(strlen(attribNames[i]))
- glBindAttribLocation(prog, attribLocations[i], attribNames[i]);
- }
-
- // Link program
- status *= glueLinkProgram(prog);
-
- // Get locations of uniforms
- if (status)
- {
- for(i = 0; i < uniformNameCt; i++)
- {
- if(strlen(uniformNames[i]))
- uniformLocations[i] = glueGetUniformLocation(prog, uniformNames[i]);
- }
- *program = prog;
- }
-
- // Release vertex and fragment shaders
- if (vertShader)
- glDeleteShader(vertShader);
- if (fragShader)
- glDeleteShader(fragShader);
-
- return status;
- }
- @end
|