Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- create an Apple default GL project from the template
- replace shaders, and ES2Renderer.m with the following:
- */
- //
- // Shader.fsh
- // helloGL
- //
- // Created by Pi on 17/02/2011.
- // Copyright 2011 __MyCompanyName__. All rights reserved.
- //
- precision mediump float;
- uniform sampler2D S0;
- varying vec2 V0;
- varying vec4 V1;
- void
- main( void )
- {
- gl_FragColor = vec4( V1 *
- texture2D( S0, V0 ) );
- }
- // ---------------------------
- //
- // Shader.vsh
- // helloGL
- //
- // Created by Pi on 17/02/2011.
- // Copyright 2011 __MyCompanyName__. All rights reserved.
- //
- attribute vec4 A0; // A0 = gl_Vertex,
- attribute vec2 A1; // A1 = glMultiTexCoord0.st
- attribute vec4 A2; // A2 = gl_Color
- varying vec2 V0;
- varying vec4 V1;
- uniform mat4 M0;
- void main( void )
- {
- V0 = vec2( A1 );
- V1 = vec4( A2 );
- gl_Position = vec4( M0 * A0 );
- }
- // ---------------------------
- //
- // ES2Renderer.m
- // helloGL
- //
- // Created by Pi on 17/02/2011.
- // Copyright 2011 __MyCompanyName__. All rights reserved.
- //
- #import "ES2Renderer.h"
- #define STRIDE ( sizeof( GLfloat ) * ( 2 + 2 + 4 ) )
- #define OFFSET( P ) ( ( const GLvoid * ) ( sizeof( GLfloat ) * ( P ) ) )
- #define eglGetError while (glGetError() != GL_NO_ERROR) printf("Error!\n")
- // #import "error.h"
- // = = =
- // uniform index
- enum {
- UNIFORM_TRANSLATE,
- NUM_UNIFORMS
- };
- GLint uniforms[NUM_UNIFORMS];
- // attribute index
- enum {
- ATTRIB_VERTEX_XY,
- ATTRIB_TEXCOORD_ST,
- ATTRIB_COLOR_RGBA,
- NUM_ATTRIBUTES
- };
- // = = =
- @interface ES2Renderer (PrivateMethods)
- - (BOOL)loadShaders;
- - (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
- - (BOOL)linkProgram:(GLuint)prog;
- - (BOOL)validateProgram:(GLuint)prog;
- @end
- // = = =
- @implementation ES2Renderer
- // - - -
- // Create an OpenGL ES 2.0 context
- - (id)init
- {
- self = [super init];
- if (! self)
- return nil;
- context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
- // loadShaders sets up the programmable pipeline, ie
- // - Generates a program object + vertex & fragment shader
- // - compiles & links program ( i.e. )
- {
- if (!context
- || ![EAGLContext setCurrentContext:context]
- || ![self loadShaders])
- {
- [self release];
- return nil;
- }
- }
- // Setup framebuffers
- {
- // Create default framebuffer object. The backing will be
- // allocated for the current layer in -resizeFromLayer
- glGenFramebuffers(1, & defaultFramebuffer);
- glGenRenderbuffers(1, & colorRenderbuffer);
- // attach renderBuffer to our frameBuffer
- // NOTE: we could alternatively attach a texture to our FBO with
- // glFramebufferTexture2D
- glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
- glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER,
- colorRenderbuffer);
- }
- {
- // Ask GL to give us a texture-ID for us to use
- glGenTextures( 1, & greyscaleTexture );
- }
- return self;
- }
- // - - -
- - (void) render
- {
- // first pass works no errors!
- static int abc = 0;
- if (abc)
- return;
- abc++;
- // CREATE A GREYSCALE TEXTURE
- {
- GLuint W = backingWidth, H = backingHeight;
- printf("Rendering @ (%d, %d)\n", W, H);
- // Create a pretty greyscale pixel pattern
- GLubyte *P = calloc( 1, ( W * H * 4 * sizeof( GLubyte ) ) );
- for ( GLuint i = 0; ( i < H ); ++i )
- {
- for ( GLuint j = 0; ( j < W ); ++j )
- {
- P[( ( i * W + j ) * 4 + 0 )] =
- P[( ( i * W + j ) * 4 + 1 )] =
- P[( ( i * W + j ) * 4 + 2 )] =
- P[( ( i * W + j ) * 4 + 3 )] = ( i ^ j );
- }
- }
- // make it the ACTIVE texture, ie functions like glTexImage2D will
- // automatically know to use THIS texture
- glBindTexture( GL_TEXTURE_2D, greyscaleTexture );
- // set some params on the ACTIVE texture
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
- // WRITE/COPY from P into active texture
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, P );
- free( P );
- eglGetError;
- }
- // - - -
- // (c) setup your vertex state (i.e. vertex array,
- // vertex buffer + index buffer if you need that)
- {
- // Vertex Array: Assumes interleaved { ..., X, Y, S, T, R, G, B, A, ... }
- static const GLfloat VA[ ] =
- {
- // X Y S T R G B A
- -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Bottom Left: Red
- 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
- 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- };
- GLuint vertexArrayBufferID;
- glBindBuffer( GL_ARRAY_BUFFER, vertexArrayBufferID );
- glBufferData( GL_ARRAY_BUFFER, sizeof( VA ), VA, GL_STATIC_DRAW );
- glVertexAttribPointer( ATTRIB_VERTEX_XY, 2, GL_FLOAT, GL_FALSE, STRIDE, OFFSET( 0 ) ); // X Y
- glVertexAttribPointer( ATTRIB_TEXCOORD_ST, 2, GL_FLOAT, GL_FALSE, STRIDE, OFFSET( 2 ) ); // S T
- glVertexAttribPointer( ATTRIB_COLOR_RGBA, 4, GL_FLOAT, GL_FALSE, STRIDE, OFFSET( 4 ) ); // R G B A
- glEnableVertexAttribArray( ATTRIB_VERTEX_XY );
- glEnableVertexAttribArray( ATTRIB_TEXCOORD_ST );
- glEnableVertexAttribArray( ATTRIB_COLOR_RGBA );
- // - - -
- // Index Array: this represents a strip of TWO triangles: {V[0], V[1], V[2]} and {V[1], V[2], V[3]}
- const GLushort IA[ ] =
- {
- 0, 1, 2, 3,
- };
- GLuint vertexIndexArrayBufID;
- glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vertexIndexArrayBufID );
- glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( IA ), IA, GL_STATIC_DRAW );
- }
- // Update uniform value
- // glUniform1f(uniforms[UNIFORM_TRANSLATE], (GLfloat)transY);
- // transY += 0.075f;
- //
- static const GLfloat M[ ] = // Assumes ( MV * P ) matrix.
- {
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f
- };
- // Setup uniform (matrix, sampler) state.
- glUniformMatrix4fv( glGetUniformLocation( uniforms[UNIFORM_TRANSLATE], "M0" ), 1, GL_FALSE, M );
- // - - - APPLES TEMPLATE CODE
- // This application only creates a single context which is already set current at this point.
- // This call is redundant, but needed if dealing with multiple contexts.
- [EAGLContext setCurrentContext:context];
- glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
- glViewport(0, 0, backingWidth, backingHeight);
- // - -
- // 1) clear the COLOR buffer <-- WORKS!!! Screen goes red!
- glClearColor(0.5f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- // - -
- glBindTexture(GL_TEXTURE_2D, greyscaleTexture);
- // make this program the ACTIVE program
- glUseProgram(program);
- // Validate program before drawing. This is a good check, but only really necessary in a debug build.
- // DEBUG macro must be defined in your debug configurations if that's not already the case.
- #if defined(DEBUG)
- if (![self validateProgram:program])
- {
- NSLog(@"Failed to validate program: %d", program);
- return;
- }
- #endif
- glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, NULL );
- if (0)
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- // - -
- // This application only creates a single color renderbuffer
- // which is already bound at this point.
- // This call is redundant, but needed if dealing with multiple renderbuffers.
- glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
- [context presentRenderbuffer: GL_RENDERBUFFER];
- }
- // - - -
- - (BOOL)compileShader:(GLuint *)shader
- type:(GLenum)type
- file:(NSString *)file
- {
- GLint status;
- const GLchar *source;
- source = (GLchar *)[[NSString stringWithContentsOfFile:file
- encoding:NSUTF8StringEncoding
- error:nil]
- UTF8String];
- if (!source)
- {
- NSLog(@"Failed to load vertex shader");
- return FALSE;
- }
- *shader = glCreateShader(type);
- glShaderSource(*shader, 1, &source, NULL);
- glCompileShader(*shader);
- #if defined(DEBUG)
- GLint logLength;
- glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
- if (logLength > 0)
- {
- GLchar *log = (GLchar *)malloc(logLength);
- glGetShaderInfoLog(*shader, logLength, &logLength, log);
- NSLog(@"Shader compile log:\n%s", log);
- free(log);
- }
- #endif
- glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
- if (status == 0)
- {
- glDeleteShader(*shader);
- return FALSE;
- }
- return TRUE;
- }
- // - - -
- - (BOOL)linkProgram:(GLuint)prog
- {
- GLint status;
- glLinkProgram(prog);
- #if defined(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 link log:\n%s", log);
- free(log);
- }
- #endif
- glGetProgramiv(prog, GL_LINK_STATUS, &status);
- if (status == 0)
- return FALSE;
- return TRUE;
- }
- // - - -
- - (BOOL)validateProgram:(GLuint)prog
- {
- GLint logLength, status;
- glValidateProgram(prog);
- 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);
- }
- glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
- if (status == 0)
- return FALSE;
- return TRUE;
- }
- // - - -
- - (BOOL)loadShaders
- {
- GLuint vertShader, fragShader;
- NSString *vertShaderPathname, *fragShaderPathname;
- // Create shader program
- program = glCreateProgram();
- // Create and compile vertex shader
- vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
- if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname])
- {
- NSLog(@"Failed to compile vertex shader");
- return FALSE;
- }
- // Create and compile fragment shader
- fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
- if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname])
- {
- NSLog(@"Failed to compile fragment shader");
- return FALSE;
- }
- // Attach vertex shader to program
- glAttachShader(program, vertShader);
- // Attach fragment shader to program
- glAttachShader(program, fragShader);
- // Bind attribute locations
- // this needs to be done prior to linking
- glBindAttribLocation(program, ATTRIB_VERTEX_XY, "A0");
- glBindAttribLocation(program, ATTRIB_TEXCOORD_ST, "A1");
- glBindAttribLocation(program, ATTRIB_COLOR_RGBA, "A2");
- // Link program
- if (![self linkProgram:program])
- {
- NSLog(@"Failed to link program: %d", program);
- if (vertShader)
- {
- glDeleteShader(vertShader);
- vertShader = 0;
- }
- if (fragShader)
- {
- glDeleteShader(fragShader);
- fragShader = 0;
- }
- if (program)
- {
- glDeleteProgram(program);
- program = 0;
- }
- return FALSE;
- }
- // Get uniform locations
- uniforms[UNIFORM_TRANSLATE] = glGetUniformLocation(program, "M0");
- // Release vertex and fragment shaders
- if (vertShader)
- glDeleteShader(vertShader);
- if (fragShader)
- glDeleteShader(fragShader);
- return TRUE;
- }
- // - - -
- - (BOOL) resizeFromLayer: (CAEAGLLayer *) layer
- {
- // Allocate color buffer backing based on the current layer size
- glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
- [context renderbufferStorage: GL_RENDERBUFFER
- fromDrawable: layer];
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, & backingWidth);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, & backingHeight);
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- {
- NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
- return NO;
- }
- return YES;
- }
- // - - -
- - (void)dealloc
- {
- // Tear down GL
- if (defaultFramebuffer)
- {
- glDeleteFramebuffers(1, & defaultFramebuffer);
- defaultFramebuffer = 0;
- }
- if (colorRenderbuffer)
- {
- glDeleteRenderbuffers(1, & colorRenderbuffer);
- colorRenderbuffer = 0;
- }
- if (program)
- {
- glDeleteProgram(program);
- program = 0;
- }
- // Tear down context
- if ([EAGLContext currentContext] == context)
- [EAGLContext setCurrentContext:nil];
- [context release];
- context = nil;
- [super dealloc];
- }
- @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement