├── ImageEffect.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── ImageEffect.xcscmblueprint └── xcuserdata │ └── vk.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── ImageEffect.xcscheme │ └── xcschememanagement.plist ├── ImageEffect ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── CLRFilter │ ├── CLRGPUImageFiler.h │ ├── CLRGPUImageFiler.m │ ├── CLRTwoInputImageFilter.h │ ├── CLRTwoInputImageFilter.m │ ├── GPUImageUnsharpMaskFilter.h │ └── GPUImageUnsharpMaskFilter.m ├── GLView.h ├── GLView.m ├── Info.plist ├── SHaderHelper.h ├── SHaderHelper.m ├── ScreenShot │ └── ImageEffect.gif ├── SimpleFragment.glsl ├── SimpleVertex.glsl ├── ViewController.h ├── ViewController.m └── main.m ├── ImageEffectTests ├── ImageEffectTests.m └── Info.plist ├── ImageEffectUITests ├── ImageEffectUITests.m └── Info.plist ├── README.md └── README.md~ /ImageEffect.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5417EA901C195EFA0068F2B9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5417EA8F1C195EFA0068F2B9 /* main.m */; }; 11 | 5417EA931C195EFA0068F2B9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5417EA921C195EFA0068F2B9 /* AppDelegate.m */; }; 12 | 5417EA961C195EFA0068F2B9 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5417EA951C195EFA0068F2B9 /* ViewController.m */; }; 13 | 5417EA991C195EFA0068F2B9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5417EA971C195EFA0068F2B9 /* Main.storyboard */; }; 14 | 5417EA9B1C195EFA0068F2B9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5417EA9A1C195EFA0068F2B9 /* Assets.xcassets */; }; 15 | 5417EA9E1C195EFA0068F2B9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5417EA9C1C195EFA0068F2B9 /* LaunchScreen.storyboard */; }; 16 | 5417EAA91C195EFA0068F2B9 /* ImageEffectTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5417EAA81C195EFA0068F2B9 /* ImageEffectTests.m */; }; 17 | 5417EAB41C195EFA0068F2B9 /* ImageEffectUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5417EAB31C195EFA0068F2B9 /* ImageEffectUITests.m */; }; 18 | 5417EACB1C19631B0068F2B9 /* GPUImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5417EACA1C1962F00068F2B9 /* GPUImage.framework */; }; 19 | 5417EACC1C19631B0068F2B9 /* GPUImage.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5417EACA1C1962F00068F2B9 /* GPUImage.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 20 | 5443218D1C199F0F000869CD /* CLRTwoInputImageFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5443218C1C199F0F000869CD /* CLRTwoInputImageFilter.m */; }; 21 | 54996C4D1C23DFBE002B2D69 /* item_powerup_fish.png in Resources */ = {isa = PBXBuildFile; fileRef = 54996C4A1C23DFBE002B2D69 /* item_powerup_fish.png */; }; 22 | 54996C4E1C23DFBE002B2D69 /* tile_floor.png in Resources */ = {isa = PBXBuildFile; fileRef = 54996C4B1C23DFBE002B2D69 /* tile_floor.png */; }; 23 | 54996C511C23DFCD002B2D69 /* GLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 54996C501C23DFCD002B2D69 /* GLView.m */; }; 24 | 54996C571C23DFEC002B2D69 /* SimpleVertex.glsl in Resources */ = {isa = PBXBuildFile; fileRef = 54996C531C23DFEC002B2D69 /* SimpleVertex.glsl */; }; 25 | 54996C581C23DFEC002B2D69 /* SimpleFragment.glsl in Resources */ = {isa = PBXBuildFile; fileRef = 54996C541C23DFEC002B2D69 /* SimpleFragment.glsl */; }; 26 | 54996C591C23DFEC002B2D69 /* SHaderHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 54996C561C23DFEC002B2D69 /* SHaderHelper.m */; }; 27 | 54B060991C1AC222009CD7F2 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54B060981C1AC222009CD7F2 /* QuartzCore.framework */; }; 28 | 54B0609B1C1AC22A009CD7F2 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54B0609A1C1AC22A009CD7F2 /* CoreVideo.framework */; }; 29 | 54B0609D1C1AC231009CD7F2 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54B0609C1C1AC231009CD7F2 /* CoreMedia.framework */; }; 30 | 54B0609F1C1AC23A009CD7F2 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54B0609E1C1AC23A009CD7F2 /* AVFoundation.framework */; }; 31 | 54B060A21C1ADA43009CD7F2 /* ImageEffect.gif in Resources */ = {isa = PBXBuildFile; fileRef = 54B060A11C1ADA43009CD7F2 /* ImageEffect.gif */; }; 32 | 54E685B61C19757B003503A1 /* CLRGPUImageFiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 54E685B51C19757B003503A1 /* CLRGPUImageFiler.m */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXContainerItemProxy section */ 36 | 5417EAA51C195EFA0068F2B9 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 5417EA831C195EFA0068F2B9 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 5417EA8A1C195EFA0068F2B9; 41 | remoteInfo = ImageEffect; 42 | }; 43 | 5417EAB01C195EFA0068F2B9 /* PBXContainerItemProxy */ = { 44 | isa = PBXContainerItemProxy; 45 | containerPortal = 5417EA831C195EFA0068F2B9 /* Project object */; 46 | proxyType = 1; 47 | remoteGlobalIDString = 5417EA8A1C195EFA0068F2B9; 48 | remoteInfo = ImageEffect; 49 | }; 50 | 5417EAC71C1962F00068F2B9 /* PBXContainerItemProxy */ = { 51 | isa = PBXContainerItemProxy; 52 | containerPortal = 5417EAC11C1962F00068F2B9 /* GPUImage.xcodeproj */; 53 | proxyType = 2; 54 | remoteGlobalIDString = BCF1A33414DDB1EC00852800; 55 | remoteInfo = GPUImage; 56 | }; 57 | 5417EAC91C1962F00068F2B9 /* PBXContainerItemProxy */ = { 58 | isa = PBXContainerItemProxy; 59 | containerPortal = 5417EAC11C1962F00068F2B9 /* GPUImage.xcodeproj */; 60 | proxyType = 2; 61 | remoteGlobalIDString = BCE209E51943F20C002FEED8; 62 | remoteInfo = GPUImageFramework; 63 | }; 64 | 5417EACD1C19631B0068F2B9 /* PBXContainerItemProxy */ = { 65 | isa = PBXContainerItemProxy; 66 | containerPortal = 5417EAC11C1962F00068F2B9 /* GPUImage.xcodeproj */; 67 | proxyType = 1; 68 | remoteGlobalIDString = BCE209E41943F20C002FEED8; 69 | remoteInfo = GPUImageFramework; 70 | }; 71 | /* End PBXContainerItemProxy section */ 72 | 73 | /* Begin PBXCopyFilesBuildPhase section */ 74 | 5417EACF1C19631B0068F2B9 /* Embed Frameworks */ = { 75 | isa = PBXCopyFilesBuildPhase; 76 | buildActionMask = 2147483647; 77 | dstPath = ""; 78 | dstSubfolderSpec = 10; 79 | files = ( 80 | 5417EACC1C19631B0068F2B9 /* GPUImage.framework in Embed Frameworks */, 81 | ); 82 | name = "Embed Frameworks"; 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | /* End PBXCopyFilesBuildPhase section */ 86 | 87 | /* Begin PBXFileReference section */ 88 | 5417EA8B1C195EFA0068F2B9 /* ImageEffect.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ImageEffect.app; sourceTree = BUILT_PRODUCTS_DIR; }; 89 | 5417EA8F1C195EFA0068F2B9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 90 | 5417EA911C195EFA0068F2B9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 91 | 5417EA921C195EFA0068F2B9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 92 | 5417EA941C195EFA0068F2B9 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 93 | 5417EA951C195EFA0068F2B9 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 94 | 5417EA981C195EFA0068F2B9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 95 | 5417EA9A1C195EFA0068F2B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 96 | 5417EA9D1C195EFA0068F2B9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97 | 5417EA9F1C195EFA0068F2B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 98 | 5417EAA41C195EFA0068F2B9 /* ImageEffectTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ImageEffectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 99 | 5417EAA81C195EFA0068F2B9 /* ImageEffectTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImageEffectTests.m; sourceTree = ""; }; 100 | 5417EAAA1C195EFA0068F2B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 101 | 5417EAAF1C195EFA0068F2B9 /* ImageEffectUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ImageEffectUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 102 | 5417EAB31C195EFA0068F2B9 /* ImageEffectUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImageEffectUITests.m; sourceTree = ""; }; 103 | 5417EAB51C195EFA0068F2B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 104 | 5417EAC11C1962F00068F2B9 /* GPUImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GPUImage.xcodeproj; path = ../../GPUImage/framework/GPUImage.xcodeproj; sourceTree = ""; }; 105 | 5443218B1C199F0F000869CD /* CLRTwoInputImageFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CLRTwoInputImageFilter.h; path = CLRFilter/CLRTwoInputImageFilter.h; sourceTree = ""; }; 106 | 5443218C1C199F0F000869CD /* CLRTwoInputImageFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CLRTwoInputImageFilter.m; path = CLRFilter/CLRTwoInputImageFilter.m; sourceTree = ""; }; 107 | 54996C4A1C23DFBE002B2D69 /* item_powerup_fish.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = item_powerup_fish.png; sourceTree = ""; }; 108 | 54996C4B1C23DFBE002B2D69 /* tile_floor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tile_floor.png; sourceTree = ""; }; 109 | 54996C4F1C23DFCD002B2D69 /* GLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLView.h; sourceTree = ""; }; 110 | 54996C501C23DFCD002B2D69 /* GLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GLView.m; sourceTree = ""; }; 111 | 54996C531C23DFEC002B2D69 /* SimpleVertex.glsl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SimpleVertex.glsl; sourceTree = ""; }; 112 | 54996C541C23DFEC002B2D69 /* SimpleFragment.glsl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SimpleFragment.glsl; sourceTree = ""; }; 113 | 54996C551C23DFEC002B2D69 /* SHaderHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHaderHelper.h; sourceTree = ""; }; 114 | 54996C561C23DFEC002B2D69 /* SHaderHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHaderHelper.m; sourceTree = ""; }; 115 | 54B060981C1AC222009CD7F2 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 116 | 54B0609A1C1AC22A009CD7F2 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; 117 | 54B0609C1C1AC231009CD7F2 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; 118 | 54B0609E1C1AC23A009CD7F2 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 119 | 54B060A11C1ADA43009CD7F2 /* ImageEffect.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = ImageEffect.gif; path = ImageEffect/ScreenShot/ImageEffect.gif; sourceTree = ""; }; 120 | 54E685B41C19757B003503A1 /* CLRGPUImageFiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CLRGPUImageFiler.h; path = CLRFilter/CLRGPUImageFiler.h; sourceTree = ""; }; 121 | 54E685B51C19757B003503A1 /* CLRGPUImageFiler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CLRGPUImageFiler.m; path = CLRFilter/CLRGPUImageFiler.m; sourceTree = ""; }; 122 | /* End PBXFileReference section */ 123 | 124 | /* Begin PBXFrameworksBuildPhase section */ 125 | 5417EA881C195EFA0068F2B9 /* Frameworks */ = { 126 | isa = PBXFrameworksBuildPhase; 127 | buildActionMask = 2147483647; 128 | files = ( 129 | 54B0609F1C1AC23A009CD7F2 /* AVFoundation.framework in Frameworks */, 130 | 54B0609D1C1AC231009CD7F2 /* CoreMedia.framework in Frameworks */, 131 | 54B0609B1C1AC22A009CD7F2 /* CoreVideo.framework in Frameworks */, 132 | 54B060991C1AC222009CD7F2 /* QuartzCore.framework in Frameworks */, 133 | 5417EACB1C19631B0068F2B9 /* GPUImage.framework in Frameworks */, 134 | ); 135 | runOnlyForDeploymentPostprocessing = 0; 136 | }; 137 | 5417EAA11C195EFA0068F2B9 /* Frameworks */ = { 138 | isa = PBXFrameworksBuildPhase; 139 | buildActionMask = 2147483647; 140 | files = ( 141 | ); 142 | runOnlyForDeploymentPostprocessing = 0; 143 | }; 144 | 5417EAAC1C195EFA0068F2B9 /* Frameworks */ = { 145 | isa = PBXFrameworksBuildPhase; 146 | buildActionMask = 2147483647; 147 | files = ( 148 | ); 149 | runOnlyForDeploymentPostprocessing = 0; 150 | }; 151 | /* End PBXFrameworksBuildPhase section */ 152 | 153 | /* Begin PBXGroup section */ 154 | 5417EA821C195EFA0068F2B9 = { 155 | isa = PBXGroup; 156 | children = ( 157 | 54B060A01C1AD9D8009CD7F2 /* ScreenShot */, 158 | 54B0609E1C1AC23A009CD7F2 /* AVFoundation.framework */, 159 | 54B0609C1C1AC231009CD7F2 /* CoreMedia.framework */, 160 | 54B0609A1C1AC22A009CD7F2 /* CoreVideo.framework */, 161 | 54B060981C1AC222009CD7F2 /* QuartzCore.framework */, 162 | 5417EAC11C1962F00068F2B9 /* GPUImage.xcodeproj */, 163 | 5417EA8D1C195EFA0068F2B9 /* ImageEffect */, 164 | 5417EAA71C195EFA0068F2B9 /* ImageEffectTests */, 165 | 5417EAB21C195EFA0068F2B9 /* ImageEffectUITests */, 166 | 5417EA8C1C195EFA0068F2B9 /* Products */, 167 | ); 168 | sourceTree = ""; 169 | }; 170 | 5417EA8C1C195EFA0068F2B9 /* Products */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 5417EA8B1C195EFA0068F2B9 /* ImageEffect.app */, 174 | 5417EAA41C195EFA0068F2B9 /* ImageEffectTests.xctest */, 175 | 5417EAAF1C195EFA0068F2B9 /* ImageEffectUITests.xctest */, 176 | ); 177 | name = Products; 178 | sourceTree = ""; 179 | }; 180 | 5417EA8D1C195EFA0068F2B9 /* ImageEffect */ = { 181 | isa = PBXGroup; 182 | children = ( 183 | 54996C471C23DFA5002B2D69 /* OpenGL */, 184 | 54E685B31C197526003503A1 /* CLRFilter */, 185 | 5417EA911C195EFA0068F2B9 /* AppDelegate.h */, 186 | 5417EA921C195EFA0068F2B9 /* AppDelegate.m */, 187 | 5417EA941C195EFA0068F2B9 /* ViewController.h */, 188 | 5417EA951C195EFA0068F2B9 /* ViewController.m */, 189 | 5417EA971C195EFA0068F2B9 /* Main.storyboard */, 190 | 5417EA9A1C195EFA0068F2B9 /* Assets.xcassets */, 191 | 5417EA9C1C195EFA0068F2B9 /* LaunchScreen.storyboard */, 192 | 5417EA9F1C195EFA0068F2B9 /* Info.plist */, 193 | 5417EA8E1C195EFA0068F2B9 /* Supporting Files */, 194 | ); 195 | path = ImageEffect; 196 | sourceTree = ""; 197 | }; 198 | 5417EA8E1C195EFA0068F2B9 /* Supporting Files */ = { 199 | isa = PBXGroup; 200 | children = ( 201 | 54996C4C1C23DFBE002B2D69 /* Art */, 202 | 5417EA8F1C195EFA0068F2B9 /* main.m */, 203 | ); 204 | name = "Supporting Files"; 205 | sourceTree = ""; 206 | }; 207 | 5417EAA71C195EFA0068F2B9 /* ImageEffectTests */ = { 208 | isa = PBXGroup; 209 | children = ( 210 | 5417EAA81C195EFA0068F2B9 /* ImageEffectTests.m */, 211 | 5417EAAA1C195EFA0068F2B9 /* Info.plist */, 212 | ); 213 | path = ImageEffectTests; 214 | sourceTree = ""; 215 | }; 216 | 5417EAB21C195EFA0068F2B9 /* ImageEffectUITests */ = { 217 | isa = PBXGroup; 218 | children = ( 219 | 5417EAB31C195EFA0068F2B9 /* ImageEffectUITests.m */, 220 | 5417EAB51C195EFA0068F2B9 /* Info.plist */, 221 | ); 222 | path = ImageEffectUITests; 223 | sourceTree = ""; 224 | }; 225 | 5417EAC21C1962F00068F2B9 /* Products */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | 5417EAC81C1962F00068F2B9 /* libGPUImage.a */, 229 | 5417EACA1C1962F00068F2B9 /* GPUImage.framework */, 230 | ); 231 | name = Products; 232 | sourceTree = ""; 233 | }; 234 | 54996C471C23DFA5002B2D69 /* OpenGL */ = { 235 | isa = PBXGroup; 236 | children = ( 237 | 54996C521C23DFE2002B2D69 /* shader */, 238 | 54996C4F1C23DFCD002B2D69 /* GLView.h */, 239 | 54996C501C23DFCD002B2D69 /* GLView.m */, 240 | ); 241 | name = OpenGL; 242 | sourceTree = ""; 243 | }; 244 | 54996C4C1C23DFBE002B2D69 /* Art */ = { 245 | isa = PBXGroup; 246 | children = ( 247 | 54996C4A1C23DFBE002B2D69 /* item_powerup_fish.png */, 248 | 54996C4B1C23DFBE002B2D69 /* tile_floor.png */, 249 | ); 250 | name = Art; 251 | path = ../../../Code4Everyone/CLROpenGLES20/CLROpenGLES20/Art; 252 | sourceTree = ""; 253 | }; 254 | 54996C521C23DFE2002B2D69 /* shader */ = { 255 | isa = PBXGroup; 256 | children = ( 257 | 54996C531C23DFEC002B2D69 /* SimpleVertex.glsl */, 258 | 54996C541C23DFEC002B2D69 /* SimpleFragment.glsl */, 259 | 54996C551C23DFEC002B2D69 /* SHaderHelper.h */, 260 | 54996C561C23DFEC002B2D69 /* SHaderHelper.m */, 261 | ); 262 | name = shader; 263 | sourceTree = ""; 264 | }; 265 | 54B060A01C1AD9D8009CD7F2 /* ScreenShot */ = { 266 | isa = PBXGroup; 267 | children = ( 268 | 54B060A11C1ADA43009CD7F2 /* ImageEffect.gif */, 269 | ); 270 | name = ScreenShot; 271 | sourceTree = ""; 272 | }; 273 | 54E685B31C197526003503A1 /* CLRFilter */ = { 274 | isa = PBXGroup; 275 | children = ( 276 | 54E685B41C19757B003503A1 /* CLRGPUImageFiler.h */, 277 | 54E685B51C19757B003503A1 /* CLRGPUImageFiler.m */, 278 | 5443218B1C199F0F000869CD /* CLRTwoInputImageFilter.h */, 279 | 5443218C1C199F0F000869CD /* CLRTwoInputImageFilter.m */, 280 | ); 281 | name = CLRFilter; 282 | sourceTree = ""; 283 | }; 284 | /* End PBXGroup section */ 285 | 286 | /* Begin PBXNativeTarget section */ 287 | 5417EA8A1C195EFA0068F2B9 /* ImageEffect */ = { 288 | isa = PBXNativeTarget; 289 | buildConfigurationList = 5417EAB81C195EFA0068F2B9 /* Build configuration list for PBXNativeTarget "ImageEffect" */; 290 | buildPhases = ( 291 | 5417EA871C195EFA0068F2B9 /* Sources */, 292 | 5417EA881C195EFA0068F2B9 /* Frameworks */, 293 | 5417EA891C195EFA0068F2B9 /* Resources */, 294 | 5417EACF1C19631B0068F2B9 /* Embed Frameworks */, 295 | ); 296 | buildRules = ( 297 | ); 298 | dependencies = ( 299 | 5417EACE1C19631B0068F2B9 /* PBXTargetDependency */, 300 | ); 301 | name = ImageEffect; 302 | productName = ImageEffect; 303 | productReference = 5417EA8B1C195EFA0068F2B9 /* ImageEffect.app */; 304 | productType = "com.apple.product-type.application"; 305 | }; 306 | 5417EAA31C195EFA0068F2B9 /* ImageEffectTests */ = { 307 | isa = PBXNativeTarget; 308 | buildConfigurationList = 5417EABB1C195EFA0068F2B9 /* Build configuration list for PBXNativeTarget "ImageEffectTests" */; 309 | buildPhases = ( 310 | 5417EAA01C195EFA0068F2B9 /* Sources */, 311 | 5417EAA11C195EFA0068F2B9 /* Frameworks */, 312 | 5417EAA21C195EFA0068F2B9 /* Resources */, 313 | ); 314 | buildRules = ( 315 | ); 316 | dependencies = ( 317 | 5417EAA61C195EFA0068F2B9 /* PBXTargetDependency */, 318 | ); 319 | name = ImageEffectTests; 320 | productName = ImageEffectTests; 321 | productReference = 5417EAA41C195EFA0068F2B9 /* ImageEffectTests.xctest */; 322 | productType = "com.apple.product-type.bundle.unit-test"; 323 | }; 324 | 5417EAAE1C195EFA0068F2B9 /* ImageEffectUITests */ = { 325 | isa = PBXNativeTarget; 326 | buildConfigurationList = 5417EABE1C195EFA0068F2B9 /* Build configuration list for PBXNativeTarget "ImageEffectUITests" */; 327 | buildPhases = ( 328 | 5417EAAB1C195EFA0068F2B9 /* Sources */, 329 | 5417EAAC1C195EFA0068F2B9 /* Frameworks */, 330 | 5417EAAD1C195EFA0068F2B9 /* Resources */, 331 | ); 332 | buildRules = ( 333 | ); 334 | dependencies = ( 335 | 5417EAB11C195EFA0068F2B9 /* PBXTargetDependency */, 336 | ); 337 | name = ImageEffectUITests; 338 | productName = ImageEffectUITests; 339 | productReference = 5417EAAF1C195EFA0068F2B9 /* ImageEffectUITests.xctest */; 340 | productType = "com.apple.product-type.bundle.ui-testing"; 341 | }; 342 | /* End PBXNativeTarget section */ 343 | 344 | /* Begin PBXProject section */ 345 | 5417EA831C195EFA0068F2B9 /* Project object */ = { 346 | isa = PBXProject; 347 | attributes = { 348 | LastUpgradeCheck = 0710; 349 | ORGANIZATIONNAME = clover; 350 | TargetAttributes = { 351 | 5417EA8A1C195EFA0068F2B9 = { 352 | CreatedOnToolsVersion = 7.1; 353 | }; 354 | 5417EAA31C195EFA0068F2B9 = { 355 | CreatedOnToolsVersion = 7.1; 356 | TestTargetID = 5417EA8A1C195EFA0068F2B9; 357 | }; 358 | 5417EAAE1C195EFA0068F2B9 = { 359 | CreatedOnToolsVersion = 7.1; 360 | TestTargetID = 5417EA8A1C195EFA0068F2B9; 361 | }; 362 | }; 363 | }; 364 | buildConfigurationList = 5417EA861C195EFA0068F2B9 /* Build configuration list for PBXProject "ImageEffect" */; 365 | compatibilityVersion = "Xcode 3.2"; 366 | developmentRegion = English; 367 | hasScannedForEncodings = 0; 368 | knownRegions = ( 369 | en, 370 | Base, 371 | ); 372 | mainGroup = 5417EA821C195EFA0068F2B9; 373 | productRefGroup = 5417EA8C1C195EFA0068F2B9 /* Products */; 374 | projectDirPath = ""; 375 | projectReferences = ( 376 | { 377 | ProductGroup = 5417EAC21C1962F00068F2B9 /* Products */; 378 | ProjectRef = 5417EAC11C1962F00068F2B9 /* GPUImage.xcodeproj */; 379 | }, 380 | ); 381 | projectRoot = ""; 382 | targets = ( 383 | 5417EA8A1C195EFA0068F2B9 /* ImageEffect */, 384 | 5417EAA31C195EFA0068F2B9 /* ImageEffectTests */, 385 | 5417EAAE1C195EFA0068F2B9 /* ImageEffectUITests */, 386 | ); 387 | }; 388 | /* End PBXProject section */ 389 | 390 | /* Begin PBXReferenceProxy section */ 391 | 5417EAC81C1962F00068F2B9 /* libGPUImage.a */ = { 392 | isa = PBXReferenceProxy; 393 | fileType = archive.ar; 394 | path = libGPUImage.a; 395 | remoteRef = 5417EAC71C1962F00068F2B9 /* PBXContainerItemProxy */; 396 | sourceTree = BUILT_PRODUCTS_DIR; 397 | }; 398 | 5417EACA1C1962F00068F2B9 /* GPUImage.framework */ = { 399 | isa = PBXReferenceProxy; 400 | fileType = wrapper.framework; 401 | path = GPUImage.framework; 402 | remoteRef = 5417EAC91C1962F00068F2B9 /* PBXContainerItemProxy */; 403 | sourceTree = BUILT_PRODUCTS_DIR; 404 | }; 405 | /* End PBXReferenceProxy section */ 406 | 407 | /* Begin PBXResourcesBuildPhase section */ 408 | 5417EA891C195EFA0068F2B9 /* Resources */ = { 409 | isa = PBXResourcesBuildPhase; 410 | buildActionMask = 2147483647; 411 | files = ( 412 | 54996C4D1C23DFBE002B2D69 /* item_powerup_fish.png in Resources */, 413 | 54996C581C23DFEC002B2D69 /* SimpleFragment.glsl in Resources */, 414 | 5417EA9E1C195EFA0068F2B9 /* LaunchScreen.storyboard in Resources */, 415 | 5417EA9B1C195EFA0068F2B9 /* Assets.xcassets in Resources */, 416 | 5417EA991C195EFA0068F2B9 /* Main.storyboard in Resources */, 417 | 54996C4E1C23DFBE002B2D69 /* tile_floor.png in Resources */, 418 | 54B060A21C1ADA43009CD7F2 /* ImageEffect.gif in Resources */, 419 | 54996C571C23DFEC002B2D69 /* SimpleVertex.glsl in Resources */, 420 | ); 421 | runOnlyForDeploymentPostprocessing = 0; 422 | }; 423 | 5417EAA21C195EFA0068F2B9 /* Resources */ = { 424 | isa = PBXResourcesBuildPhase; 425 | buildActionMask = 2147483647; 426 | files = ( 427 | ); 428 | runOnlyForDeploymentPostprocessing = 0; 429 | }; 430 | 5417EAAD1C195EFA0068F2B9 /* Resources */ = { 431 | isa = PBXResourcesBuildPhase; 432 | buildActionMask = 2147483647; 433 | files = ( 434 | ); 435 | runOnlyForDeploymentPostprocessing = 0; 436 | }; 437 | /* End PBXResourcesBuildPhase section */ 438 | 439 | /* Begin PBXSourcesBuildPhase section */ 440 | 5417EA871C195EFA0068F2B9 /* Sources */ = { 441 | isa = PBXSourcesBuildPhase; 442 | buildActionMask = 2147483647; 443 | files = ( 444 | 5417EA961C195EFA0068F2B9 /* ViewController.m in Sources */, 445 | 5417EA931C195EFA0068F2B9 /* AppDelegate.m in Sources */, 446 | 5417EA901C195EFA0068F2B9 /* main.m in Sources */, 447 | 54E685B61C19757B003503A1 /* CLRGPUImageFiler.m in Sources */, 448 | 5443218D1C199F0F000869CD /* CLRTwoInputImageFilter.m in Sources */, 449 | 54996C591C23DFEC002B2D69 /* SHaderHelper.m in Sources */, 450 | 54996C511C23DFCD002B2D69 /* GLView.m in Sources */, 451 | ); 452 | runOnlyForDeploymentPostprocessing = 0; 453 | }; 454 | 5417EAA01C195EFA0068F2B9 /* Sources */ = { 455 | isa = PBXSourcesBuildPhase; 456 | buildActionMask = 2147483647; 457 | files = ( 458 | 5417EAA91C195EFA0068F2B9 /* ImageEffectTests.m in Sources */, 459 | ); 460 | runOnlyForDeploymentPostprocessing = 0; 461 | }; 462 | 5417EAAB1C195EFA0068F2B9 /* Sources */ = { 463 | isa = PBXSourcesBuildPhase; 464 | buildActionMask = 2147483647; 465 | files = ( 466 | 5417EAB41C195EFA0068F2B9 /* ImageEffectUITests.m in Sources */, 467 | ); 468 | runOnlyForDeploymentPostprocessing = 0; 469 | }; 470 | /* End PBXSourcesBuildPhase section */ 471 | 472 | /* Begin PBXTargetDependency section */ 473 | 5417EAA61C195EFA0068F2B9 /* PBXTargetDependency */ = { 474 | isa = PBXTargetDependency; 475 | target = 5417EA8A1C195EFA0068F2B9 /* ImageEffect */; 476 | targetProxy = 5417EAA51C195EFA0068F2B9 /* PBXContainerItemProxy */; 477 | }; 478 | 5417EAB11C195EFA0068F2B9 /* PBXTargetDependency */ = { 479 | isa = PBXTargetDependency; 480 | target = 5417EA8A1C195EFA0068F2B9 /* ImageEffect */; 481 | targetProxy = 5417EAB01C195EFA0068F2B9 /* PBXContainerItemProxy */; 482 | }; 483 | 5417EACE1C19631B0068F2B9 /* PBXTargetDependency */ = { 484 | isa = PBXTargetDependency; 485 | name = GPUImageFramework; 486 | targetProxy = 5417EACD1C19631B0068F2B9 /* PBXContainerItemProxy */; 487 | }; 488 | /* End PBXTargetDependency section */ 489 | 490 | /* Begin PBXVariantGroup section */ 491 | 5417EA971C195EFA0068F2B9 /* Main.storyboard */ = { 492 | isa = PBXVariantGroup; 493 | children = ( 494 | 5417EA981C195EFA0068F2B9 /* Base */, 495 | ); 496 | name = Main.storyboard; 497 | sourceTree = ""; 498 | }; 499 | 5417EA9C1C195EFA0068F2B9 /* LaunchScreen.storyboard */ = { 500 | isa = PBXVariantGroup; 501 | children = ( 502 | 5417EA9D1C195EFA0068F2B9 /* Base */, 503 | ); 504 | name = LaunchScreen.storyboard; 505 | sourceTree = ""; 506 | }; 507 | /* End PBXVariantGroup section */ 508 | 509 | /* Begin XCBuildConfiguration section */ 510 | 5417EAB61C195EFA0068F2B9 /* Debug */ = { 511 | isa = XCBuildConfiguration; 512 | buildSettings = { 513 | ALWAYS_SEARCH_USER_PATHS = NO; 514 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 515 | CLANG_CXX_LIBRARY = "libc++"; 516 | CLANG_ENABLE_MODULES = YES; 517 | CLANG_ENABLE_OBJC_ARC = YES; 518 | CLANG_WARN_BOOL_CONVERSION = YES; 519 | CLANG_WARN_CONSTANT_CONVERSION = YES; 520 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 521 | CLANG_WARN_EMPTY_BODY = YES; 522 | CLANG_WARN_ENUM_CONVERSION = YES; 523 | CLANG_WARN_INT_CONVERSION = YES; 524 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 525 | CLANG_WARN_UNREACHABLE_CODE = YES; 526 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 527 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 528 | COPY_PHASE_STRIP = NO; 529 | DEBUG_INFORMATION_FORMAT = dwarf; 530 | ENABLE_STRICT_OBJC_MSGSEND = YES; 531 | ENABLE_TESTABILITY = YES; 532 | GCC_C_LANGUAGE_STANDARD = gnu99; 533 | GCC_DYNAMIC_NO_PIC = NO; 534 | GCC_NO_COMMON_BLOCKS = YES; 535 | GCC_OPTIMIZATION_LEVEL = 0; 536 | GCC_PREPROCESSOR_DEFINITIONS = ( 537 | "DEBUG=1", 538 | "$(inherited)", 539 | ); 540 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 541 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 542 | GCC_WARN_UNDECLARED_SELECTOR = YES; 543 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 544 | GCC_WARN_UNUSED_FUNCTION = YES; 545 | GCC_WARN_UNUSED_VARIABLE = YES; 546 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 547 | MTL_ENABLE_DEBUG_INFO = YES; 548 | ONLY_ACTIVE_ARCH = YES; 549 | SDKROOT = iphoneos; 550 | TARGETED_DEVICE_FAMILY = "1,2"; 551 | }; 552 | name = Debug; 553 | }; 554 | 5417EAB71C195EFA0068F2B9 /* Release */ = { 555 | isa = XCBuildConfiguration; 556 | buildSettings = { 557 | ALWAYS_SEARCH_USER_PATHS = NO; 558 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 559 | CLANG_CXX_LIBRARY = "libc++"; 560 | CLANG_ENABLE_MODULES = YES; 561 | CLANG_ENABLE_OBJC_ARC = YES; 562 | CLANG_WARN_BOOL_CONVERSION = YES; 563 | CLANG_WARN_CONSTANT_CONVERSION = YES; 564 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 565 | CLANG_WARN_EMPTY_BODY = YES; 566 | CLANG_WARN_ENUM_CONVERSION = YES; 567 | CLANG_WARN_INT_CONVERSION = YES; 568 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 569 | CLANG_WARN_UNREACHABLE_CODE = YES; 570 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 571 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 572 | COPY_PHASE_STRIP = NO; 573 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 574 | ENABLE_NS_ASSERTIONS = NO; 575 | ENABLE_STRICT_OBJC_MSGSEND = YES; 576 | GCC_C_LANGUAGE_STANDARD = gnu99; 577 | GCC_NO_COMMON_BLOCKS = YES; 578 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 579 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 580 | GCC_WARN_UNDECLARED_SELECTOR = YES; 581 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 582 | GCC_WARN_UNUSED_FUNCTION = YES; 583 | GCC_WARN_UNUSED_VARIABLE = YES; 584 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 585 | MTL_ENABLE_DEBUG_INFO = NO; 586 | SDKROOT = iphoneos; 587 | TARGETED_DEVICE_FAMILY = "1,2"; 588 | VALIDATE_PRODUCT = YES; 589 | }; 590 | name = Release; 591 | }; 592 | 5417EAB91C195EFA0068F2B9 /* Debug */ = { 593 | isa = XCBuildConfiguration; 594 | buildSettings = { 595 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 596 | HEADER_SEARCH_PATHS = ( 597 | /Users/vk/workspace/GPUImage/framework/Source, 598 | /Users/vk/workspace/GPUImage/framework/Source/iOS, 599 | ); 600 | INFOPLIST_FILE = ImageEffect/Info.plist; 601 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 602 | PRODUCT_BUNDLE_IDENTIFIER = clover.ImageEffect; 603 | PRODUCT_NAME = "$(TARGET_NAME)"; 604 | }; 605 | name = Debug; 606 | }; 607 | 5417EABA1C195EFA0068F2B9 /* Release */ = { 608 | isa = XCBuildConfiguration; 609 | buildSettings = { 610 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 611 | HEADER_SEARCH_PATHS = ( 612 | /Users/vk/workspace/GPUImage/framework/Source, 613 | /Users/vk/workspace/GPUImage/framework/Source/iOS, 614 | ); 615 | INFOPLIST_FILE = ImageEffect/Info.plist; 616 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 617 | PRODUCT_BUNDLE_IDENTIFIER = clover.ImageEffect; 618 | PRODUCT_NAME = "$(TARGET_NAME)"; 619 | }; 620 | name = Release; 621 | }; 622 | 5417EABC1C195EFA0068F2B9 /* Debug */ = { 623 | isa = XCBuildConfiguration; 624 | buildSettings = { 625 | BUNDLE_LOADER = "$(TEST_HOST)"; 626 | INFOPLIST_FILE = ImageEffectTests/Info.plist; 627 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 628 | PRODUCT_BUNDLE_IDENTIFIER = clover.ImageEffectTests; 629 | PRODUCT_NAME = "$(TARGET_NAME)"; 630 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ImageEffect.app/ImageEffect"; 631 | }; 632 | name = Debug; 633 | }; 634 | 5417EABD1C195EFA0068F2B9 /* Release */ = { 635 | isa = XCBuildConfiguration; 636 | buildSettings = { 637 | BUNDLE_LOADER = "$(TEST_HOST)"; 638 | INFOPLIST_FILE = ImageEffectTests/Info.plist; 639 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 640 | PRODUCT_BUNDLE_IDENTIFIER = clover.ImageEffectTests; 641 | PRODUCT_NAME = "$(TARGET_NAME)"; 642 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ImageEffect.app/ImageEffect"; 643 | }; 644 | name = Release; 645 | }; 646 | 5417EABF1C195EFA0068F2B9 /* Debug */ = { 647 | isa = XCBuildConfiguration; 648 | buildSettings = { 649 | INFOPLIST_FILE = ImageEffectUITests/Info.plist; 650 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 651 | PRODUCT_BUNDLE_IDENTIFIER = clover.ImageEffectUITests; 652 | PRODUCT_NAME = "$(TARGET_NAME)"; 653 | TEST_TARGET_NAME = ImageEffect; 654 | USES_XCTRUNNER = YES; 655 | }; 656 | name = Debug; 657 | }; 658 | 5417EAC01C195EFA0068F2B9 /* Release */ = { 659 | isa = XCBuildConfiguration; 660 | buildSettings = { 661 | INFOPLIST_FILE = ImageEffectUITests/Info.plist; 662 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 663 | PRODUCT_BUNDLE_IDENTIFIER = clover.ImageEffectUITests; 664 | PRODUCT_NAME = "$(TARGET_NAME)"; 665 | TEST_TARGET_NAME = ImageEffect; 666 | USES_XCTRUNNER = YES; 667 | }; 668 | name = Release; 669 | }; 670 | /* End XCBuildConfiguration section */ 671 | 672 | /* Begin XCConfigurationList section */ 673 | 5417EA861C195EFA0068F2B9 /* Build configuration list for PBXProject "ImageEffect" */ = { 674 | isa = XCConfigurationList; 675 | buildConfigurations = ( 676 | 5417EAB61C195EFA0068F2B9 /* Debug */, 677 | 5417EAB71C195EFA0068F2B9 /* Release */, 678 | ); 679 | defaultConfigurationIsVisible = 0; 680 | defaultConfigurationName = Release; 681 | }; 682 | 5417EAB81C195EFA0068F2B9 /* Build configuration list for PBXNativeTarget "ImageEffect" */ = { 683 | isa = XCConfigurationList; 684 | buildConfigurations = ( 685 | 5417EAB91C195EFA0068F2B9 /* Debug */, 686 | 5417EABA1C195EFA0068F2B9 /* Release */, 687 | ); 688 | defaultConfigurationIsVisible = 0; 689 | defaultConfigurationName = Release; 690 | }; 691 | 5417EABB1C195EFA0068F2B9 /* Build configuration list for PBXNativeTarget "ImageEffectTests" */ = { 692 | isa = XCConfigurationList; 693 | buildConfigurations = ( 694 | 5417EABC1C195EFA0068F2B9 /* Debug */, 695 | 5417EABD1C195EFA0068F2B9 /* Release */, 696 | ); 697 | defaultConfigurationIsVisible = 0; 698 | defaultConfigurationName = Release; 699 | }; 700 | 5417EABE1C195EFA0068F2B9 /* Build configuration list for PBXNativeTarget "ImageEffectUITests" */ = { 701 | isa = XCConfigurationList; 702 | buildConfigurations = ( 703 | 5417EABF1C195EFA0068F2B9 /* Debug */, 704 | 5417EAC01C195EFA0068F2B9 /* Release */, 705 | ); 706 | defaultConfigurationIsVisible = 0; 707 | defaultConfigurationName = Release; 708 | }; 709 | /* End XCConfigurationList section */ 710 | }; 711 | rootObject = 5417EA831C195EFA0068F2B9 /* Project object */; 712 | } 713 | -------------------------------------------------------------------------------- /ImageEffect.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ImageEffect.xcodeproj/project.xcworkspace/xcshareddata/ImageEffect.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "3CC195312ACE0307FC523BCFB26C780E02FD46B2", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "E609DD15689CC93D8F4D219EB393F30F9F726178" : 0, 8 | "3CC195312ACE0307FC523BCFB26C780E02FD46B2" : 0 9 | }, 10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "AA221A14-27A9-4CD2-9080-BE96AF6B6403", 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 12 | "E609DD15689CC93D8F4D219EB393F30F9F726178" : "..\/GPUImage", 13 | "3CC195312ACE0307FC523BCFB26C780E02FD46B2" : "ImageEffect\/" 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "ImageEffect", 16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "ImageEffect.xcodeproj", 18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 19 | { 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/celesius\/ImageEffect.git", 21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "3CC195312ACE0307FC523BCFB26C780E02FD46B2" 23 | }, 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/BradLarson\/GPUImage.git", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "E609DD15689CC93D8F4D219EB393F30F9F726178" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /ImageEffect.xcodeproj/xcuserdata/vk.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 40 | 52 | 53 | 67 | 68 | 82 | 83 | 84 | 85 | 86 | 88 | 100 | 101 | 102 | 104 | 116 | 117 | 118 | 120 | 132 | 133 | 134 | 136 | 148 | 149 | 150 | 152 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /ImageEffect.xcodeproj/xcuserdata/vk.xcuserdatad/xcschemes/ImageEffect.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /ImageEffect.xcodeproj/xcuserdata/vk.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ImageEffect.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 5417EA8A1C195EFA0068F2B9 16 | 17 | primary 18 | 19 | 20 | 5417EAA31C195EFA0068F2B9 21 | 22 | primary 23 | 24 | 25 | 5417EAAE1C195EFA0068F2B9 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ImageEffect/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ImageEffect 4 | // 5 | // Created by vk on 15/12/10. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /ImageEffect/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ImageEffect 4 | // 5 | // Created by vk on 15/12/10. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | 21 | return YES; 22 | } 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 27 | } 28 | 29 | - (void)applicationDidEnterBackground:(UIApplication *)application { 30 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 32 | } 33 | 34 | - (void)applicationWillEnterForeground:(UIApplication *)application { 35 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 36 | } 37 | 38 | - (void)applicationDidBecomeActive:(UIApplication *)application { 39 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 40 | } 41 | 42 | - (void)applicationWillTerminate:(UIApplication *)application { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /ImageEffect/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /ImageEffect/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ImageEffect/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ImageEffect/CLRFilter/CLRGPUImageFiler.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLRGPUImageFiler.h 3 | // ImageEffect 4 | // 5 | // Created by vk on 15/12/10. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CLRGPUImageFiler : GPUImageFilterGroup//GPUImageTwoInputFilter 12 | 13 | @property (nonatomic, assign) GLfloat inputData; 14 | 15 | @property (nonatomic, assign) GLfloat upDown; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ImageEffect/CLRFilter/CLRGPUImageFiler.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLRGPUImageFiler.m 3 | // ImageEffect 4 | // 5 | // Created by vk on 15/12/10. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import "CLRGPUImageFiler.h" 10 | #import "CLRTwoInputImageFilter.h" 11 | 12 | @interface CLRGPUImageFiler() 13 | 14 | @property (nonatomic, strong) GPUImageCannyEdgeDetectionFilter *cannyFilter; 15 | @property (nonatomic, strong) CLRTwoInputImageFilter *clrTwoFilter; 16 | @property (nonatomic, strong) GPUImageDilationFilter *dilationFilter; 17 | //@property (nonatomic, strong) GPUImageFilter *clrTwoFilter; 18 | 19 | @end 20 | 21 | @implementation CLRGPUImageFiler 22 | 23 | - (id)init; 24 | { 25 | // if (!(self = [super initWithFragmentShaderFromString:kCLRGPUImageFilterFragmentShaderString])) 26 | // { 27 | // return nil; 28 | // } 29 | if(self = [super init]) { 30 | _cannyFilter = [[GPUImageCannyEdgeDetectionFilter alloc]init]; 31 | [self addFilter:_cannyFilter]; 32 | 33 | _dilationFilter = [[GPUImageDilationFilter alloc]initWithRadius:2]; 34 | [_cannyFilter addTarget:_dilationFilter]; 35 | 36 | _clrTwoFilter = [[CLRTwoInputImageFilter alloc]init]; //[[CLRTwoInputImageFilter alloc]initWithFragmentShaderFromString:kCLRGPUImageFilterFragmentShaderString]; 37 | [self addFilter:_clrTwoFilter]; 38 | 39 | //[_cannyFilter addTarget:_clrTwoFilter atTextureLocation:1]; 40 | [_dilationFilter addTarget:_clrTwoFilter atTextureLocation:1]; 41 | self.initialFilters = [NSArray arrayWithObjects:_cannyFilter,_clrTwoFilter, nil]; 42 | // self.initialFilters = [NSArray arrayWithObject:_cannyFilter]; 43 | self.terminalFilter = _clrTwoFilter; 44 | 45 | } 46 | //inputDataUniform = [_clrTwoFilter->filterProgram uniformIndex:@"testDataIn"]; 47 | //inputDataUniform = [filterProgram uniformIndex:@"testDataIn"]; 48 | //spatialDecayUniform = [filterProgram uniformIndex:@"spatialDecay"]; 49 | 50 | //[self setSpatialDecay:0.1]; 51 | 52 | return self; 53 | } 54 | 55 | - (void)setInputData:(GLfloat)inputData { 56 | _inputData = inputData; 57 | _clrTwoFilter.inputData = _inputData; 58 | } 59 | 60 | - (void)setUpDown:(GLfloat)upDown { 61 | _upDown = upDown; 62 | _clrTwoFilter.updown = _upDown; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /ImageEffect/CLRFilter/CLRTwoInputImageFilter.h: -------------------------------------------------------------------------------- 1 | // 2 | // CLRTwoInputImageFilter.h 3 | // ImageEffect 4 | // 5 | // Created by vk on 15/12/10. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CLRTwoInputImageFilter : GPUImageTwoInputFilter 12 | { 13 | GLuint inputDataUniform; 14 | GLuint upDownUniform; 15 | } 16 | 17 | @property (nonatomic, assign) GLfloat inputData; 18 | @property (nonatomic, assign) GLfloat updown; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /ImageEffect/CLRFilter/CLRTwoInputImageFilter.m: -------------------------------------------------------------------------------- 1 | // 2 | // CLRTwoInputImageFilter.m 3 | // ImageEffect 4 | // 5 | // Created by vk on 15/12/10. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import "CLRTwoInputImageFilter.h" 10 | 11 | NSString *const kCLRGPUImageFilterFragmentShaderString = SHADER_STRING 12 | ( 13 | 14 | varying highp vec2 textureCoordinate; 15 | 16 | uniform sampler2D inputImageTexture; 17 | 18 | varying highp vec2 textureCoordinate2; 19 | uniform sampler2D inputImageTexture2; 20 | 21 | uniform highp float dataIn; 22 | uniform highp float upDown; 23 | 24 | 25 | void main() { 26 | 27 | highp vec4 color1 = texture2D(inputImageTexture, textureCoordinate); 28 | highp vec4 color2 = texture2D(inputImageTexture2, textureCoordinate2); 29 | highp vec4 outColor; 30 | highp float alpha; 31 | 32 | if(upDown < 0.5) { //down up 33 | alpha = 1.0 - ((textureCoordinate.y - dataIn)/0.5); 34 | } 35 | else { 36 | alpha = (textureCoordinate.y - dataIn)/0.5; 37 | } 38 | 39 | if(color2.r != 0.0) { 40 | if(textureCoordinate.y > dataIn && textureCoordinate.y < dataIn + 0.5 ){ 41 | outColor.r = alpha + color1.r; 42 | outColor.g = 0.0 + color1.g; 43 | outColor.b = 0.0 + color1.b; 44 | outColor.a = 1.0; 45 | }else{ 46 | outColor = color1; 47 | } 48 | } else { 49 | outColor = color1; 50 | } 51 | 52 | if(upDown < 0.5) { 53 | if(textureCoordinate.y > dataIn && textureCoordinate.y < dataIn + 0.01 ) { 54 | outColor.r = (0.0 + color1.r ) / 2.0; 55 | outColor.g = (1.0 + color1.g ) / 2.0; 56 | outColor.b = (1.0 + color1.b ) / 2.0; 57 | outColor.a = 0.8; 58 | } 59 | } else { 60 | if(textureCoordinate.y > dataIn + (0.5 - 0.01) && textureCoordinate.y < dataIn + 0.5 ){ 61 | outColor.r = (0.0 + color1.r ) / 2.0; 62 | outColor.g = (1.0 + color1.g ) / 2.0; 63 | outColor.b = (1.0 + color1.b ) / 2.0; 64 | outColor.a = 0.8; 65 | } 66 | } 67 | 68 | gl_FragColor = outColor; 69 | } 70 | ); 71 | 72 | @implementation CLRTwoInputImageFilter 73 | 74 | - (id)init 75 | { 76 | if (self != [super initWithFragmentShaderFromString:kCLRGPUImageFilterFragmentShaderString ]) { 77 | return nil; 78 | } 79 | 80 | //inputDataUniform = [filterProgram ] 81 | inputDataUniform = [filterProgram uniformIndex:@"dataIn"]; 82 | upDownUniform = [filterProgram uniformIndex:@"upDown"]; 83 | 84 | return self; 85 | } 86 | 87 | - (void)setInputData:(GLfloat)inputData{ 88 | _inputData = inputData; 89 | [self setFloat:_inputData forUniform:inputDataUniform program:filterProgram]; 90 | } 91 | 92 | - (void)setUpdown:(GLfloat)updown { 93 | _updown = updown; 94 | [self setFloat:_updown forUniform:upDownUniform program:filterProgram]; 95 | } 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /ImageEffect/CLRFilter/GPUImageUnsharpMaskFilter.h: -------------------------------------------------------------------------------- 1 | #import "GPUImageFilterGroup.h" 2 | 3 | @class GPUImageGaussianBlurFilter; 4 | 5 | @interface GPUImageUnsharpMaskFilter : GPUImageFilterGroup 6 | { 7 | GPUImageGaussianBlurFilter *blurFilter; 8 | GPUImageFilter *unsharpMaskFilter; 9 | } 10 | // The blur radius of the underlying Gaussian blur. The default is 4.0. 11 | @property (readwrite, nonatomic) CGFloat blurRadiusInPixels; 12 | 13 | // The strength of the sharpening, from 0.0 on up, with a default of 1.0 14 | @property(readwrite, nonatomic) CGFloat intensity; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /ImageEffect/CLRFilter/GPUImageUnsharpMaskFilter.m: -------------------------------------------------------------------------------- 1 | #import "GPUImageUnsharpMaskFilter.h" 2 | #import "GPUImageFilter.h" 3 | #import "GPUImageTwoInputFilter.h" 4 | #import "GPUImageGaussianBlurFilter.h" 5 | 6 | #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE 7 | NSString *const kGPUImageUnsharpMaskFragmentShaderString = SHADER_STRING 8 | ( 9 | varying highp vec2 textureCoordinate; 10 | varying highp vec2 textureCoordinate2; 11 | 12 | uniform sampler2D inputImageTexture; 13 | uniform sampler2D inputImageTexture2; 14 | 15 | uniform highp float intensity; 16 | 17 | void main() 18 | { 19 | lowp vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate); 20 | lowp vec3 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb; 21 | 22 | gl_FragColor = vec4(sharpImageColor.rgb * intensity + blurredImageColor * (1.0 - intensity), sharpImageColor.a); 23 | // gl_FragColor = mix(blurredImageColor, sharpImageColor, intensity); 24 | // gl_FragColor = vec4(sharpImageColor.rgb - (blurredImageColor.rgb * intensity), 1.0); 25 | } 26 | ); 27 | #else 28 | NSString *const kGPUImageUnsharpMaskFragmentShaderString = SHADER_STRING 29 | ( 30 | varying vec2 textureCoordinate; 31 | varying vec2 textureCoordinate2; 32 | 33 | uniform sampler2D inputImageTexture; 34 | uniform sampler2D inputImageTexture2; 35 | 36 | uniform float intensity; 37 | 38 | void main() 39 | { 40 | vec4 sharpImageColor = texture2D(inputImageTexture, textureCoordinate); 41 | vec3 blurredImageColor = texture2D(inputImageTexture2, textureCoordinate2).rgb; 42 | 43 | gl_FragColor = vec4(sharpImageColor.rgb * intensity + blurredImageColor * (1.0 - intensity), sharpImageColor.a); 44 | // gl_FragColor = mix(blurredImageColor, sharpImageColor, intensity); 45 | // gl_FragColor = vec4(sharpImageColor.rgb - (blurredImageColor.rgb * intensity), 1.0); 46 | } 47 | ); 48 | #endif 49 | 50 | @implementation GPUImageUnsharpMaskFilter 51 | 52 | @synthesize blurRadiusInPixels; 53 | @synthesize intensity = _intensity; 54 | 55 | - (id)init; 56 | { 57 | if (!(self = [super init])) 58 | { 59 | return nil; 60 | } 61 | 62 | // First pass: apply a variable Gaussian blur 63 | blurFilter = [[GPUImageGaussianBlurFilter alloc] init]; 64 | [self addFilter:blurFilter]; 65 | 66 | // Second pass: combine the blurred image with the original sharp one 67 | unsharpMaskFilter = [[GPUImageTwoInputFilter alloc] initWithFragmentShaderFromString:kGPUImageUnsharpMaskFragmentShaderString]; 68 | [self addFilter:unsharpMaskFilter]; 69 | 70 | // Texture location 0 needs to be the sharp image for both the blur and the second stage processing 71 | [blurFilter addTarget:unsharpMaskFilter atTextureLocation:1]; 72 | 73 | self.initialFilters = [NSArray arrayWithObjects:blurFilter, unsharpMaskFilter, nil]; 74 | self.terminalFilter = unsharpMaskFilter; 75 | 76 | self.intensity = 1.0; 77 | self.blurRadiusInPixels = 4.0; 78 | 79 | return self; 80 | } 81 | 82 | #pragma mark - 83 | #pragma mark Accessors 84 | 85 | - (void)setBlurRadiusInPixels:(CGFloat)newValue; 86 | { 87 | blurFilter.blurRadiusInPixels = newValue; 88 | } 89 | 90 | - (CGFloat)blurRadiusInPixels; 91 | { 92 | return blurFilter.blurRadiusInPixels; 93 | } 94 | 95 | - (void)setIntensity:(CGFloat)newValue; 96 | { 97 | _intensity = newValue; 98 | [unsharpMaskFilter setFloat:newValue forUniformName:@"intensity"]; 99 | } 100 | 101 | @end -------------------------------------------------------------------------------- /ImageEffect/GLView.h: -------------------------------------------------------------------------------- 1 | // 2 | // GLView.h 3 | // CLROpenGLES20 4 | // 5 | // Created by vk on 15/11/29. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import 13 | 14 | @interface GLView : UIView 15 | 16 | /** 17 | * openGL绘图层 18 | */ 19 | @property (nonatomic, strong) CAEAGLLayer *eaglLayer; 20 | /** 21 | * OpenGL上下文 22 | */ 23 | @property (nonatomic, strong) EAGLContext *context; 24 | /** 25 | * OpenGL颜色渲染Buffer 26 | */ 27 | @property (nonatomic, assign) GLuint colorRenderBuffer; 28 | 29 | - (void) rotateAxisY:(float)axisY andAxisX:(float)axisX; 30 | 31 | @end 32 | 33 | -------------------------------------------------------------------------------- /ImageEffect/GLView.m: -------------------------------------------------------------------------------- 1 | // 2 | // GLView.m 3 | // CLROpenGLES20 4 | // 5 | // Created by vk on 15/11/29. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | #import "GLView.h" 9 | #import "SHaderHelper.h" 10 | #import 11 | 12 | #define TEX_COORD_MAX 4 13 | /** 14 | * There are two types of shaders: 15 | Vertex shaders are programs that get called once per vertex in your scene. So if you are rendering a simple scene with a single square, with one vertex at each corner, this would be called four times. Its job is to perform some calculations such as lighting, geometry transforms, etc., figure out the final position of the vertex, and also pass on some data to the fragment shader. 16 | Fragment shaders are programs that get called once per pixel (sort of) in your scene. So if you’re rendering that same simple scene with a single square, it will be called once for each pixel that the square covers. Fragment shaders can also perform lighting calculations, etc, but their most important job is to set the final color for the pixel. 17 | */ 18 | 19 | typedef struct{ 20 | float Position[3]; 21 | float Color[4]; 22 | float TexCoord[2]; 23 | } Vertex; 24 | /* 25 | const Vertex Vertices[] = { 26 | {{1, -1, 0}, {1, 0, 0, 1}}, 27 | {{1, 1, 0}, {0, 1, 0, 1}}, 28 | {{-1, 1, 0}, {0, 0, 1, 1}}, 29 | {{-1, -1, 0}, {0, 0, 0, 1}} 30 | }; 31 | 32 | const GLubyte Indices[] = { 33 | 0, 1, 2, 34 | 2, 3, 0 35 | }; 36 | */ 37 | /* 38 | const Vertex Vertices[] = { 39 | {{1, -1, 1} , {1, 0, 0, 1}, {1, 0}}, 40 | {{1, 1, 1} , {1, 0, 0, 1}, {1, 1}}, 41 | {{-1, 1, 1} , {0, 1, 0, 1}, {0, 1}}, 42 | {{-1, -1, 1} , {0, 1, 0, 1}, {0, 0}}, 43 | {{1, -1, -1} , {1, 0, 0, 1}, {1, 0}}, 44 | {{1, 1, -1} , {1, 0, 0, 1}, {1, 1}}, 45 | {{-1, 1, -1} , {0, 1, 0, 1}, {0, 1}}, 46 | {{-1, -1, -1}, {0, 1, 0, 1}, {0, 0}} 47 | }; 48 | 49 | const GLubyte Indices[] = { 50 | // Front 51 | 0, 1, 2, 52 | 2, 3, 0, 53 | // Back 54 | 4, 6, 5, 55 | 4, 7, 6, 56 | // Left 57 | 2, 7, 3, 58 | 7, 6, 2, 59 | // Right 60 | 0, 4, 1, 61 | 4, 1, 5, 62 | // Top 63 | 6, 2, 1, 64 | 1, 6, 5, 65 | // Bottom 66 | 0, 3, 7, 67 | 0, 7, 4 68 | }; 69 | */ 70 | const Vertex Vertices[] = { 71 | // Front 72 | {{1, -1, 0}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, 73 | {{1, 1, 0}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, 74 | {{-1, 1, 0}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, 75 | {{-1, -1, 0}, {0, 0, 0, 1}, {0, 0}}, 76 | // Back 77 | {{1, 1, -2}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, 78 | {{-1, -1, -2}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, 79 | {{1, -1, -2}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, 80 | {{-1, 1, -2}, {0, 0, 0, 1}, {0, 0}}, 81 | // Left 82 | {{-1, -1, 0}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, 83 | {{-1, 1, 0}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, 84 | {{-1, 1, -2}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, 85 | {{-1, -1, -2}, {0, 0, 0, 1}, {0, 0}}, 86 | // Right 87 | {{1, -1, -2}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, 88 | {{1, 1, -2}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, 89 | {{1, 1, 0}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, 90 | {{1, -1, 0}, {0, 0, 0, 1}, {0, 0}}, 91 | // Top 92 | {{1, 1, 0}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, 93 | {{1, 1, -2}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, 94 | {{-1, 1, -2}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, 95 | {{-1, 1, 0}, {0, 0, 0, 1}, {0, 0}}, 96 | // Bottom 97 | {{1, -1, -2}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, 98 | {{1, -1, 0}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, 99 | {{-1, -1, 0}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, 100 | {{-1, -1, -2}, {0, 0, 0, 1}, {0, 0}} 101 | }; 102 | 103 | const GLubyte Indices[] = { 104 | // Front 105 | 0, 1, 2, 106 | 2, 3, 0, 107 | // Back 108 | 4, 5, 6, 109 | 4, 5, 7, 110 | // Left 111 | 8, 9, 10, 112 | 10, 11, 8, 113 | // Right 114 | 12, 13, 14, 115 | 14, 15, 12, 116 | // Top 117 | 16, 17, 18, 118 | 18, 19, 16, 119 | // Bottom 120 | 20, 21, 22, 121 | 22, 23, 20 122 | }; 123 | 124 | 125 | // 1) Add to top of file 126 | const Vertex Vertices2[] = { 127 | {{0.5, -0.5, 0.01}, {1, 1, 1, 1}, {1, 1}}, 128 | {{0.5, 0.5, 0.01}, {1, 1, 1, 1}, {1, 0}}, 129 | {{-0.5, 0.5, 0.01}, {1, 1, 1, 1}, {0, 0}}, 130 | {{-0.5, -0.5, 0.01}, {1, 1, 1, 1}, {0, 1}}, 131 | }; 132 | 133 | const GLubyte Indices2[] = { 134 | 1, 0, 2, 3 135 | }; 136 | 137 | @interface GLView () { 138 | GLfloat cubeAxisX; 139 | GLfloat cubeAxisY; 140 | } 141 | 142 | @property (nonatomic, assign) GLuint positionSlot; 143 | @property (nonatomic, assign) GLuint colorSlot; 144 | @property (nonatomic, assign) GLuint projectionUniform; 145 | @property (nonatomic, assign) GLuint modelViewUniform; 146 | @property (nonatomic, assign) GLKMatrix4 modelTMat; 147 | 148 | /** 149 | * texture variables 150 | */ 151 | @property (nonatomic, assign) GLuint floorTexture; 152 | @property (nonatomic, assign) GLuint fishTexture; 153 | @property (nonatomic, assign) GLuint texCoordSlot; 154 | @property (nonatomic, assign) GLuint textureUniform; 155 | 156 | @property (nonatomic, assign) GLuint vertexBuffer; 157 | @property (nonatomic, assign) GLuint indexBuffer; 158 | @property (nonatomic, assign) GLuint vertexBuffer2; 159 | @property (nonatomic, assign) GLuint indexBuffer2; 160 | 161 | @end 162 | 163 | @implementation GLView 164 | /** 165 | * To set up a view to display OpenGL content, you need to set it’s default layer to a special kind of layer called a CAEAGLLayer. The way you set the default layer is to simply overwrite the layerClass method, like you just did above. 166 | * 167 | * @return 168 | */ 169 | + (Class)layerClass { 170 | return [CAEAGLLayer class]; 171 | } 172 | 173 | - (id)initWithFrame:(CGRect)frame { 174 | if(self = [super initWithFrame:frame]) { 175 | [self setupLayer]; 176 | [self setupContext]; 177 | [self setupBuffer]; 178 | [self setupVBOs]; 179 | [self compileShaders]; 180 | [self setupProjection]; 181 | [self initTransform]; 182 | //[self render]; 183 | _floorTexture = [self setupTexture:@"tile_floor.png"]; 184 | _fishTexture = [self setupTexture:@"item_powerup_fish.png"]; 185 | [self setupDisplayLink]; 186 | //[self renderProcess]; 187 | //[self setupDisplayLink]; 188 | 189 | } 190 | return self; 191 | } 192 | 193 | - (void)setupDisplayLink { 194 | CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(renderFrame:)]; 195 | [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 196 | } 197 | 198 | /** 199 | * By default, CALayers are set to non-opaque (i.e. transparent). However, this is bad for performance reasons (especially with OpenGL), so it’s best to set this as opaque when possible. 200 | */ 201 | - (void)setupLayer { 202 | _eaglLayer = (CAEAGLLayer *)self.layer; 203 | _eaglLayer.opaque = YES; 204 | } 205 | 206 | - (void)setupContext { 207 | _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 208 | if (!_context) { 209 | NSLog(@"Failed to initialize OpenGLES 2.0 context"); 210 | exit(1); 211 | } 212 | if (![EAGLContext setCurrentContext:_context]) { 213 | NSLog(@"Failed to set current OpenGL context"); 214 | exit(1); 215 | } 216 | } 217 | /** 218 | * setup renderbuffer 219 | There are three steps to create a render buffer: 220 | 1.Call glGenRenderbuffers to create a new render buffer object. This returns a unique integer for the the render buffer (we store it here in _colorRenderBuffer). Sometimes you’ll see this unique integer referred to as an “OpenGL name.” 221 | 2.Call glBindRenderbuffer to tell OpenGL “whenever I refer to GL_RENDERBUFFER, I really mean _colorRenderBuffer.” 222 | 3.Finally, allocate some storage for the render buffer. The EAGLContext you created earlier has a method you can use for this called renderbufferStorage. 223 | 224 | * setup framebuffer 225 | The last function call (glFramebufferRenderbuffer) is new however. It lets you attach the render buffer you created earlier to the frame buffer’s GL_COLOR_ATTACHMENT0 slot. 226 | */ 227 | - (void)setupBuffer { 228 | 229 | /** 230 | * depthbuffer 231 | */ 232 | GLuint depthbuffer; 233 | glGenRenderbuffers(1, &depthbuffer); 234 | glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer); 235 | /* 236 | int width, height; 237 | glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); 238 | glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); 239 | glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); 240 | */ 241 | glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, self.frame.size.width, self.frame.size.height); 242 | /** 243 | * renderbuffer 244 | */ 245 | glGenRenderbuffers(1, &_colorRenderBuffer); 246 | glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer); 247 | [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer]; 248 | /** 249 | * framebuffer 250 | */ 251 | GLuint framebuffer; 252 | glGenFramebuffers(1, &framebuffer); 253 | glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 254 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer); 255 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer); 256 | 257 | } 258 | 259 | - (void)setupVBOs { 260 | //GLuint vertexBuffer; 261 | glGenBuffers(1, &_vertexBuffer); 262 | glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 263 | glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); 264 | 265 | glGenBuffers(1, &_indexBuffer); 266 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); 267 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW); 268 | 269 | glGenBuffers(1, &_vertexBuffer2); 270 | glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2); 271 | glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW); 272 | 273 | glGenBuffers(1, &_indexBuffer2); 274 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer2); 275 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices2), Indices2, GL_STATIC_DRAW); 276 | 277 | } 278 | 279 | -(void)setupProjection 280 | { 281 | // Generate a perspective matrix with a 60 degree FOV 282 | float aspect = self.frame.size.width / self.frame.size.height; 283 | GLKMatrix4 projectionMatrix; 284 | projectionMatrix = GLKMatrix4Identity; 285 | projectionMatrix = GLKMatrix4MakePerspective(80.0*M_PI/180, aspect, 0.5f, 2000.0f); 286 | // Load projection matrix 287 | //glUniformMatrix4fv(_projectionSlot, 1, GL_FALSE, (GLfloat*)&_projectionMatrix.m[0][0]); 288 | glUniformMatrix4fv(_projectionUniform, 1,GL_FALSE, &projectionMatrix.m[0]); 289 | //glEnable(GL_CULL_FACE); 290 | } 291 | 292 | - (void) initTransform{ 293 | _modelTMat = GLKMatrix4Identity; 294 | _modelTMat = GLKMatrix4Translate(_modelTMat, 0, 0, -7.0); 295 | glUniformMatrix4fv(_modelViewUniform, 1.0, GL_FALSE, _modelTMat.m); 296 | } 297 | 298 | - (void) setupTransform:(CADisplayLink *)displayLink { 299 | _modelTMat = GLKMatrix4Identity; 300 | _modelTMat = GLKMatrix4Translate(_modelTMat, sin(CACurrentMediaTime()), cos(CACurrentMediaTime()), -7.0); 301 | static float currentRotation = 0; 302 | 303 | currentRotation += displayLink.duration*90; 304 | _modelTMat = GLKMatrix4Rotate(_modelTMat, currentRotation*M_PI/180, 1, 1, 0); 305 | 306 | glUniformMatrix4fv(_modelViewUniform, 1.0, GL_FALSE, _modelTMat.m); 307 | } 308 | 309 | - (GLuint)setupTexture:(NSString *)fileName { 310 | // 1 311 | CGImageRef spriteImage = [UIImage imageNamed:fileName].CGImage; 312 | if (!spriteImage) { 313 | NSLog(@"Failed to load image %@", fileName); 314 | exit(1); 315 | } 316 | 317 | // 2 318 | size_t width = CGImageGetWidth(spriteImage); 319 | size_t height = CGImageGetHeight(spriteImage); 320 | 321 | GLubyte * spriteData = (GLubyte *) calloc(width*height*4, sizeof(GLubyte)); 322 | 323 | CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4, 324 | CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast); 325 | 326 | // 3 327 | CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage); 328 | 329 | CGContextRelease(spriteContext); 330 | 331 | // 4 332 | GLuint texName; 333 | glGenTextures(1, &texName); 334 | glBindTexture(GL_TEXTURE_2D, texName); 335 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 336 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData); 337 | 338 | free(spriteData); 339 | return texName; 340 | } 341 | 342 | 343 | - (void) updateColor { 344 | 345 | float rc = (sin(CACurrentMediaTime()) + 2.0) /2.0; 346 | /* 347 | const Vertex NewVertices[] = { 348 | {{1, -1, 0}, {rc, 0, 0, 1}}, 349 | {{1, 1, 0}, {0, 1, 0, 1}}, 350 | {{-1, 1, 0}, {0, 0, 1, 1}}, 351 | {{-1, -1, 0}, {0, 0, 0, 1}} 352 | }; 353 | */ 354 | 355 | const Vertex NewVertices[] = { 356 | {{1, -1, 1}, {rc, 0, 1.0-rc, 1} , {1, 0}}, 357 | {{1, 1, 1}, {rc, 0, 1.0-rc, 1} , {1, 1}}, 358 | {{-1, 1, 1}, {0, 1, 0, 1} , {0, 1}}, 359 | {{-1, -1, 1}, {0, 1, 0, 1} , {0, 0}}, 360 | {{1, -1, -1}, {rc, 0, 1.0-rc, 1} , {1, 0}}, 361 | {{1, 1, -1}, {rc, 0, 1.0-rc, 1} , {1, 1}}, 362 | {{-1, 1, -1}, {0, 1, 0, 1} , {0, 1}}, 363 | {{-1, -1, -1}, {0, 1, 0, 1} , {0, 0}} 364 | }; 365 | 366 | 367 | glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 368 | glBufferData(GL_ARRAY_BUFFER, sizeof(NewVertices), NewVertices, GL_STATIC_DRAW); 369 | } 370 | 371 | - (void)render:(CADisplayLink *)displayLink { 372 | 373 | glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 374 | glEnable(GL_BLEND); 375 | 376 | glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0); 377 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 378 | glEnable(GL_DEPTH_TEST); 379 | //[self updateColor]; 380 | [self setupTransform:displayLink]; 381 | 382 | // 1 383 | glViewport(0, 0, self.frame.size.width, self.frame.size.height); 384 | glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 385 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); 386 | 387 | // 2 388 | glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 389 | sizeof(Vertex), 0); 390 | glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, 391 | sizeof(Vertex), (GLvoid*) (sizeof(float) * 3)); 392 | 393 | 394 | glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, 395 | sizeof(Vertex), (GLvoid*) (sizeof(float) * 7)); 396 | 397 | glActiveTexture(GL_TEXTURE0); 398 | glBindTexture(GL_TEXTURE_2D, _floorTexture); 399 | glUniform1i(_textureUniform, 0); 400 | 401 | // 3 402 | glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]),GL_UNSIGNED_BYTE, 0); 403 | 404 | /** 405 | * texture2 406 | */ 407 | glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2); 408 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer2); 409 | 410 | glActiveTexture(GL_TEXTURE0); 411 | glBindTexture(GL_TEXTURE_2D, _fishTexture); 412 | glUniform1i(_textureUniform, 0); 413 | 414 | // glUniformMatrix4fv(_modelViewUniform, 1.0, GL_FALSE, _modelTMat.m); ?? 415 | 416 | glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); 417 | glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3)); 418 | glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7)); 419 | 420 | glDrawElements(GL_TRIANGLE_STRIP, sizeof(Indices2)/sizeof(Indices2[0]), GL_UNSIGNED_BYTE, 0); 421 | 422 | /** 423 | * Call a method on the OpenGL context to present the render/color buffer to the UIView’s layer! 424 | */ 425 | [_context presentRenderbuffer:GL_RENDERBUFFER]; 426 | } 427 | 428 | - (void)renderByCtrl:(CADisplayLink *)displayLink{ 429 | [self setupTransform:displayLink]; 430 | [self renderProcess]; 431 | } 432 | 433 | - (void)renderWall { 434 | 435 | 436 | } 437 | 438 | 439 | - (void)drawCube { 440 | 441 | glEnableVertexAttribArray(_positionSlot); 442 | glEnableVertexAttribArray(_colorSlot); 443 | glEnableVertexAttribArray(_texCoordSlot); 444 | glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 445 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); 446 | 447 | // 2 448 | glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 449 | sizeof(Vertex), 0); 450 | glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, 451 | sizeof(Vertex), (GLvoid*) (sizeof(float) * 3)); 452 | 453 | 454 | glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, 455 | sizeof(Vertex), (GLvoid*) (sizeof(float) * 7)); 456 | 457 | glActiveTexture(GL_TEXTURE0); 458 | glBindTexture(GL_TEXTURE_2D, _floorTexture); 459 | glUniform1i(_textureUniform, 0); 460 | 461 | // 3 462 | glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]),GL_UNSIGNED_BYTE, 0); 463 | 464 | /** 465 | * texture2 466 | */ 467 | glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2); 468 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer2); 469 | 470 | glActiveTexture(GL_TEXTURE0); 471 | glBindTexture(GL_TEXTURE_2D, _fishTexture); 472 | glUniform1i(_textureUniform, 0); 473 | 474 | // glUniformMatrix4fv(_modelViewUniform, 1.0, GL_FALSE, _modelTMat.m); ?? 475 | 476 | glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); 477 | glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3)); 478 | glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7)); 479 | 480 | glDrawElements(GL_TRIANGLE_STRIP, sizeof(Indices2)/sizeof(Indices2[0]), GL_UNSIGNED_BYTE, 0); 481 | glDisableVertexAttribArray(_positionSlot); 482 | glDisableVertexAttribArray(_colorSlot); 483 | glDisableVertexAttribArray(_texCoordSlot); 484 | 485 | } 486 | - (void)renderProcess { 487 | glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 488 | glEnable(GL_BLEND); 489 | glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0); 490 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 491 | glEnable(GL_DEPTH_TEST); 492 | //[self updateColor]; 493 | //[self setupTransform:displayLink]; 494 | // 1 495 | glViewport(0, 0, self.frame.size.width, self.frame.size.height); 496 | 497 | [self updateCubeTran]; 498 | [self drawCube]; 499 | /** 500 | * Call a method on the OpenGL context to present the render/color buffer to the UIView’s layer! 501 | */ 502 | [_context presentRenderbuffer:GL_RENDERBUFFER]; 503 | } 504 | 505 | - (void)compileShaders { 506 | 507 | // 1 508 | GLuint vertexShader = [SHaderHelper compileShader:@"SimpleVertex" 509 | withType:GL_VERTEX_SHADER]; 510 | GLuint fragmentShader = [SHaderHelper compileShader:@"SimpleFragment" 511 | withType:GL_FRAGMENT_SHADER]; 512 | 513 | // 2 514 | GLuint programHandle = glCreateProgram(); 515 | glAttachShader(programHandle, vertexShader); 516 | glAttachShader(programHandle, fragmentShader); 517 | glLinkProgram(programHandle); 518 | 519 | // 3 520 | GLint linkSuccess; 521 | glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess); 522 | if (linkSuccess == GL_FALSE) { 523 | GLchar messages[256]; 524 | glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]); 525 | NSString *messageString = [NSString stringWithUTF8String:messages]; 526 | NSLog(@"%@", messageString); 527 | exit(1); 528 | } 529 | 530 | // 4 531 | glUseProgram(programHandle); 532 | 533 | // 5 534 | _positionSlot = glGetAttribLocation(programHandle, "Position"); 535 | _colorSlot = glGetAttribLocation(programHandle, "SourceColor"); 536 | _projectionUniform = glGetUniformLocation(programHandle, "Projection"); 537 | _modelViewUniform = glGetUniformLocation(programHandle, "ModelView"); 538 | 539 | _texCoordSlot = glGetAttribLocation(programHandle, "TexCoordIn"); 540 | _textureUniform = glGetUniformLocation(programHandle, "Texture"); 541 | } 542 | 543 | #pragma touch move 544 | - (void) rotateAxisY:(float)axisY andAxisX:(float)axisX { 545 | 546 | //_modelTMat = GLKMatrix4Identity; 547 | //_modelTMat = GLKMatrix4Translate(_modelTMat, 0, 0, -7.0); 548 | //_modelTMat = GLKMatrix4Translate(_modelTMat, sin(CACurrentMediaTime()), cos(CACurrentMediaTime()), -7.0); 549 | //static float currentRotation = 0; 550 | //currentRotation += displayLink.duration*90; 551 | //_modelTMat = GLKMatrix4Rotate(_modelTMat, axisX*M_PI/180, axisY*M_PI/180, 1, 0); 552 | 553 | //_modelTMat = GLKMatrix4Rotate(_modelTMat, axisX*M_PI/180, 1, 0, 0); 554 | //_modelTMat = GLKMatrix4Rotate(_modelTMat, axisY*M_PI/180, 0, 1, 0); 555 | cubeAxisX = axisX; 556 | cubeAxisY = axisY; 557 | } 558 | 559 | - (void) updateCubeTran { 560 | GLKMatrix4 xR = GLKMatrix4MakeXRotation(cubeAxisX*M_PI/180); 561 | GLKMatrix4 yR = GLKMatrix4MakeYRotation(cubeAxisY*M_PI/180); 562 | _modelTMat = GLKMatrix4Multiply(_modelTMat, xR); 563 | _modelTMat = GLKMatrix4Multiply(_modelTMat, yR); 564 | glUniformMatrix4fv(_modelViewUniform, 1.0, GL_FALSE, _modelTMat.m); 565 | cubeAxisX = 0; 566 | cubeAxisY = 0; 567 | } 568 | 569 | - (void) renderFrame:(CADisplayLink *)displayLink { 570 | [self renderProcess]; 571 | } 572 | 573 | @end 574 | -------------------------------------------------------------------------------- /ImageEffect/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | UIFileSharingEnabled 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /ImageEffect/SHaderHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // SHaderHelper.h 3 | // CLROpenGLES20 4 | // 5 | // Created by vk on 15/11/29. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | @interface SHaderHelper : NSObject 14 | 15 | + (GLuint)compileShader:(NSString*)shaderName withType:(GLenum)shaderType; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ImageEffect/SHaderHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // SHaderHelper.m 3 | // CLROpenGLES20 4 | // 5 | // Created by vk on 15/11/29. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import "SHaderHelper.h" 10 | 11 | @implementation SHaderHelper 12 | + (GLuint)compileShader:(NSString*)shaderName withType:(GLenum)shaderType { 13 | 14 | // 1 15 | NSString* shaderPath = [[NSBundle mainBundle] pathForResource:shaderName 16 | ofType:@"glsl"]; 17 | NSError* error; 18 | NSString* shaderString = [NSString stringWithContentsOfFile:shaderPath 19 | encoding:NSUTF8StringEncoding error:&error]; 20 | if (!shaderString) { 21 | NSLog(@"Error loading shader: %@", error.localizedDescription); 22 | exit(1); 23 | } 24 | 25 | // 2 26 | GLuint shaderHandle = glCreateShader(shaderType); 27 | 28 | // 3 29 | const char * shaderStringUTF8 = [shaderString UTF8String]; 30 | GLint shaderStringLength = (GLint)shaderString.length; 31 | glShaderSource(shaderHandle, 1, &shaderStringUTF8, &shaderStringLength); 32 | 33 | // 4 34 | glCompileShader(shaderHandle); 35 | 36 | // 5 37 | GLint compileSuccess; 38 | glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess); 39 | if (compileSuccess == GL_FALSE) { 40 | GLchar messages[256]; 41 | glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]); 42 | NSString *messageString = [NSString stringWithUTF8String:messages]; 43 | NSLog(@"%@", messageString); 44 | exit(1); 45 | } 46 | 47 | return shaderHandle; 48 | 49 | } 50 | @end 51 | -------------------------------------------------------------------------------- /ImageEffect/ScreenShot/ImageEffect.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/celesius/ImageEffect/16588286e2336f3ead32ecf035b19a1cbbc17e9f/ImageEffect/ScreenShot/ImageEffect.gif -------------------------------------------------------------------------------- /ImageEffect/SimpleFragment.glsl: -------------------------------------------------------------------------------- 1 | varying highp vec4 DestinationColor; 2 | varying highp vec2 TexCoordOut; 3 | uniform sampler2D Texture; 4 | 5 | void main(void) { 6 | gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut); 7 | } -------------------------------------------------------------------------------- /ImageEffect/SimpleVertex.glsl: -------------------------------------------------------------------------------- 1 | attribute vec4 Position; 2 | attribute vec4 SourceColor; 3 | 4 | uniform mat4 Projection; 5 | uniform mat4 ModelView; 6 | 7 | varying vec4 DestinationColor; 8 | 9 | attribute vec2 TexCoordIn; 10 | varying vec2 TexCoordOut; 11 | 12 | void main (void) { 13 | DestinationColor = SourceColor; 14 | gl_Position = Projection * ModelView * Position; 15 | TexCoordOut = TexCoordIn; 16 | } -------------------------------------------------------------------------------- /ImageEffect/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ImageEffect 4 | // 5 | // Created by vk on 15/12/10. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ImageEffect/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ImageEffect 4 | // 5 | // Created by vk on 15/12/10. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import 11 | #import "CLRFilter/CLRGPUImageFiler.h" 12 | #import 13 | #import "GLView.h" 14 | 15 | #define clamp(a) (a>255?255:(a<0?0:a)); 16 | 17 | //#define DEBUG_CAPTURE_DISPLAY 18 | 19 | @interface ViewController () 20 | { 21 | float moveX; 22 | float moveY; 23 | CGPoint lastTouch; 24 | } 25 | 26 | //@property (nonatomic, strong) GPUImageStillCamera *stillCamera; 27 | @property (nonatomic, strong) GPUImageVideoCamera *stillCamera; 28 | @property (nonatomic, strong) GPUImageCannyEdgeDetectionFilter *cannyEdgeFilter; 29 | @property (nonatomic, strong) CLRGPUImageFiler *clrFilter; 30 | /** 31 | * 测试取得未处理图像显示用view,不需要的话可以去掉 32 | */ 33 | @property (nonatomic, strong) UIImageView *myView; 34 | /** 35 | * 测试GL显示的View,不需要的话可以去掉 36 | */ 37 | @property (nonatomic, strong) GLView *glView; 38 | 39 | @end 40 | 41 | @implementation ViewController 42 | 43 | - (void)viewDidLoad { 44 | [super viewDidLoad]; 45 | 46 | _stillCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetPhoto cameraPosition:AVCaptureDevicePositionBack]; 47 | _stillCamera.outputImageOrientation = UIInterfaceOrientationPortrait; 48 | 49 | _stillCamera.delegate = self; 50 | //_stillCamera.frameRate = 30; 51 | 52 | GPUImageView *filteredVideoView = [[GPUImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.bounds.size.width, CGRectGetHeight(self.view.bounds))]; 53 | _clrFilter = [[CLRGPUImageFiler alloc]init]; 54 | 55 | _cannyEdgeFilter = [[GPUImageCannyEdgeDetectionFilter alloc] init]; 56 | [_stillCamera addTarget: _clrFilter]; 57 | [_clrFilter addTarget:filteredVideoView]; 58 | 59 | [_stillCamera startCameraCapture]; 60 | [self.view addSubview:filteredVideoView]; 61 | 62 | #ifdef DEBUG_CAPTURE_DISPLAY 63 | _myView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 10, 60, 80)]; 64 | [self.view addSubview:_myView]; 65 | 66 | _glView = [[GLView alloc]initWithFrame:CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds), CGRectGetWidth(self.view.bounds)/2.0, CGRectGetHeight(self.view.bounds)/2.0)]; 67 | [self.view addSubview:_glView]; 68 | #endif 69 | 70 | [self setupDisplayLink]; 71 | 72 | // Do any additional setup after loading the view, typically from a nib. 73 | } 74 | 75 | - (void)setupDisplayLink { 76 | CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(refreshDisp:)]; 77 | [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 78 | } 79 | 80 | - (void)refreshDisp:(CADisplayLink *)displayLink { 81 | static float timeLast = 0; 82 | float time = sin( CACurrentMediaTime() ); 83 | time = (((time + 1.0)/2.0) * 1.5 ) - 0.5; 84 | if((time - timeLast) > 0.0) { 85 | _clrFilter.upDown = 0.6; 86 | } 87 | else { 88 | _clrFilter.upDown = 0.0; 89 | } 90 | timeLast = time; 91 | _clrFilter.inputData = time; 92 | } 93 | 94 | - (void)willOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer { 95 | 96 | UIImage *getImage = [[UIImage alloc]initWithCGImage:[self imageFromSampleBuffer:sampleBuffer].CGImage scale:[UIScreen mainScreen].scale orientation:UIImageOrientationRight]; //[self imageFromSampleBuffer:sampleBuffer]; 97 | 98 | NSLog(@"%@",getImage.description); 99 | NSLog(@"%d",getImage.imageOrientation); 100 | 101 | dispatch_async(dispatch_get_main_queue(), ^{ 102 | _myView.image = getImage; 103 | }); 104 | } 105 | 106 | - (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer 107 | { 108 | // Get a CMSampleBuffer's Core Video image buffer for the media data 109 | CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 110 | // Lock the base address of the pixel buffer 111 | CVPixelBufferLockBaseAddress(imageBuffer, 0); 112 | 113 | // Get the number of bytes per row for the pixel buffer 114 | void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 115 | 116 | // Get the number of bytes per row for the pixel buffer 117 | size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 118 | // Get the pixel buffer width and height 119 | size_t width = CVPixelBufferGetWidth(imageBuffer); 120 | size_t height = CVPixelBufferGetHeight(imageBuffer); 121 | NSLog(@"vv %d ",(int)bytesPerRow ); 122 | 123 | 124 | //CVPlanarPixelBufferInfo_YCbCrBiPlanar *bufferInfo = (CVPlanarPixelBufferInfo_YCbCrBiPlanar *)baseAddress; 125 | //get the cbrbuffer base address 126 | //uint8_t* cbrBuff = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 1); 127 | 128 | // This just moved the pointer past the offset 129 | baseAddress = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0); 130 | 131 | // UIImage *image = [self makeUIImage:baseAddress bufferInfo:bufferInfo width:width height:height bytesPerRow:bytesPerRow]; 132 | // UIImage *image = [self makeUIImage:baseAddress cBCrBuffer:cbrBuff bufferInfo:bufferInfo width:width height:height bytesPerRow:bytesPerRow]; 133 | 134 | // Create a device-dependent RGB color space 135 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 136 | 137 | 138 | // Create a bitmap graphics context with the sample buffer data 139 | CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, 140 | bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 141 | // Create a Quartz image from the pixel data in the bitmap graphics context 142 | CGImageRef quartzImage = CGBitmapContextCreateImage(context); 143 | 144 | 145 | // Unlock the pixel buffer 146 | CVPixelBufferUnlockBaseAddress(imageBuffer,0); 147 | 148 | 149 | // Free up the context and color space 150 | CGContextRelease(context); 151 | CGColorSpaceRelease(colorSpace); 152 | 153 | // Create an image object from the Quartz image 154 | UIImage *image = [UIImage imageWithCGImage:quartzImage]; 155 | 156 | // Release the Quartz image 157 | CGImageRelease(quartzImage); 158 | 159 | NSLog(@"%d",image.imageOrientation); 160 | 161 | return (image); 162 | } 163 | 164 | 165 | - (UIImage *)makeUIImage:(uint8_t *)inBaseAddress bufferInfo:(CVPlanarPixelBufferInfo_YCbCrBiPlanar *)inBufferInfo width:(size_t)inWidth height:(size_t)inHeight bytesPerRow:(size_t)inBytesPerRow { 166 | 167 | NSUInteger yPitch = EndianU32_BtoN(inBufferInfo->componentInfoY.rowBytes); 168 | 169 | uint8_t *rgbBuffer = (uint8_t *)malloc(inWidth * inHeight * 4); 170 | uint8_t *yBuffer = (uint8_t *)inBaseAddress; 171 | uint8_t val; 172 | int bytesPerPixel = 4; 173 | 174 | // for each byte in the input buffer, fill in the output buffer with four bytes 175 | // the first byte is the Alpha channel, then the next three contain the same 176 | // value of the input buffer 177 | for(int y = 0; y < inHeight*inWidth; y++) 178 | { 179 | val = yBuffer[y]; 180 | // Alpha channel 181 | rgbBuffer[(y*bytesPerPixel)] = 0xff; 182 | 183 | // next three bytes same as input 184 | rgbBuffer[(y*bytesPerPixel)+1] = rgbBuffer[(y*bytesPerPixel)+2] = rgbBuffer[y*bytesPerPixel+3] = val; 185 | } 186 | 187 | // Create a device-dependent RGB color space 188 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 189 | 190 | CGContextRef context = CGBitmapContextCreate(rgbBuffer, yPitch, inHeight, 8, 191 | yPitch*bytesPerPixel, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast); 192 | 193 | CGImageRef quartzImage = CGBitmapContextCreateImage(context); 194 | 195 | CGContextRelease(context); 196 | CGColorSpaceRelease(colorSpace); 197 | 198 | UIImage *image = [UIImage imageWithCGImage:quartzImage]; 199 | 200 | CGImageRelease(quartzImage); 201 | free(rgbBuffer); 202 | return image; 203 | } 204 | 205 | - (UIImage *)makeUIImage:(uint8_t *)inBaseAddress cBCrBuffer:(uint8_t*)cbCrBuffer bufferInfo:(CVPlanarPixelBufferInfo_YCbCrBiPlanar *)inBufferInfo width:(size_t)inWidth height:(size_t)inHeight bytesPerRow:(size_t)inBytesPerRow { 206 | 207 | NSUInteger yPitch = EndianU32_BtoN(inBufferInfo->componentInfoY.rowBytes); 208 | NSUInteger cbCrOffset = EndianU32_BtoN(inBufferInfo->componentInfoCbCr.offset); 209 | uint8_t *rgbBuffer = (uint8_t *)malloc(inWidth * inHeight * 4); 210 | NSUInteger cbCrPitch = EndianU32_BtoN(inBufferInfo->componentInfoCbCr.rowBytes); 211 | uint8_t *yBuffer = (uint8_t *)inBaseAddress; 212 | //uint8_t *cbCrBuffer = inBaseAddress + cbCrOffset; 213 | uint8_t val; 214 | int bytesPerPixel = 4; 215 | 216 | for(int y = 0; y < inHeight; y++) 217 | { 218 | uint8_t *rgbBufferLine = &rgbBuffer[y * inWidth * bytesPerPixel]; 219 | uint8_t *yBufferLine = &yBuffer[y * yPitch]; 220 | uint8_t *cbCrBufferLine = &cbCrBuffer[(y >> 1) * cbCrPitch]; 221 | 222 | for(int x = 0; x < inWidth; x++) 223 | { 224 | int16_t y = yBufferLine[x]; 225 | int16_t cb = cbCrBufferLine[x & ~1] - 128; 226 | int16_t cr = cbCrBufferLine[x | 1] - 128; 227 | 228 | uint8_t *rgbOutput = &rgbBufferLine[x*bytesPerPixel]; 229 | 230 | int16_t r = (int16_t)roundf( y + cr * 1.4 ); 231 | int16_t g = (int16_t)roundf( y + cb * -0.343 + cr * -0.711 ); 232 | int16_t b = (int16_t)roundf( y + cb * 1.765); 233 | 234 | //ABGR 235 | rgbOutput[0] = 0xff; 236 | rgbOutput[1] = clamp(b); 237 | rgbOutput[2] = clamp(g); 238 | rgbOutput[3] = clamp(r); 239 | } 240 | } 241 | 242 | // Create a device-dependent RGB color space 243 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 244 | NSLog(@"ypitch:%lu inHeight:%zu bytesPerPixel:%d",(unsigned long)yPitch,inHeight,bytesPerPixel); 245 | NSLog(@"cbcrPitch:%lu",cbCrPitch); 246 | CGContextRef context = CGBitmapContextCreate(rgbBuffer, inWidth, inHeight, 8, 247 | inWidth*bytesPerPixel, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast); 248 | 249 | CGImageRef quartzImage = CGBitmapContextCreateImage(context); 250 | 251 | CGContextRelease(context); 252 | CGColorSpaceRelease(colorSpace); 253 | 254 | UIImage *image = [UIImage imageWithCGImage:quartzImage]; 255 | 256 | CGImageRelease(quartzImage); 257 | free(rgbBuffer); 258 | return image; 259 | } 260 | 261 | #pragma touch screen 262 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 263 | UITouch *touch = [touches anyObject]; 264 | CGPoint location =[touch locationInView:_glView]; 265 | moveX = 0; 266 | moveY = 0; 267 | lastTouch = location; 268 | } 269 | 270 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 271 | UITouch *touch = [touches anyObject]; 272 | CGPoint location =[touch locationInView:_glView]; 273 | moveX = location.x - lastTouch.x; 274 | moveY = location.y - lastTouch.y; 275 | lastTouch = location; 276 | NSLog(@" XM = %f XY = %f ", moveX, moveY); 277 | [self.glView rotateAxisY:moveX andAxisX:moveY]; 278 | } 279 | 280 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 281 | UITouch *touch = [touches anyObject]; 282 | CGPoint location =[touch locationInView:_glView]; 283 | moveX = location.x - lastTouch.x; 284 | moveY = location.y - lastTouch.y; 285 | lastTouch = location; 286 | } 287 | 288 | - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 289 | 290 | } 291 | 292 | 293 | - (void)didReceiveMemoryWarning { 294 | [super didReceiveMemoryWarning]; 295 | // Dispose of any resources that can be recreated. 296 | } 297 | 298 | @end 299 | -------------------------------------------------------------------------------- /ImageEffect/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ImageEffect 4 | // 5 | // Created by vk on 15/12/10. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ImageEffectTests/ImageEffectTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ImageEffectTests.m 3 | // ImageEffectTests 4 | // 5 | // Created by vk on 15/12/10. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ImageEffectTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ImageEffectTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /ImageEffectTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ImageEffectUITests/ImageEffectUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ImageEffectUITests.m 3 | // ImageEffectUITests 4 | // 5 | // Created by vk on 15/12/10. 6 | // Copyright © 2015年 clover. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ImageEffectUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ImageEffectUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /ImageEffectUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ImageEffect 2 | 用GPUImage实现部分视觉效果
3 | 2015.12.10
4 | 首先添加一个扫描线的视觉效果
5 | 思路:原图与边缘图合并输出,边缘图用渐变蓝色.
6 | 1、用GL合并两个图层然后显示(感觉较复杂,不过可以用于静态图扫描效果)
7 | 2、用GPUImage实时滤镜合并两个图层(看着较简单,感觉只能在动态图上修改)
8 | 9 | 2015.12.11
10 | 1、已经利用GPUImage完成了扫描效果,效果图如下:
11 | ![alt tag](https://github.com/celesius/ImageEffect/blob/master/ImageEffect/ScreenShot/ImageEffect.gif)
12 | 2、后续用尝试使用OpenGL实现此效果
13 | -------------------------------------------------------------------------------- /README.md~: -------------------------------------------------------------------------------- 1 | # ImageEffect 2 | 用GPUImage实现部分视觉效果 3 | 2015.12.10 4 | 1、首先添加一个扫描线的视觉效果 5 | 思路:原图与边缘图合并输出,边缘图用渐变蓝色 6 | --------------------------------------------------------------------------------