diff --git a/README.md b/README.md index 59b48d085..5f5b77263 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,14 @@ For example, an application that takes in live video from the camera, converts t - **GPUImageScreenBlendFilter**: Applies a screen blend of two images +- **GPUImageExclusionBlendFilter**: Applies an exclusion blend of two images + +- **GPUImageDifferenceBlendFilter**: Applies a difference blend of two images + +- **GPUImageHardLightBlendFilter**: Applies a hard light blend of two images + +- **GPUImageSoftLightBlendFilter**: Applies a soft light blend of two images + ### Visual effects ### - **GPUImagePixellateFilter**: Applies a pixellation effect on an image or video diff --git a/examples/CubeExample/Classes/CubeExampleAppDelegate.h b/examples/CubeExample/Classes/CubeExampleAppDelegate.h new file mode 100644 index 000000000..586aa869c --- /dev/null +++ b/examples/CubeExample/Classes/CubeExampleAppDelegate.h @@ -0,0 +1,14 @@ +#import + +@class EAGLView; + +@interface CubeExampleAppDelegate : NSObject { + UIWindow *window; + EAGLView *glView; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet EAGLView *glView; + +@end + diff --git a/examples/CubeExample/Classes/CubeExampleAppDelegate.m b/examples/CubeExample/Classes/CubeExampleAppDelegate.m new file mode 100644 index 000000000..5aaddf45f --- /dev/null +++ b/examples/CubeExample/Classes/CubeExampleAppDelegate.m @@ -0,0 +1,34 @@ +#import "CubeExampleAppDelegate.h" +#import "EAGLView.h" + +@implementation CubeExampleAppDelegate + +@synthesize window; +@synthesize glView; + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ +} + +- (void)dealloc +{ + [window release]; + [glView release]; + + [super dealloc]; +} + +@end diff --git a/examples/CubeExample/Classes/EAGLView.h b/examples/CubeExample/Classes/EAGLView.h new file mode 100644 index 000000000..2a81c5811 --- /dev/null +++ b/examples/CubeExample/Classes/EAGLView.h @@ -0,0 +1,16 @@ +#import +#import + +#import "ESRenderer.h" + +@interface EAGLView : UIView +{ + CGPoint lastMovementPosition; +@private + id renderer; + +} + +- (void)drawView:(id)sender; + +@end diff --git a/examples/CubeExample/Classes/EAGLView.m b/examples/CubeExample/Classes/EAGLView.m new file mode 100644 index 000000000..46e7afd6f --- /dev/null +++ b/examples/CubeExample/Classes/EAGLView.m @@ -0,0 +1,92 @@ +#import "EAGLView.h" + +#import "ES2Renderer.h" + +@implementation EAGLView + +// You must implement this method ++ (Class)layerClass +{ + return [CAEAGLLayer class]; +} + +//The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: +- (id)initWithCoder:(NSCoder*)coder +{ + if ((self = [super initWithCoder:coder])) + { + // Set scaling to account for Retina display + if ([self respondsToSelector:@selector(setContentScaleFactor:)]) + { + self.contentScaleFactor = [[UIScreen mainScreen] scale]; + } + + // Get the layer + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + + eaglLayer.opaque = TRUE; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + + renderer = [[ES2Renderer alloc] init]; + } + + return self; +} + +- (void)dealloc +{ + [renderer release]; + + [super dealloc]; +} + +#pragma mark - +#pragma mark UIView layout methods + +- (void)drawView:(id)sender +{ + [renderer renderByRotatingAroundX:0 rotatingAroundY:0]; +} + +- (void)layoutSubviews +{ + NSLog(@"Scale factor: %f", self.contentScaleFactor); + [renderer resizeFromLayer:(CAEAGLLayer*)self.layer]; + [self drawView:nil]; +} + +#pragma mark - +#pragma mark Touch-handling methods + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + NSMutableSet *currentTouches = [[[event touchesForView:self] mutableCopy] autorelease]; + [currentTouches minusSet:touches]; + + // New touches are not yet included in the current touches for the view + lastMovementPosition = [[touches anyObject] locationInView:self]; +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; +{ + CGPoint currentMovementPosition = [[touches anyObject] locationInView:self]; + [renderer renderByRotatingAroundX:(lastMovementPosition.x - currentMovementPosition.x) rotatingAroundY:(lastMovementPosition.y - currentMovementPosition.y)]; + lastMovementPosition = currentMovementPosition; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + NSMutableSet *remainingTouches = [[[event touchesForView:self] mutableCopy] autorelease]; + [remainingTouches minusSet:touches]; + + lastMovementPosition = [[remainingTouches anyObject] locationInView:self]; +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + // Handle touches canceled the same as as a touches ended event + [self touchesEnded:touches withEvent:event]; +} + +@end diff --git a/examples/CubeExample/Classes/ES2Renderer.h b/examples/CubeExample/Classes/ES2Renderer.h new file mode 100644 index 000000000..fc0eb85a5 --- /dev/null +++ b/examples/CubeExample/Classes/ES2Renderer.h @@ -0,0 +1,39 @@ +#import "ESRenderer.h" + +#import +#import +#import +#import "GPUImage.h" + +@class PVRTexture; + +@interface ES2Renderer : NSObject +{ +@private + EAGLContext *context; + + GLuint textureForCubeFace; + + // The pixel dimensions of the CAEAGLLayer + GLint backingWidth; + GLint backingHeight; + + // The OpenGL ES names for the framebuffer and renderbuffer used to render to this view + GLuint defaultFramebuffer, colorRenderbuffer, depthBuffer, msaaFramebuffer, msaaRenderbuffer, msaaDepthbuffer; + + CATransform3D currentCalculatedMatrix; + + GLuint program; + + GPUImageVideoCamera *videoCamera; + GPUImageFilter *inputFilter, *outputFilter; + GPUImageTextureOutput *textureOutput; + +} + +- (void)renderByRotatingAroundX:(float)xRotation rotatingAroundY:(float)yRotation; +- (BOOL)resizeFromLayer:(CAEAGLLayer *)layer; +- (void)convert3DTransform:(CATransform3D *)transform3D toMatrix:(GLfloat *)matrix; + +@end + diff --git a/examples/CubeExample/Classes/ES2Renderer.m b/examples/CubeExample/Classes/ES2Renderer.m new file mode 100644 index 000000000..aa4b518aa --- /dev/null +++ b/examples/CubeExample/Classes/ES2Renderer.m @@ -0,0 +1,628 @@ +#import "ES2Renderer.h" + +#define DRAWTEXTURE 1 + +//#define MSAA 1 + +// uniform index +enum { + UNIFORM_MODELVIEWMATRIX, + UNIFORM_TEXTURE, + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// attribute index +enum { + ATTRIB_VERTEX, + ATTRIB_TEXTUREPOSITION, + 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 +{ + if ((self = [super init])) + { +// context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + context = [[GPUImageOpenGLESContext sharedImageProcessingOpenGLESContext] context]; + + if (!context || ![EAGLContext setCurrentContext:context] || ![self loadShaders]) + { + [self release]; + return nil; + } + + currentCalculatedMatrix = CATransform3DIdentity; + currentCalculatedMatrix = CATransform3DScale(currentCalculatedMatrix, 0.5, 0.5 * (320.0/480.0), 0.5); + + glEnable(GL_TEXTURE_2D); + + // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer + glGenFramebuffers(1, &defaultFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); + + glGenRenderbuffers(1, &colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); + + videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack]; +// inputFilter = [[GPUImagePixellateFilter alloc] init]; + inputFilter = [[GPUImageSepiaFilter alloc] init]; + GPUImageRotationFilter *rotationFilter = [[GPUImageRotationFilter alloc] initWithRotation:kGPUImageRotateRight]; + textureOutput = [[GPUImageTextureOutput alloc] init]; + textureOutput.delegate = self; + + [videoCamera addTarget:rotationFilter]; + [rotationFilter addTarget:inputFilter]; + [inputFilter addTarget:textureOutput]; + + [videoCamera startCameraCapture]; + + } + + return self; +} + +- (void)renderByRotatingAroundX:(float)xRotation rotatingAroundY:(float)yRotation; +{ + /* static const GLfloat cubeVertices[] = { + -1.0, -1.0, -1.0, // 0 + 1.0, -1.0, -1.0, // 1 + 1.0, 1.0, -1.0, // 2 + -1.0, 1.0, -1.0, // 3 + -1.0, -1.0, 1.0, // 4 + 1.0, -1.0, 1.0, // 5 + 1.0, 1.0, 1.0, // 6 + -1.0, 1.0, 1.0 // 7 + }; */ +/* static const GLushort cubeIndices[] = { + 0, 2, 1, + 0, 3, 2, + + 1, 2, 6, + 6, 5, 1, + + 4, 5, 6, + 6, 7, 4, + + 2, 3, 6, + 6, 3, 7, + + 0, 7, 3, + 0, 4, 7, + + 0, 1, 5, + 0, 5, 4 + };*/ + + static const GLfloat cubeVertices[] = { + -1.0, -1.0, -1.0, // 0 + 1.0, 1.0, -1.0, // 2 + 1.0, -1.0, -1.0, // 1 + + -1.0, -1.0, -1.0, // 0 + -1.0, 1.0, -1.0, // 3 + 1.0, 1.0, -1.0, // 2 + + 1.0, -1.0, -1.0, // 1 + 1.0, 1.0, -1.0, // 2 + 1.0, 1.0, 1.0, // 6 + + 1.0, 1.0, 1.0, // 6 + 1.0, -1.0, 1.0, // 5 + 1.0, -1.0, -1.0, // 1 + + -1.0, -1.0, 1.0, // 4 + 1.0, -1.0, 1.0, // 5 + 1.0, 1.0, 1.0, // 6 + + 1.0, 1.0, 1.0, // 6 + -1.0, 1.0, 1.0, // 7 + -1.0, -1.0, 1.0, // 4 + + 1.0, 1.0, -1.0, // 2 + -1.0, 1.0, -1.0, // 3 + 1.0, 1.0, 1.0, // 6 + + 1.0, 1.0, 1.0, // 6 + -1.0, 1.0, -1.0, // 3 + -1.0, 1.0, 1.0, // 7 + + -1.0, -1.0, -1.0, // 0 + -1.0, 1.0, 1.0, // 7 + -1.0, 1.0, -1.0, // 3 + + -1.0, -1.0, -1.0, // 0 + -1.0, -1.0, 1.0, // 4 + -1.0, 1.0, 1.0, // 7 + + -1.0, -1.0, -1.0, // 0 + 1.0, -1.0, -1.0, // 1 + 1.0, -1.0, 1.0, // 5 + + -1.0, -1.0, -1.0, // 0 + 1.0, -1.0, 1.0, // 5 + -1.0, -1.0, 1.0 // 4 + }; + + /* + static const GLfloat cubeVertices[] = { + -1.0, -1.0, 1.0, + 1.0, -1.0, 1.0, + -1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + -1.0, -1.0, -1.0, + 1.0, -1.0, -1.0, + -1.0, 1.0, -1.0, + 1.0, 1.0, -1.0, + }; + + static const GLushort cubeIndices[] = { + 0, 1, 2, 3, 7, 1, 5, 4, 7, 6, 2, 4, 0, 1 + }; + */ +#ifdef DRAWTEXTURE + /* + const GLfloat cubeTexCoords[] = { + 1.0, 0.0, + 0.0, 0.0, + 1.0, 1.0, + 0.0, 1.0, + 0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, + 1.0, 1.0, + 0.0, 1.0, + 0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, + }; +*/ + const GLfloat cubeTexCoords[] = { + 0.0, 0.0, + 1.0, 1.0, + 1.0, 0.0, + + 0.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, + + 0.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, + + 1.0, 1.0, + 1.0, 0.0, + 0.0, 0.0, + + 1.0, 0.0, + 0.0, 0.0, + 0.0, 1.0, + + 0.0, 1.0, + 1.0, 1.0, + 1.0, 0.0, + + 0.0, 1.0, + 1.0, 1.0, + 0.0, 0.0, + + 0.0, 0.0, + 1.0, 1.0, + 1.0, 0.0, + + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, + + 1.0, 0.0, + 0.0, 0.0, + 0.0, 1.0, + + 0.0, 1.0, + 1.0, 1.0, + 1.0, 0.0, + + 0.0, 1.0, + 1.0, 0.0, + 0.0, 0.0 + + + }; +#endif + + // 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]; + +#ifdef MSAA + glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer); +#else + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); +#endif + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + // This application only creates a single default framebuffer which is already bound at this point. + // This call is redundant, but needed if dealing with multiple framebuffers. + + + + glViewport(0, 0, backingWidth, backingHeight); + +// glClearColor(0.5f, 0.5f, 0.5f, 1.0f); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // Use shader program + glUseProgram(program); + + // Perform incremental rotation based on current angles in X and Y + + if ((xRotation != 0.0) || (yRotation != 0.0)) + { + GLfloat totalRotation = sqrt(xRotation*xRotation + yRotation*yRotation); + + CATransform3D temporaryMatrix = CATransform3DRotate(currentCalculatedMatrix, totalRotation * M_PI / 180.0, + ((xRotation/totalRotation) * currentCalculatedMatrix.m12 + (yRotation/totalRotation) * currentCalculatedMatrix.m11), + ((xRotation/totalRotation) * currentCalculatedMatrix.m22 + (yRotation/totalRotation) * currentCalculatedMatrix.m21), + ((xRotation/totalRotation) * currentCalculatedMatrix.m32 + (yRotation/totalRotation) * currentCalculatedMatrix.m31)); + if ((temporaryMatrix.m11 >= -100.0) && (temporaryMatrix.m11 <= 100.0)) + currentCalculatedMatrix = temporaryMatrix; + } + else + { + } +// GLfloat totalRotation = sqrt(xRotation*xRotation + yRotation*yRotation); + + +// +// CATransform3D temporaryMatrix = CATransform3DRotate(currentCalculatedMatrix, totalRotation * M_PI / 180.0, +// ((xRotation/totalRotation) * currentCalculatedMatrix.m12 + (yRotation/totalRotation) * currentCalculatedMatrix.m11), +// ((xRotation/totalRotation) * currentCalculatedMatrix.m22 + (yRotation/totalRotation) * currentCalculatedMatrix.m21), +// ((xRotation/totalRotation) * currentCalculatedMatrix.m32 + (yRotation/totalRotation) * currentCalculatedMatrix.m31)); +// if ((temporaryMatrix.m11 >= -100.0) && (temporaryMatrix.m11 <= 100.0)) +// { +// currentCalculatedMatrix = temporaryMatrix; +// } + + GLfloat currentModelViewMatrix[16]; + + + [self convert3DTransform:¤tCalculatedMatrix toMatrix:currentModelViewMatrix]; + +#ifdef DRAWTEXTURE + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE4); + + + glBindTexture(GL_TEXTURE_2D, textureForCubeFace); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#endif + + // Update uniform value + glUniform1i(uniforms[UNIFORM_TEXTURE], 4); + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWMATRIX], 1, 0, currentModelViewMatrix); + + // Update attribute values + glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, cubeVertices); + glEnableVertexAttribArray(ATTRIB_VERTEX); + glVertexAttribPointer(ATTRIB_TEXTUREPOSITION, 2, GL_FLOAT, 0, 0, cubeTexCoords); + glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITION); + + // 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 + + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Draw +// glDrawElements(GL_TRIANGLE_STRIP, 14, GL_UNSIGNED_SHORT, cubeIndices); +// glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, cubeIndices); + + // 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. + +#ifdef MSAA + glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, msaaFramebuffer); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, defaultFramebuffer); + + glResolveMultisampleFramebufferAPPLE(); +#endif + 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, "position"); + glBindAttribLocation(program, ATTRIB_TEXTUREPOSITION, "inputTextureCoordinate"); + + // 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_MODELVIEWMATRIX] = glGetUniformLocation(program, "modelViewProjMatrix"); + uniforms[UNIFORM_TEXTURE] = glGetUniformLocation(program, "texture"); + + // Release vertex and fragment shaders + if (vertShader) + glDeleteShader(vertShader); + if (fragShader) + glDeleteShader(fragShader); + + return TRUE; +} + +- (BOOL)resizeFromLayer:(CAEAGLLayer *)layer +{ + [EAGLContext setCurrentContext:context]; + // Allocate color buffer backing based on the current layer size + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); + glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); + [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight); + +// glGenRenderbuffers(1, &depthBuffer); +// glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer); +// glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, backingWidth, backingHeight); +// glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer); +// + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + return NO; + } +#ifdef MSAA + // Multisampled antialiasing + glGenFramebuffers(1, &msaaFramebuffer); + glGenRenderbuffers(1, &msaaRenderbuffer); + + glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer); + glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer); + + // 4X MSAA + glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, 4, GL_RGBA8_OES, backingWidth, backingHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaaRenderbuffer); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + return NO; + + } +#endif + + 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]; +} + +- (void)convert3DTransform:(CATransform3D *)transform3D toMatrix:(GLfloat *)matrix; +{ + // struct CATransform3D + // { + // CGFloat m11, m12, m13, m14; + // CGFloat m21, m22, m23, m24; + // CGFloat m31, m32, m33, m34; + // CGFloat m41, m42, m43, m44; + // }; + + matrix[0] = (GLfloat)transform3D->m11; + matrix[1] = (GLfloat)transform3D->m12; + matrix[2] = (GLfloat)transform3D->m13; + matrix[3] = (GLfloat)transform3D->m14; + matrix[4] = (GLfloat)transform3D->m21; + matrix[5] = (GLfloat)transform3D->m22; + matrix[6] = (GLfloat)transform3D->m23; + matrix[7] = (GLfloat)transform3D->m24; + matrix[8] = (GLfloat)transform3D->m31; + matrix[9] = (GLfloat)transform3D->m32; + matrix[10] = (GLfloat)transform3D->m33; + matrix[11] = (GLfloat)transform3D->m34; + matrix[12] = (GLfloat)transform3D->m41; + matrix[13] = (GLfloat)transform3D->m42; + matrix[14] = (GLfloat)transform3D->m43; + matrix[15] = (GLfloat)transform3D->m44; +} + +#pragma mark - +#pragma mark GPUImageTextureOutputDelegate delegate method + +- (void)newFrameReadyFromTextureOutput:(GPUImageTextureOutput *)callbackTextureOutput; +{ + textureForCubeFace = callbackTextureOutput.texture; + + [self renderByRotatingAroundX:0.0 rotatingAroundY:0.0]; +} + +@end diff --git a/examples/CubeExample/Classes/ESRenderer.h b/examples/CubeExample/Classes/ESRenderer.h new file mode 100644 index 000000000..49f6f56b0 --- /dev/null +++ b/examples/CubeExample/Classes/ESRenderer.h @@ -0,0 +1,11 @@ +#import + +#import +#import + +@protocol ESRenderer + +- (void)renderByRotatingAroundX:(float)xRotation rotatingAroundY:(float)yRotation; +- (BOOL)resizeFromLayer:(CAEAGLLayer *)layer; + +@end diff --git a/examples/CubeExample/CubeExample-Info.plist b/examples/CubeExample/CubeExample-Info.plist new file mode 100644 index 000000000..a45013de2 --- /dev/null +++ b/examples/CubeExample/CubeExample-Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UIStatusBarHidden + + + diff --git a/examples/CubeExample/CubeExample.xcodeproj/project.pbxproj b/examples/CubeExample/CubeExample.xcodeproj/project.pbxproj new file mode 100755 index 000000000..83772bfd1 --- /dev/null +++ b/examples/CubeExample/CubeExample.xcodeproj/project.pbxproj @@ -0,0 +1,376 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* CubeExampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* CubeExampleAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2514C27310084DB100A42282 /* ES2Renderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2514C27010084DB100A42282 /* ES2Renderer.m */; }; + 2514C27B10084DCA00A42282 /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 2514C27910084DCA00A42282 /* Shader.fsh */; }; + 2514C27C10084DCA00A42282 /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 2514C27A10084DCA00A42282 /* Shader.vsh */; }; + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 28FD14FE0DC6FC130079059D /* EAGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28FD14FD0DC6FC130079059D /* EAGLView.m */; }; + 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD14FF0DC6FC520079059D /* OpenGLES.framework */; }; + 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD15070DC6FC5B0079059D /* QuartzCore.framework */; }; + BCB6B8A41505A9840041703B /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCB6B8A11505A9840041703B /* AVFoundation.framework */; }; + BCB6B8A51505A9840041703B /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCB6B8A21505A9840041703B /* CoreMedia.framework */; }; + BCB6B8A61505A9840041703B /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCB6B8A31505A9840041703B /* CoreVideo.framework */; }; + BCB6B8A91505A9AA0041703B /* libGPUImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BCB6B88C150447DF0041703B /* libGPUImage.a */; }; + BCB6B8C41505C2780041703B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCB6B8C31505C2780041703B /* CoreGraphics.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + BCB6B88B150447DF0041703B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BCB6B883150447DF0041703B /* GPUImage.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BCF1A33414DDB1EC00852800; + remoteInfo = GPUImage; + }; + BCB6B88D150447DF0041703B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BCB6B883150447DF0041703B /* GPUImage.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BCF1A34414DDB1EC00852800; + remoteInfo = GPUImageTests; + }; + BCB6B8A71505A9A40041703B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BCB6B883150447DF0041703B /* GPUImage.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BCF1A33314DDB1EC00852800; + remoteInfo = GPUImage; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* CubeExampleAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CubeExampleAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* CubeExampleAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CubeExampleAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* CubeExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CubeExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 2514C26F10084DB100A42282 /* ES2Renderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ES2Renderer.h; sourceTree = ""; }; + 2514C27010084DB100A42282 /* ES2Renderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ES2Renderer.m; sourceTree = ""; }; + 2514C27110084DB100A42282 /* ESRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESRenderer.h; sourceTree = ""; }; + 2514C27910084DCA00A42282 /* Shader.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 2514C27A10084DCA00A42282 /* Shader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + 28FD14FC0DC6FC130079059D /* EAGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAGLView.h; sourceTree = ""; }; + 28FD14FD0DC6FC130079059D /* EAGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAGLView.m; sourceTree = ""; }; + 28FD14FF0DC6FC520079059D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 28FD15070DC6FC5B0079059D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32CA4F630368D1EE00C91783 /* CubeExample_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CubeExample_Prefix.pch; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* CubeExample-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "CubeExample-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + BCB6B883150447DF0041703B /* GPUImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GPUImage.xcodeproj; path = ../../framework/GPUImage.xcodeproj; sourceTree = ""; }; + BCB6B8A11505A9840041703B /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + BCB6B8A21505A9840041703B /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; + BCB6B8A31505A9840041703B /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; + BCB6B8C31505C2780041703B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BCB6B8C41505C2780041703B /* CoreGraphics.framework in Frameworks */, + BCB6B8A91505A9AA0041703B /* libGPUImage.a in Frameworks */, + BCB6B8A41505A9840041703B /* AVFoundation.framework in Frameworks */, + BCB6B8A51505A9840041703B /* CoreMedia.framework in Frameworks */, + BCB6B8A61505A9840041703B /* CoreVideo.framework in Frameworks */, + 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */, + 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */, + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 2514C26F10084DB100A42282 /* ES2Renderer.h */, + 2514C27010084DB100A42282 /* ES2Renderer.m */, + 2514C27110084DB100A42282 /* ESRenderer.h */, + 28FD14FC0DC6FC130079059D /* EAGLView.h */, + 28FD14FD0DC6FC130079059D /* EAGLView.m */, + 1D3623240D0F684500981E51 /* CubeExampleAppDelegate.h */, + 1D3623250D0F684500981E51 /* CubeExampleAppDelegate.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* CubeExample.app */, + ); + name = Products; + sourceTree = ""; + }; + 2514C27610084DB600A42282 /* Shaders */ = { + isa = PBXGroup; + children = ( + 2514C27910084DCA00A42282 /* Shader.fsh */, + 2514C27A10084DCA00A42282 /* Shader.vsh */, + ); + name = Shaders; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 2514C27610084DB600A42282 /* Shaders */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* CubeExample_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 28AD733E0D9D9553002E5188 /* MainWindow.xib */, + 8D1107310486CEB800E47090 /* CubeExample-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + BCB6B883150447DF0041703B /* GPUImage.xcodeproj */, + BCB6B8A11505A9840041703B /* AVFoundation.framework */, + BCB6B8A21505A9840041703B /* CoreMedia.framework */, + BCB6B8C31505C2780041703B /* CoreGraphics.framework */, + BCB6B8A31505A9840041703B /* CoreVideo.framework */, + 28FD15070DC6FC5B0079059D /* QuartzCore.framework */, + 28FD14FF0DC6FC520079059D /* OpenGLES.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + BCB6B884150447DF0041703B /* Products */ = { + isa = PBXGroup; + children = ( + BCB6B88C150447DF0041703B /* libGPUImage.a */, + BCB6B88E150447DF0041703B /* GPUImageTests.octest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* CubeExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "CubeExample" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + BCB6B8A81505A9A40041703B /* PBXTargetDependency */, + ); + name = CubeExample; + productName = CubeExample; + productReference = 1D6058910D05DD3D006BFB54 /* CubeExample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "CubeExample" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = BCB6B884150447DF0041703B /* Products */; + ProjectRef = BCB6B883150447DF0041703B /* GPUImage.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* CubeExample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + BCB6B88C150447DF0041703B /* libGPUImage.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libGPUImage.a; + remoteRef = BCB6B88B150447DF0041703B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + BCB6B88E150447DF0041703B /* GPUImageTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = GPUImageTests.octest; + remoteRef = BCB6B88D150447DF0041703B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2514C27B10084DCA00A42282 /* Shader.fsh in Resources */, + 2514C27C10084DCA00A42282 /* Shader.vsh in Resources */, + 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* CubeExampleAppDelegate.m in Sources */, + 28FD14FE0DC6FC130079059D /* EAGLView.m in Sources */, + 2514C27310084DB100A42282 /* ES2Renderer.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + BCB6B8A81505A9A40041703B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GPUImage; + targetProxy = BCB6B8A71505A9A40041703B /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = CubeExample_Prefix.pch; + "GCC_THUMB_SUPPORT[arch=armv6]" = ""; + INFOPLIST_FILE = "CubeExample-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + PRODUCT_NAME = CubeExample; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = CubeExample_Prefix.pch; + "GCC_THUMB_SUPPORT[arch=armv6]" = ""; + INFOPLIST_FILE = "CubeExample-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + PRODUCT_NAME = CubeExample; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "../../framework/**"; + PREBINDING = NO; + SDKROOT = iphoneos; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "../../framework/**"; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + PREBINDING = NO; + SDKROOT = iphoneos; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "CubeExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "CubeExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/examples/CubeExample/CubeExample_Prefix.pch b/examples/CubeExample/CubeExample_Prefix.pch new file mode 100644 index 000000000..133341760 --- /dev/null +++ b/examples/CubeExample/CubeExample_Prefix.pch @@ -0,0 +1,14 @@ +// +// Prefix header for all source files of the 'CubeExample' target in the 'CubeExample' project +// + +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iPhone SDK 3.0 and later." +#endif + +#ifdef __OBJC__ +#import +#import +#endif diff --git a/examples/CubeExample/MainWindow.xib b/examples/CubeExample/MainWindow.xib new file mode 100644 index 000000000..d75ecb8fd --- /dev/null +++ b/examples/CubeExample/MainWindow.xib @@ -0,0 +1,239 @@ + + + + 800 + 10D541 + 760 + 1038.29 + 460.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 81 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + IBCocoaTouchFramework + + + + 1316 + + YES + + + 1298 + {320, 480} + + + 3 + MQA + + NO + IBCocoaTouchFramework + + + + {320, 480} + + + 1 + MSAxIDEAA + + NO + IBCocoaTouchFramework + YES + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + glView + + + + 9 + + + + + YES + + 0 + + + + + + 2 + + + YES + + + + + + -1 + + + File's Owner + + + 3 + + + + + 8 + + + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 8.CustomClassName + 8.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + + YES + + + {{228, 376}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + CubeExampleAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + EAGLView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 9 + + + + YES + + EAGLView + UIView + + IBProjectSource + Classes/EAGLView.h + + + + CubeExampleAppDelegate + NSObject + + YES + + YES + glView + window + + + YES + EAGLView + UIWindow + + + + IBProjectSource + Classes/CubeExampleAppDelegate.h + + + + + 0 + IBCocoaTouchFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + CubeExample.xcodeproj + 3 + 81 + + diff --git a/examples/CubeExample/Shaders/Shader.fsh b/examples/CubeExample/Shaders/Shader.fsh new file mode 100644 index 000000000..0e8263848 --- /dev/null +++ b/examples/CubeExample/Shaders/Shader.fsh @@ -0,0 +1,9 @@ +varying highp vec2 textureCoordinate; + +uniform sampler2D texture; + +void main() +{ + gl_FragColor = texture2D(texture, textureCoordinate); +// gl_FragColor = vec4(textureCoordinate, 1.0, 1.0); +} diff --git a/examples/CubeExample/Shaders/Shader.vsh b/examples/CubeExample/Shaders/Shader.vsh new file mode 100644 index 000000000..6866ba59a --- /dev/null +++ b/examples/CubeExample/Shaders/Shader.vsh @@ -0,0 +1,12 @@ +attribute vec4 position; +attribute vec4 inputTextureCoordinate; + +varying vec2 textureCoordinate; + +uniform mat4 modelViewProjMatrix; + +void main() +{ + gl_Position = modelViewProjMatrix * position; + textureCoordinate = inputTextureCoordinate.xy; +} diff --git a/examples/CubeExample/main.m b/examples/CubeExample/main.m new file mode 100644 index 000000000..1ccea0fe0 --- /dev/null +++ b/examples/CubeExample/main.m @@ -0,0 +1,16 @@ +// +// main.m +// CubeExample +// +// Created by Brad Larson on 4/20/2010. +// + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/framework/GPUImage.xcodeproj/project.pbxproj b/framework/GPUImage.xcodeproj/project.pbxproj index 43d3a2070..a62a56c8d 100644 --- a/framework/GPUImage.xcodeproj/project.pbxproj +++ b/framework/GPUImage.xcodeproj/project.pbxproj @@ -94,6 +94,8 @@ BCB6B8751504234A0041703B /* GPUImageHardLightBlendFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6B86D1504234A0041703B /* GPUImageHardLightBlendFilter.m */; }; BCB6B8761504234A0041703B /* GPUImageSoftLightBlendFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB6B86E1504234A0041703B /* GPUImageSoftLightBlendFilter.h */; }; BCB6B8771504234A0041703B /* GPUImageSoftLightBlendFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6B86F1504234A0041703B /* GPUImageSoftLightBlendFilter.m */; }; + BCB6B8BB1505BF940041703B /* GPUImageTextureOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB6B8B91505BF940041703B /* GPUImageTextureOutput.h */; }; + BCB6B8BC1505BF940041703B /* GPUImageTextureOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6B8BA1505BF940041703B /* GPUImageTextureOutput.m */; }; BCC93A0F1501D1BF00958B26 /* GPUImageFastBlurFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC93A0D1501D1BF00958B26 /* GPUImageFastBlurFilter.h */; }; BCC93A101501D1BF00958B26 /* GPUImageFastBlurFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC93A0E1501D1BF00958B26 /* GPUImageFastBlurFilter.m */; }; BCC93A1E1501E42F00958B26 /* GPUImageTwoPassFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC93A1C1501E42E00958B26 /* GPUImageTwoPassFilter.h */; }; @@ -212,6 +214,8 @@ BCB6B86D1504234A0041703B /* GPUImageHardLightBlendFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageHardLightBlendFilter.m; path = Source/GPUImageHardLightBlendFilter.m; sourceTree = SOURCE_ROOT; }; BCB6B86E1504234A0041703B /* GPUImageSoftLightBlendFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageSoftLightBlendFilter.h; path = Source/GPUImageSoftLightBlendFilter.h; sourceTree = SOURCE_ROOT; }; BCB6B86F1504234A0041703B /* GPUImageSoftLightBlendFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageSoftLightBlendFilter.m; path = Source/GPUImageSoftLightBlendFilter.m; sourceTree = SOURCE_ROOT; }; + BCB6B8B91505BF940041703B /* GPUImageTextureOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageTextureOutput.h; path = Source/GPUImageTextureOutput.h; sourceTree = SOURCE_ROOT; }; + BCB6B8BA1505BF940041703B /* GPUImageTextureOutput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageTextureOutput.m; path = Source/GPUImageTextureOutput.m; sourceTree = SOURCE_ROOT; }; BCC93A0D1501D1BF00958B26 /* GPUImageFastBlurFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageFastBlurFilter.h; path = Source/GPUImageFastBlurFilter.h; sourceTree = SOURCE_ROOT; }; BCC93A0E1501D1BF00958B26 /* GPUImageFastBlurFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageFastBlurFilter.m; path = Source/GPUImageFastBlurFilter.m; sourceTree = SOURCE_ROOT; }; BCC93A1C1501E42E00958B26 /* GPUImageTwoPassFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageTwoPassFilter.h; path = Source/GPUImageTwoPassFilter.h; sourceTree = SOURCE_ROOT; }; @@ -376,6 +380,8 @@ BC1B715614F49DAA00ACA2AB /* GPUImageRawData.m */, BC1B727F14FB16AF00ACA2AB /* GPUImageMovieWriter.h */, BC1B728014FB16AF00ACA2AB /* GPUImageMovieWriter.m */, + BCB6B8B91505BF940041703B /* GPUImageTextureOutput.h */, + BCB6B8BA1505BF940041703B /* GPUImageTextureOutput.m */, ); name = Outputs; sourceTree = ""; @@ -529,6 +535,7 @@ BCB6B8721504234A0041703B /* GPUImageExclusionBlendFilter.h in Headers */, BCB6B8741504234A0041703B /* GPUImageHardLightBlendFilter.h in Headers */, BCB6B8761504234A0041703B /* GPUImageSoftLightBlendFilter.h in Headers */, + BCB6B8BB1505BF940041703B /* GPUImageTextureOutput.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -674,6 +681,7 @@ BCB6B8731504234A0041703B /* GPUImageExclusionBlendFilter.m in Sources */, BCB6B8751504234A0041703B /* GPUImageHardLightBlendFilter.m in Sources */, BCB6B8771504234A0041703B /* GPUImageSoftLightBlendFilter.m in Sources */, + BCB6B8BC1505BF940041703B /* GPUImageTextureOutput.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/framework/Source/GPUImage.h b/framework/Source/GPUImage.h index 34e0e97cc..80b44273b 100644 --- a/framework/Source/GPUImage.h +++ b/framework/Source/GPUImage.h @@ -10,6 +10,7 @@ #import "GPUImageRawData.h" #import "GPUImageMovieWriter.h" #import "GPUImageFilterPipeline.h" +#import "GPUImageTextureOutput.h" // Filters #import "GPUImageFilter.h" diff --git a/framework/Source/GPUImageColorMatrixFilter.h b/framework/Source/GPUImageColorMatrixFilter.h index 71c847009..33d72c26c 100644 --- a/framework/Source/GPUImageColorMatrixFilter.h +++ b/framework/Source/GPUImageColorMatrixFilter.h @@ -1,21 +1,5 @@ #import "GPUImageFilter.h" -struct GPUVector4 { - GLfloat one; - GLfloat two; - GLfloat three; - GLfloat four; -}; -typedef struct GPUVector4 GPUVector4; - -struct GPUMatrix4x4 { - GPUVector4 one; - GPUVector4 two; - GPUVector4 three; - GPUVector4 four; -}; -typedef struct GPUMatrix4x4 GPUMatrix4x4; - @interface GPUImageColorMatrixFilter : GPUImageFilter { GLint colorMatrixUniform; diff --git a/framework/Source/GPUImageFilter.h b/framework/Source/GPUImageFilter.h index 2649874a9..2815721e7 100644 --- a/framework/Source/GPUImageFilter.h +++ b/framework/Source/GPUImageFilter.h @@ -7,6 +7,22 @@ extern NSString *const kGPUImageVertexShaderString; +struct GPUVector4 { + GLfloat one; + GLfloat two; + GLfloat three; + GLfloat four; +}; +typedef struct GPUVector4 GPUVector4; + +struct GPUMatrix4x4 { + GPUVector4 one; + GPUVector4 two; + GPUVector4 three; + GPUVector4 four; +}; +typedef struct GPUMatrix4x4 GPUMatrix4x4; + @interface GPUImageFilter : GPUImageOutput { GLuint filterSourceTexture, filterSourceTexture2; diff --git a/framework/Source/GPUImageTextureOutput.h b/framework/Source/GPUImageTextureOutput.h new file mode 100644 index 000000000..9fe5e6459 --- /dev/null +++ b/framework/Source/GPUImageTextureOutput.h @@ -0,0 +1,15 @@ +#import +#import "GPUImageOpenGLESContext.h" + +@protocol GPUImageTextureOutputDelegate; + +@interface GPUImageTextureOutput : NSObject + +@property(readwrite, unsafe_unretained, nonatomic) id delegate; +@property(readonly) GLint texture; + +@end + +@protocol GPUImageTextureOutputDelegate +- (void)newFrameReadyFromTextureOutput:(GPUImageTextureOutput *)callbackTextureOutput; +@end \ No newline at end of file diff --git a/framework/Source/GPUImageTextureOutput.m b/framework/Source/GPUImageTextureOutput.m new file mode 100644 index 000000000..b2d0f87ff --- /dev/null +++ b/framework/Source/GPUImageTextureOutput.m @@ -0,0 +1,35 @@ +#import "GPUImageTextureOutput.h" + +@implementation GPUImageTextureOutput + +@synthesize delegate = _delegate; +@synthesize texture = _texture; + +#pragma mark - +#pragma mark GPUImageInput protocol + +- (void)newFrameReady; +{ + [_delegate newFrameReadyFromTextureOutput:self]; +} + +- (NSInteger)nextAvailableTextureIndex; +{ + return 0; +} + +- (void)setInputTexture:(GLuint)newInputTexture atIndex:(NSInteger)textureIndex; +{ + _texture = newInputTexture; +} + +- (void)setInputSize:(CGSize)newSize; +{ +} + +- (CGSize)maximumOutputSize; +{ + return CGSizeZero; +} + +@end diff --git a/framework/Source/GPUImageVideoCamera.m b/framework/Source/GPUImageVideoCamera.m index 3f8bcbaaf..42ff0c88b 100644 --- a/framework/Source/GPUImageVideoCamera.m +++ b/framework/Source/GPUImageVideoCamera.m @@ -195,8 +195,6 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CM CVPixelBufferUnlockBaseAddress(cameraFrame, 0); -// glBindTexture(outputTexture, 0); - // Flush the CVOpenGLESTexture cache and release the texture CVOpenGLESTextureCacheFlush(coreVideoTextureCache, 0); CFRelease(texture);