├── .gitignore ├── DCPaintBoard.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── DCPaintBoard ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── Particle.imageset │ │ ├── Contents.json │ │ ├── Particle.png │ │ └── Particle@2x.png │ ├── black.imageset │ │ ├── Contents.json │ │ ├── black.png │ │ └── black@2x.png │ ├── blue.imageset │ │ ├── Contents.json │ │ ├── blue.png │ │ └── blue@2x.png │ ├── btn_eraser.imageset │ │ ├── Contents.json │ │ ├── btn_eraser.png │ │ └── btn_eraser@2x.png │ ├── btn_eraser_press.imageset │ │ ├── Contents.json │ │ ├── btn_eraser_press.png │ │ └── btn_eraser_press@2x.png │ ├── btn_mark_black.imageset │ │ ├── Contents.json │ │ ├── btn_mark_black.png │ │ └── btn_mark_black@2x.png │ ├── btn_mark_blue.imageset │ │ ├── Contents.json │ │ ├── btn_mark_blue.png │ │ └── btn_mark_blue@2x.png │ ├── btn_mark_green.imageset │ │ ├── Contents.json │ │ ├── btn_mark_green.png │ │ └── btn_mark_green@2x.png │ ├── btn_mark_red.imageset │ │ ├── Contents.json │ │ ├── btn_mark_red.png │ │ └── btn_mark_red@2x.png │ ├── down.imageset │ │ ├── Contents.json │ │ ├── down.png │ │ └── down@2x.png │ ├── green.imageset │ │ ├── Contents.json │ │ ├── green.png │ │ └── green@2x.png │ ├── nomal.imageset │ │ ├── Contents.json │ │ └── nomal.png │ ├── red.imageset │ │ ├── Contents.json │ │ ├── red.png │ │ └── red@2x.png │ └── select.imageset │ │ ├── Contents.json │ │ └── select.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── DCCommon.h ├── Info.plist ├── PaintBoard │ ├── BeziPathPaint │ │ ├── DCBeizierPath.h │ │ ├── DCBeizierPath.m │ │ ├── DCBezierPaintBoard.h │ │ └── DCBezierPaintBoard.m │ ├── OpenGLPaint │ │ ├── DCOpenGLDrawView.h │ │ ├── DCOpenGLDrawView.m │ │ ├── Shaders │ │ │ ├── point.fsh │ │ │ └── point.vsh │ │ ├── UIView+Frame.h │ │ ├── UIView+Frame.m │ │ ├── UtilSrc │ │ │ ├── debug.h │ │ │ ├── fileUtil.h │ │ │ ├── fileUtil.m │ │ │ ├── shaderUtil.c │ │ │ └── shaderUtil.h │ │ └── 说明.h │ └── UndoBezipath │ │ ├── DCUndoBeziPathPaintBoard.h │ │ └── DCUndoBeziPathPaintBoard.m ├── ViewController.h ├── ViewController.m └── main.m ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | 20 | ## Other 21 | *.xccheckout 22 | *.moved-aside 23 | *.xcuserstate 24 | *.xcscmblueprint 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | -------------------------------------------------------------------------------- /DCPaintBoard.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1822BDA71CCFBB81005BEFED /* DCUndoBeziPathPaintBoard.m in Sources */ = {isa = PBXBuildFile; fileRef = 1822BDA61CCFBB81005BEFED /* DCUndoBeziPathPaintBoard.m */; }; 11 | 1824B25A1CCE71CF00EEB2C6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1824B2591CCE71CF00EEB2C6 /* main.m */; }; 12 | 1824B25D1CCE71CF00EEB2C6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1824B25C1CCE71CF00EEB2C6 /* AppDelegate.m */; }; 13 | 1824B2601CCE71CF00EEB2C6 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1824B25F1CCE71CF00EEB2C6 /* ViewController.m */; }; 14 | 1824B2631CCE71CF00EEB2C6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1824B2611CCE71CF00EEB2C6 /* Main.storyboard */; }; 15 | 1824B2651CCE71CF00EEB2C6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1824B2641CCE71CF00EEB2C6 /* Assets.xcassets */; }; 16 | 1824B2681CCE71CF00EEB2C6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1824B2661CCE71CF00EEB2C6 /* LaunchScreen.storyboard */; }; 17 | 1824B2771CCFA6C700EEB2C6 /* DCBezierPaintBoard.m in Sources */ = {isa = PBXBuildFile; fileRef = 1824B2761CCFA6C700EEB2C6 /* DCBezierPaintBoard.m */; }; 18 | 1824B27A1CCFA6E200EEB2C6 /* DCBeizierPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 1824B2791CCFA6E200EEB2C6 /* DCBeizierPath.m */; }; 19 | 18F9431D1CD2642800240C0B /* UIView+Frame.m in Sources */ = {isa = PBXBuildFile; fileRef = 18F9431C1CD2642800240C0B /* UIView+Frame.m */; }; 20 | 18FCB85A1CD10662008E90E4 /* DCOpenGLDrawView.m in Sources */ = {isa = PBXBuildFile; fileRef = 18FCB8591CD10662008E90E4 /* DCOpenGLDrawView.m */; }; 21 | 18FCB8651CD107D1008E90E4 /* point.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 18FCB85D1CD107D1008E90E4 /* point.fsh */; }; 22 | 18FCB8661CD107D1008E90E4 /* point.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 18FCB85E1CD107D1008E90E4 /* point.vsh */; }; 23 | 18FCB8671CD107D1008E90E4 /* fileUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 18FCB8621CD107D1008E90E4 /* fileUtil.m */; }; 24 | 18FCB8681CD107D1008E90E4 /* shaderUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = 18FCB8631CD107D1008E90E4 /* shaderUtil.c */; }; 25 | 18FCB86A1CD10800008E90E4 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18FCB8691CD10800008E90E4 /* OpenGLES.framework */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 1822BDA51CCFBB81005BEFED /* DCUndoBeziPathPaintBoard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DCUndoBeziPathPaintBoard.h; sourceTree = ""; }; 30 | 1822BDA61CCFBB81005BEFED /* DCUndoBeziPathPaintBoard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DCUndoBeziPathPaintBoard.m; sourceTree = ""; }; 31 | 1824B2551CCE71CF00EEB2C6 /* DCPaintBoard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DCPaintBoard.app; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | 1824B2591CCE71CF00EEB2C6 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 33 | 1824B25B1CCE71CF00EEB2C6 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 34 | 1824B25C1CCE71CF00EEB2C6 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 35 | 1824B25E1CCE71CF00EEB2C6 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 36 | 1824B25F1CCE71CF00EEB2C6 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 37 | 1824B2621CCE71CF00EEB2C6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 38 | 1824B2641CCE71CF00EEB2C6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 39 | 1824B2671CCE71CF00EEB2C6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 40 | 1824B2691CCE71CF00EEB2C6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | 1824B2731CCE796700EEB2C6 /* DCCommon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DCCommon.h; sourceTree = ""; }; 42 | 1824B2751CCFA6C700EEB2C6 /* DCBezierPaintBoard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DCBezierPaintBoard.h; sourceTree = ""; }; 43 | 1824B2761CCFA6C700EEB2C6 /* DCBezierPaintBoard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DCBezierPaintBoard.m; sourceTree = ""; }; 44 | 1824B2781CCFA6E200EEB2C6 /* DCBeizierPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DCBeizierPath.h; sourceTree = ""; }; 45 | 1824B2791CCFA6E200EEB2C6 /* DCBeizierPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DCBeizierPath.m; sourceTree = ""; }; 46 | 18F9431B1CD2642800240C0B /* UIView+Frame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Frame.h"; sourceTree = ""; }; 47 | 18F9431C1CD2642800240C0B /* UIView+Frame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Frame.m"; sourceTree = ""; }; 48 | 18FCB8581CD10662008E90E4 /* DCOpenGLDrawView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DCOpenGLDrawView.h; sourceTree = ""; }; 49 | 18FCB8591CD10662008E90E4 /* DCOpenGLDrawView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DCOpenGLDrawView.m; sourceTree = ""; }; 50 | 18FCB85B1CD107D1008E90E4 /* 说明.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "说明.h"; sourceTree = ""; }; 51 | 18FCB85D1CD107D1008E90E4 /* point.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = point.fsh; sourceTree = ""; }; 52 | 18FCB85E1CD107D1008E90E4 /* point.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = point.vsh; sourceTree = ""; }; 53 | 18FCB8601CD107D1008E90E4 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = ""; }; 54 | 18FCB8611CD107D1008E90E4 /* fileUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fileUtil.h; sourceTree = ""; }; 55 | 18FCB8621CD107D1008E90E4 /* fileUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = fileUtil.m; sourceTree = ""; }; 56 | 18FCB8631CD107D1008E90E4 /* shaderUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = shaderUtil.c; sourceTree = ""; }; 57 | 18FCB8641CD107D1008E90E4 /* shaderUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shaderUtil.h; sourceTree = ""; }; 58 | 18FCB8691CD10800008E90E4 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; 59 | /* End PBXFileReference section */ 60 | 61 | /* Begin PBXFrameworksBuildPhase section */ 62 | 1824B2521CCE71CF00EEB2C6 /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | 18FCB86A1CD10800008E90E4 /* OpenGLES.framework in Frameworks */, 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXFrameworksBuildPhase section */ 71 | 72 | /* Begin PBXGroup section */ 73 | 1822BDA41CCFBB61005BEFED /* UndoBezipath */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 1822BDA51CCFBB81005BEFED /* DCUndoBeziPathPaintBoard.h */, 77 | 1822BDA61CCFBB81005BEFED /* DCUndoBeziPathPaintBoard.m */, 78 | ); 79 | path = UndoBezipath; 80 | sourceTree = ""; 81 | }; 82 | 1824B24C1CCE71CF00EEB2C6 = { 83 | isa = PBXGroup; 84 | children = ( 85 | 18FCB8691CD10800008E90E4 /* OpenGLES.framework */, 86 | 1824B2571CCE71CF00EEB2C6 /* DCPaintBoard */, 87 | 1824B2561CCE71CF00EEB2C6 /* Products */, 88 | ); 89 | sourceTree = ""; 90 | }; 91 | 1824B2561CCE71CF00EEB2C6 /* Products */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 1824B2551CCE71CF00EEB2C6 /* DCPaintBoard.app */, 95 | ); 96 | name = Products; 97 | sourceTree = ""; 98 | }; 99 | 1824B2571CCE71CF00EEB2C6 /* DCPaintBoard */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 1824B26F1CCE71EC00EEB2C6 /* PaintBoard */, 103 | 1824B25B1CCE71CF00EEB2C6 /* AppDelegate.h */, 104 | 1824B25C1CCE71CF00EEB2C6 /* AppDelegate.m */, 105 | 1824B25E1CCE71CF00EEB2C6 /* ViewController.h */, 106 | 1824B25F1CCE71CF00EEB2C6 /* ViewController.m */, 107 | 1824B2731CCE796700EEB2C6 /* DCCommon.h */, 108 | 1824B2611CCE71CF00EEB2C6 /* Main.storyboard */, 109 | 1824B2641CCE71CF00EEB2C6 /* Assets.xcassets */, 110 | 1824B2661CCE71CF00EEB2C6 /* LaunchScreen.storyboard */, 111 | 1824B2691CCE71CF00EEB2C6 /* Info.plist */, 112 | 1824B2581CCE71CF00EEB2C6 /* Supporting Files */, 113 | ); 114 | path = DCPaintBoard; 115 | sourceTree = ""; 116 | }; 117 | 1824B2581CCE71CF00EEB2C6 /* Supporting Files */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 1824B2591CCE71CF00EEB2C6 /* main.m */, 121 | ); 122 | name = "Supporting Files"; 123 | sourceTree = ""; 124 | }; 125 | 1824B26F1CCE71EC00EEB2C6 /* PaintBoard */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 18FCB8571CD1064E008E90E4 /* OpenGLPaint */, 129 | 1822BDA41CCFBB61005BEFED /* UndoBezipath */, 130 | 1824B2741CCFA6C700EEB2C6 /* BeziPathPaint */, 131 | ); 132 | path = PaintBoard; 133 | sourceTree = ""; 134 | }; 135 | 1824B2741CCFA6C700EEB2C6 /* BeziPathPaint */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 1824B2751CCFA6C700EEB2C6 /* DCBezierPaintBoard.h */, 139 | 1824B2761CCFA6C700EEB2C6 /* DCBezierPaintBoard.m */, 140 | 1824B2781CCFA6E200EEB2C6 /* DCBeizierPath.h */, 141 | 1824B2791CCFA6E200EEB2C6 /* DCBeizierPath.m */, 142 | ); 143 | path = BeziPathPaint; 144 | sourceTree = ""; 145 | }; 146 | 18FCB8571CD1064E008E90E4 /* OpenGLPaint */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 18FCB85B1CD107D1008E90E4 /* 说明.h */, 150 | 18F9431B1CD2642800240C0B /* UIView+Frame.h */, 151 | 18F9431C1CD2642800240C0B /* UIView+Frame.m */, 152 | 18FCB8581CD10662008E90E4 /* DCOpenGLDrawView.h */, 153 | 18FCB8591CD10662008E90E4 /* DCOpenGLDrawView.m */, 154 | 18FCB85C1CD107D1008E90E4 /* Shaders */, 155 | 18FCB85F1CD107D1008E90E4 /* UtilSrc */, 156 | ); 157 | path = OpenGLPaint; 158 | sourceTree = ""; 159 | }; 160 | 18FCB85C1CD107D1008E90E4 /* Shaders */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 18FCB85D1CD107D1008E90E4 /* point.fsh */, 164 | 18FCB85E1CD107D1008E90E4 /* point.vsh */, 165 | ); 166 | path = Shaders; 167 | sourceTree = ""; 168 | }; 169 | 18FCB85F1CD107D1008E90E4 /* UtilSrc */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | 18FCB8601CD107D1008E90E4 /* debug.h */, 173 | 18FCB8611CD107D1008E90E4 /* fileUtil.h */, 174 | 18FCB8621CD107D1008E90E4 /* fileUtil.m */, 175 | 18FCB8631CD107D1008E90E4 /* shaderUtil.c */, 176 | 18FCB8641CD107D1008E90E4 /* shaderUtil.h */, 177 | ); 178 | path = UtilSrc; 179 | sourceTree = ""; 180 | }; 181 | /* End PBXGroup section */ 182 | 183 | /* Begin PBXNativeTarget section */ 184 | 1824B2541CCE71CF00EEB2C6 /* DCPaintBoard */ = { 185 | isa = PBXNativeTarget; 186 | buildConfigurationList = 1824B26C1CCE71CF00EEB2C6 /* Build configuration list for PBXNativeTarget "DCPaintBoard" */; 187 | buildPhases = ( 188 | 1824B2511CCE71CF00EEB2C6 /* Sources */, 189 | 1824B2521CCE71CF00EEB2C6 /* Frameworks */, 190 | 1824B2531CCE71CF00EEB2C6 /* Resources */, 191 | ); 192 | buildRules = ( 193 | ); 194 | dependencies = ( 195 | ); 196 | name = DCPaintBoard; 197 | productName = DCPaintBoard; 198 | productReference = 1824B2551CCE71CF00EEB2C6 /* DCPaintBoard.app */; 199 | productType = "com.apple.product-type.application"; 200 | }; 201 | /* End PBXNativeTarget section */ 202 | 203 | /* Begin PBXProject section */ 204 | 1824B24D1CCE71CF00EEB2C6 /* Project object */ = { 205 | isa = PBXProject; 206 | attributes = { 207 | LastUpgradeCheck = 0710; 208 | ORGANIZATIONNAME = Wade; 209 | TargetAttributes = { 210 | 1824B2541CCE71CF00EEB2C6 = { 211 | CreatedOnToolsVersion = 7.1.1; 212 | }; 213 | }; 214 | }; 215 | buildConfigurationList = 1824B2501CCE71CF00EEB2C6 /* Build configuration list for PBXProject "DCPaintBoard" */; 216 | compatibilityVersion = "Xcode 3.2"; 217 | developmentRegion = English; 218 | hasScannedForEncodings = 0; 219 | knownRegions = ( 220 | en, 221 | Base, 222 | ); 223 | mainGroup = 1824B24C1CCE71CF00EEB2C6; 224 | productRefGroup = 1824B2561CCE71CF00EEB2C6 /* Products */; 225 | projectDirPath = ""; 226 | projectRoot = ""; 227 | targets = ( 228 | 1824B2541CCE71CF00EEB2C6 /* DCPaintBoard */, 229 | ); 230 | }; 231 | /* End PBXProject section */ 232 | 233 | /* Begin PBXResourcesBuildPhase section */ 234 | 1824B2531CCE71CF00EEB2C6 /* Resources */ = { 235 | isa = PBXResourcesBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | 1824B2681CCE71CF00EEB2C6 /* LaunchScreen.storyboard in Resources */, 239 | 1824B2651CCE71CF00EEB2C6 /* Assets.xcassets in Resources */, 240 | 18FCB8661CD107D1008E90E4 /* point.vsh in Resources */, 241 | 18FCB8651CD107D1008E90E4 /* point.fsh in Resources */, 242 | 1824B2631CCE71CF00EEB2C6 /* Main.storyboard in Resources */, 243 | ); 244 | runOnlyForDeploymentPostprocessing = 0; 245 | }; 246 | /* End PBXResourcesBuildPhase section */ 247 | 248 | /* Begin PBXSourcesBuildPhase section */ 249 | 1824B2511CCE71CF00EEB2C6 /* Sources */ = { 250 | isa = PBXSourcesBuildPhase; 251 | buildActionMask = 2147483647; 252 | files = ( 253 | 1824B2601CCE71CF00EEB2C6 /* ViewController.m in Sources */, 254 | 1822BDA71CCFBB81005BEFED /* DCUndoBeziPathPaintBoard.m in Sources */, 255 | 1824B25D1CCE71CF00EEB2C6 /* AppDelegate.m in Sources */, 256 | 18FCB8671CD107D1008E90E4 /* fileUtil.m in Sources */, 257 | 1824B2771CCFA6C700EEB2C6 /* DCBezierPaintBoard.m in Sources */, 258 | 18FCB85A1CD10662008E90E4 /* DCOpenGLDrawView.m in Sources */, 259 | 1824B25A1CCE71CF00EEB2C6 /* main.m in Sources */, 260 | 18FCB8681CD107D1008E90E4 /* shaderUtil.c in Sources */, 261 | 18F9431D1CD2642800240C0B /* UIView+Frame.m in Sources */, 262 | 1824B27A1CCFA6E200EEB2C6 /* DCBeizierPath.m in Sources */, 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | /* End PBXSourcesBuildPhase section */ 267 | 268 | /* Begin PBXVariantGroup section */ 269 | 1824B2611CCE71CF00EEB2C6 /* Main.storyboard */ = { 270 | isa = PBXVariantGroup; 271 | children = ( 272 | 1824B2621CCE71CF00EEB2C6 /* Base */, 273 | ); 274 | name = Main.storyboard; 275 | sourceTree = ""; 276 | }; 277 | 1824B2661CCE71CF00EEB2C6 /* LaunchScreen.storyboard */ = { 278 | isa = PBXVariantGroup; 279 | children = ( 280 | 1824B2671CCE71CF00EEB2C6 /* Base */, 281 | ); 282 | name = LaunchScreen.storyboard; 283 | sourceTree = ""; 284 | }; 285 | /* End PBXVariantGroup section */ 286 | 287 | /* Begin XCBuildConfiguration section */ 288 | 1824B26A1CCE71CF00EEB2C6 /* Debug */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | ALWAYS_SEARCH_USER_PATHS = NO; 292 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 293 | CLANG_CXX_LIBRARY = "libc++"; 294 | CLANG_ENABLE_MODULES = YES; 295 | CLANG_ENABLE_OBJC_ARC = YES; 296 | CLANG_WARN_BOOL_CONVERSION = YES; 297 | CLANG_WARN_CONSTANT_CONVERSION = YES; 298 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 299 | CLANG_WARN_EMPTY_BODY = YES; 300 | CLANG_WARN_ENUM_CONVERSION = YES; 301 | CLANG_WARN_INT_CONVERSION = YES; 302 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 303 | CLANG_WARN_UNREACHABLE_CODE = YES; 304 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 305 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 306 | COPY_PHASE_STRIP = NO; 307 | DEBUG_INFORMATION_FORMAT = dwarf; 308 | ENABLE_STRICT_OBJC_MSGSEND = YES; 309 | ENABLE_TESTABILITY = YES; 310 | GCC_C_LANGUAGE_STANDARD = gnu99; 311 | GCC_DYNAMIC_NO_PIC = NO; 312 | GCC_NO_COMMON_BLOCKS = YES; 313 | GCC_OPTIMIZATION_LEVEL = 0; 314 | GCC_PREPROCESSOR_DEFINITIONS = ( 315 | "DEBUG=1", 316 | "$(inherited)", 317 | ); 318 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 319 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 320 | GCC_WARN_UNDECLARED_SELECTOR = YES; 321 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 322 | GCC_WARN_UNUSED_FUNCTION = YES; 323 | GCC_WARN_UNUSED_VARIABLE = YES; 324 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 325 | MTL_ENABLE_DEBUG_INFO = YES; 326 | ONLY_ACTIVE_ARCH = YES; 327 | SDKROOT = iphoneos; 328 | }; 329 | name = Debug; 330 | }; 331 | 1824B26B1CCE71CF00EEB2C6 /* Release */ = { 332 | isa = XCBuildConfiguration; 333 | buildSettings = { 334 | ALWAYS_SEARCH_USER_PATHS = NO; 335 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 336 | CLANG_CXX_LIBRARY = "libc++"; 337 | CLANG_ENABLE_MODULES = YES; 338 | CLANG_ENABLE_OBJC_ARC = YES; 339 | CLANG_WARN_BOOL_CONVERSION = YES; 340 | CLANG_WARN_CONSTANT_CONVERSION = YES; 341 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 342 | CLANG_WARN_EMPTY_BODY = YES; 343 | CLANG_WARN_ENUM_CONVERSION = YES; 344 | CLANG_WARN_INT_CONVERSION = YES; 345 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 346 | CLANG_WARN_UNREACHABLE_CODE = YES; 347 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 348 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 349 | COPY_PHASE_STRIP = NO; 350 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 351 | ENABLE_NS_ASSERTIONS = NO; 352 | ENABLE_STRICT_OBJC_MSGSEND = YES; 353 | GCC_C_LANGUAGE_STANDARD = gnu99; 354 | GCC_NO_COMMON_BLOCKS = YES; 355 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 356 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 357 | GCC_WARN_UNDECLARED_SELECTOR = YES; 358 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 359 | GCC_WARN_UNUSED_FUNCTION = YES; 360 | GCC_WARN_UNUSED_VARIABLE = YES; 361 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 362 | MTL_ENABLE_DEBUG_INFO = NO; 363 | SDKROOT = iphoneos; 364 | VALIDATE_PRODUCT = YES; 365 | }; 366 | name = Release; 367 | }; 368 | 1824B26D1CCE71CF00EEB2C6 /* Debug */ = { 369 | isa = XCBuildConfiguration; 370 | buildSettings = { 371 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 372 | INFOPLIST_FILE = DCPaintBoard/Info.plist; 373 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 374 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 375 | PRODUCT_BUNDLE_IDENTIFIER = WD.DCPaintBoard; 376 | PRODUCT_NAME = "$(TARGET_NAME)"; 377 | TARGETED_DEVICE_FAMILY = 2; 378 | }; 379 | name = Debug; 380 | }; 381 | 1824B26E1CCE71CF00EEB2C6 /* Release */ = { 382 | isa = XCBuildConfiguration; 383 | buildSettings = { 384 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 385 | INFOPLIST_FILE = DCPaintBoard/Info.plist; 386 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 387 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 388 | PRODUCT_BUNDLE_IDENTIFIER = WD.DCPaintBoard; 389 | PRODUCT_NAME = "$(TARGET_NAME)"; 390 | TARGETED_DEVICE_FAMILY = 2; 391 | }; 392 | name = Release; 393 | }; 394 | /* End XCBuildConfiguration section */ 395 | 396 | /* Begin XCConfigurationList section */ 397 | 1824B2501CCE71CF00EEB2C6 /* Build configuration list for PBXProject "DCPaintBoard" */ = { 398 | isa = XCConfigurationList; 399 | buildConfigurations = ( 400 | 1824B26A1CCE71CF00EEB2C6 /* Debug */, 401 | 1824B26B1CCE71CF00EEB2C6 /* Release */, 402 | ); 403 | defaultConfigurationIsVisible = 0; 404 | defaultConfigurationName = Release; 405 | }; 406 | 1824B26C1CCE71CF00EEB2C6 /* Build configuration list for PBXNativeTarget "DCPaintBoard" */ = { 407 | isa = XCConfigurationList; 408 | buildConfigurations = ( 409 | 1824B26D1CCE71CF00EEB2C6 /* Debug */, 410 | 1824B26E1CCE71CF00EEB2C6 /* Release */, 411 | ); 412 | defaultConfigurationIsVisible = 0; 413 | defaultConfigurationName = Release; 414 | }; 415 | /* End XCConfigurationList section */ 416 | }; 417 | rootObject = 1824B24D1CCE71CF00EEB2C6 /* Project object */; 418 | } 419 | -------------------------------------------------------------------------------- /DCPaintBoard.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DCPaintBoard/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/25. 6 | // Copyright © 2016年 Wade. 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 | -------------------------------------------------------------------------------- /DCPaintBoard/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/25. 6 | // Copyright © 2016年 Wade. 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 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // 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. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // 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. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /DCPaintBoard/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 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/Particle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Particle.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Particle@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/Particle.imageset/Particle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/Particle.imageset/Particle.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/Particle.imageset/Particle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/Particle.imageset/Particle@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/black.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "black.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "black@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/black.imageset/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/black.imageset/black.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/black.imageset/black@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/black.imageset/black@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/blue.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "blue.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "blue@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/blue.imageset/blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/blue.imageset/blue.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/blue.imageset/blue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/blue.imageset/blue@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_eraser.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "btn_eraser.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "btn_eraser@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_eraser.imageset/btn_eraser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_eraser.imageset/btn_eraser.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_eraser.imageset/btn_eraser@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_eraser.imageset/btn_eraser@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_eraser_press.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "btn_eraser_press.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "btn_eraser_press@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_eraser_press.imageset/btn_eraser_press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_eraser_press.imageset/btn_eraser_press.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_eraser_press.imageset/btn_eraser_press@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_eraser_press.imageset/btn_eraser_press@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_black.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "btn_mark_black.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "btn_mark_black@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_black.imageset/btn_mark_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_mark_black.imageset/btn_mark_black.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_black.imageset/btn_mark_black@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_mark_black.imageset/btn_mark_black@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_blue.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "btn_mark_blue.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "btn_mark_blue@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_blue.imageset/btn_mark_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_mark_blue.imageset/btn_mark_blue.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_blue.imageset/btn_mark_blue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_mark_blue.imageset/btn_mark_blue@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_green.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "btn_mark_green.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "btn_mark_green@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_green.imageset/btn_mark_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_mark_green.imageset/btn_mark_green.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_green.imageset/btn_mark_green@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_mark_green.imageset/btn_mark_green@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_red.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "btn_mark_red.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "btn_mark_red@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_red.imageset/btn_mark_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_mark_red.imageset/btn_mark_red.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/btn_mark_red.imageset/btn_mark_red@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/btn_mark_red.imageset/btn_mark_red@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/down.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "down.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "down@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/down.imageset/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/down.imageset/down.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/down.imageset/down@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/down.imageset/down@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/green.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "green.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "green@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/green.imageset/green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/green.imageset/green.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/green.imageset/green@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/green.imageset/green@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/nomal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "nomal.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/nomal.imageset/nomal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/nomal.imageset/nomal.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/red.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "red.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "red@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/red.imageset/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/red.imageset/red.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/red.imageset/red@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/red.imageset/red@2x.png -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/select.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "select.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /DCPaintBoard/Assets.xcassets/select.imageset/select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ddviper/DCDrawView/8e58c1e9a632b29557ff0b7837290255ba8031a2/DCPaintBoard/Assets.xcassets/select.imageset/select.png -------------------------------------------------------------------------------- /DCPaintBoard/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 | -------------------------------------------------------------------------------- /DCPaintBoard/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 | 45 | 67 | 89 | 90 | 91 | 92 | 103 | 118 | 132 | 144 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 200 | 208 | 216 | 224 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | -------------------------------------------------------------------------------- /DCPaintBoard/DCCommon.h: -------------------------------------------------------------------------------- 1 | // 2 | // DCCommon.h 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/26. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #ifndef DCCommon_h 10 | #define DCCommon_h 11 | 12 | typedef enum{ 13 | DCPaintColorRed = 1, 14 | DCPaintColorGreen = 2, 15 | DCPaintColorBlue = 3, 16 | DCPaintColorBlack = 4 17 | } DCPaintColor; 18 | 19 | 20 | typedef enum{ 21 | DCPaintBoardTypeBezi = 1, 22 | DCPaintBoardTypeBeziUndo = 2, 23 | DCPaintBoardTypeOpenGL = 3 24 | } DCPaintBoardType; 25 | 26 | static NSInteger const kLineWidth = 5; 27 | static NSInteger const kEraseLineWidth = 20; 28 | #endif /* DCCommon_h */ 29 | -------------------------------------------------------------------------------- /DCPaintBoard/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 | 40 | 41 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/BeziPathPaint/DCBeizierPath.h: -------------------------------------------------------------------------------- 1 | // 2 | // DCBeizierPath.h 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/26. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DCBeizierPath : UIBezierPath 12 | @property (nonatomic,copy) UIColor *lineColor; 13 | @property (nonatomic,assign) BOOL isErase; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/BeziPathPaint/DCBeizierPath.m: -------------------------------------------------------------------------------- 1 | // 2 | // DCBeizierPath.m 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/26. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import "DCBeizierPath.h" 10 | 11 | @implementation DCBeizierPath 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/BeziPathPaint/DCBezierPaintBoard.h: -------------------------------------------------------------------------------- 1 | // 2 | // DCBezierPaintBoard.h 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/25. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DCBezierPaintBoard : UIView 12 | /** 13 | * 画线的颜色 14 | */ 15 | @property (nonatomic, strong) UIColor *lineColor; 16 | /** 17 | * 是否是橡皮擦状态 18 | */ 19 | @property (nonatomic, assign) BOOL isErase; 20 | 21 | /** 22 | * 清楚画笔 23 | */ 24 | - (void)clear; 25 | @end 26 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/BeziPathPaint/DCBezierPaintBoard.m: -------------------------------------------------------------------------------- 1 | // 2 | // DCBezierPaintBoard.m 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/25. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import "DCBezierPaintBoard.h" 10 | #import "DCCommon.h" 11 | #import "DCBeizierPath.h" 12 | 13 | 14 | @interface DCBezierPaintBoard() 15 | @property (nonatomic, strong) NSMutableArray *beziPathArrM; 16 | 17 | @property (nonatomic, strong) DCBeizierPath *beziPath; 18 | @end 19 | 20 | @implementation DCBezierPaintBoard 21 | 22 | - (NSMutableArray *)beziPathArrM{ 23 | if (!_beziPathArrM) { 24 | _beziPathArrM = [NSMutableArray array]; 25 | } 26 | return _beziPathArrM; 27 | } 28 | 29 | - (void)setIsErase:(BOOL)isErase{ 30 | _isErase = isErase; 31 | NSLog(@"setIsErase--%d",isErase); 32 | } 33 | 34 | 35 | #pragma mark - touch方法 36 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 37 | UITouch *touch = [touches anyObject]; 38 | 39 | CGPoint currentPoint = [touch locationInView:self]; 40 | // NSLog(@"touchesBegan--%@",NSStringFromCGPoint(currentPoint)); 41 | self.beziPath = [[DCBeizierPath alloc] init]; 42 | self.beziPath.lineColor = self.lineColor; 43 | self.beziPath.isErase = self.isErase; 44 | [self.beziPath moveToPoint:currentPoint]; 45 | 46 | [self.beziPathArrM addObject:self.beziPath]; 47 | } 48 | 49 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ 50 | UITouch *touch = [touches anyObject]; 51 | 52 | CGPoint currentPoint = [touch locationInView:self]; 53 | CGPoint previousPoint = [touch previousLocationInView:self]; 54 | // NSLog(@"touchesMoved--%@",NSStringFromCGPoint(currentPoint)); 55 | 56 | CGPoint midP = midPoint(previousPoint,currentPoint); 57 | 58 | [self.beziPath addQuadCurveToPoint:currentPoint controlPoint:midP]; 59 | 60 | [self setNeedsDisplay]; 61 | } 62 | 63 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 64 | UITouch *touch = [touches anyObject]; 65 | 66 | CGPoint currentPoint = [touch locationInView:self]; 67 | CGPoint previousPoint = [touch previousLocationInView:self]; 68 | 69 | // NSLog(@"touchesEnded--%@",NSStringFromCGPoint(currentPoint)); 70 | 71 | CGPoint midP = midPoint(previousPoint,currentPoint); 72 | 73 | [self.beziPath addQuadCurveToPoint:currentPoint controlPoint:midP]; 74 | 75 | [self setNeedsDisplay]; 76 | 77 | } 78 | 79 | 80 | // 计算中间点 81 | CGPoint midPoint(CGPoint p1, CGPoint p2) 82 | { 83 | return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5); 84 | } 85 | 86 | #pragma mark - 绘画方法 87 | - (void)drawRect:(CGRect)rect 88 | { 89 | //获取上下文 90 | if(self.beziPathArrM.count){ 91 | for (DCBeizierPath *path in self.beziPathArrM) { 92 | if (path.isErase) { 93 | [[UIColor clearColor] setStroke]; 94 | }else{ 95 | [path.lineColor setStroke]; 96 | } 97 | 98 | path.lineJoinStyle = kCGLineJoinRound; 99 | path.lineCapStyle = kCGLineCapRound; 100 | if (path.isErase) { 101 | path.lineWidth = kEraseLineWidth; 102 | [path strokeWithBlendMode:kCGBlendModeCopy alpha:1.0]; 103 | } else { 104 | path.lineWidth = kLineWidth; 105 | [path strokeWithBlendMode:kCGBlendModeNormal alpha:1.0]; 106 | } 107 | [path stroke]; 108 | } 109 | } 110 | 111 | [super drawRect:rect]; 112 | } 113 | 114 | - (void)clear{ 115 | 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/DCOpenGLDrawView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DCOpenGLDrawView.h 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/27. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DCOpenGLDrawView : UIView 12 | /** 13 | * 画线的颜色 14 | */ 15 | @property (nonatomic, strong) UIColor *lineColor; 16 | /** 17 | * 是否是橡皮擦状态 18 | */ 19 | @property (nonatomic, assign) BOOL isErase; 20 | /** 21 | * 清楚画笔 22 | */ 23 | - (void)clear; 24 | @end 25 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/DCOpenGLDrawView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DCOpenGLDrawView.m 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/27. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import "DCOpenGLDrawView.h" 10 | #import 11 | #import 12 | #import 13 | 14 | #import 15 | 16 | #import "shaderUtil.h" 17 | #import "fileUtil.h" 18 | #import "debug.h" 19 | #import "DCCommon.h" 20 | #import "UIView+Frame.h" 21 | 22 | #define kBrushOpacity (1.0 / 3.0) 23 | #define kBrushPixelStep 3 24 | #define kBrushScale 2 25 | // Shaders 26 | enum { 27 | PROGRAM_POINT, 28 | NUM_PROGRAMS 29 | }; 30 | 31 | enum { 32 | UNIFORM_MVP, 33 | UNIFORM_POINT_SIZE, 34 | UNIFORM_VERTEX_COLOR, 35 | UNIFORM_TEXTURE, 36 | NUM_UNIFORMS 37 | }; 38 | 39 | enum { 40 | ATTRIB_VERTEX, 41 | NUM_ATTRIBS 42 | }; 43 | 44 | typedef struct { 45 | char *vert, *frag; 46 | GLint uniform[NUM_UNIFORMS]; 47 | GLuint id; 48 | } programInfo_t; 49 | 50 | 51 | programInfo_t program[NUM_PROGRAMS] = { 52 | { "point.vsh", "point.fsh" }, // PROGRAM_POINT 53 | }; 54 | 55 | // Texture 56 | typedef struct { 57 | GLuint id; 58 | GLsizei width, height; 59 | } textureInfo_t; 60 | 61 | @interface DCOpenGLDrawView() 62 | { 63 | // The pixel dimensions of the backbuffer 64 | // 画布的大小 65 | GLint backingWidth; 66 | GLint backingHeight; 67 | 68 | EAGLContext *context; 69 | 70 | // OpenGL names for the renderbuffer and framebuffers used to render to this view 71 | GLuint viewRenderbuffer, viewFramebuffer; 72 | 73 | // OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) 74 | GLuint depthRenderbuffer; 75 | 76 | textureInfo_t brushTexture; // brush texture 77 | GLfloat brushColor[4]; // brush color 78 | 79 | Boolean firstTouch; 80 | Boolean needsErase; 81 | 82 | // Shader objects 83 | GLuint vertexShader; 84 | GLuint fragmentShader; 85 | GLuint shaderProgram; 86 | 87 | // Buffer Objects 88 | GLuint vboId; 89 | 90 | BOOL initialized; 91 | } 92 | 93 | /** 94 | * 保存当前画的一笔的所有点 画完保存后既删除 95 | */ 96 | @property (nonatomic, strong) NSMutableArray *pointsArrM; 97 | 98 | /** 99 | * 保存所有画的点和 不清空 100 | */ 101 | @property (nonatomic, strong) NSMutableDictionary *pathsDictM; 102 | 103 | // 当前点 104 | @property(nonatomic, readwrite) CGPoint location; 105 | 106 | // 上一个点 107 | @property(nonatomic, readwrite) CGPoint previousLocation; 108 | 109 | 110 | @end 111 | 112 | @implementation DCOpenGLDrawView 113 | 114 | - (void)setLineColor:(UIColor *)lineColor{ 115 | _lineColor = lineColor; 116 | if (lineColor == [UIColor blackColor]) { 117 | [self setBrushColorWithRed:0 green:0 blue:0 alpha:1]; 118 | } 119 | else if (lineColor == [UIColor redColor]) { 120 | [self setBrushColorWithRed:1 green:0 blue:0 alpha:1]; 121 | } 122 | else if (lineColor == [UIColor greenColor]) { 123 | [self setBrushColorWithRed:0 green:1 blue:0 alpha:1]; 124 | } 125 | else if (lineColor == [UIColor greenColor]) 126 | { 127 | [self setBrushColorWithRed:0 green:0 blue:1 alpha:1]; 128 | }else { 129 | [self setBrushColorWithRed:0 green:0 blue:0 alpha:1]; 130 | } 131 | } 132 | 133 | - (NSMutableDictionary *)pathsDictM{ 134 | if (!_pathsDictM) { 135 | _pathsDictM = [NSMutableDictionary dictionary]; 136 | } 137 | return _pathsDictM; 138 | } 139 | 140 | 141 | // 保存当前一笔的所有点 142 | - (NSMutableArray *)pointsArrM{ 143 | if (!_pointsArrM) { 144 | _pointsArrM = [NSMutableArray array]; 145 | } 146 | return _pointsArrM; 147 | } 148 | 149 | /** 150 | * 设置是否是橡皮擦 151 | * 152 | * @param isErase 153 | */ 154 | - (void)setIsErase:(BOOL)isErase 155 | { 156 | _isErase = isErase; 157 | if (isErase) { 158 | 159 | [self setBrushColorWithRed:0 green:0 blue:0 alpha:0]; 160 | // 161 | glBlendFunc(GL_ONE, GL_ZERO); 162 | 163 | }else{ 164 | [self setBrushColorWithRed:1 green:0 blue:0 alpha:1]; 165 | glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 166 | } 167 | // [self setupShaders]; 168 | } 169 | 170 | 171 | + (Class)layerClass 172 | { 173 | return [CAEAGLLayer class]; 174 | } 175 | 176 | 177 | // The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: 178 | // GL视图存储在nib文件。当它从未归档-initWithCoder发送: 179 | - (id)initWithCoder:(NSCoder*)coder { 180 | 181 | if ((self = [super initWithCoder:coder])) { 182 | 183 | // 2、在init的方法中,从基类获取layer属性,并将其转型至CAEAGLLayer 184 | CAEAGLLayer *eaglLayer = (CAEAGLLayer *)super.layer; 185 | 186 | eaglLayer.opaque = YES;//无需Quartz处理透明度 187 | // In this application, we want to retain the EAGLDrawable contents after a call to presentRenderbuffer. 188 | 189 | 190 | eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: 191 | [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; 192 | 193 | /* 194 | 后面的参数有两个选择 195 | kEAGLRenderingAPIOpenGLES1=1 表示用渲染库的API版本是1.1 196 | kEAGLRenderingAPIOpenGLES2=2 表示用渲染库的API版本是2.0 197 | */ 198 | context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 199 | 200 | 201 | // //设定当期上下文对象 202 | if (!context || ![EAGLContext setCurrentContext:context]) { 203 | return nil; 204 | } 205 | 206 | // Set the view's scale factor as you wish 207 | self.contentScaleFactor = [[UIScreen mainScreen] scale]; 208 | 209 | // Make sure to start with a cleared buffer 210 | needsErase = YES; 211 | } 212 | 213 | return self; 214 | } 215 | 216 | //如果我们的视图的大小,我们将要求布局子视图。 217 | //这是一个完美的机会来更新framebuffer这样 218 | //同样大小的显示区域。 219 | -(void)layoutSubviews 220 | { 221 | [EAGLContext setCurrentContext:context]; 222 | 223 | if (!initialized) { 224 | initialized = [self initGL]; 225 | } 226 | else { 227 | [self resizeFromLayer:(CAEAGLLayer*)self.layer]; 228 | } 229 | 230 | // Clear the framebuffer the first time it is allocated 231 | if (needsErase) { 232 | [self clearDrawImageView]; 233 | needsErase = NO; 234 | } 235 | 236 | } 237 | 238 | 239 | // 创建一个纹理的图像 240 | - (textureInfo_t)textureFromName:(NSString *)name 241 | { 242 | CGImageRef brushImage; 243 | CGContextRef brushContext; 244 | GLubyte *brushData; 245 | size_t width, height; 246 | GLuint texId; 247 | textureInfo_t texture; 248 | 249 | // First create a UIImage object from the data in a image file, and then extract the Core Graphics image 250 | brushImage = [UIImage imageNamed:name].CGImage; 251 | 252 | // Get the width and height of the image 253 | width = CGImageGetWidth(brushImage); 254 | height = CGImageGetHeight(brushImage); 255 | 256 | // Make sure the image exists 257 | if(brushImage) { 258 | // Allocate memory needed for the bitmap context 259 | brushData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte)); 260 | // Use the bitmatp creation function provided by the Core Graphics framework. 261 | brushContext = CGBitmapContextCreate(brushData, width, height, 8, width * 4, CGImageGetColorSpace(brushImage), kCGImageAlphaPremultipliedLast); 262 | // After you create the context, you can draw the image to the context. 263 | CGContextDrawImage(brushContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), brushImage); 264 | // You don't need the context at this point, so you need to release it to avoid memory leaks. 265 | CGContextRelease(brushContext); 266 | // Use OpenGL ES to generate a name for the texture. 267 | // //创建渲染缓冲管线 268 | glGenTextures(1, &texId); 269 | // Bind the texture name. 270 | //绑定渲染缓冲管线 271 | glBindTexture(GL_TEXTURE_2D, texId); 272 | // Set the texture parameters to use a minifying filter and a linear filer (weighted average) 273 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 274 | // Specify a 2D texture image, providing the a pointer to the image data in memory 275 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)width, (int)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, brushData); 276 | // Release the image data; it's no longer needed 277 | free(brushData); 278 | 279 | texture.id = texId; 280 | texture.width = (int)width; 281 | texture.height = (int)height; 282 | } 283 | 284 | return texture; 285 | } 286 | 287 | // 初始化GL 288 | - (BOOL)initGL 289 | { 290 | // Generate IDs for a framebuffer object and a color renderbuffer 291 | ////创建帧缓冲管线 292 | glGenFramebuffers(1, &viewFramebuffer); 293 | //绑定渲染缓冲管线 294 | glGenRenderbuffers(1, &viewRenderbuffer); 295 | 296 | //绑定帧缓冲管线 297 | glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer); 298 | 299 | 300 | //将渲染缓冲区附加到帧缓冲区上 301 | glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer); 302 | // This call associates the storage for the current render buffer with the EAGLDrawable (our CAEAGLLayer) 303 | // allowing us to draw into a buffer that will later be rendered to screen wherever the layer is (which corresponds with our view). 304 | [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(id)self.layer]; 305 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer); 306 | 307 | glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth); 308 | glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight); 309 | 310 | // For this sample, we do not need a depth buffer. If you do, this is how you can create one and attach it to the framebuffer: 311 | // glGenRenderbuffers(1, &depthRenderbuffer); 312 | // glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); 313 | // glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, backingWidth, backingHeight); 314 | // glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); 315 | 316 | if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 317 | { 318 | NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); 319 | return NO; 320 | } 321 | 322 | //创建显示区域 323 | glViewport(0, 0, backingWidth, backingHeight); 324 | 325 | // Create a Vertex Buffer Object to hold our data 326 | glGenBuffers(1, &vboId); 327 | 328 | // Load the brush texture 329 | // 设置笔头 330 | brushTexture = [self textureFromName:@"Particle"]; 331 | 332 | // Load shaders 333 | [self setupShaders]; 334 | 335 | // Enable blending and set a blending function appropriate for premultiplied alpha pixel data 336 | glEnable(GL_BLEND); 337 | glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 338 | 339 | return YES; 340 | } 341 | 342 | 343 | - (BOOL)resizeFromLayer:(CAEAGLLayer *)layer 344 | { 345 | // Allocate color buffer backing based on the current layer size 346 | glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer); 347 | [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; 348 | glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth); 349 | glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight); 350 | 351 | // For this sample, we do not need a depth buffer. If you do, this is how you can allocate depth buffer backing: 352 | // glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); 353 | // glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, backingWidth, backingHeight); 354 | // glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); 355 | 356 | if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 357 | { 358 | NSLog(@"Failed to make complete framebuffer objectz %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); 359 | return NO; 360 | } 361 | 362 | // Update projection matrix 363 | GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(0, backingWidth, 0, backingHeight, -1, 1); 364 | GLKMatrix4 modelViewMatrix = GLKMatrix4Identity; // this sample uses a constant identity modelView matrix 365 | GLKMatrix4 MVPMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); 366 | 367 | glUseProgram(program[PROGRAM_POINT].id); 368 | glUniformMatrix4fv(program[PROGRAM_POINT].uniform[UNIFORM_MVP], 1, GL_FALSE, MVPMatrix.m); 369 | 370 | // Update viewport 371 | glViewport(0, 0, backingWidth, backingHeight); 372 | 373 | return YES; 374 | } 375 | 376 | - (void)setupShaders 377 | { 378 | for (int i = 0; i < NUM_PROGRAMS; i++) 379 | { 380 | char *vsrc = readFile(pathForResource(program[i].vert)); 381 | char *fsrc = readFile(pathForResource(program[i].frag)); 382 | GLsizei attribCt = 0; 383 | GLchar *attribUsed[NUM_ATTRIBS]; 384 | GLint attrib[NUM_ATTRIBS]; 385 | GLchar *attribName[NUM_ATTRIBS] = { 386 | "inVertex", 387 | }; 388 | const GLchar *uniformName[NUM_UNIFORMS] = { 389 | "MVP", "pointSize", "vertexColor", "texture", 390 | }; 391 | 392 | // auto-assign known attribs 393 | for (int j = 0; j < NUM_ATTRIBS; j++) 394 | { 395 | if (strstr(vsrc, attribName[j])) 396 | { 397 | attrib[attribCt] = j; 398 | attribUsed[attribCt++] = attribName[j]; 399 | } 400 | } 401 | 402 | glueCreateProgram(vsrc, fsrc, 403 | attribCt, (const GLchar **)&attribUsed[0], attrib, 404 | NUM_UNIFORMS, &uniformName[0], program[i].uniform, 405 | &program[i].id); 406 | free(vsrc); 407 | free(fsrc); 408 | 409 | // Set constant/initalize uniforms 410 | if (i == PROGRAM_POINT) 411 | { 412 | glUseProgram(program[PROGRAM_POINT].id); 413 | 414 | // the brush texture will be bound to texture unit 0 415 | glUniform1i(program[PROGRAM_POINT].uniform[UNIFORM_TEXTURE], 0); 416 | 417 | // viewing matrices 418 | GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(0, backingWidth, 0, backingHeight, -1, 1); 419 | GLKMatrix4 modelViewMatrix = GLKMatrix4Identity; // this sample uses a constant identity modelView matrix 420 | GLKMatrix4 MVPMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); 421 | 422 | glUniformMatrix4fv(program[PROGRAM_POINT].uniform[UNIFORM_MVP], 1, GL_FALSE, MVPMatrix.m); 423 | 424 | // point size 425 | glUniform1f(program[PROGRAM_POINT].uniform[UNIFORM_POINT_SIZE], brushTexture.width / kBrushScale); 426 | 427 | // initialize brush color 428 | glUniform4fv(program[PROGRAM_POINT].uniform[UNIFORM_VERTEX_COLOR], 1, brushColor); 429 | } 430 | } 431 | 432 | glError(); 433 | } 434 | 435 | 436 | 437 | // 根据两点画线的方法 438 | - (void)renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end 439 | { 440 | // NSLog(@"drawLineWithPoints--%@--%@",NSStringFromCGPoint(start),NSStringFromCGPoint(end)); 441 | static GLfloat* vertexBuffer = NULL; 442 | static NSUInteger vertexMax = 64; 443 | NSUInteger vertexCount = 0, 444 | count, 445 | i; 446 | 447 | [EAGLContext setCurrentContext:context]; 448 | glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer); 449 | 450 | // Convert locations from Points to Pixels 451 | CGFloat scale = self.contentScaleFactor; 452 | 453 | start.x *= scale; 454 | start.y *= scale; 455 | end.x *= scale; 456 | end.y *= scale; 457 | 458 | // Allocate vertex array buffer 459 | if(vertexBuffer == NULL) 460 | vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat)); 461 | 462 | // Add points to the buffer so there are drawing points every X pixels 463 | count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y)) / kBrushPixelStep), 1); 464 | for(i = 0; i < count; ++i) { 465 | if(vertexCount == vertexMax) { 466 | vertexMax = 2 * vertexMax; 467 | vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat)); 468 | } 469 | 470 | vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count); 471 | vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count); 472 | vertexCount += 1; 473 | } 474 | 475 | // Load data to the Vertex Buffer Object 476 | glBindBuffer(GL_ARRAY_BUFFER, vboId); 477 | glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vertexBuffer, GL_STATIC_DRAW); 478 | 479 | 480 | glEnableVertexAttribArray(ATTRIB_VERTEX); 481 | glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, 0); 482 | 483 | // Draw 484 | glUseProgram(program[PROGRAM_POINT].id); 485 | 486 | // 画线 487 | glDrawArrays(GL_POINTS, 0, (int)vertexCount); 488 | 489 | // Display the buffer 490 | glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer); 491 | [context presentRenderbuffer:GL_RENDERBUFFER]; 492 | } 493 | 494 | 495 | // 清楚 496 | - (void)clearDrawImageView 497 | { 498 | [EAGLContext setCurrentContext:context]; 499 | 500 | // Clear the buffer 501 | glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer); 502 | glClearColor(0.0, 0.0, 0.0, 0.0); 503 | glClear(GL_COLOR_BUFFER_BIT); 504 | 505 | // Display the buffer 506 | glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer); 507 | [context presentRenderbuffer:GL_RENDERBUFFER]; 508 | } 509 | 510 | - (void)setBrushColorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha 511 | { 512 | // Update the brush color 513 | brushColor[0] = red ; 514 | brushColor[1] = green ; 515 | brushColor[2] = blue ; 516 | brushColor[3] = alpha; 517 | 518 | if (initialized) { 519 | glUseProgram(program[PROGRAM_POINT].id); 520 | // 设置画笔颜色 521 | glUniform4fv(program[PROGRAM_POINT].uniform[UNIFORM_VERTEX_COLOR], 1, brushColor); 522 | } 523 | } 524 | 525 | 526 | 527 | // Releases resources when they are not longer needed. 528 | - (void)dealloc 529 | { 530 | // Destroy framebuffers and renderbuffers 531 | if (viewFramebuffer) { 532 | glDeleteFramebuffers(1, &viewFramebuffer); 533 | viewFramebuffer = 0; 534 | } 535 | if (viewRenderbuffer) { 536 | glDeleteRenderbuffers(1, &viewRenderbuffer); 537 | viewRenderbuffer = 0; 538 | } 539 | if (depthRenderbuffer) 540 | { 541 | glDeleteRenderbuffers(1, &depthRenderbuffer); 542 | depthRenderbuffer = 0; 543 | } 544 | // texture 545 | if (brushTexture.id) { 546 | glDeleteTextures(1, &brushTexture.id); 547 | brushTexture.id = 0; 548 | } 549 | // vbo 550 | if (vboId) { 551 | glDeleteBuffers(1, &vboId); 552 | vboId = 0; 553 | } 554 | 555 | // tear down context 556 | if ([EAGLContext currentContext] == context) 557 | [EAGLContext setCurrentContext:nil]; 558 | } 559 | 560 | 561 | #pragma mark ------Touch方法 562 | /** 563 | * touch 方法 564 | */ 565 | 566 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 567 | { 568 | // CGRect bounds = [self bounds]; 569 | UITouch* touch = [[event touchesForView:self] anyObject]; 570 | 571 | // firstTouch = YES; 572 | 573 | // 转换触点从UIView引用到OpenGL 1(倒翻转) 574 | // Convert touch point from UIView referential to OpenGL one (upside-down flip) 575 | _previousLocation = [touch locationInView:self]; 576 | _previousLocation.y = self.height - _previousLocation.y; 577 | 578 | CGPoint currentPoint = [touch locationInView:self]; 579 | NSDictionary *dict = @{@"x":@(currentPoint.x),@"y":@(currentPoint.y)}; 580 | 581 | [self.pointsArrM addObject:dict]; 582 | 583 | // NSLog(@"touchesBegan--%@",dict); 584 | } 585 | 586 | 587 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 588 | { 589 | // CGRect bounds = [self bounds]; 590 | UITouch* touch = [[event touchesForView:self] anyObject]; 591 | 592 | _location = [touch locationInView:self]; 593 | _location.y = self.height - _location.y; 594 | _previousLocation = [touch previousLocationInView:self]; 595 | _previousLocation.y = self.height - _previousLocation.y; 596 | 597 | [self renderLineFromPoint:_previousLocation toPoint:_location]; 598 | 599 | CGPoint currentPoint = [touch locationInView:self]; 600 | NSDictionary *dict = @{@"x":@(currentPoint.x),@"y":@(currentPoint.y)}; 601 | [self.pointsArrM addObject:dict]; 602 | // NSLog(@"touchesMoved--%@",dict); 603 | 604 | } 605 | 606 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 607 | { 608 | 609 | UITouch* touch = [[event touchesForView:self] anyObject]; 610 | _location = [touch locationInView:self]; 611 | _location.y = self.height - _location.y; 612 | 613 | _previousLocation = [touch previousLocationInView:self]; 614 | _previousLocation.y = self.height - _previousLocation.y; 615 | 616 | [self renderLineFromPoint:_previousLocation toPoint:_location]; 617 | 618 | _location = CGPointMake(0, 0); 619 | _previousLocation = CGPointMake(0, 0); 620 | 621 | CGPoint currentPoint = [touch locationInView:self]; 622 | NSDictionary *dict = @{@"x":@(currentPoint.x),@"y":@(currentPoint.y)}; 623 | [self.pointsArrM addObject:dict]; 624 | 625 | 626 | // NSLog(@"touchesEnded--%@",dict); 627 | } 628 | 629 | 630 | 631 | - (void)clear{ 632 | [self clearDrawImageView]; 633 | } 634 | @end 635 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/Shaders/point.fsh: -------------------------------------------------------------------------------- 1 | /* 2 | File: color.fsh 3 | Abstract: A fragment shader that draws points with assigned color and 4 | texture. 5 | Version: 1.13 6 | 7 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 8 | Inc. ("Apple") in consideration of your agreement to the following 9 | terms, and your use, installation, modification or redistribution of 10 | this Apple software constitutes acceptance of these terms. If you do 11 | not agree with these terms, please do not use, install, modify or 12 | redistribute this Apple software. 13 | 14 | In consideration of your agreement to abide by the following terms, and 15 | subject to these terms, Apple grants you a personal, non-exclusive 16 | license, under Apple's copyrights in this original Apple software (the 17 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 18 | Software, with or without modifications, in source and/or binary forms; 19 | provided that if you redistribute the Apple Software in its entirety and 20 | without modifications, you must retain this notice and the following 21 | text and disclaimers in all such redistributions of the Apple Software. 22 | Neither the name, trademarks, service marks or logos of Apple Inc. may 23 | be used to endorse or promote products derived from the Apple Software 24 | without specific prior written permission from Apple. Except as 25 | expressly stated in this notice, no other rights or licenses, express or 26 | implied, are granted by Apple herein, including but not limited to any 27 | patent rights that may be infringed by your derivative works or by other 28 | works in which the Apple Software may be incorporated. 29 | 30 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 31 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 32 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 33 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 34 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 35 | 36 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 37 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 38 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 39 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 40 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 41 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 42 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 43 | POSSIBILITY OF SUCH DAMAGE. 44 | 45 | Copyright (C) 2014 Apple Inc. All Rights Reserved. 46 | 47 | */ 48 | 49 | uniform sampler2D texture; 50 | varying lowp vec4 color; 51 | // 片段着色器 52 | void main() 53 | { 54 | 55 | gl_FragColor = color * texture2D(texture, gl_PointCoord); 56 | } 57 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/Shaders/point.vsh: -------------------------------------------------------------------------------- 1 | /* 2 | File: color.vsh 3 | Abstract: A vertex shader that draws points with assigned color. 4 | Version: 1.13 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2014 Apple Inc. All Rights Reserved. 45 | 46 | */ 47 | 48 | attribute vec4 inVertex; 49 | 50 | uniform mat4 MVP; // mat4 一般存储4个Vec4的矩阵向量 51 | uniform float pointSize; 52 | uniform lowp vec4 vertexColor; // vec4 表示存储4个浮点数数据的数组 一般存储颜色RGBA值 53 | 54 | varying lowp vec4 color; 55 | 56 | // 顶点着色器 57 | void main() 58 | { 59 | gl_Position = MVP * inVertex; 60 | gl_PointSize = pointSize; 61 | color = vertexColor; 62 | } 63 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/UIView+Frame.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Frame.h 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/28. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (Frame) 12 | @property (nonatomic, assign) CGFloat x; 13 | @property (nonatomic, assign) CGFloat y; 14 | @property (nonatomic, assign) CGFloat centerX; 15 | @property (nonatomic, assign) CGFloat centerY; 16 | @property (nonatomic, assign) CGFloat width; 17 | @property (nonatomic, assign) CGFloat height; 18 | @property (nonatomic, assign) CGSize size; 19 | @property (nonatomic, assign) CGFloat maxX; 20 | @property (nonatomic, assign) CGFloat MaxY; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/UIView+Frame.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Frame.m 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/28. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import "UIView+Frame.h" 10 | 11 | @implementation UIView (Frame) 12 | - (void)setSize:(CGSize)size 13 | { 14 | CGRect frame = self.frame; 15 | frame.size = size; 16 | self.frame = frame; 17 | } 18 | 19 | - (CGSize)size 20 | { 21 | return self.frame.size; 22 | } 23 | 24 | - (void)setX:(CGFloat)x 25 | { 26 | CGRect frame = self.frame; 27 | frame.origin.x = x; 28 | self.frame = frame; 29 | } 30 | 31 | - (CGFloat)x 32 | { 33 | return self.frame.origin.x; 34 | } 35 | 36 | - (void)setY:(CGFloat)y 37 | { 38 | CGRect frame = self.frame; 39 | frame.origin.y = y; 40 | self.frame = frame; 41 | } 42 | 43 | - (CGFloat)y 44 | { 45 | return self.frame.origin.y; 46 | } 47 | 48 | - (void)setWidth:(CGFloat)width 49 | { 50 | CGRect frame = self.frame; 51 | frame.size.width = width; 52 | self.frame = frame; 53 | } 54 | 55 | - (CGFloat)width 56 | { 57 | return self.frame.size.width; 58 | } 59 | 60 | - (void)setHeight:(CGFloat)height 61 | { 62 | CGRect frame = self.frame; 63 | frame.size.height = height; 64 | self.frame = frame; 65 | } 66 | 67 | - (CGFloat)height 68 | { 69 | return self.frame.size.height; 70 | } 71 | 72 | - (void)setMaxX:(CGFloat)maxX 73 | { 74 | CGRect frame = self.frame; 75 | frame.origin.x = maxX - self.frame.size.width; 76 | self.frame = frame; 77 | } 78 | 79 | - (CGFloat)maxX 80 | { 81 | return self.frame.size.width + self.frame.origin.x; 82 | } 83 | 84 | - (void)setMaxY:(CGFloat)MaxY 85 | { 86 | CGRect frame = self.frame; 87 | frame.origin.y = MaxY - self.frame.size.height; 88 | self.frame = frame; 89 | } 90 | 91 | - (CGFloat)MaxY 92 | { 93 | return self.frame.size.height + self.frame.origin.y; 94 | } 95 | 96 | - (void)setCenterX:(CGFloat)centerX 97 | { 98 | CGPoint center = self.center; 99 | center.x = centerX; 100 | self.center = center; 101 | } 102 | 103 | - (CGFloat)centerX 104 | { 105 | return self.center.x; 106 | } 107 | 108 | - (void)setCenterY:(CGFloat)centerY 109 | { 110 | CGPoint center = self.center; 111 | center.y = centerY; 112 | self.center = center; 113 | } 114 | 115 | - (CGFloat)centerY 116 | { 117 | return self.center.y; 118 | } 119 | @end 120 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/UtilSrc/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | File: debug.h 3 | Abstract: Utility functions for debugging. 4 | Version: 1.13 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2014 Apple Inc. All Rights Reserved. 45 | 46 | */ 47 | 48 | #define glError() { \ 49 | GLenum err = glGetError(); \ 50 | if (err != GL_NO_ERROR) { \ 51 | printf("glError: %04x caught at %s:%u\n", err, __FILE__, __LINE__); \ 52 | } \ 53 | } 54 | 55 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/UtilSrc/fileUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | File: fileUtil.h 3 | Abstract: Functions for loading source files. 4 | Version: 1.13 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2014 Apple Inc. All Rights Reserved. 45 | 46 | */ 47 | 48 | #ifndef FILEUTIL_H 49 | #define FILEUTIL_H 50 | 51 | const char *pathForResource(const char *name); 52 | char *readFile(const char *name); 53 | 54 | #endif /* FILEUTIL_H */ 55 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/UtilSrc/fileUtil.m: -------------------------------------------------------------------------------- 1 | /* 2 | File: fileUtil.m 3 | Abstract: Functions for loading source files. 4 | Version: 1.13 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2014 Apple Inc. All Rights Reserved. 45 | 46 | */ 47 | 48 | #import 49 | #import 50 | 51 | const char *pathForResource(const char *name) 52 | { 53 | NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:name] ofType: nil]; 54 | return [path fileSystemRepresentation]; 55 | } 56 | 57 | char *readFile(const char *name) 58 | { 59 | struct stat statbuf; 60 | FILE *fh; 61 | char *source; 62 | 63 | fh = fopen(name, "r"); 64 | if (fh == 0) 65 | return 0; 66 | 67 | stat(name, &statbuf); 68 | source = (char *) malloc(statbuf.st_size + 1); 69 | fread(source, statbuf.st_size, 1, fh); 70 | source[statbuf.st_size] = '\0'; 71 | fclose(fh); 72 | 73 | return source; 74 | } 75 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/UtilSrc/shaderUtil.c: -------------------------------------------------------------------------------- 1 | /* 2 | File: shaderUtil.c 3 | Abstract: Functions that compile, link and validate shader programs. 4 | Version: 1.13 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2014 Apple Inc. All Rights Reserved. 45 | 46 | */ 47 | 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include "ShaderUtil.h" 53 | #include "debug.h" 54 | 55 | 56 | #define LogInfo printf 57 | #define LogError printf 58 | 59 | 60 | /* Compile a shader from the provided source(s) */ 61 | GLint glueCompileShader(GLenum target, GLsizei count, const GLchar **sources, GLuint *shader) 62 | { 63 | GLint logLength, status; 64 | 65 | *shader = glCreateShader(target); 66 | glShaderSource(*shader, count, sources, NULL); 67 | glCompileShader(*shader); 68 | glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); 69 | if (logLength > 0) 70 | { 71 | GLchar *log = (GLchar *)malloc(logLength); 72 | glGetShaderInfoLog(*shader, logLength, &logLength, log); 73 | LogInfo("Shader compile log:\n%s", log); 74 | free(log); 75 | } 76 | 77 | glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); 78 | if (status == 0) 79 | { 80 | int i; 81 | 82 | LogError("Failed to compile shader:\n"); 83 | for (i = 0; i < count; i++) 84 | LogInfo("%s", sources[i]); 85 | } 86 | glError(); 87 | 88 | return status; 89 | } 90 | 91 | 92 | /* Link a program with all currently attached shaders */ 93 | GLint glueLinkProgram(GLuint program) 94 | { 95 | GLint logLength, status; 96 | 97 | glLinkProgram(program); 98 | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); 99 | if (logLength > 0) 100 | { 101 | GLchar *log = (GLchar *)malloc(logLength); 102 | glGetProgramInfoLog(program, logLength, &logLength, log); 103 | LogInfo("Program link log:\n%s", log); 104 | free(log); 105 | } 106 | 107 | glGetProgramiv(program, GL_LINK_STATUS, &status); 108 | if (status == 0) 109 | LogError("Failed to link program %d", program); 110 | glError(); 111 | 112 | return status; 113 | } 114 | 115 | 116 | /* Validate a program (for i.e. inconsistent samplers) */ 117 | GLint glueValidateProgram(GLuint program) 118 | { 119 | GLint logLength, status; 120 | 121 | glValidateProgram(program); 122 | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); 123 | if (logLength > 0) 124 | { 125 | GLchar *log = (GLchar *)malloc(logLength); 126 | glGetProgramInfoLog(program, logLength, &logLength, log); 127 | LogInfo("Program validate log:\n%s", log); 128 | free(log); 129 | } 130 | 131 | glGetProgramiv(program, GL_VALIDATE_STATUS, &status); 132 | if (status == 0) 133 | LogError("Failed to validate program %d", program); 134 | glError(); 135 | 136 | return status; 137 | } 138 | 139 | 140 | /* Return named uniform location after linking */ 141 | GLint glueGetUniformLocation(GLuint program, const GLchar *uniformName) 142 | { 143 | GLint loc; 144 | 145 | loc = glGetUniformLocation(program, uniformName); 146 | 147 | return loc; 148 | } 149 | 150 | 151 | /* Convenience wrapper that compiles, links, enumerates uniforms and attribs */ 152 | GLint glueCreateProgram(const GLchar *vertSource, const GLchar *fragSource, 153 | GLsizei attribNameCt, const GLchar **attribNames, 154 | const GLint *attribLocations, 155 | GLsizei uniformNameCt, const GLchar **uniformNames, 156 | GLint *uniformLocations, 157 | GLuint *program) 158 | { 159 | GLuint vertShader = 0, fragShader = 0, prog = 0, status = 1, i; 160 | 161 | prog = glCreateProgram(); 162 | 163 | status *= glueCompileShader(GL_VERTEX_SHADER, 1, &vertSource, &vertShader); 164 | status *= glueCompileShader(GL_FRAGMENT_SHADER, 1, &fragSource, &fragShader); 165 | glAttachShader(prog, vertShader); 166 | glAttachShader(prog, fragShader); 167 | 168 | for (i = 0; i < attribNameCt; i++) 169 | { 170 | if(strlen(attribNames[i])) 171 | glBindAttribLocation(prog, attribLocations[i], attribNames[i]); 172 | } 173 | 174 | status *= glueLinkProgram(prog); 175 | status *= glueValidateProgram(prog); 176 | 177 | if (status) 178 | { 179 | for(i = 0; i < uniformNameCt; i++) 180 | { 181 | if(strlen(uniformNames[i])) 182 | uniformLocations[i] = glueGetUniformLocation(prog, uniformNames[i]); 183 | } 184 | *program = prog; 185 | } 186 | if (vertShader) 187 | glDeleteShader(vertShader); 188 | if (fragShader) 189 | glDeleteShader(fragShader); 190 | glError(); 191 | 192 | return status; 193 | } 194 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/UtilSrc/shaderUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | File: shaderUtil.h 3 | Abstract: Functions that compile, link and validate shader programs. 4 | Version: 1.13 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2014 Apple Inc. All Rights Reserved. 45 | 46 | */ 47 | 48 | #ifndef SHADERUTIL_H 49 | #define SHADERUTIL_H 50 | 51 | #import 52 | 53 | /* Shader Utilities */ 54 | GLint glueCompileShader(GLenum target, GLsizei count, const GLchar **sources, GLuint *shader); 55 | GLint glueLinkProgram(GLuint program); 56 | GLint glueValidateProgram(GLuint program); 57 | GLint glueGetUniformLocation(GLuint program, const GLchar *name); 58 | 59 | /* Shader Conveniences */ 60 | GLint glueCreateProgram(const GLchar *vertSource, const GLchar *fragSource, 61 | GLsizei attribNameCt, const GLchar **attribNames, 62 | const GLint *attribLocations, 63 | GLsizei uniformNameCt, const GLchar **uniformNames, 64 | GLint *uniformLocations, 65 | GLuint *program); 66 | 67 | #ifdef __cplusplus 68 | } 69 | #endif 70 | 71 | #endif /* SHADERUTIL_H */ 72 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/OpenGLPaint/说明.h: -------------------------------------------------------------------------------- 1 | // 2 | // 说明.h 3 | // GLPaintPad 4 | // 5 | // Created by Wade on 16/4/21. 6 | // Copyright © 2016年 collegepre. All rights reserved. 7 | // 8 | 9 | #ifndef ___h 10 | #define ___h 11 | 12 | //在 GLSL 中,实际有三种标签可以赋值给我们的变量: 13 | 14 | Uniforms 15 | Attributes 16 | Varyings 17 | Uniforms 是一种外界和你的着色器交流的方式。Uniforms 是为在一个渲染循环里不变的输入值设计的。如果你正在应用茶色滤镜,并且你已经指定了滤镜的强度,那么这些就是在渲染过程中不需要改变的事情,你可以把它作为 Uniform 输入。 Uniform 在顶点着色器和片段着色器里都可以被访问到。 18 | 19 | Attributes 仅仅可以在顶点着色器中被访问。Attribute 是在随着每一个顶点不同而会发生变动的输入值,例如顶点的位置和纹理坐标等。顶点着色器利用这些变量来计算位置,以它们为基础计算一些值,然后把这些值以 varyings 的方式传到片段着色器。 20 | 21 | 最后,但同样重要的,是 varyings 标签。Varying 在顶点着色器和片段着色器都会出现。Varying 是用来在顶点着色器和片段着色器传递信息的,并且在顶点着色器和片段着色器中必须有匹配的名字。数值在顶点着色器被写入到 varying ,然后在片段着色器被读出。被写入 varying 中的值,在片段着色器中会被以插值的形式插入到两个顶点直接的各个像素中去。 22 | 23 | 回看我们之前写的简单的着色器的例子,在顶点着色器和片段着色器中都用 varying 声明了 textureCoordinate。我们在顶点着色器中写入 varying 的值。然后我们把它传入片段着色器,并在片段着色器中读取和处理。 24 | 25 | 26 | 27 | 28 | //向量 29 | 在 GLSL 中,你会用到很多向量和向量类型。向量是一个很棘手的话题,它们表面上看起来很直观,但是因为它们有很多用途,这使我们在使用它们时常常会感到迷惑。 30 | 31 | 在 GLSL 环境中,向量是一个类似数组的特殊的数据类型。每一种类型都有固定的可以保存的元素。深入研究一下,你甚至可以获得数组可以存储的数值的精确的类型。但是在大多数情况下,只要使用通用的向量类型就足够了。 32 | 33 | 有三种向量类型你会经常看到: 34 | 35 | vec2 36 | vec3 37 | vec4 38 | 这些向量类型包含特定数量的浮点数:vec2 包含两个浮点数,vec3 包含三个浮点数,vec4 包含四个浮点数。 39 | 40 | 这些类型可以被用在着色器中可能被改变或者持有的多种数据类型中。在片段着色器中,很明显 X 和 Y 坐标是的你想保存的信息。 (X,Y) 存储在 vec2 中就很合适。 41 | 42 | 在图像处理过程中,另一个你可能想持续追踪的事情就是每个像素的 R,G,B,A 值。这些可以被存储在 vec4 中。 43 | 44 | 45 | //矩阵 46 | 现在我们已经了解了向量,接下来继续了解矩阵。矩阵和向量很相似,但是它们添加了额外一层的复杂度。矩阵是一个浮点数数组的数组,而不是单个的简单浮点数数组。 47 | 48 | 类似于向量,你将会经常处理的矩阵对象是: 49 | 50 | mat2 51 | mat3 52 | mat4 53 | vec2 保存两个浮点数,mat 保存相当于两个 vec2 对象的值。将向量对象传递到矩阵对象并不是必须的,只需要有足够填充矩阵的浮点数即可。在 mat2 中,你需要传入两个 vec2 或者四个浮点数。因为你可以给向量命名,而且相比于直接传浮点数,你只需要负责两个对象,而不是四个,所以非常推荐使用封装好的值来存储你的数字,这样更利于追踪。对于 mat4 会更复杂一些,因为你要负责 16 个数字,而不是 4 个。 54 | 55 | 在我们 mat2 的例子中,我们有两个 vec2 对象。每个 vec2 对象代表一行。每个 vec2 对象的第一个元素代表一列。构建你的矩阵对象的时候,确保每个值都放在了正确的行和列上是很重要的,否则使用它们进行运算肯定得不到正确的结果。 56 | 57 | 既然我们有了矩阵也有了填充矩阵的向量,问题来了:“我们要用它们做什么呢?“ 我们可以存储点和颜色或者其他的一些的信息,但是要如果通过修改它们来做一些很酷的事情呢? 58 | #endif /* ___h */ 59 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/UndoBezipath/DCUndoBeziPathPaintBoard.h: -------------------------------------------------------------------------------- 1 | // 2 | // DCUndoBeziPathPaintBoard.h 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/26. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DCUndoBeziPathPaintBoard : UIView 12 | /** 13 | * 画线的颜色 14 | */ 15 | @property (nonatomic, strong) UIColor *lineColor; 16 | /** 17 | * 是否是橡皮擦状态 18 | */ 19 | @property (nonatomic, assign) BOOL isErase; 20 | /** 21 | * 清楚画笔 22 | */ 23 | - (void)clear; 24 | @end 25 | -------------------------------------------------------------------------------- /DCPaintBoard/PaintBoard/UndoBezipath/DCUndoBeziPathPaintBoard.m: -------------------------------------------------------------------------------- 1 | // 2 | // DCUndoBeziPathPaintBoard.m 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/26. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import "DCUndoBeziPathPaintBoard.h" 10 | #import "DCCommon.h" 11 | 12 | @interface DCUndoBeziPathPaintBoard() 13 | // 存储正在画的点 14 | @property (strong, nonatomic) NSMutableArray *pointsArrM; 15 | //正在画的所有的点集合 16 | @property (strong, nonatomic) NSMutableArray *linesArrM; 17 | // 存储所有路径 18 | @property (strong, nonatomic) NSMutableDictionary *pathsDictM; 19 | 20 | 21 | 22 | 23 | @property (nonatomic, strong) NSUndoManager *undoManager; 24 | @property (nonatomic, assign) CGPoint currentPoint; 25 | @property (nonatomic, assign) CGPoint previousPoint1; 26 | @property (nonatomic, assign) CGPoint previousPoint2; 27 | @property (nonatomic, strong) UIImage *curImage; 28 | @property (nonatomic, assign) CGContextRef context; 29 | @property (nonatomic, assign) BOOL isSeachPoints; 30 | 31 | @property (nonatomic, assign) CGFloat lineWidth; 32 | 33 | -(void)undo; 34 | - (UIImage *)imageRepresentation; 35 | 36 | 37 | @end 38 | 39 | 40 | @implementation DCUndoBeziPathPaintBoard 41 | @synthesize undoManager; 42 | - (NSMutableArray *)linesArrM 43 | { 44 | if (!_linesArrM) { 45 | _linesArrM = [NSMutableArray array]; 46 | } 47 | return _linesArrM; 48 | } 49 | 50 | 51 | - (NSMutableArray *)pointsArrM 52 | { 53 | if (!_pointsArrM) { 54 | _pointsArrM = [NSMutableArray array]; 55 | } 56 | return _pointsArrM; 57 | } 58 | 59 | - (NSMutableDictionary *)pathsDictM 60 | { 61 | if (!_pathsDictM) { 62 | _pathsDictM = [NSMutableDictionary dictionary]; 63 | } 64 | return _pathsDictM; 65 | } 66 | 67 | - (void)setIsErase:(BOOL)isErase 68 | { 69 | _isErase = isErase; 70 | self.lineWidth = isErase?kEraseLineWidth:kLineWidth; 71 | } 72 | 73 | - (void)awakeFromNib{ 74 | [self setup]; 75 | } 76 | 77 | // 画笔的初始化设置 78 | -(void)setup 79 | { 80 | self.multipleTouchEnabled = YES; 81 | self.lineWidth = 5; 82 | 83 | self.lineColor =[UIColor blackColor]; 84 | 85 | NSUndoManager *tempUndoManager = [[NSUndoManager alloc] init]; 86 | [tempUndoManager setLevelsOfUndo:10]; 87 | [self setUndoManager:tempUndoManager]; 88 | } 89 | 90 | - (UIImage *)imageRepresentation 91 | { 92 | UIGraphicsBeginImageContext(self.bounds.size); 93 | [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 94 | UIImage *image= UIGraphicsGetImageFromCurrentImageContext(); 95 | UIGraphicsEndImageContext(); 96 | return image; 97 | } 98 | 99 | // 重写了undo方法 100 | -(void)undo 101 | { 102 | if ([self.undoManager canUndo]) 103 | { 104 | [self.undoManager undo]; 105 | NSData *data; 106 | if (UIImagePNGRepresentation(self.curImage) == nil) 107 | data = UIImageJPEGRepresentation(self.curImage, 1); 108 | else 109 | data = UIImagePNGRepresentation(self.curImage); 110 | NSFileManager *fileManager = [NSFileManager defaultManager]; 111 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);//程序文件夹主目录 112 | NSString *documentsDirectory = [paths objectAtIndex:0];//Document目录 113 | static int i =1; 114 | [fileManager createFileAtPath:[documentsDirectory stringByAppendingString:[NSString stringWithFormat:@"/image%d.png",i++]] contents:data attributes:nil]; 115 | self.previousPoint1=CGPointMake(0, 0); 116 | self.previousPoint2=CGPointMake(0, 0); 117 | self.currentPoint = CGPointMake(0, 0); 118 | [self setNeedsDisplay]; 119 | } 120 | } 121 | 122 | // 清楚画面和存储的数据 123 | -(void)clear 124 | { 125 | // [self setImage:nil]; 126 | self.previousPoint1=CGPointMake(0, 0); 127 | self.previousPoint2=CGPointMake(0, 0); 128 | self.currentPoint = CGPointMake(0, 0); 129 | [self setNeedsDisplay]; 130 | } 131 | 132 | 133 | // 计算中间点 134 | CGPoint midPoint1(CGPoint p1, CGPoint p2) 135 | { 136 | return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5); 137 | } 138 | 139 | #pragma mark -touchesBegan方法 140 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 141 | { 142 | // [[self.undoManager prepareWithInvocationTarget:self] setImage:[self imageRepresentation]]; 143 | 144 | UITouch *touch = [touches anyObject]; 145 | 146 | CGPoint currentPoint = [touch locationInView:self]; 147 | 148 | self.previousPoint1 = [touch locationInView:self]; 149 | self.previousPoint2 = [touch locationInView:self]; 150 | self.currentPoint = [touch locationInView:self]; 151 | 152 | CGMutablePathRef path = CGPathCreateMutable(); 153 | CGPathMoveToPoint(path, NULL, self.previousPoint1.x, self.previousPoint1.y); 154 | 155 | 156 | [self.pointsArrM removeAllObjects]; 157 | // 添加点集合 158 | NSDictionary *dict = @{@"x":@(currentPoint.x),@"y":@(currentPoint.y)}; 159 | [self.pointsArrM addObject:dict]; 160 | } 161 | 162 | #pragma mark -touchesMoved方法 163 | -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 164 | { 165 | UITouch *touch = [touches anyObject]; 166 | 167 | CGPoint currentPoint = [touch locationInView:self]; 168 | self.previousPoint2 = self.previousPoint1; 169 | self.previousPoint1 = [touch previousLocationInView:self]; 170 | self.currentPoint = [touch locationInView:self]; 171 | 172 | CGPoint mid1 = midPoint1(self.previousPoint1, self.previousPoint2); 173 | CGPoint mid2 = midPoint1(self.currentPoint, self.previousPoint1); 174 | CGMutablePathRef path = CGPathCreateMutable(); 175 | CGPathMoveToPoint(path, NULL, mid1.x, mid1.y); 176 | CGPathAddQuadCurveToPoint(path, NULL, self.previousPoint1.x, self.previousPoint1.y, mid2.x, mid2.y); 177 | 178 | CGRect bounds = CGPathGetBoundingBox(path); 179 | CGPathRelease(path); 180 | CGRect drawBox = bounds; 181 | 182 | //Pad our values so the bounding box respects our line width 183 | drawBox.origin.x -= self.lineWidth * 2; 184 | drawBox.origin.y -= self.lineWidth * 2; 185 | drawBox.size.width += self.lineWidth * 4; 186 | drawBox.size.height += self.lineWidth * 4; 187 | 188 | UIGraphicsBeginImageContext(drawBox.size); 189 | [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 190 | self.curImage = UIGraphicsGetImageFromCurrentImageContext(); 191 | UIGraphicsEndImageContext(); 192 | 193 | [self setNeedsDisplayInRect:drawBox]; 194 | // 195 | NSDictionary *dict = @{@"x":@(currentPoint.x),@"y":@(currentPoint.y)}; 196 | 197 | [self.pointsArrM addObject:dict]; 198 | } 199 | 200 | 201 | #pragma mark -touchesEnded方法 202 | -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 203 | { 204 | // if([touches count] >= 2)return; 205 | UITouch *touch = [touches anyObject]; 206 | CGPoint currentPoint = [touch locationInView:self]; 207 | NSDictionary *dict = @{@"x":@(currentPoint.x),@"y":@(currentPoint.y)}; 208 | self.previousPoint2 = self.previousPoint1; 209 | self.previousPoint1 = [touch previousLocationInView:self]; 210 | self.currentPoint = [touch locationInView:self]; 211 | 212 | CGPoint mid1 = midPoint1(self.previousPoint1, self.previousPoint2); 213 | CGPoint mid2 = midPoint1(self.currentPoint, self.previousPoint1); 214 | 215 | CGMutablePathRef path = CGPathCreateMutable(); 216 | CGPathMoveToPoint(path, NULL, mid1.x, mid1.y); 217 | CGPathAddQuadCurveToPoint(path, NULL, self.previousPoint1.x, self.previousPoint1.y, mid2.x, mid2.y); 218 | 219 | //绘画 220 | CGRect bounds = CGPathGetBoundingBox(path); 221 | CGPathRelease(path); 222 | CGRect drawBox = bounds; 223 | 224 | //Pad our values so the bounding box respects our line width 225 | drawBox.origin.x -= self.lineWidth * 2; 226 | drawBox.origin.y -= self.lineWidth * 2; 227 | drawBox.size.width += self.lineWidth * 4; 228 | drawBox.size.height += self.lineWidth * 4; 229 | 230 | UIGraphicsBeginImageContext(drawBox.size); 231 | [self.layer renderInContext:UIGraphicsGetCurrentContext()]; 232 | self.curImage = UIGraphicsGetImageFromCurrentImageContext(); 233 | UIGraphicsEndImageContext(); 234 | 235 | [self setNeedsDisplayInRect:drawBox]; 236 | 237 | [self.pointsArrM addObject:dict]; 238 | 239 | 240 | } 241 | 242 | #pragma mark - 绘画方法 243 | - (void)drawRect:(CGRect)rect 244 | { 245 | //获取上下文 246 | [self.curImage drawAtPoint:CGPointMake(0, 0)]; 247 | CGPoint mid1 = midPoint1(self.previousPoint1, self.previousPoint2); 248 | CGPoint mid2 = midPoint1(self.currentPoint, self.previousPoint1); 249 | 250 | // 251 | self.context = UIGraphicsGetCurrentContext(); 252 | 253 | [self.layer renderInContext:self.context]; 254 | 255 | CGContextMoveToPoint(self.context, mid1.x, mid1.y); 256 | 257 | // CGPathAddQuadCurveToPoint 258 | CGContextAddQuadCurveToPoint(self.context, self.previousPoint1.x, self.previousPoint1.y, mid2.x, mid2.y); 259 | 260 | CGContextSetLineCap(self.context, kCGLineCapRound); 261 | 262 | CGContextSetLineWidth(self.context, self.isErase? kEraseLineWidth:kLineWidth); 263 | 264 | CGContextSetStrokeColorWithColor(self.context, self.isErase?[UIColor clearColor].CGColor:self.lineColor.CGColor); 265 | 266 | CGContextSetLineJoin(self.context, kCGLineJoinRound); 267 | 268 | CGContextSetBlendMode(self.context, self.isErase ? kCGBlendModeDestinationIn:kCGBlendModeNormal); 269 | 270 | CGContextStrokePath(self.context); 271 | 272 | [super drawRect:rect]; 273 | } 274 | 275 | 276 | @end 277 | -------------------------------------------------------------------------------- /DCPaintBoard/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/25. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /DCPaintBoard/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/25. 6 | // Copyright © 2016年 Wade. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "DCCommon.h" 11 | #import "DCBezierPaintBoard.h" 12 | #import "DCUndoBeziPathPaintBoard.h" 13 | #import "DCOpenGLDrawView.h" 14 | 15 | @interface ViewController () 16 | @property (weak, nonatomic) IBOutlet DCOpenGLDrawView *openGlDrawView; 17 | 18 | @property (weak, nonatomic) IBOutlet DCUndoBeziPathPaintBoard *undoDrawView; 19 | 20 | @property (weak, nonatomic) IBOutlet DCBezierPaintBoard *beziPathDrawView; 21 | 22 | @property (weak, nonatomic) IBOutlet UIButton *selectColorBtn; 23 | @property (weak, nonatomic) IBOutlet UIButton *beziPathBtn; 24 | @property (weak, nonatomic) IBOutlet UIButton *undoBeziPath; 25 | @property (weak, nonatomic) IBOutlet UIButton *openGLBtn; 26 | @property (weak, nonatomic) IBOutlet UIView *colorView; 27 | @property (weak, nonatomic) IBOutlet UIButton *eraseBtn; 28 | 29 | @property (nonatomic, assign)DCPaintColor selectPaintColor; 30 | @property (nonatomic, assign) BOOL isErase; 31 | @property (nonatomic, assign) DCPaintBoardType paintBoardType; 32 | 33 | 34 | @property (nonatomic, strong) UIColor *paintColor; 35 | 36 | @end 37 | 38 | @implementation ViewController 39 | /** 40 | * 画笔颜色set方法 41 | * 42 | * @param selectPaintColor <#selectPaintColor description#> 43 | */ 44 | - (void)setSelectPaintColor:(DCPaintColor)selectPaintColor 45 | { 46 | _selectPaintColor = selectPaintColor; 47 | switch (selectPaintColor) { 48 | case DCPaintColorRed: 49 | self.paintColor = [UIColor redColor]; 50 | break; 51 | case DCPaintColorBlue: 52 | self.paintColor = [UIColor blueColor]; 53 | break; 54 | case DCPaintColorGreen: 55 | self.paintColor = [UIColor greenColor]; 56 | break; 57 | case DCPaintColorBlack: 58 | self.paintColor = [UIColor blackColor]; 59 | break; 60 | default: 61 | self.paintColor = [UIColor blackColor]; 62 | break; 63 | } 64 | 65 | self.beziPathDrawView.lineColor = self.paintColor; 66 | self.undoDrawView.lineColor = self.paintColor; 67 | self.openGlDrawView.lineColor = self.paintColor; 68 | } 69 | 70 | - (void)setPaintBoardType:(DCPaintBoardType)paintBoardType 71 | { 72 | _paintBoardType = paintBoardType; 73 | switch (paintBoardType) { 74 | case DCPaintBoardTypeBezi:{ 75 | self.beziPathDrawView.hidden = NO; 76 | self.undoDrawView.hidden = YES; 77 | self.openGlDrawView.hidden = YES; 78 | break; 79 | } 80 | case DCPaintBoardTypeBeziUndo:{ 81 | self.beziPathDrawView.hidden = YES; 82 | self.undoDrawView.hidden = NO; 83 | self.openGlDrawView.hidden = YES; 84 | break; 85 | } 86 | case DCPaintBoardTypeOpenGL:{ 87 | self.beziPathDrawView.hidden = YES; 88 | self.undoDrawView.hidden = YES; 89 | self.openGlDrawView.hidden = NO; 90 | break; 91 | } 92 | 93 | default: 94 | { 95 | self.beziPathDrawView.hidden = NO; 96 | self.undoDrawView.hidden = YES; 97 | self.openGlDrawView.hidden = YES; 98 | break; 99 | } 100 | } 101 | } 102 | 103 | - (void)setIsErase:(BOOL)isErase{ 104 | _isErase = isErase; 105 | self.beziPathDrawView.isErase = isErase; 106 | self.undoDrawView.isErase = isErase; 107 | self.openGlDrawView.isErase = isErase; 108 | } 109 | 110 | - (void)viewDidLoad { 111 | [super viewDidLoad]; 112 | 113 | UILongPressGestureRecognizer *longpress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longpresseraseBtn:)]; 114 | longpress.minimumPressDuration = 0.5; //定义按的时间 115 | [self.eraseBtn addGestureRecognizer:longpress]; 116 | } 117 | 118 | - (void)longpresseraseBtn:(UILongPressGestureRecognizer *)gest{ 119 | [self.undoDrawView clear]; 120 | [self.openGlDrawView clear]; 121 | [self.beziPathDrawView clear]; 122 | } 123 | 124 | 125 | - (void)viewWillAppear:(BOOL)animated 126 | { 127 | [super viewWillAppear:animated]; 128 | [self selectPaintBoardBtnClcik:self.beziPathBtn]; 129 | [self selectColorBtnClick:_selectColorBtn]; 130 | self.selectPaintColor = DCPaintColorBlack; 131 | 132 | self.openGlDrawView.backgroundColor = [UIColor clearColor]; 133 | } 134 | 135 | 136 | /** 137 | * 画笔颜色按钮 138 | * 139 | * @param sender 画笔按钮 140 | */ 141 | - (IBAction)selectColorBtnClick:(UIButton *)sender { 142 | sender.selected = !sender.selected; 143 | self.colorView.hidden = sender.selected; 144 | } 145 | 146 | /** 147 | * 颜色选择按钮 148 | * 149 | * @param sender 颜色按钮 150 | */ 151 | - (IBAction)colorBtnSelect:(UIButton *)sender { 152 | if (sender.tag == 105) { 153 | 154 | }else{ 155 | self.selectPaintColor = (DCPaintColor)sender.tag - 100; 156 | } 157 | switch (self.selectPaintColor) { 158 | case DCPaintColorRed: 159 | { 160 | [self.selectColorBtn setImage:[UIImage imageNamed:@"btn_mark_red"] forState:UIControlStateSelected]; 161 | break; 162 | } 163 | case DCPaintColorBlue: 164 | { 165 | [self.selectColorBtn setImage:[UIImage imageNamed:@"btn_mark_blue"] forState:UIControlStateSelected]; 166 | break; 167 | } 168 | case DCPaintColorGreen: 169 | { 170 | [self.selectColorBtn setImage:[UIImage imageNamed:@"btn_mark_green"] forState:UIControlStateSelected]; 171 | break; 172 | } 173 | 174 | default: 175 | case DCPaintColorBlack: 176 | { 177 | [self.selectColorBtn setImage:[UIImage imageNamed:@"btn_mark_black"] forState:UIControlStateSelected]; 178 | break; 179 | } 180 | } 181 | self.colorView.hidden = YES; 182 | self.selectColorBtn.selected = YES; 183 | } 184 | 185 | 186 | /** 187 | * 点击橡皮擦按钮 188 | * 189 | * @param sender 橡皮擦按钮 190 | */ 191 | - (IBAction)eraseBtnClick:(UIButton *)sender { 192 | sender.selected = !sender.selected; 193 | self.isErase = sender.selected; 194 | } 195 | 196 | 197 | /** 198 | * 点击选中的是那一种画板 199 | * 200 | * @param sender 画板种类按钮 201 | */ 202 | - (IBAction)selectPaintBoardBtnClcik:(UIButton *)sender { 203 | if (!sender.selected) { 204 | self.paintBoardType = (DCPaintBoardType)sender.tag; 205 | switch (sender.tag) { 206 | case DCPaintBoardTypeBezi: 207 | { 208 | self.beziPathBtn.selected = YES; 209 | self.undoBeziPath.selected = NO; 210 | self.openGLBtn.selected = NO; 211 | break; 212 | } 213 | case DCPaintBoardTypeBeziUndo: 214 | { 215 | self.beziPathBtn.selected = NO; 216 | self.undoBeziPath.selected = YES; 217 | self.openGLBtn.selected = NO; 218 | break; 219 | } 220 | case DCPaintBoardTypeOpenGL: 221 | { 222 | self.beziPathBtn.selected = NO; 223 | self.undoBeziPath.selected = NO; 224 | self.openGLBtn.selected = YES; 225 | break; 226 | } 227 | 228 | default: 229 | { 230 | self.beziPathBtn.selected = YES; 231 | self.undoBeziPath.selected = NO; 232 | self.openGLBtn.selected = NO; 233 | break; 234 | } 235 | } 236 | } 237 | 238 | } 239 | 240 | @end 241 | -------------------------------------------------------------------------------- /DCPaintBoard/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DCPaintBoard 4 | // 5 | // Created by Wade on 16/4/25. 6 | // Copyright © 2016年 Wade. 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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Wade.D 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DCDrawView --------------------------------------------------------------------------------