├── .gitignore ├── GLImageProcessing.xcodeproj └── project.pbxproj └── GLImageProcessing ├── EAGLView.h ├── EAGLView.m ├── GLImageProcessing-Info.plist ├── GLImageProcessing-Prefix.pch ├── GLImageProcessingAppDelegate.h ├── GLImageProcessingAppDelegate.m ├── GLTexture.h ├── GLTexture.m ├── ImageProcessingViewController.h ├── ImageProcessingViewController.m ├── Shaders ├── BrightnessShader.fsh ├── GrayscaleShader.fsh ├── RippleShader.fsh ├── SaturationShader.fsh ├── SepiaShader.fsh ├── Shader.fsh ├── Shader.vsh └── VignetteShader.fsh ├── en.lproj ├── ImageProcessingViewController.xib ├── InfoPlist.strings └── MainWindow.xib ├── main.m └── source_image.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore .DS_Store files 2 | *.DS_Store 3 | 4 | #ignore .xcworkspace 5 | project.xcworkspace 6 | 7 | #ignore xcuserdata 8 | xcuserdata 9 | 10 | #ignore checkpoints folder 11 | Checkpoints 12 | -------------------------------------------------------------------------------- /GLImageProcessing.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 012ABFED140B187B002A801F /* GLTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = 012ABFEC140B187B002A801F /* GLTexture.m */; }; 11 | 01549D10140BA9F9002A4C8E /* GrayscaleShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 01549D0F140BA9F9002A4C8E /* GrayscaleShader.fsh */; }; 12 | 015E9AFD140B8EBA00DF7CB8 /* source_image.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 015E9AFC140B8EBA00DF7CB8 /* source_image.jpg */; }; 13 | 01969B59141017540017DAB7 /* VignetteShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 01969B58141017540017DAB7 /* VignetteShader.fsh */; }; 14 | 0199F8FB14023C6A0038AA29 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0199F8FA14023C6A0038AA29 /* UIKit.framework */; }; 15 | 0199F8FD14023C6A0038AA29 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0199F8FC14023C6A0038AA29 /* Foundation.framework */; }; 16 | 0199F8FF14023C6A0038AA29 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0199F8FE14023C6A0038AA29 /* CoreGraphics.framework */; }; 17 | 0199F90114023C6A0038AA29 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0199F90014023C6A0038AA29 /* QuartzCore.framework */; }; 18 | 0199F90314023C6A0038AA29 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0199F90214023C6A0038AA29 /* OpenGLES.framework */; }; 19 | 0199F90914023C6B0038AA29 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0199F90714023C6B0038AA29 /* InfoPlist.strings */; }; 20 | 0199F90B14023C6B0038AA29 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0199F90A14023C6B0038AA29 /* main.m */; }; 21 | 0199F90F14023C6B0038AA29 /* GLImageProcessingAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0199F90E14023C6B0038AA29 /* GLImageProcessingAppDelegate.m */; }; 22 | 0199F91214023C6B0038AA29 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0199F91014023C6B0038AA29 /* MainWindow.xib */; }; 23 | 0199F91414023C6B0038AA29 /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 0199F91314023C6B0038AA29 /* Shader.fsh */; }; 24 | 0199F91614023C6B0038AA29 /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 0199F91514023C6B0038AA29 /* Shader.vsh */; }; 25 | 0199F91914023C6B0038AA29 /* EAGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0199F91814023C6B0038AA29 /* EAGLView.m */; }; 26 | 0199F91C14023C6B0038AA29 /* ImageProcessingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0199F91B14023C6B0038AA29 /* ImageProcessingViewController.m */; }; 27 | 0199F91F14023C6B0038AA29 /* ImageProcessingViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0199F91D14023C6B0038AA29 /* ImageProcessingViewController.xib */; }; 28 | 01BD310C140F6BBF00E2DC24 /* SepiaShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 01BD310B140F6BBF00E2DC24 /* SepiaShader.fsh */; }; 29 | 01BD311A140F7E2D00E2DC24 /* BrightnessShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 01BD3119140F7E2D00E2DC24 /* BrightnessShader.fsh */; }; 30 | 01BD3121140F8E9900E2DC24 /* SaturationShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 01BD3120140F8E9900E2DC24 /* SaturationShader.fsh */; }; 31 | 01BD3128140F92C500E2DC24 /* RippleShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 01BD3127140F92C500E2DC24 /* RippleShader.fsh */; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 012ABFEB140B187B002A801F /* GLTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLTexture.h; sourceTree = ""; }; 36 | 012ABFEC140B187B002A801F /* GLTexture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GLTexture.m; sourceTree = ""; }; 37 | 01549D0F140BA9F9002A4C8E /* GrayscaleShader.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = GrayscaleShader.fsh; path = Shaders/GrayscaleShader.fsh; sourceTree = ""; }; 38 | 015E9AFC140B8EBA00DF7CB8 /* source_image.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = source_image.jpg; sourceTree = ""; }; 39 | 01969B58141017540017DAB7 /* VignetteShader.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = VignetteShader.fsh; path = Shaders/VignetteShader.fsh; sourceTree = ""; }; 40 | 0199F8F614023C6A0038AA29 /* GLImageProcessing.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GLImageProcessing.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 0199F8FA14023C6A0038AA29 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 42 | 0199F8FC14023C6A0038AA29 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 43 | 0199F8FE14023C6A0038AA29 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 44 | 0199F90014023C6A0038AA29 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 45 | 0199F90214023C6A0038AA29 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; 46 | 0199F90614023C6A0038AA29 /* GLImageProcessing-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GLImageProcessing-Info.plist"; sourceTree = ""; }; 47 | 0199F90814023C6B0038AA29 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 48 | 0199F90A14023C6B0038AA29 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 49 | 0199F90C14023C6B0038AA29 /* GLImageProcessing-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "GLImageProcessing-Prefix.pch"; sourceTree = ""; }; 50 | 0199F90D14023C6B0038AA29 /* GLImageProcessingAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GLImageProcessingAppDelegate.h; sourceTree = ""; }; 51 | 0199F90E14023C6B0038AA29 /* GLImageProcessingAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GLImageProcessingAppDelegate.m; sourceTree = ""; }; 52 | 0199F91114023C6B0038AA29 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; 53 | 0199F91314023C6B0038AA29 /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; 54 | 0199F91514023C6B0038AA29 /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; 55 | 0199F91714023C6B0038AA29 /* EAGLView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EAGLView.h; sourceTree = ""; }; 56 | 0199F91814023C6B0038AA29 /* EAGLView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EAGLView.m; sourceTree = ""; }; 57 | 0199F91A14023C6B0038AA29 /* ImageProcessingViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageProcessingViewController.h; sourceTree = ""; }; 58 | 0199F91B14023C6B0038AA29 /* ImageProcessingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImageProcessingViewController.m; sourceTree = ""; }; 59 | 0199F91E14023C6B0038AA29 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ImageProcessingViewController.xib; sourceTree = ""; }; 60 | 01BD310B140F6BBF00E2DC24 /* SepiaShader.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = SepiaShader.fsh; path = Shaders/SepiaShader.fsh; sourceTree = ""; }; 61 | 01BD3119140F7E2D00E2DC24 /* BrightnessShader.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = BrightnessShader.fsh; path = Shaders/BrightnessShader.fsh; sourceTree = ""; }; 62 | 01BD3120140F8E9900E2DC24 /* SaturationShader.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = SaturationShader.fsh; path = Shaders/SaturationShader.fsh; sourceTree = ""; }; 63 | 01BD3127140F92C500E2DC24 /* RippleShader.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = RippleShader.fsh; path = Shaders/RippleShader.fsh; sourceTree = ""; }; 64 | /* End PBXFileReference section */ 65 | 66 | /* Begin PBXFrameworksBuildPhase section */ 67 | 0199F8F314023C6A0038AA29 /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | 0199F8FB14023C6A0038AA29 /* UIKit.framework in Frameworks */, 72 | 0199F8FD14023C6A0038AA29 /* Foundation.framework in Frameworks */, 73 | 0199F8FF14023C6A0038AA29 /* CoreGraphics.framework in Frameworks */, 74 | 0199F90114023C6A0038AA29 /* QuartzCore.framework in Frameworks */, 75 | 0199F90314023C6A0038AA29 /* OpenGLES.framework in Frameworks */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | /* End PBXFrameworksBuildPhase section */ 80 | 81 | /* Begin PBXGroup section */ 82 | 012ABFDF140AFFE4002A801F /* Application */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 0199F90D14023C6B0038AA29 /* GLImageProcessingAppDelegate.h */, 86 | 0199F90E14023C6B0038AA29 /* GLImageProcessingAppDelegate.m */, 87 | 0199F91014023C6B0038AA29 /* MainWindow.xib */, 88 | ); 89 | name = Application; 90 | sourceTree = ""; 91 | }; 92 | 012ABFE0140AFFF2002A801F /* Controllers */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 0199F91A14023C6B0038AA29 /* ImageProcessingViewController.h */, 96 | 0199F91B14023C6B0038AA29 /* ImageProcessingViewController.m */, 97 | 0199F91D14023C6B0038AA29 /* ImageProcessingViewController.xib */, 98 | ); 99 | name = Controllers; 100 | sourceTree = ""; 101 | }; 102 | 012ABFE1140B0007002A801F /* Views */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 0199F91714023C6B0038AA29 /* EAGLView.h */, 106 | 0199F91814023C6B0038AA29 /* EAGLView.m */, 107 | ); 108 | name = Views; 109 | sourceTree = ""; 110 | }; 111 | 012AC004140B6EF6002A801F /* Model */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 012ABFEB140B187B002A801F /* GLTexture.h */, 115 | 012ABFEC140B187B002A801F /* GLTexture.m */, 116 | ); 117 | name = Model; 118 | sourceTree = ""; 119 | }; 120 | 0199F8EB14023C6A0038AA29 = { 121 | isa = PBXGroup; 122 | children = ( 123 | 0199F90414023C6A0038AA29 /* GLImageProcessing */, 124 | 0199F8F914023C6A0038AA29 /* Frameworks */, 125 | 0199F8F714023C6A0038AA29 /* Products */, 126 | ); 127 | sourceTree = ""; 128 | }; 129 | 0199F8F714023C6A0038AA29 /* Products */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 0199F8F614023C6A0038AA29 /* GLImageProcessing.app */, 133 | ); 134 | name = Products; 135 | sourceTree = ""; 136 | }; 137 | 0199F8F914023C6A0038AA29 /* Frameworks */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 0199F8FA14023C6A0038AA29 /* UIKit.framework */, 141 | 0199F8FC14023C6A0038AA29 /* Foundation.framework */, 142 | 0199F8FE14023C6A0038AA29 /* CoreGraphics.framework */, 143 | 0199F90014023C6A0038AA29 /* QuartzCore.framework */, 144 | 0199F90214023C6A0038AA29 /* OpenGLES.framework */, 145 | ); 146 | name = Frameworks; 147 | sourceTree = ""; 148 | }; 149 | 0199F90414023C6A0038AA29 /* GLImageProcessing */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 012ABFDF140AFFE4002A801F /* Application */, 153 | 012ABFE0140AFFF2002A801F /* Controllers */, 154 | 012ABFE1140B0007002A801F /* Views */, 155 | 012AC004140B6EF6002A801F /* Model */, 156 | 0199F92514023D4A0038AA29 /* Shaders */, 157 | 0199F90514023C6A0038AA29 /* Supporting Files */, 158 | ); 159 | path = GLImageProcessing; 160 | sourceTree = ""; 161 | }; 162 | 0199F90514023C6A0038AA29 /* Supporting Files */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 015E9AFC140B8EBA00DF7CB8 /* source_image.jpg */, 166 | 0199F90614023C6A0038AA29 /* GLImageProcessing-Info.plist */, 167 | 0199F90714023C6B0038AA29 /* InfoPlist.strings */, 168 | 0199F90A14023C6B0038AA29 /* main.m */, 169 | 0199F90C14023C6B0038AA29 /* GLImageProcessing-Prefix.pch */, 170 | ); 171 | name = "Supporting Files"; 172 | sourceTree = ""; 173 | }; 174 | 0199F92514023D4A0038AA29 /* Shaders */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 01969B58141017540017DAB7 /* VignetteShader.fsh */, 178 | 01BD3127140F92C500E2DC24 /* RippleShader.fsh */, 179 | 01BD3120140F8E9900E2DC24 /* SaturationShader.fsh */, 180 | 01BD3119140F7E2D00E2DC24 /* BrightnessShader.fsh */, 181 | 01BD310B140F6BBF00E2DC24 /* SepiaShader.fsh */, 182 | 01549D0F140BA9F9002A4C8E /* GrayscaleShader.fsh */, 183 | 0199F91314023C6B0038AA29 /* Shader.fsh */, 184 | 0199F91514023C6B0038AA29 /* Shader.vsh */, 185 | ); 186 | name = Shaders; 187 | sourceTree = ""; 188 | }; 189 | /* End PBXGroup section */ 190 | 191 | /* Begin PBXNativeTarget section */ 192 | 0199F8F514023C6A0038AA29 /* GLImageProcessing */ = { 193 | isa = PBXNativeTarget; 194 | buildConfigurationList = 0199F92214023C6B0038AA29 /* Build configuration list for PBXNativeTarget "GLImageProcessing" */; 195 | buildPhases = ( 196 | 0199F8F214023C6A0038AA29 /* Sources */, 197 | 0199F8F314023C6A0038AA29 /* Frameworks */, 198 | 0199F8F414023C6A0038AA29 /* Resources */, 199 | ); 200 | buildRules = ( 201 | ); 202 | dependencies = ( 203 | ); 204 | name = GLImageProcessing; 205 | productName = GLImageProcessing; 206 | productReference = 0199F8F614023C6A0038AA29 /* GLImageProcessing.app */; 207 | productType = "com.apple.product-type.application"; 208 | }; 209 | /* End PBXNativeTarget section */ 210 | 211 | /* Begin PBXProject section */ 212 | 0199F8ED14023C6A0038AA29 /* Project object */ = { 213 | isa = PBXProject; 214 | attributes = { 215 | LastUpgradeCheck = 0430; 216 | ORGANIZATIONNAME = "Aged & Distilled"; 217 | }; 218 | buildConfigurationList = 0199F8F014023C6A0038AA29 /* Build configuration list for PBXProject "GLImageProcessing" */; 219 | compatibilityVersion = "Xcode 3.2"; 220 | developmentRegion = English; 221 | hasScannedForEncodings = 0; 222 | knownRegions = ( 223 | en, 224 | ); 225 | mainGroup = 0199F8EB14023C6A0038AA29; 226 | productRefGroup = 0199F8F714023C6A0038AA29 /* Products */; 227 | projectDirPath = ""; 228 | projectRoot = ""; 229 | targets = ( 230 | 0199F8F514023C6A0038AA29 /* GLImageProcessing */, 231 | ); 232 | }; 233 | /* End PBXProject section */ 234 | 235 | /* Begin PBXResourcesBuildPhase section */ 236 | 0199F8F414023C6A0038AA29 /* Resources */ = { 237 | isa = PBXResourcesBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | 0199F90914023C6B0038AA29 /* InfoPlist.strings in Resources */, 241 | 0199F91214023C6B0038AA29 /* MainWindow.xib in Resources */, 242 | 0199F91414023C6B0038AA29 /* Shader.fsh in Resources */, 243 | 0199F91614023C6B0038AA29 /* Shader.vsh in Resources */, 244 | 01549D10140BA9F9002A4C8E /* GrayscaleShader.fsh in Resources */, 245 | 01BD310C140F6BBF00E2DC24 /* SepiaShader.fsh in Resources */, 246 | 01BD311A140F7E2D00E2DC24 /* BrightnessShader.fsh in Resources */, 247 | 01BD3121140F8E9900E2DC24 /* SaturationShader.fsh in Resources */, 248 | 01BD3128140F92C500E2DC24 /* RippleShader.fsh in Resources */, 249 | 01969B59141017540017DAB7 /* VignetteShader.fsh in Resources */, 250 | 0199F91F14023C6B0038AA29 /* ImageProcessingViewController.xib in Resources */, 251 | 015E9AFD140B8EBA00DF7CB8 /* source_image.jpg in Resources */, 252 | ); 253 | runOnlyForDeploymentPostprocessing = 0; 254 | }; 255 | /* End PBXResourcesBuildPhase section */ 256 | 257 | /* Begin PBXSourcesBuildPhase section */ 258 | 0199F8F214023C6A0038AA29 /* Sources */ = { 259 | isa = PBXSourcesBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | 0199F90B14023C6B0038AA29 /* main.m in Sources */, 263 | 0199F90F14023C6B0038AA29 /* GLImageProcessingAppDelegate.m in Sources */, 264 | 0199F91914023C6B0038AA29 /* EAGLView.m in Sources */, 265 | 0199F91C14023C6B0038AA29 /* ImageProcessingViewController.m in Sources */, 266 | 012ABFED140B187B002A801F /* GLTexture.m in Sources */, 267 | ); 268 | runOnlyForDeploymentPostprocessing = 0; 269 | }; 270 | /* End PBXSourcesBuildPhase section */ 271 | 272 | /* Begin PBXVariantGroup section */ 273 | 0199F90714023C6B0038AA29 /* InfoPlist.strings */ = { 274 | isa = PBXVariantGroup; 275 | children = ( 276 | 0199F90814023C6B0038AA29 /* en */, 277 | ); 278 | name = InfoPlist.strings; 279 | sourceTree = ""; 280 | }; 281 | 0199F91014023C6B0038AA29 /* MainWindow.xib */ = { 282 | isa = PBXVariantGroup; 283 | children = ( 284 | 0199F91114023C6B0038AA29 /* en */, 285 | ); 286 | name = MainWindow.xib; 287 | sourceTree = ""; 288 | }; 289 | 0199F91D14023C6B0038AA29 /* ImageProcessingViewController.xib */ = { 290 | isa = PBXVariantGroup; 291 | children = ( 292 | 0199F91E14023C6B0038AA29 /* en */, 293 | ); 294 | name = ImageProcessingViewController.xib; 295 | sourceTree = ""; 296 | }; 297 | /* End PBXVariantGroup section */ 298 | 299 | /* Begin XCBuildConfiguration section */ 300 | 0199F92014023C6B0038AA29 /* Debug */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | ALWAYS_SEARCH_USER_PATHS = NO; 304 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 305 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 306 | COPY_PHASE_STRIP = NO; 307 | GCC_C_LANGUAGE_STANDARD = gnu99; 308 | GCC_DYNAMIC_NO_PIC = NO; 309 | GCC_OPTIMIZATION_LEVEL = 0; 310 | GCC_PREPROCESSOR_DEFINITIONS = ( 311 | "DEBUG=1", 312 | "$(inherited)", 313 | ); 314 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 315 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 316 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 317 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 318 | GCC_WARN_UNUSED_VARIABLE = YES; 319 | IPHONEOS_DEPLOYMENT_TARGET = 4.3; 320 | RUN_CLANG_STATIC_ANALYZER = YES; 321 | SDKROOT = iphoneos; 322 | }; 323 | name = Debug; 324 | }; 325 | 0199F92114023C6B0038AA29 /* Release */ = { 326 | isa = XCBuildConfiguration; 327 | buildSettings = { 328 | ALWAYS_SEARCH_USER_PATHS = NO; 329 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = YES; 332 | GCC_C_LANGUAGE_STANDARD = gnu99; 333 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 334 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 335 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 336 | GCC_WARN_UNUSED_VARIABLE = YES; 337 | IPHONEOS_DEPLOYMENT_TARGET = 4.3; 338 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 339 | RUN_CLANG_STATIC_ANALYZER = YES; 340 | SDKROOT = iphoneos; 341 | VALIDATE_PRODUCT = YES; 342 | }; 343 | name = Release; 344 | }; 345 | 0199F92314023C6B0038AA29 /* Debug */ = { 346 | isa = XCBuildConfiguration; 347 | buildSettings = { 348 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 349 | GCC_PREFIX_HEADER = "GLImageProcessing/GLImageProcessing-Prefix.pch"; 350 | "GCC_THUMB_SUPPORT[arch=armv6]" = ""; 351 | INFOPLIST_FILE = "GLImageProcessing/GLImageProcessing-Info.plist"; 352 | PRODUCT_NAME = "$(TARGET_NAME)"; 353 | WRAPPER_EXTENSION = app; 354 | }; 355 | name = Debug; 356 | }; 357 | 0199F92414023C6B0038AA29 /* Release */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 361 | GCC_PREFIX_HEADER = "GLImageProcessing/GLImageProcessing-Prefix.pch"; 362 | "GCC_THUMB_SUPPORT[arch=armv6]" = ""; 363 | INFOPLIST_FILE = "GLImageProcessing/GLImageProcessing-Info.plist"; 364 | PRODUCT_NAME = "$(TARGET_NAME)"; 365 | WRAPPER_EXTENSION = app; 366 | }; 367 | name = Release; 368 | }; 369 | /* End XCBuildConfiguration section */ 370 | 371 | /* Begin XCConfigurationList section */ 372 | 0199F8F014023C6A0038AA29 /* Build configuration list for PBXProject "GLImageProcessing" */ = { 373 | isa = XCConfigurationList; 374 | buildConfigurations = ( 375 | 0199F92014023C6B0038AA29 /* Debug */, 376 | 0199F92114023C6B0038AA29 /* Release */, 377 | ); 378 | defaultConfigurationIsVisible = 0; 379 | defaultConfigurationName = Release; 380 | }; 381 | 0199F92214023C6B0038AA29 /* Build configuration list for PBXNativeTarget "GLImageProcessing" */ = { 382 | isa = XCConfigurationList; 383 | buildConfigurations = ( 384 | 0199F92314023C6B0038AA29 /* Debug */, 385 | 0199F92414023C6B0038AA29 /* Release */, 386 | ); 387 | defaultConfigurationIsVisible = 0; 388 | defaultConfigurationName = Release; 389 | }; 390 | /* End XCConfigurationList section */ 391 | }; 392 | rootObject = 0199F8ED14023C6A0038AA29 /* Project object */; 393 | } 394 | -------------------------------------------------------------------------------- /GLImageProcessing/EAGLView.h: -------------------------------------------------------------------------------- 1 | // 2 | // EAGLView.h 3 | // OpenGLES_iPhone 4 | // 5 | // Created by mmalc Crawford on 11/18/10. 6 | // Copyright 2010 Apple Inc. All rights reserved. 7 | // 8 | // This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. 9 | // The view content is basically an EAGL surface you render your OpenGL scene into. 10 | // Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. 11 | 12 | #import 13 | 14 | #import 15 | #import 16 | 17 | @class EAGLContext; 18 | 19 | 20 | @interface EAGLView : UIView 21 | 22 | @property (nonatomic, retain) EAGLContext *context; 23 | 24 | - (void)setFramebuffer; 25 | - (BOOL)presentFramebuffer; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /GLImageProcessing/EAGLView.m: -------------------------------------------------------------------------------- 1 | // 2 | // EAGLView.m 3 | // OpenGLES_iPhone 4 | // 5 | // Created by mmalc Crawford on 11/18/10. 6 | // Copyright 2010 Apple Inc. All rights reserved. 7 | // 8 | 9 | #import "EAGLView.h" 10 | 11 | #import 12 | 13 | 14 | @interface EAGLView () 15 | { 16 | // The pixel dimensions of the CAEAGLLayer. 17 | GLint framebufferWidth; 18 | GLint framebufferHeight; 19 | 20 | // The OpenGL ES names for the framebuffer and renderbuffer used to render to this view. 21 | GLuint defaultFramebuffer; 22 | GLuint colorRenderbuffer; 23 | } 24 | 25 | - (void)createFramebuffer; 26 | - (void)deleteFramebuffer; 27 | 28 | @end 29 | 30 | @implementation EAGLView 31 | 32 | #pragma mark - Synthesize properties 33 | 34 | @synthesize context = context_; 35 | 36 | #pragma mark - Lifecycle 37 | 38 | - (id)initWithCoder:(NSCoder*)coder 39 | { 40 | self = [super initWithCoder:coder]; 41 | if (self) 42 | { 43 | CAEAGLLayer* eaglLayer = (CAEAGLLayer *)self.layer; 44 | 45 | eaglLayer.opaque = TRUE; 46 | eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: 47 | [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, 48 | kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, 49 | nil]; 50 | 51 | // If we are on a retina display, make sure we set the scale factor of our view so that our CAEAGLLayer is sized to match the display. This will allow us to draw at the higher resolution of the retina display with GL 52 | 53 | if ([[UIScreen mainScreen] scale] == 2.0) 54 | self.contentScaleFactor = 2.0; 55 | } 56 | 57 | return self; 58 | } 59 | 60 | - (void)dealloc 61 | { 62 | [self deleteFramebuffer]; 63 | [context_ release]; 64 | 65 | [super dealloc]; 66 | } 67 | 68 | #pragma mark - UIView 69 | 70 | + (Class)layerClass 71 | { 72 | return [CAEAGLLayer class]; 73 | } 74 | 75 | - (void)layoutSubviews 76 | { 77 | // The framebuffer will be re-created at the beginning of the next setFramebuffer method call. 78 | [self deleteFramebuffer]; 79 | } 80 | 81 | #pragma mark - Properties 82 | 83 | - (void)setContext:(EAGLContext *)newContext 84 | { 85 | if (context_ != newContext) 86 | { 87 | [self deleteFramebuffer]; 88 | [context_ release]; 89 | context_ = [newContext retain];; 90 | 91 | [EAGLContext setCurrentContext:nil]; 92 | } 93 | } 94 | 95 | #pragma mark - Framebuffer 96 | 97 | - (void)createFramebuffer 98 | { 99 | if (self.context && !defaultFramebuffer) 100 | { 101 | [EAGLContext setCurrentContext:self.context]; 102 | 103 | // Create default framebuffer object. 104 | glGenFramebuffers(1, &defaultFramebuffer); 105 | glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); 106 | 107 | // Create color render buffer and allocate backing store. 108 | glGenRenderbuffers(1, &colorRenderbuffer); 109 | glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); 110 | [self.context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; 111 | glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth); 112 | glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight); 113 | 114 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); 115 | 116 | if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 117 | NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); 118 | } 119 | } 120 | 121 | - (void)deleteFramebuffer 122 | { 123 | if (self.context) 124 | { 125 | [EAGLContext setCurrentContext:self.context]; 126 | 127 | if (defaultFramebuffer) 128 | { 129 | glDeleteFramebuffers(1, &defaultFramebuffer); 130 | defaultFramebuffer = 0; 131 | } 132 | 133 | if (colorRenderbuffer) 134 | { 135 | glDeleteRenderbuffers(1, &colorRenderbuffer); 136 | colorRenderbuffer = 0; 137 | } 138 | } 139 | } 140 | 141 | - (void)setFramebuffer 142 | { 143 | if (self.context) 144 | { 145 | [EAGLContext setCurrentContext:self.context]; 146 | 147 | if (!defaultFramebuffer) 148 | [self createFramebuffer]; 149 | 150 | glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); 151 | 152 | glViewport(0, 0, framebufferWidth, framebufferHeight); 153 | } 154 | } 155 | 156 | - (BOOL)presentFramebuffer 157 | { 158 | BOOL success = FALSE; 159 | 160 | if (self.context) 161 | { 162 | [EAGLContext setCurrentContext:self.context]; 163 | 164 | glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); 165 | 166 | success = [self.context presentRenderbuffer:GL_RENDERBUFFER]; 167 | } 168 | 169 | return success; 170 | } 171 | 172 | 173 | @end 174 | -------------------------------------------------------------------------------- /GLImageProcessing/GLImageProcessing-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleDocumentTypes 10 | 11 | CFBundleExecutable 12 | ${EXECUTABLE_NAME} 13 | CFBundleIconFile 14 | 15 | CFBundleIdentifier 16 | AgedDistilled.${PRODUCT_NAME:rfc1034identifier} 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | ${PRODUCT_NAME} 21 | CFBundlePackageType 22 | APPL 23 | CFBundleShortVersionString 24 | 1.0 25 | CFBundleSignature 26 | ???? 27 | CFBundleURLTypes 28 | 29 | CFBundleVersion 30 | 1.0 31 | LSRequiresIPhoneOS 32 | 33 | NSMainNibFile 34 | MainWindow 35 | UIRequiredDeviceCapabilities 36 | 37 | opengles-2 38 | 39 | UIStatusBarHidden 40 | 41 | UISupportedInterfaceOrientations 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | UTExportedTypeDeclarations 48 | 49 | UTImportedTypeDeclarations 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /GLImageProcessing/GLImageProcessing-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'GLImageProcessing' target in the 'GLImageProcessing' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iPhone SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /GLImageProcessing/GLImageProcessingAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // GLImageProcessingAppDelegate.h 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ImageProcessingViewController; 12 | 13 | @interface GLImageProcessingAppDelegate : NSObject 14 | 15 | @property (nonatomic, retain) IBOutlet UIWindow* window; 16 | @property (nonatomic, retain) IBOutlet ImageProcessingViewController* viewController; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /GLImageProcessing/GLImageProcessingAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // GLImageProcessingAppDelegate.m 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | #import "GLImageProcessingAppDelegate.h" 10 | 11 | #import "EAGLView.h" 12 | 13 | #import "ImageProcessingViewController.h" 14 | 15 | @implementation GLImageProcessingAppDelegate 16 | 17 | @synthesize window = window_; 18 | @synthesize viewController = viewController_; 19 | 20 | #pragma mark - Lifecycle 21 | 22 | - (void)dealloc 23 | { 24 | [window_ release]; 25 | [viewController_ release]; 26 | [super dealloc]; 27 | } 28 | 29 | #pragma mark - UIApplicationDelegate 30 | 31 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 32 | { 33 | self.window.rootViewController = self.viewController; 34 | return YES; 35 | } 36 | 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /GLImageProcessing/GLTexture.h: -------------------------------------------------------------------------------- 1 | // 2 | // GLTexture.h 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/28/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface GLTexture : NSObject 13 | 14 | @property (nonatomic, assign, readonly) GLuint textureName; 15 | // returns the GL name assigned to this texture 16 | 17 | + (GLTexture*) textureWithImage:(UIImage*)image; 18 | 19 | - (void) bindToTextureUnit:(GLenum)textureUnit; 20 | // Bind this texture to the specified textureUnit; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /GLImageProcessing/GLTexture.m: -------------------------------------------------------------------------------- 1 | // 2 | // GLTexture.m 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/28/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | #import "GLTexture.h" 10 | 11 | @interface GLTexture () 12 | 13 | @property (nonatomic, assign, readwrite) GLuint textureName; 14 | 15 | @end 16 | 17 | @implementation GLTexture 18 | 19 | @synthesize textureName = textureName_; 20 | 21 | 22 | #pragma mark - Class methods 23 | 24 | + (GLTexture*) textureWithImage:(UIImage*)image 25 | { 26 | return [[[self alloc] initWithImage:image] autorelease]; 27 | } 28 | 29 | 30 | #pragma mark - Lifecycle 31 | 32 | - (id)initWithImage:(UIImage*)image 33 | { 34 | self = [super init]; 35 | if (self) 36 | { 37 | GLsizei width = image.size.width; 38 | GLsizei height = image.size.height; 39 | 40 | GLubyte* textureData = (GLubyte*) calloc(width * height * 4, sizeof(GLubyte)); 41 | // allocate memory for the bitmap context we will draw the image into 42 | 43 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 44 | // We are going to force the source data to RGB space in the event it was some other color space 45 | 46 | CGContextRef textureContext = CGBitmapContextCreate(textureData, width, height, 8, width * 4, 47 | colorSpace, kCGImageAlphaPremultipliedLast); 48 | // We are going to use pre-multiplied data. Our later processing may need to account for this when manipulating RGB values 49 | 50 | CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), image.CGImage); 51 | // Draw the image into the bitmap context 52 | 53 | glGenTextures(1, &textureName_); 54 | glBindTexture(GL_TEXTURE_2D, self.textureName); 55 | // Get a texture name and bind it as the current 2D texture in the GL state 56 | 57 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData); 58 | // copy the bitmap data backing the CGBitmapContext over to GL into the texture we have bound 59 | 60 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 61 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 62 | // depending on your application, you may want different scaling filters for the source texture 63 | // for instance you may want scaling to produce a pixelated zoom instead of smoothing 64 | 65 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 66 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 67 | // GL_CLAMP_TO_EDGE means that samples beyond the texture bounds will be replicated edge pixels 68 | // this mode is required to use textures that are not powers for two in size. 69 | 70 | CGColorSpaceRelease(colorSpace); 71 | CGContextRelease(textureContext); 72 | free(textureData); 73 | // glTextImge2D has copied the pixel data over to the GL state, so we can release it safely 74 | } 75 | 76 | return self; 77 | } 78 | 79 | - (void)dealloc 80 | { 81 | glDeleteTextures(1, &textureName_); 82 | [super dealloc]; 83 | } 84 | 85 | #pragma mark - Binding 86 | 87 | - (void) bindToTextureUnit:(GLenum)textureUnit 88 | { 89 | glActiveTexture(textureUnit); 90 | glBindTexture(GL_TEXTURE_2D, self.textureName); 91 | // set the active texture unit and bind this texture to it 92 | } 93 | 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /GLImageProcessing/ImageProcessingViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ImageProcessingViewController.h 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import 12 | #import 13 | #import 14 | 15 | @interface ImageProcessingViewController : UIViewController 16 | 17 | @property(nonatomic, retain) IBOutlet UISlider* slider; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /GLImageProcessing/ImageProcessingViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ImageProcessingViewController.m 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "ImageProcessingViewController.h" 12 | #import "EAGLView.h" 13 | #import "GLTexture.h" 14 | 15 | #pragma mark Enumerations 16 | 17 | // Attributes 18 | enum { 19 | ATTRIB_VERTEX, 20 | ATTRIB_TEXTURE_COORDINATES, 21 | NUM_ATTRIBUTES 22 | }; 23 | 24 | // Uniforms 25 | enum { 26 | UNIFORM_SOURCE_TEXTURE, 27 | UNIFORM_AMOUNT_SCALAR, 28 | UNIFORM_MVP_MATRIX, 29 | NUM_UNIFORMS 30 | }; 31 | 32 | #pragma mark - Statics 33 | 34 | static GLint uniforms[NUM_UNIFORMS]; 35 | 36 | #pragma mark - 37 | 38 | @interface ImageProcessingViewController () 39 | { 40 | GLuint program; 41 | } 42 | 43 | @property (nonatomic, retain) EAGLContext* context; 44 | @property (nonatomic, retain) GLTexture* sourceImage; 45 | 46 | - (CGContextRef)newBitmapContextForSize:(CGSize)size; 47 | - (UIImage*)imageByRenderingViewAtSize:(CGSize)size; 48 | - (void)renderIntoCurrentGLContextWithTransform:(CATransform3D)transform; 49 | - (void)drawFrame; 50 | 51 | - (BOOL)loadShaders; 52 | - (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; 53 | - (BOOL)linkProgram:(GLuint)prog; 54 | - (BOOL)validateProgram:(GLuint)prog; 55 | 56 | - (IBAction)sliderValueChanged:(id)sender; 57 | 58 | @end 59 | 60 | @implementation ImageProcessingViewController 61 | 62 | @synthesize slider = slider_; 63 | @synthesize context = context_; 64 | @synthesize sourceImage = sourceImage_; 65 | 66 | #pragma mark - Lifecycle 67 | 68 | - (void)dealloc 69 | { 70 | if (program) 71 | { 72 | glDeleteProgram(program); 73 | program = 0; 74 | } 75 | 76 | // Tear down context. 77 | if ([EAGLContext currentContext] == self.context) 78 | [EAGLContext setCurrentContext:nil]; 79 | 80 | [context_ release]; 81 | [sourceImage_ release]; 82 | [slider_ release]; 83 | 84 | [super dealloc]; 85 | } 86 | 87 | 88 | #pragma mark - UINibLoading 89 | 90 | - (void)awakeFromNib 91 | { 92 | EAGLContext* context = [[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2] autorelease]; 93 | 94 | if (!context) 95 | NSLog(@"Failed to create ES 2.0 context"); 96 | else if (![EAGLContext setCurrentContext:context]) 97 | NSLog(@"Failed to set ES context current"); 98 | 99 | self.context = context; 100 | 101 | [(EAGLView *)self.view setContext:self.context]; 102 | [(EAGLView *)self.view setFramebuffer]; 103 | 104 | if ([self.context API] == kEAGLRenderingAPIOpenGLES2) 105 | [self loadShaders]; 106 | 107 | self.sourceImage = [GLTexture textureWithImage:[UIImage imageNamed:@"source_image.jpg"]]; 108 | 109 | UITapGestureRecognizer* tapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewTapped:)] autorelease]; 110 | [self.view addGestureRecognizer:tapRecognizer]; 111 | } 112 | 113 | 114 | #pragma mark - UIViewController 115 | 116 | - (void)viewDidUnload 117 | { 118 | [super viewDidUnload]; 119 | 120 | if (program) 121 | { 122 | glDeleteProgram(program); 123 | program = 0; 124 | } 125 | 126 | // Tear down context. 127 | if ([EAGLContext currentContext] == self.context) 128 | [EAGLContext setCurrentContext:nil]; 129 | 130 | self.context = nil; 131 | self.slider = nil; 132 | self.sourceImage = nil; 133 | } 134 | 135 | - (void)viewDidAppear:(BOOL)animated 136 | { 137 | [self drawFrame]; 138 | } 139 | 140 | #pragma mark - Actions 141 | 142 | 143 | - (IBAction)sliderValueChanged:(id)sender 144 | { 145 | [self drawFrame]; 146 | } 147 | 148 | - (void)viewTapped:(id)sender 149 | { 150 | // We'll double the size of the veiw just to demonstrate how it works. On a Retina device this will result in scaling the content larger than the original 640 x 960 iamge 151 | 152 | GLsizei width = self.view.layer.bounds.size.width * self.view.contentScaleFactor * 2.0; 153 | GLsizei height = self.view.layer.bounds.size.height * self.view.contentScaleFactor * 2.0; 154 | UIImage* image = [self imageByRenderingViewAtSize:(CGSize){width, height}]; 155 | UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); 156 | UIAlertView* view = [[[UIAlertView alloc] initWithTitle:@"Image Saved" message:@"Processed image has been saved to the Camera Roll in the Photo Library" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] autorelease]; 157 | [view show]; 158 | } 159 | 160 | 161 | #pragma mark - Bitmaps 162 | 163 | - (CGContextRef) newBitmapContextForSize:(CGSize)size 164 | { 165 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 166 | CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big; 167 | int rowByteWidth = size.width * 4; 168 | 169 | CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, rowByteWidth, colorSpace, bitmapInfo); 170 | CGColorSpaceRelease( colorSpace ); 171 | 172 | return context; 173 | } 174 | 175 | #pragma mark - Draw 176 | 177 | - (UIImage*)imageByRenderingViewAtSize:(CGSize)size; 178 | { 179 | // Explicitly make a new Framebuffer so there is control over the size of the final rendered image. If the source image is smaller than the destination framebuffer, scaling will occur, which could degrade image quality. This techinque is useful when the original image is larger than the screen size and you want to maintain that resolution. Note that the device HW limits the renderBuffer size, just like the maxium texture size. On latest generation iOS Devices the limit is 2048 x 2048 (4096 x 4096 for iPad 2). On older devices the limit is 1024 x 1024. 180 | 181 | GLuint framebuffer; 182 | glGenFramebuffers(1, &framebuffer); 183 | glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 184 | 185 | GLuint colorRenderbuffer; 186 | glGenRenderbuffers(1, &colorRenderbuffer); 187 | glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); 188 | glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, size.width, size.height); 189 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); 190 | 191 | GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 192 | if(status != GL_FRAMEBUFFER_COMPLETE) 193 | NSLog(@"failed to make complete framebuffer object %x", status); 194 | 195 | // establish the viewport coordinates to match the size of the buffer; 196 | glViewport(0, 0, size.width, size.height); 197 | 198 | // draw our image into the framebuffer using a transform that will invert the image by scaling the Y axis by -1.0 199 | CATransform3D transform = CATransform3DMakeScale(1.0, -1.0, 1.0); 200 | [self renderIntoCurrentGLContextWithTransform:transform]; 201 | 202 | // Create a Core Graphics bitmap context 203 | CGContextRef context = [self newBitmapContextForSize:size]; 204 | CGContextClearRect(context, (CGRect){0.0, 0.0, size.width, size.height}); 205 | 206 | // copy the rendered pixels from the GL Framebuffer to the Core Graphics bitmap 207 | void* pixelData = CGBitmapContextGetData(context); 208 | glReadPixels(0, 0, size.width, size.height, GL_RGBA, GL_UNSIGNED_BYTE, pixelData); 209 | 210 | CGImageRef contextImage = CGBitmapContextCreateImage(context); 211 | CGContextRelease(context); 212 | 213 | glDeleteFramebuffers(1, &framebuffer); 214 | glDeleteRenderbuffers(1, &colorRenderbuffer); 215 | 216 | UIImage* image = [[[UIImage alloc] initWithCGImage:contextImage] autorelease]; 217 | CGImageRelease(contextImage); 218 | 219 | return image; 220 | } 221 | 222 | - (void)renderIntoCurrentGLContextWithTransform:(CATransform3D)transform 223 | { 224 | // Here we declare a set of vertices that define a square that is paralell to the viewing plane. 225 | // These are effectively normalized device viewing space coordinates because we are not manipulating the modelview or projection transformations from their defaults and we have set up the viewport to match the size of our view 226 | static const GLfloat squareVertices[] = 227 | { 228 | -1.0f, -1.0f, 229 | 1.0f, -1.0f, 230 | -1.0f, 1.0f, 231 | 1.0f, 1.0f, 232 | }; 233 | 234 | // Here we declare an texture coordinates that map the source texture to the quad defined above. We simply place each corner of the source image on a corner of the quad. 235 | 236 | static const GLfloat textureCoordinates[] = 237 | { 238 | 0.0f, 1.0f, 239 | 1.0f, 1.0f, 240 | 0.0f, 0.0f, 241 | 1.0f, 0.0f, 242 | }; 243 | 244 | glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 245 | glClear(GL_COLOR_BUFFER_BIT); 246 | 247 | // Use shader program. 248 | glUseProgram(program); 249 | 250 | // Update attribute values. 251 | glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); 252 | glEnableVertexAttribArray(ATTRIB_VERTEX); 253 | glVertexAttribPointer(ATTRIB_TEXTURE_COORDINATES, 2, GL_FLOAT, 0, 0, textureCoordinates); 254 | glEnableVertexAttribArray(ATTRIB_TEXTURE_COORDINATES); 255 | 256 | // Bind the source texture to a texture unit and set the source sampler for the shader to that texture unit 257 | [self.sourceImage bindToTextureUnit:GL_TEXTURE0]; 258 | glUniform1i(uniforms[UNIFORM_SOURCE_TEXTURE], 0); 259 | 260 | // Set the amount (this will come from the slider shortly) 261 | glUniform1f(uniforms[UNIFORM_AMOUNT_SCALAR], self.slider.value); 262 | 263 | // Set the transform matrix 264 | GLfloat matrix[16] = { transform.m11, transform.m12, transform.m13, transform.m14, 265 | transform.m21, transform.m22, transform.m23, transform.m24, 266 | transform.m31, transform.m32, transform.m33, transform.m34, 267 | transform.m41, transform.m42, transform.m43, transform.m44 }; 268 | 269 | glUniformMatrix4fv(uniforms[UNIFORM_MVP_MATRIX], 1, 0, matrix); 270 | 271 | // Validate program before drawing. This is a good check, but only really necessary in a debug build. 272 | // DEBUG macro must be defined in your debug configurations if that's not already the case. 273 | #if defined(DEBUG) 274 | if (![self validateProgram:program]) 275 | { 276 | NSLog(@"Failed to validate program: %d", program); 277 | return; 278 | } 279 | #endif 280 | 281 | // This causes GL to draw our scene with the current state- including the vertices and texture coordinate attributes we have supplied to the state above. The drawing is raterized into the current framebuffer 282 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 283 | 284 | } 285 | 286 | - (void)drawFrame 287 | { 288 | // This makes the context and framebuffer associated with our view current. GL State and drawing commands will be targeted to that context and render in that framebuffer 289 | [(EAGLView *)self.view setFramebuffer]; 290 | 291 | CATransform3D transform = CATransform3DIdentity; 292 | [self renderIntoCurrentGLContextWithTransform:transform]; 293 | 294 | [(EAGLView *)self.view presentFramebuffer]; 295 | } 296 | 297 | #pragma mark - Shaders 298 | 299 | - (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file 300 | { 301 | GLint status; 302 | const GLchar *source; 303 | 304 | source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; 305 | if (!source) 306 | { 307 | NSLog(@"Failed to load vertex shader"); 308 | return FALSE; 309 | } 310 | 311 | *shader = glCreateShader(type); 312 | glShaderSource(*shader, 1, &source, NULL); 313 | glCompileShader(*shader); 314 | 315 | #if defined(DEBUG) 316 | GLint logLength; 317 | glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); 318 | if (logLength > 0) 319 | { 320 | GLchar *log = (GLchar *)malloc(logLength); 321 | glGetShaderInfoLog(*shader, logLength, &logLength, log); 322 | NSLog(@"Shader compile log:\n%s", log); 323 | free(log); 324 | } 325 | #endif 326 | 327 | glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); 328 | if (status == 0) 329 | { 330 | glDeleteShader(*shader); 331 | return FALSE; 332 | } 333 | 334 | return TRUE; 335 | } 336 | 337 | - (BOOL)linkProgram:(GLuint)prog 338 | { 339 | GLint status; 340 | 341 | glLinkProgram(prog); 342 | 343 | #if defined(DEBUG) 344 | GLint logLength; 345 | glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); 346 | if (logLength > 0) 347 | { 348 | GLchar *log = (GLchar *)malloc(logLength); 349 | glGetProgramInfoLog(prog, logLength, &logLength, log); 350 | NSLog(@"Program link log:\n%s", log); 351 | free(log); 352 | } 353 | #endif 354 | 355 | glGetProgramiv(prog, GL_LINK_STATUS, &status); 356 | if (status == 0) 357 | return FALSE; 358 | 359 | return TRUE; 360 | } 361 | 362 | - (BOOL)validateProgram:(GLuint)prog 363 | { 364 | GLint logLength, status; 365 | 366 | glValidateProgram(prog); 367 | glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); 368 | if (logLength > 0) 369 | { 370 | GLchar *log = (GLchar *)malloc(logLength); 371 | glGetProgramInfoLog(prog, logLength, &logLength, log); 372 | NSLog(@"Program validate log:\n%s", log); 373 | free(log); 374 | } 375 | 376 | glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); 377 | if (status == 0) 378 | return FALSE; 379 | 380 | return TRUE; 381 | } 382 | 383 | - (BOOL)loadShaders 384 | { 385 | GLuint vertShader, fragShader; 386 | NSString *vertShaderPathname, *fragShaderPathname; 387 | 388 | // Create shader program. 389 | program = glCreateProgram(); 390 | 391 | // Create and compile vertex shader. 392 | vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; 393 | if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) 394 | { 395 | NSLog(@"Failed to compile vertex shader"); 396 | return FALSE; 397 | } 398 | 399 | // Create and compile fragment shader. 400 | fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"VignetteShader" ofType:@"fsh"]; 401 | if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) 402 | { 403 | NSLog(@"Failed to compile fragment shader"); 404 | return FALSE; 405 | } 406 | 407 | // Attach vertex shader to program. 408 | glAttachShader(program, vertShader); 409 | 410 | // Attach fragment shader to program. 411 | glAttachShader(program, fragShader); 412 | 413 | // Bind attribute locations. 414 | // This needs to be done prior to linking. 415 | glBindAttribLocation(program, ATTRIB_VERTEX, "position"); 416 | glBindAttribLocation(program, ATTRIB_TEXTURE_COORDINATES, "textureCoordinate"); 417 | 418 | // Link program. 419 | if (![self linkProgram:program]) 420 | { 421 | NSLog(@"Failed to link program: %d", program); 422 | 423 | if (vertShader) 424 | { 425 | glDeleteShader(vertShader); 426 | vertShader = 0; 427 | } 428 | if (fragShader) 429 | { 430 | glDeleteShader(fragShader); 431 | fragShader = 0; 432 | } 433 | if (program) 434 | { 435 | glDeleteProgram(program); 436 | program = 0; 437 | } 438 | 439 | return FALSE; 440 | } 441 | 442 | // Get Uniform locations from the linked programs 443 | uniforms[UNIFORM_SOURCE_TEXTURE] = glGetUniformLocation(program, "sourceTexture"); 444 | uniforms[UNIFORM_AMOUNT_SCALAR] = glGetUniformLocation(program, "amount"); 445 | uniforms[UNIFORM_MVP_MATRIX] = glGetUniformLocation(program, "mvpMatrix"); 446 | 447 | // Release vertex and fragment shaders. 448 | if (vertShader) 449 | glDeleteShader(vertShader); 450 | if (fragShader) 451 | glDeleteShader(fragShader); 452 | 453 | return TRUE; 454 | } 455 | 456 | @end 457 | -------------------------------------------------------------------------------- /GLImageProcessing/Shaders/BrightnessShader.fsh: -------------------------------------------------------------------------------- 1 | // 2 | // BrightnessShader.fsh 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | precision mediump float; 10 | 11 | varying vec2 interpolatedTextureCoordinate; 12 | uniform sampler2D sourceTexture; 13 | uniform float amount; 14 | // the 'amount' uniform variable is set by the client before rendering (just like sourceTexture) 15 | // ranges from 0.0 to 1.0 for darkening 16 | // ranges for 1.0 to ~infinty for brightening. capping around 10.0 or so works pretty well. 17 | 18 | void main() 19 | { 20 | vec3 target = vec3(0.0, 0.0, 0.0); 21 | // for brightness the target is black or zero intensity in each channel 22 | 23 | vec4 source = texture2D(sourceTexture, interpolatedTextureCoordinate); 24 | // sample the original pixel 25 | 26 | // our formula is : 27 | // (1-amount) * target + (amount * source) 28 | 29 | target = (1.0 - amount) * target; 30 | source.rgb = target + (amount * source.rgb); 31 | // for a completely black source, target is always zero, so we could simplfy this! 32 | 33 | gl_FragColor = source; 34 | } 35 | -------------------------------------------------------------------------------- /GLImageProcessing/Shaders/GrayscaleShader.fsh: -------------------------------------------------------------------------------- 1 | // 2 | // GrayscaleShader.fsh 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | precision mediump float; 10 | varying vec2 interpolatedTextureCoordinate; 11 | // Vertex shader provides this value for each vertex. When we read it here, it will be interpolated (perspective correct) for the fragment we are coloring based on its location in respect each relevant vertex 12 | 13 | uniform sampler2D sourceTexture; 14 | // This uniform is of the special type sampler2D. The value of this type is the texture unit to sample from. The value should be provided by the client and should be the texture unit we have bound our source texture too in the GL state. 15 | 16 | void main() 17 | { 18 | // Grayscale conversion is a weighted average of the RGB components, where green contributes the most, red the next and blue the least. The exect coefficients to use depends on the gamma of the original image and a variety of other factors including what is perhaps pleasing asthetically. The values used here are assume a linear-gamma source and presentation on a modern diplay 19 | vec3 coefficients = vec3(0.2125, 0.7154, 0.0721); 20 | 21 | vec4 source = texture2D(sourceTexture, interpolatedTextureCoordinate); 22 | // sample the original pixel 23 | 24 | float l = dot(coefficients, source.rgb); 25 | // use the dot product operator on the RGB values of the source. This is effectively (c1 * r) + (c2 * g) + (c3 * b) 26 | 27 | source.rgb = vec3(l, l, l); 28 | // use the luminance value for each of the 3 components. Note that alpha is preserved 29 | 30 | gl_FragColor = source; 31 | } 32 | -------------------------------------------------------------------------------- /GLImageProcessing/Shaders/RippleShader.fsh: -------------------------------------------------------------------------------- 1 | // 2 | // RippleShader.fsh 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | precision mediump float; 10 | 11 | varying vec2 interpolatedTextureCoordinate; 12 | uniform sampler2D sourceTexture; 13 | uniform float amount; 14 | // the 'amount' uniform variable is set by the client before rendering 15 | // this controls the # of ripples. Suggested values are [0 .. 100] 16 | 17 | const float PI = 3.14159265358979323846264; 18 | 19 | void main() 20 | { 21 | // We can simulate a water ripple with a sin wave that is 'dampened' by a gaussian (bell curve) 22 | 23 | // we sample from the source texture based on the distance from the pixel we are sampling from the center. That distance is the parameter to a the dampened sin fucntion. The new coordinate is the pixel we will actually sample for the output 24 | 25 | float amplitude = 0.03; 26 | // amplitude of ripples 0.0 - 1.0 are good values 27 | vec2 position = vec2(0.5, 0.5); 28 | // center of the ripple in texture coordinates. This puts it in the center 29 | float sigma = 5.0; 30 | // shape of gaussian bell that controls dampenning 31 | 32 | float distance = distance(position, interpolatedTextureCoordinate); 33 | float sinCurve = (sin ( amount * distance * 2.0 * PI) * amplitude ); 34 | float dampened = (1.0 / sqrt(2.0 * PI)) * exp((-sigma) * pow(distance, 2.0)) * sinCurve; 35 | 36 | vec2 displacedCoordinate = vec2(interpolatedTextureCoordinate.x + dampened, interpolatedTextureCoordinate.y + dampened); 37 | vec4 source = texture2D(sourceTexture, displacedCoordinate); 38 | // sample the 'displaced' pixel 39 | 40 | gl_FragColor = source; 41 | 42 | // This code can give you a way to visualize the curve we are using for displacement 43 | //float boosted = dampened * 100.0; 44 | //gl_FragColor = vec4(boosted, boosted, boosted, 1.0); 45 | } 46 | -------------------------------------------------------------------------------- /GLImageProcessing/Shaders/SaturationShader.fsh: -------------------------------------------------------------------------------- 1 | // 2 | // SaturationShader.fsh 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | precision mediump float; 10 | 11 | varying vec2 interpolatedTextureCoordinate; 12 | uniform sampler2D sourceTexture; 13 | uniform float amount; 14 | // the 'amount' uniform variable is set by the client before rendering 15 | 16 | const vec3 coefficients = vec3(0.2125, 0.7154, 0.0721); 17 | 18 | void main() 19 | { 20 | vec4 source = texture2D(sourceTexture, interpolatedTextureCoordinate); 21 | // sample the original pixel 22 | 23 | vec3 target = vec3(dot(coefficients, source.rgb)); 24 | // for brightness the target is black or zero intensity in each channel 25 | 26 | source.rgb = mix(target, source.rgb, amount); 27 | // using buil-in mix() function to do the interpolation. Probably optimized! 28 | 29 | gl_FragColor = source; 30 | } 31 | -------------------------------------------------------------------------------- /GLImageProcessing/Shaders/SepiaShader.fsh: -------------------------------------------------------------------------------- 1 | // 2 | // SepiaShader.fsh 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | precision mediump float; 10 | 11 | varying vec2 interpolatedTextureCoordinate; 12 | uniform sampler2D sourceTexture; 13 | 14 | 15 | void main() 16 | { 17 | vec3 coefficients = vec3(0.2125, 0.7154, 0.0721); 18 | // common rgb to gray weighting 19 | vec3 sepiaWeights = vec3(0.23, 0.11, 0.00); 20 | //boost the red a bit, the green a bit less and leave the blue 21 | 22 | vec4 source = texture2D(sourceTexture, interpolatedTextureCoordinate); 23 | // sample the original pixel 24 | 25 | float l = dot(coefficients, source.rgb); 26 | // perceptual luminance of the rgb source 27 | 28 | source.rgb = vec3(l, l, l) + sepiaWeights; 29 | // weight the luminence by the sepia values 30 | 31 | gl_FragColor = source; 32 | } 33 | -------------------------------------------------------------------------------- /GLImageProcessing/Shaders/Shader.fsh: -------------------------------------------------------------------------------- 1 | // 2 | // Shader.fsh 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | varying mediump vec2 interpolatedTextureCoordinate; 10 | // Vertex shader provides this value for each vertex. When we read it here, it will be interpolated (perspective correct) for the fragment we are coloring based on its location in respect each relevant vertex 11 | 12 | uniform sampler2D sourceTexture; 13 | // This uniform is of the special type sampler2D. The value of this type is the texture unit to sample from. The value should be provided by the client and should be the texture unit we have bound our source texture too in the GL state. 14 | 15 | void main() 16 | { 17 | // sample from the source texture with texture2D. Use the interpolated texture coordinate we get from the vertex shader. Simply output this value as the color of the fragment 18 | 19 | gl_FragColor = texture2D(sourceTexture, interpolatedTextureCoordinate); 20 | } 21 | -------------------------------------------------------------------------------- /GLImageProcessing/Shaders/Shader.vsh: -------------------------------------------------------------------------------- 1 | // 2 | // Shader.vsh 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | attribute vec4 position; 10 | // This attribute comes from the client application 11 | // represents the location of each vertex to render 12 | 13 | attribute vec2 textureCoordinate; 14 | // This attribute comes from the client application 15 | // represents teh texture coordinates to use for this vertex 16 | 17 | uniform mat4 mvpMatrix; 18 | // a tranformation matrix supplied by the client to go from model and view space to clip space 19 | 20 | varying vec2 interpolatedTextureCoordinate; 21 | // This varible is interpolated for each fragment from the contributing vertices 22 | 23 | void main() 24 | { 25 | gl_Position = mvpMatrix * position; 26 | 27 | // make the texture coordinate attribute the client set for this vertex available to the fragment shader 28 | interpolatedTextureCoordinate = textureCoordinate; 29 | } 30 | -------------------------------------------------------------------------------- /GLImageProcessing/Shaders/VignetteShader.fsh: -------------------------------------------------------------------------------- 1 | // 2 | // VignetteShader.fsh 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | precision highp float; 10 | 11 | varying vec2 interpolatedTextureCoordinate; 12 | uniform sampler2D sourceTexture; 13 | uniform float amount; 14 | // this controls the radius of the vignette. Suggested values are [0 .. 50] 15 | 16 | const float PI = 3.14159265358979323846264; 17 | 18 | const vec4 backgroundColor = vec4(0.0, 0.0, 0.0, 1.0); 19 | // this could be a uniform from the client to expose control of the color 20 | 21 | const vec2 center = vec2(0.5, 0.5); 22 | // this could also be a uniform from the client to expose control of the center 23 | 24 | void main() 25 | { 26 | // Use a 2-D radial gaussain to blend source with background color 27 | 28 | vec4 source = texture2D(sourceTexture, interpolatedTextureCoordinate); 29 | float sigma = amount; 30 | // sigma in the gaussian equation controls the shape of the bell 31 | // in our use this is effectively the radius of the vignette 32 | 33 | float distance = distance(center, interpolatedTextureCoordinate); 34 | float alpha = 2.0 * (1.0 / sqrt(2.0 * PI)) * exp((-sigma) * pow(distance, 2.0)); 35 | //alpha = clamp(alpha, 0.0, 1.0); 36 | // make sure alpha is always between 0 and 1 37 | 38 | gl_FragColor = mix(backgroundColor, source, alpha); 39 | 40 | // This code can give you a way to visualize the curve we are using for blending 41 | //gl_FragColor = vec4(alpha, alpha, alpha, 1.0); 42 | } 43 | -------------------------------------------------------------------------------- /GLImageProcessing/en.lproj/ImageProcessingViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1024 5 | 11B26 6 | 1592 7 | 1138 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 532 12 | 13 | 14 | YES 15 | IBProxyObject 16 | IBUIView 17 | IBUISlider 18 | 19 | 20 | YES 21 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 22 | 23 | 24 | YES 25 | 26 | YES 27 | 28 | 29 | 30 | 31 | YES 32 | 33 | IBFilesOwner 34 | IBCocoaTouchFramework 35 | 36 | 37 | IBFirstResponder 38 | IBCocoaTouchFramework 39 | 40 | 41 | 42 | 274 43 | 44 | YES 45 | 46 | 47 | 292 48 | {{18, 418}, {284, 23}} 49 | 50 | 51 | 52 | _NS:605 53 | NO 54 | IBCocoaTouchFramework 55 | 0 56 | 0 57 | 5 58 | 25 59 | 60 | 61 | {320, 460} 62 | 63 | 64 | 65 | 66 | 3 67 | MQA 68 | 69 | 2 70 | 71 | 72 | NO 73 | IBCocoaTouchFramework 74 | 75 | 76 | 77 | 78 | YES 79 | 80 | 81 | view 82 | 83 | 84 | 85 | 3 86 | 87 | 88 | 89 | slider 90 | 91 | 92 | 93 | 7 94 | 95 | 96 | 97 | sliderValueChanged: 98 | 99 | 100 | 13 101 | 102 | 8 103 | 104 | 105 | 106 | 107 | YES 108 | 109 | 0 110 | 111 | 112 | 113 | 114 | 115 | -1 116 | 117 | 118 | File's Owner 119 | 120 | 121 | -2 122 | 123 | 124 | 125 | 126 | 2 127 | 128 | 129 | YES 130 | 131 | 132 | 133 | View - EAGLView 134 | 135 | 136 | 5 137 | 138 | 139 | 140 | 141 | 142 | 143 | YES 144 | 145 | YES 146 | -1.CustomClassName 147 | -1.IBPluginDependency 148 | -2.CustomClassName 149 | -2.IBPluginDependency 150 | 2.CustomClassName 151 | 2.IBPluginDependency 152 | 5.IBPluginDependency 153 | 154 | 155 | YES 156 | ImageProcessingViewController 157 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 158 | UIResponder 159 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 160 | EAGLView 161 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 162 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 163 | 164 | 165 | 166 | YES 167 | 168 | 169 | 170 | 171 | 172 | YES 173 | 174 | 175 | 176 | 177 | 8 178 | 179 | 180 | 181 | YES 182 | 183 | EAGLView 184 | UIView 185 | 186 | IBProjectSource 187 | ./Classes/EAGLView.h 188 | 189 | 190 | 191 | ImageProcessingViewController 192 | UIViewController 193 | 194 | slider 195 | UISlider 196 | 197 | 198 | slider 199 | 200 | slider 201 | UISlider 202 | 203 | 204 | 205 | IBProjectSource 206 | ./Classes/ImageProcessingViewController.h 207 | 208 | 209 | 210 | 211 | 0 212 | IBCocoaTouchFramework 213 | 214 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 215 | 216 | 217 | 218 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 219 | 220 | 221 | YES 222 | 3 223 | 532 224 | 225 | 226 | -------------------------------------------------------------------------------- /GLImageProcessing/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /GLImageProcessing/en.lproj/MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1056 5 | 11B26 6 | 1592 7 | 1138 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 532 12 | 13 | 14 | YES 15 | IBUIWindow 16 | IBUICustomObject 17 | IBUIViewController 18 | IBProxyObject 19 | 20 | 21 | YES 22 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 23 | 24 | 25 | YES 26 | 27 | YES 28 | 29 | 30 | 31 | 32 | YES 33 | 34 | IBFilesOwner 35 | IBCocoaTouchFramework 36 | 37 | 38 | IBFirstResponder 39 | IBCocoaTouchFramework 40 | 41 | 42 | IBCocoaTouchFramework 43 | 44 | 45 | ImageProcessingViewController 46 | 47 | 1 48 | 1 49 | 50 | YES 51 | IBCocoaTouchFramework 52 | NO 53 | 54 | 55 | 56 | 1316 57 | 58 | {320, 480} 59 | 60 | 61 | 62 | 1 63 | MSAxIDEAA 64 | 65 | NO 66 | IBCocoaTouchFramework 67 | YES 68 | YES 69 | 70 | 71 | 72 | 73 | YES 74 | 75 | 76 | delegate 77 | 78 | 79 | 80 | 4 81 | 82 | 83 | 84 | window 85 | 86 | 87 | 88 | 5 89 | 90 | 91 | 92 | viewController 93 | 94 | 95 | 96 | 11 97 | 98 | 99 | 100 | 101 | YES 102 | 103 | 0 104 | 105 | 106 | 107 | 108 | 109 | 2 110 | 111 | 112 | YES 113 | 114 | 115 | 116 | 117 | -1 118 | 119 | 120 | File's Owner 121 | 122 | 123 | 3 124 | 125 | 126 | Image Processing App Delegate 127 | 128 | 129 | -2 130 | 131 | 132 | 133 | 134 | 10 135 | 136 | 137 | 138 | 139 | 140 | 141 | YES 142 | 143 | YES 144 | -1.CustomClassName 145 | -1.IBPluginDependency 146 | -2.CustomClassName 147 | -2.IBPluginDependency 148 | 10.CustomClassName 149 | 10.IBPluginDependency 150 | 2.IBAttributePlaceholdersKey 151 | 2.IBPluginDependency 152 | 3.CustomClassName 153 | 3.IBPluginDependency 154 | 155 | 156 | YES 157 | UIApplication 158 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 159 | UIResponder 160 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 161 | ImageProcessingViewController 162 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 163 | 164 | YES 165 | 166 | 167 | 168 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 169 | GLImageProcessingAppDelegate 170 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 171 | 172 | 173 | 174 | YES 175 | 176 | 177 | 178 | 179 | 180 | YES 181 | 182 | 183 | 184 | 185 | 11 186 | 187 | 188 | 189 | YES 190 | 191 | GLImageProcessingAppDelegate 192 | NSObject 193 | 194 | YES 195 | 196 | YES 197 | viewController 198 | window 199 | 200 | 201 | YES 202 | ImageProcessingViewController 203 | UIWindow 204 | 205 | 206 | 207 | YES 208 | 209 | YES 210 | viewController 211 | window 212 | 213 | 214 | YES 215 | 216 | viewController 217 | ImageProcessingViewController 218 | 219 | 220 | window 221 | UIWindow 222 | 223 | 224 | 225 | 226 | IBProjectSource 227 | ./Classes/GLImageProcessingAppDelegate.h 228 | 229 | 230 | 231 | ImageProcessingViewController 232 | UIViewController 233 | 234 | IBProjectSource 235 | ./Classes/ImageProcessingViewController.h 236 | 237 | 238 | 239 | 240 | 0 241 | IBCocoaTouchFramework 242 | 243 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 244 | 245 | 246 | YES 247 | 3 248 | 532 249 | 250 | 251 | -------------------------------------------------------------------------------- /GLImageProcessing/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // GLImageProcessing 4 | // 5 | // Created by Chris Parrish on 8/22/11. 6 | // Copyright 2011 Aged & Distilled. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 14 | int retVal = UIApplicationMain(argc, argv, nil, nil); 15 | [pool release]; 16 | return retVal; 17 | } 18 | -------------------------------------------------------------------------------- /GLImageProcessing/source_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twenty3/GLImageProcessing/d16d87d6b0cdb127efdf7f31ce033060ddd6e8a3/GLImageProcessing/source_image.jpg --------------------------------------------------------------------------------