├── 全景_图片 ├── test3.jpg ├── ViewController.h ├── AppDelegate.h ├── main.m ├── HTYGLKVC.h ├── Header.h ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── Main.storyboard │ └── LaunchScreen.storyboard ├── AppDelegate.m ├── ViewController.m └── HTYGLKVC.m ├── 全景_图片.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcuserdata │ └── lanou.xcuserdatad │ │ └── xcschemes │ │ └── 全景_图片.xcscheme └── project.pbxproj ├── 全景_图片Tests └── _____Tests.m └── 全景_图片UITests └── _____UITests.m /全景_图片/test3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WushuputiGH/Panorama/HEAD/全景_图片/test3.jpg -------------------------------------------------------------------------------- /全景_图片.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /全景_图片/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // 全景_图片 4 | // 5 | // Created by huang.ziyang on 16/8/4. 6 | // Copyright © 2016年 H. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface ViewController : GLKViewController 13 | 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /全景_图片/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // 全景_图片 4 | // 5 | // Created by huang.ziyang on 16/8/4. 6 | // Copyright © 2016年 H. 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 | -------------------------------------------------------------------------------- /全景_图片/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // 全景_图片 4 | // 5 | // Created by huang.ziyang on 16/8/4. 6 | // Copyright © 2016年 H. 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 | -------------------------------------------------------------------------------- /全景_图片/HTYGLKVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // HTYGLKVC.h 3 | // HTY360Player 4 | // 5 | // Created by  on 11/8/15. 6 | // Copyright © 2015 Hanton. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | 14 | @interface HTYGLKVC : GLKViewController 15 | 16 | @property (assign, nonatomic, readonly) BOOL isUsingMotion; 17 | 18 | - (void)startDeviceMotion; 19 | - (void)stopDeviceMotion; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /全景_图片Tests/_____Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // _____Tests.m 3 | // 全景_图片Tests 4 | // 5 | // Created by huang.ziyang on 16/8/4. 6 | // Copyright © 2016年 H. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface _____Tests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation _____Tests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /全景_图片/Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Header.h 3 | // 全景_图片 4 | // 5 | // Created by huang.ziyang on 16/8/4. 6 | // Copyright © 2016年 H. All rights reserved. 7 | // 8 | 9 | #ifndef Header_h 10 | #define Header_h 11 | 12 | 13 | #define ES_PI (3.14159265f) 14 | #define MAX_OVERTURE 95.0 15 | #define MIN_OVERTURE 25.0 16 | #define DEFAULT_OVERTURE 85.0 17 | #define ES_PI (3.14159265f) 18 | #define ROLL_CORRECTION ES_PI/2.0 19 | #define FramesPerSecond 30 20 | #define SphereSliceNum 200 21 | #define SphereRadius 1.0 22 | #define SphereScale 300 23 | 24 | // For digital component video the color format YCbCr is used. 25 | // ITU-R BT.709, which is the standard for HDTV. 26 | // http://www.equasys.de/colorconversion.html 27 | const GLfloat kColorConversion709[] = { 28 | 1.164, 1.164, 1.164, 29 | 0.0, -0.213, 2.112, 30 | 1.793, -0.533, 0.0, 31 | }; 32 | 33 | // Uniform index. 34 | enum { 35 | UNIFORM_MODELVIEWPROJECTION_MATRIX, 36 | UNIFORM_Y, 37 | UNIFORM_UV, 38 | UNIFORM_COLOR_CONVERSION_MATRIX, 39 | NUM_UNIFORMS 40 | }; 41 | GLint uniforms[NUM_UNIFORMS]; 42 | 43 | 44 | #endif /* Header_h */ 45 | -------------------------------------------------------------------------------- /全景_图片UITests/_____UITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // _____UITests.m 3 | // 全景_图片UITests 4 | // 5 | // Created by huang.ziyang on 16/8/4. 6 | // Copyright © 2016年 H. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface _____UITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation _____UITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /全景_图片/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /全景_图片/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /全景_图片/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 | -------------------------------------------------------------------------------- /全景_图片/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // 全景_图片 4 | // 5 | // Created by huang.ziyang on 16/8/4. 6 | // Copyright © 2016年 H. 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 | -------------------------------------------------------------------------------- /全景_图片.xcodeproj/xcuserdata/lanou.xcuserdatad/xcschemes/全景_图片.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /全景_图片/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // 全景_图片 4 | // 5 | // Created by huang.ziyang on 16/8/4. 6 | // Copyright © 2016年 H. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import 11 | #define ES_PI (3.14159265f) 12 | 13 | 14 | 15 | @interface ViewController () 16 | 17 | 18 | @property (nonatomic, strong)EAGLContext *context; // 渲染环境 19 | @property (nonatomic, assign)CGFloat overture; // 相机的广角角度 20 | 21 | 22 | /// 索引数 23 | @property (nonatomic, assign)int numIndices; 24 | 25 | /// 顶点索引缓存指针 26 | @property (nonatomic, assign)GLuint vertexIndicesBufferID; 27 | 28 | /// 顶点缓存指针 29 | @property (nonatomic, assign)GLuint vertexBufferID; 30 | 31 | /// 纹理缓存指针 32 | @property (nonatomic, assign)GLuint vertexTexCoordID; 33 | 34 | /// 着色器 35 | @property (nonatomic, strong)GLKBaseEffect *effect; 36 | 37 | /// 图片的纹理信息 38 | @property (nonatomic, strong)GLKTextureInfo *textureInfo; 39 | 40 | /// 运动管理(加速器与陀螺仪) 41 | @property (nonatomic, strong)CMMotionManager *motionManager; 42 | 43 | /// 运动属性 44 | //@property (nonatomic, strong)CMAttitude *referenceAttitude; 45 | 46 | /// 模型坐标系 47 | @property (nonatomic, assign)GLKMatrix4 modelViewMatrix; 48 | 49 | 50 | /// 平移手势 51 | @property (nonatomic, strong)UIPanGestureRecognizer *pan; 52 | /// 平移时候x轴的偏移量 53 | @property (nonatomic, assign)CGFloat panX; 54 | @property (nonatomic, assign)CGFloat panY; 55 | 56 | /// 缩放手势 57 | @property (nonatomic, strong)UIPinchGestureRecognizer *pinch; 58 | /// 缩放比例 59 | @property (nonatomic, assign)CGFloat scale; 60 | 61 | 62 | @end 63 | 64 | @implementation ViewController 65 | 66 | - (void)viewDidLoad { 67 | [super viewDidLoad]; 68 | 69 | 70 | /// 使用ES2创建一个"EAGLContext" 71 | self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 72 | 73 | /// 将“view”的context设置为这个“EAGLContext”实例的引用 74 | GLKView *view = (GLKView *)self.view; 75 | view.context = self.context; 76 | /// 设置颜色格式和深度格式 77 | view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; 78 | view.drawableDepthFormat = GLKViewDrawableDepthFormat24; 79 | 80 | self.preferredFramesPerSecond = 30; 81 | 82 | /// 设置GL 83 | [self setupGL]; 84 | 85 | /// 检测屏幕位置(加速器与陀螺仪) 86 | [self startDeviceMotion]; 87 | 88 | /// 添加手势 89 | [self addGestureRecognizer]; 90 | 91 | 92 | } 93 | 94 | 95 | #pragma mark ---设置GL--- 96 | 97 | - (void)setupGL { 98 | 99 | /// 将此“EAGLContext”实例设置为OpenGL的“当前激活”的“Context”, 这样,以后所有“GL”的指令均作用在这个“Context”上 100 | [EAGLContext setCurrentContext:self.context]; 101 | /// 激活“深度检测”: 注意, 设置深度检测一定要放在设置上一句的下面, 要不然context还没有激活 102 | glEnable(GL_DEPTH_TEST); 103 | 104 | 105 | /// 设置buffer 106 | [self setupBuffers]; 107 | 108 | } 109 | 110 | 111 | 112 | - (void)setupBuffers{ 113 | 114 | /// 顶点 115 | GLfloat *vVertices = NULL; 116 | 117 | /// 纹理 118 | GLfloat *vTextCoord = NULL; 119 | 120 | /// 索引 121 | GLushort *indices = NULL; 122 | 123 | int numVertices = 0; 124 | 125 | self.numIndices = esGenSphere(200, 1.0, &vVertices, &vTextCoord, &indices, &numVertices); 126 | 127 | // /// 将c数组, 转化为OC数组 128 | // 129 | // NSMutableArray *array = [NSMutableArray array]; 130 | // for (int i = 0; i< numVertices; i++) { 131 | // float n = vVertices[i]; 132 | // [array addObject:[NSNumber numberWithFloat:n]]; 133 | // } 134 | 135 | 136 | /// 索引 137 | glGenBuffers(1, &_vertexIndicesBufferID); 138 | // GL_ELEMENT_ARRAY_BUFFER(表示索引数据) 139 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.vertexIndicesBufferID); 140 | 141 | /** 142 | * self.numIndices*sizeof(GLushort) : 索引缓冲的长度, 143 | indices索引缓冲的数据, 参数“GL_STATIC_DRAW”,它表示此缓冲区内容只能被修改一次,但可以无限次读取。 144 | */ 145 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.numIndices*sizeof(GLushort), indices, GL_STATIC_DRAW); 146 | 147 | /// 顶点数据 148 | glGenBuffers(1, &_vertexBufferID); 149 | glBindBuffer(GL_ARRAY_BUFFER, self.vertexBufferID); 150 | glBufferData(GL_ARRAY_BUFFER, numVertices*3*sizeof(GLfloat), vVertices, GL_STATIC_DRAW); 151 | /// 激活顶点位置属性 152 | glEnableVertexAttribArray(GLKVertexAttribPosition); 153 | glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*3, NULL); 154 | 155 | /// 纹理数据 156 | glGenBuffers(1, &_vertexTexCoordID); 157 | glBindBuffer(GL_ARRAY_BUFFER, self.vertexTexCoordID); 158 | glBufferData(GL_ARRAY_BUFFER, numVertices*2*sizeof(GLfloat), vTextCoord, GL_DYNAMIC_DRAW); 159 | 160 | glEnableVertexAttribArray(GLKVertexAttribTexCoord0); 161 | glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, NULL); 162 | 163 | /// 将图片转换成为纹理信息 164 | NSString *testPath = [[NSBundle mainBundle] pathForResource:@"test3" ofType:@"jpg"]; 165 | 166 | /// 由于OpenGL的默认坐标系设置在左下角, 而GLKit在左上角, 因此需要转换 167 | NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], GLKTextureLoaderOriginBottomLeft, nil]; 168 | 169 | self.textureInfo = [GLKTextureLoader textureWithContentsOfFile:testPath options:options error:nil]; 170 | 171 | /// 设置着色器的纹理 172 | self.effect = [[GLKBaseEffect alloc] init]; 173 | self.effect. texture2d0.enabled = GL_TRUE; 174 | self.effect.texture2d0.name = self.textureInfo.name; 175 | // 176 | 177 | 178 | } 179 | 180 | #pragma mark --- 生成球的几何结构---- 181 | #pragma mark - Generate Sphere 182 | //https://github.com/danginsburg/opengles-book-samples/blob/604a02cc84f9cc4369f7efe93d2a1d7f2cab2ba7/iPhone/Common/esUtil.h#L110 183 | int esGenSphere(int numSlices, float radius, float **vertices, 184 | float **texCoords, uint16_t **indices, int *numVertices_out) { 185 | int numParallels = numSlices / 2; 186 | int numVertices = (numParallels + 1) * (numSlices + 1); 187 | int numIndices = numParallels * numSlices * 6; 188 | float angleStep = (2.0f * 3.14159265f) / ((float) numSlices); 189 | 190 | if (vertices != NULL) { 191 | *vertices = malloc(sizeof(float) * 3 * numVertices); 192 | } 193 | 194 | if (texCoords != NULL) { 195 | *texCoords = malloc(sizeof(float) * 2 * numVertices); 196 | } 197 | 198 | if (indices != NULL) { 199 | *indices = malloc(sizeof(uint16_t) * numIndices); 200 | } 201 | 202 | for (int i = 0; i < numParallels + 1; i++) { 203 | for (int j = 0; j < numSlices + 1; j++) { 204 | int vertex = (i * (numSlices + 1) + j) * 3; 205 | 206 | if (vertices) { 207 | (*vertices)[vertex + 0] = radius * sinf(angleStep * (float)i) * sinf(angleStep * (float)j); 208 | (*vertices)[vertex + 1] = radius * cosf(angleStep * (float)i); 209 | (*vertices)[vertex + 2] = radius * sinf(angleStep * (float)i) * cosf(angleStep * (float)j); 210 | } 211 | 212 | if (texCoords) { 213 | int texIndex = (i * (numSlices + 1) + j) * 2; 214 | (*texCoords)[texIndex + 0] = (float)j / (float)numSlices; 215 | (*texCoords)[texIndex + 1] = 1.0f - ((float)i / (float)numParallels); 216 | } 217 | } 218 | } 219 | 220 | // Generate the indices 221 | if (indices != NULL) { 222 | uint16_t *indexBuf = (*indices); 223 | for (int i = 0; i < numParallels ; i++) { 224 | for (int j = 0; j < numSlices; j++) { 225 | *indexBuf++ = i * (numSlices + 1) + j; 226 | *indexBuf++ = (i + 1) * (numSlices + 1) + j; 227 | *indexBuf++ = (i + 1) * (numSlices + 1) + (j + 1); 228 | 229 | *indexBuf++ = i * (numSlices + 1) + j; 230 | *indexBuf++ = (i + 1) * (numSlices + 1) + (j + 1); 231 | *indexBuf++ = i * (numSlices + 1) + (j + 1); 232 | } 233 | } 234 | } 235 | 236 | if (numVertices_out) { 237 | *numVertices_out = numVertices; 238 | } 239 | 240 | return numIndices; 241 | } 242 | 243 | #pragma mark ---开始驱动位置检测(加速区与陀螺仪)--- 244 | 245 | - (CMMotionManager *)motionManager{ 246 | if (!_motionManager) { 247 | _motionManager = [[CMMotionManager alloc] init]; 248 | 249 | /**设置运动更新间隔*/ 250 | _motionManager.deviceMotionUpdateInterval = 1.0 / 60.0; 251 | 252 | /**是否展示运动?*/ 253 | _motionManager.showsDeviceMovementDisplay = YES; 254 | 255 | } 256 | return _motionManager; 257 | } 258 | 259 | - (void)startDeviceMotion{ 260 | 261 | /**设置初始坐标系, 并开始监控 262 | CMAttitudeReferenceFrameXArbitraryCorrectedZVertical: 描述的参考系默认设备平放(垂直于Z轴),在X轴上取任意值。实际上当你开始刚开始对设备进行motion更新的时候X轴就被固定了。不过这里还使用了罗盘来对陀螺仪的测量数据做了误差修正 263 | 使用pull形式获取数据 264 | */ 265 | 266 | [self.motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryCorrectedZVertical]; 267 | 268 | 269 | self.modelViewMatrix = GLKMatrix4Identity; 270 | 271 | 272 | } 273 | 274 | 275 | #pragma mark -----添加手势----- 276 | 277 | - (void)addGestureRecognizer{ 278 | 279 | /// 平移手势 280 | self.pan =[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)]; 281 | [self.view addGestureRecognizer:self.pan]; 282 | 283 | /// 捏合手势 284 | self.pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchAction:)]; 285 | [self.view addGestureRecognizer:self.pinch]; 286 | self.scale = 1.0; 287 | } 288 | 289 | - (void)panAction:(UIPanGestureRecognizer *)pan{ 290 | 291 | // 获取位置 292 | CGPoint point = [pan translationInView:self.view]; 293 | self.panX += point.x; 294 | self.panY += point.y; 295 | 296 | //每次变换之后, 把改变值归零 297 | [pan setTranslation:CGPointZero inView:self.view]; 298 | 299 | } 300 | 301 | - (void)pinchAction:(UIPinchGestureRecognizer *)pinch{ 302 | self.scale *= pinch.scale; 303 | pinch.scale = 1.0; 304 | } 305 | 306 | #pragma mark ---GLKViewDelegate, 绘制---- 307 | 308 | - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{ 309 | 310 | /**清除颜色缓冲区内容时候: 使用蓝色填充*/ 311 | glClearColor(0.3f, 0.6f, 1.0f, 1.0f); 312 | /**清除颜色缓冲区与深度缓冲区内容*/ 313 | glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 314 | [self.effect prepareToDraw]; 315 | glDrawElements(GL_TRIANGLES, self.numIndices, GL_UNSIGNED_SHORT, 0); 316 | } 317 | 318 | #pragma mark ---变换坐标系投影------- 319 | 320 | - (void)update{ 321 | 322 | CGSize size = self.view.bounds.size; 323 | float aspect = fabs(size.width / size.height); 324 | 325 | /** 326 | * 根据缩放比例, 设置焦距 327 | */ 328 | CGFloat ovyRadians = 100 / self.scale; 329 | 330 | // ovyRadians不小于50, 不大于110; 331 | if (ovyRadians < 50) { 332 | ovyRadians = 50; 333 | self.scale = 1 / (50.0/100); 334 | } 335 | if (ovyRadians>110) { 336 | ovyRadians = 110; 337 | self.scale = 1 / (110.0/100); 338 | } 339 | 340 | 341 | /**GLKMatrix4MakePerspective 配置透视图 342 | 第一个参数, 类似于相机的焦距, 比如10表示窄角度, 100表示广角 一般65-75; 343 | 第二个参数: 表示时屏幕的纵横比 344 | 第三个, 第四参数: 是为了实现透视效果, 近大远处小, 要确保模型位于远近平面之间 345 | */ 346 | 347 | GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(ovyRadians), aspect, 0.1f, 400.0f); 348 | projectionMatrix = GLKMatrix4Scale(projectionMatrix, -1.0f, 1.0f, 1.0f); 349 | 350 | CMDeviceMotion *deviceMotion = self.motionManager.deviceMotion; 351 | 352 | double w = deviceMotion.attitude.quaternion.w; 353 | double wx = deviceMotion.attitude.quaternion.x; 354 | double wy = deviceMotion.attitude.quaternion.y; 355 | double wz = deviceMotion.attitude.quaternion.z; 356 | 357 | NSLog(@"w = %f, wx = %f, wy = %f wz = %f", w, wx, wy,wz); 358 | 359 | projectionMatrix = GLKMatrix4RotateX(projectionMatrix, -0.005*self.panY); 360 | 361 | GLKQuaternion quaternion = GLKQuaternionMake(-wx, wy, wz, w); 362 | GLKMatrix4 rotation = GLKMatrix4MakeWithQuaternion(quaternion); 363 | 364 | projectionMatrix = GLKMatrix4Multiply(projectionMatrix, rotation); 365 | 366 | /// 为了保证在水平放置手机的时候, 是从下往上看, 因此首先坐标系沿着x轴旋转90度 367 | projectionMatrix = GLKMatrix4RotateX(projectionMatrix, M_PI_2); 368 | self.effect.transform.projectionMatrix = projectionMatrix; 369 | 370 | 371 | GLKMatrix4 modelViewMatrix = GLKMatrix4Identity; 372 | modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, 0.005*self.panX); 373 | // self.panX = 0; 374 | // modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, 0.01*self.panY); 375 | // self.panY = 0; 376 | self.effect.transform.modelviewMatrix = modelViewMatrix; 377 | 378 | } 379 | 380 | 381 | 382 | - (void)didReceiveMemoryWarning { 383 | [super didReceiveMemoryWarning]; 384 | // Dispose of any resources that can be recreated. 385 | } 386 | 387 | @end 388 | -------------------------------------------------------------------------------- /全景_图片/HTYGLKVC.m: -------------------------------------------------------------------------------- 1 | // 2 | // HTYGLKVC.m 3 | // HTY360Player 4 | // 5 | // Created by  on 11/8/15. 6 | // Copyright © 2015 Hanton. All rights reserved. 7 | // 8 | 9 | #import "HTYGLKVC.h" 10 | #import "GLProgram.h" 11 | #import 12 | #import "Header.h" 13 | 14 | #define MAX_OVERTURE 95.0 15 | #define MIN_OVERTURE 25.0 16 | #define DEFAULT_OVERTURE 85.0 17 | //#define ES_PI (3.14159265f) 18 | #define ROLL_CORRECTION ES_PI/2.0 19 | #define FramesPerSecond 30 20 | #define SphereSliceNum 200 21 | #define SphereRadius 1.0 22 | #define SphereScale 300 23 | 24 | // For digital component video the color format YCbCr is used. 25 | // ITU-R BT.709, which is the standard for HDTV. 26 | // http://www.equasys.de/colorconversion.html 27 | //const GLfloat kColorConversion709[] = { 28 | // 1.164, 1.164, 1.164, 29 | // 0.0, -0.213, 2.112, 30 | // 1.793, -0.533, 0.0, 31 | //}; 32 | 33 | // Uniform index. 34 | 35 | 36 | @interface HTYGLKVC () 37 | 38 | @property (strong, nonatomic) EAGLContext *context; 39 | @property (strong, nonatomic) GLProgram *program; 40 | @property (strong, nonatomic) NSMutableArray *currentTouches; 41 | @property (strong, nonatomic) CMMotionManager *motionManager; 42 | @property (strong, nonatomic) CMAttitude *referenceAttitude; 43 | @property (nonatomic, strong) CADisplayLink *displayLink; 44 | @property (assign, nonatomic) CGFloat overture; 45 | @property (assign, nonatomic) CGFloat fingerRotationX; 46 | @property (assign, nonatomic) CGFloat fingerRotationY; 47 | @property (assign, nonatomic) CGFloat savedGyroRotationX; 48 | @property (assign, nonatomic) CGFloat savedGyroRotationY; 49 | @property (assign, nonatomic) int numIndices; 50 | @property (assign, nonatomic) CVOpenGLESTextureRef lumaTexture; 51 | @property (assign, nonatomic) CVOpenGLESTextureRef chromaTexture; 52 | @property (assign, nonatomic) CVOpenGLESTextureCacheRef videoTextureCache; 53 | @property (assign, nonatomic) GLKMatrix4 modelViewProjectionMatrix; 54 | @property (assign, nonatomic) GLuint vertexIndicesBufferID; 55 | @property (assign, nonatomic) GLuint vertexBufferID; 56 | @property (assign, nonatomic) GLuint vertexTexCoordID; 57 | @property (assign, nonatomic) GLuint vertexTexCoordAttributeIndex; 58 | @property (assign, nonatomic, readwrite) BOOL isUsingMotion; 59 | 60 | - (void)setupGL; 61 | - (void)tearDownGL; 62 | - (void)buildProgram; 63 | 64 | @end 65 | 66 | @implementation HTYGLKVC 67 | 68 | - (void)viewDidLoad { 69 | [super viewDidLoad]; 70 | 71 | self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 72 | 73 | if (!self.context) { 74 | NSLog(@"Failed to create ES context"); 75 | } 76 | 77 | GLKView *view = (GLKView *)self.view; 78 | view.context = self.context; 79 | view.drawableDepthFormat = GLKViewDrawableDepthFormat24; 80 | view.contentScaleFactor = [UIScreen mainScreen].scale; 81 | 82 | self.preferredFramesPerSecond = FramesPerSecond; 83 | self.overture = DEFAULT_OVERTURE; 84 | 85 | // [self addGesture]; 86 | [self setupGL]; 87 | [self startDeviceMotion]; 88 | } 89 | 90 | //- (void)refreshTexture { 91 | // CVReturn err; 92 | // CVPixelBufferRef pixelBuffer = [self.videoPlayerController retrievePixelBufferToDraw]; 93 | // if (pixelBuffer != nil) { 94 | // GLsizei textureWidth = (GLsizei)CVPixelBufferGetWidth(pixelBuffer); 95 | // GLsizei textureHeight = (GLsizei)CVPixelBufferGetHeight(pixelBuffer); 96 | // 97 | // if (!self.videoTextureCache) { 98 | // NSLog(@"No video texture cache"); 99 | // return; 100 | // } 101 | // 102 | //// [self cleanUpTextures]; 103 | // 104 | // // Y-plane 105 | //// glActiveTexture(GL_TEXTURE0); 106 | // err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, 107 | // self.videoTextureCache, 108 | // pixelBuffer, 109 | // NULL, 110 | // GL_TEXTURE_2D, 111 | // GL_RED_EXT, 112 | // textureWidth, 113 | // textureHeight, 114 | // GL_RED_EXT, 115 | // GL_UNSIGNED_BYTE, 116 | // 0, 117 | // &_lumaTexture); 118 | // if (err) { 119 | // NSLog(@"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err); 120 | // } 121 | // 122 | //// glBindTexture(CVOpenGLESTextureGetTarget(self.lumaTexture), CVOpenGLESTextureGetName(self.lumaTexture)); 123 | //// 124 | //// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 125 | //// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 126 | //// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 127 | //// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 128 | //// 129 | // // UV-plane. 130 | // glActiveTexture(GL_TEXTURE1); 131 | // err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, 132 | // self.videoTextureCache, 133 | // pixelBuffer, 134 | // NULL, 135 | // GL_TEXTURE_2D, 136 | // GL_RG_EXT, 137 | // textureWidth/2, 138 | // textureHeight/2, 139 | // GL_RG_EXT, 140 | // GL_UNSIGNED_BYTE, 141 | // 1, 142 | // &_chromaTexture); 143 | // if (err) { 144 | // NSLog(@"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err); 145 | // } 146 | // 147 | //// glBindTexture(CVOpenGLESTextureGetTarget(self.chromaTexture), CVOpenGLESTextureGetName(self.chromaTexture)); 148 | // 149 | // 150 | // NSString *testPath = [[NSBundle mainBundle] pathForResource:@"test3" ofType:@"jpg"]; 151 | // GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:testPath options:nil error:nil]; 152 | // glBindTexture(textureInfo.target, textureInfo.name); 153 | // 154 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 155 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 156 | // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 157 | // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 158 | // 159 | // CFRelease(pixelBuffer); 160 | // } 161 | //} 162 | 163 | //- (void)dealloc { 164 | // [self stopDeviceMotion]; 165 | // [self tearDownVideoCache]; 166 | // [self tearDownGL]; 167 | // 168 | // if ([EAGLContext currentContext] == _context) { 169 | // [EAGLContext setCurrentContext:nil]; 170 | // } 171 | //} 172 | 173 | //- (void)tearDownGL { 174 | // [EAGLContext setCurrentContext:self.context]; 175 | // 176 | // glDeleteBuffers(1, &_vertexIndicesBufferID); 177 | // glDeleteBuffers(1, &_vertexBufferID); 178 | // glDeleteBuffers(1, &_vertexTexCoordID); 179 | // 180 | // self.program = nil; 181 | //} 182 | 183 | //- (void)tearDownVideoCache { 184 | // [self cleanUpTextures]; 185 | // 186 | // CFRelease(_videoTextureCache); 187 | // self.videoTextureCache = nil; 188 | //} 189 | 190 | //- (UIInterfaceOrientationMask)supportedInterfaceOrientations { 191 | // return UIInterfaceOrientationMaskLandscape; 192 | //} 193 | // 194 | //- (void)addGesture { 195 | // UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self 196 | // action:@selector(handlePinchGesture:)]; 197 | // [self.view addGestureRecognizer:pinchRecognizer]; 198 | // 199 | // UITapGestureRecognizer *singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self 200 | // action:@selector(handleSingleTapGesture:)]; 201 | // singleTapRecognizer.numberOfTapsRequired = 1; 202 | // [self.view addGestureRecognizer:singleTapRecognizer]; 203 | //} 204 | // 205 | #pragma mark - Texture Cleanup 206 | 207 | //- (void)cleanUpTextures { 208 | // if (self.lumaTexture) { 209 | // CFRelease(_lumaTexture); 210 | // self.lumaTexture = NULL; 211 | // } 212 | // 213 | // if (self.chromaTexture) { 214 | // CFRelease(_chromaTexture); 215 | // self.chromaTexture = NULL; 216 | // } 217 | // 218 | // // Periodic texture cache flush every frame 219 | // CVOpenGLESTextureCacheFlush(_videoTextureCache, 0); 220 | //} 221 | 222 | #pragma mark - Generate Sphere 223 | //https://github.com/danginsburg/opengles-book-samples/blob/604a02cc84f9cc4369f7efe93d2a1d7f2cab2ba7/iPhone/Common/esUtil.h#L110 224 | int esGenSphere(int numSlices, float radius, float **vertices, 225 | float **texCoords, uint16_t **indices, int *numVertices_out) { 226 | int numParallels = numSlices / 2; 227 | int numVertices = (numParallels + 1) * (numSlices + 1); 228 | int numIndices = numParallels * numSlices * 6; 229 | float angleStep = (2.0f * ES_PI) / ((float) numSlices); 230 | 231 | if (vertices != NULL) { 232 | *vertices = malloc(sizeof(float) * 3 * numVertices); 233 | } 234 | 235 | if (texCoords != NULL) { 236 | *texCoords = malloc(sizeof(float) * 2 * numVertices); 237 | } 238 | 239 | if (indices != NULL) { 240 | *indices = malloc(sizeof(uint16_t) * numIndices); 241 | } 242 | 243 | for (int i = 0; i < numParallels + 1; i++) { 244 | for (int j = 0; j < numSlices + 1; j++) { 245 | int vertex = (i * (numSlices + 1) + j) * 3; 246 | 247 | if (vertices) { 248 | (*vertices)[vertex + 0] = radius * sinf(angleStep * (float)i) * sinf(angleStep * (float)j); 249 | (*vertices)[vertex + 1] = radius * cosf(angleStep * (float)i); 250 | (*vertices)[vertex + 2] = radius * sinf(angleStep * (float)i) * cosf(angleStep * (float)j); 251 | } 252 | 253 | if (texCoords) { 254 | int texIndex = (i * (numSlices + 1) + j) * 2; 255 | (*texCoords)[texIndex + 0] = (float)j / (float)numSlices; 256 | (*texCoords)[texIndex + 1] = 1.0f - ((float)i / (float)numParallels); 257 | } 258 | } 259 | } 260 | 261 | // Generate the indices 262 | if (indices != NULL) { 263 | uint16_t *indexBuf = (*indices); 264 | for (int i = 0; i < numParallels ; i++) { 265 | for (int j = 0; j < numSlices; j++) { 266 | *indexBuf++ = i * (numSlices + 1) + j; 267 | *indexBuf++ = (i + 1) * (numSlices + 1) + j; 268 | *indexBuf++ = (i + 1) * (numSlices + 1) + (j + 1); 269 | 270 | *indexBuf++ = i * (numSlices + 1) + j; 271 | *indexBuf++ = (i + 1) * (numSlices + 1) + (j + 1); 272 | *indexBuf++ = i * (numSlices + 1) + (j + 1); 273 | } 274 | } 275 | } 276 | 277 | if (numVertices_out) { 278 | *numVertices_out = numVertices; 279 | } 280 | 281 | return numIndices; 282 | } 283 | 284 | #pragma mark - Setup OpenGL 285 | 286 | - (void)setupGL { 287 | [EAGLContext setCurrentContext:self.context]; 288 | [self buildProgram]; 289 | [self setupBuffers]; 290 | // [self setupVideoCache]; 291 | [self.program use]; 292 | glUniform1i(uniforms[UNIFORM_Y], 0); 293 | glUniform1i(uniforms[UNIFORM_UV], 1); 294 | glUniformMatrix3fv(uniforms[UNIFORM_COLOR_CONVERSION_MATRIX], 1, GL_FALSE, kColorConversion709); 295 | } 296 | 297 | - (void)setupBuffers { 298 | GLfloat *vVertices = NULL; 299 | GLfloat *vTextCoord = NULL; 300 | GLushort *indices = NULL; 301 | int numVertices = 0; 302 | self.numIndices = esGenSphere(SphereSliceNum, SphereRadius, &vVertices, &vTextCoord, &indices, &numVertices); 303 | 304 | //Indices 305 | glGenBuffers(1, &_vertexIndicesBufferID); 306 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.vertexIndicesBufferID); 307 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.numIndices*sizeof(GLushort), indices, GL_STATIC_DRAW); 308 | 309 | // Vertex 310 | glGenBuffers(1, &_vertexBufferID); 311 | glBindBuffer(GL_ARRAY_BUFFER, self.vertexBufferID); 312 | glBufferData(GL_ARRAY_BUFFER, numVertices*3*sizeof(GLfloat), vVertices, GL_STATIC_DRAW); 313 | 314 | glEnableVertexAttribArray(GLKVertexAttribPosition); 315 | glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*3, NULL); 316 | 317 | // Texture Coordinates 318 | glGenBuffers(1, &_vertexTexCoordID); 319 | glBindBuffer(GL_ARRAY_BUFFER, self.vertexTexCoordID); 320 | glBufferData(GL_ARRAY_BUFFER, numVertices*2*sizeof(GLfloat), vTextCoord, GL_DYNAMIC_DRAW); 321 | 322 | glEnableVertexAttribArray(self.vertexTexCoordAttributeIndex); 323 | glVertexAttribPointer(self.vertexTexCoordAttributeIndex, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, NULL); 324 | 325 | 326 | glActiveTexture(GL_TEXTURE1); 327 | NSString *testPath = [[NSBundle mainBundle] pathForResource:@"test3" ofType:@"jpg"]; 328 | GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:testPath options:nil error:nil]; 329 | glBindTexture(textureInfo.target, textureInfo.name); 330 | 331 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 332 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 333 | glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 334 | glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 335 | 336 | } 337 | 338 | //- (void)setupVideoCache { 339 | // if (!self.videoTextureCache) { 340 | // CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, self.context, NULL, &_videoTextureCache); 341 | // if (err != noErr) { 342 | // NSLog(@"Error at CVOpenGLESTextureCacheCreate %d", err); 343 | // return; 344 | // } 345 | // } 346 | //} 347 | 348 | #pragma mark - Device Motion 349 | 350 | - (void)startDeviceMotion { 351 | self.isUsingMotion = NO; 352 | 353 | self.motionManager = [[CMMotionManager alloc] init]; 354 | self.referenceAttitude = nil; 355 | self.motionManager.deviceMotionUpdateInterval = 1.0 / 60.0; 356 | self.motionManager.gyroUpdateInterval = 1.0f / 60; 357 | self.motionManager.showsDeviceMovementDisplay = YES; 358 | 359 | [self.motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryCorrectedZVertical]; 360 | 361 | self.referenceAttitude = self.motionManager.deviceMotion.attitude; // Maybe nil actually. reset it later when we have data 362 | 363 | self.savedGyroRotationX = 0; 364 | self.savedGyroRotationY = 0; 365 | 366 | self.isUsingMotion = YES; 367 | } 368 | 369 | //- (void)stopDeviceMotion { 370 | // self.fingerRotationX = self.savedGyroRotationX-self.referenceAttitude.roll- ROLL_CORRECTION; 371 | // self.fingerRotationY = self.savedGyroRotationY; 372 | // 373 | // self.isUsingMotion = NO; 374 | // [self.motionManager stopDeviceMotionUpdates]; 375 | // self.motionManager = nil; 376 | //} 377 | 378 | #pragma mark - GLKViewController Subclass 379 | //As an alternative to implementing a glkViewControllerUpdate: method in a delegate, your subclass can provide an update method instead. 380 | //https://developer.apple.com/library/ios/documentation/GLkit/Reference/GLKViewController_ClassRef/index.html 381 | - (void)update { 382 | float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); 383 | GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(self.overture), aspect, 0.1f, 400.0f); 384 | projectionMatrix = GLKMatrix4Rotate(projectionMatrix, ES_PI, 1.0f, 0.0f, 0.0f); 385 | 386 | GLKMatrix4 modelViewMatrix = GLKMatrix4Identity; 387 | float scale = SphereScale; 388 | modelViewMatrix = GLKMatrix4Scale(modelViewMatrix, scale, scale, scale); 389 | if(self.isUsingMotion) { 390 | CMDeviceMotion *deviceMotion = self.motionManager.deviceMotion; 391 | if (deviceMotion != nil) { 392 | CMAttitude *attitude = deviceMotion.attitude; 393 | 394 | if (self.referenceAttitude != nil) { 395 | [attitude multiplyByInverseOfAttitude:self.referenceAttitude]; 396 | } else { 397 | //NSLog(@"was nil : set new attitude", nil); 398 | self.referenceAttitude = deviceMotion.attitude; 399 | } 400 | 401 | float cRoll = -fabs(attitude.roll); // Up/Down landscape 402 | float cYaw = attitude.yaw; // Left/ Right landscape 403 | float cPitch = attitude.pitch; // Depth landscape 404 | 405 | UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 406 | if (orientation == UIDeviceOrientationLandscapeRight ){ 407 | cPitch = cPitch*-1; // correct depth when in landscape right 408 | } 409 | 410 | modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, cRoll); // Up/Down axis 411 | modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, cPitch); 412 | modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, cYaw); 413 | 414 | modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, ROLL_CORRECTION); 415 | 416 | modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, self.fingerRotationX); 417 | modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, self.fingerRotationY); 418 | 419 | self.savedGyroRotationX = cRoll + ROLL_CORRECTION + self.fingerRotationX; 420 | self.savedGyroRotationY = cPitch + self.fingerRotationY; 421 | } 422 | } else { 423 | modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, self.fingerRotationX); 424 | modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, self.fingerRotationY); 425 | } 426 | 427 | self.modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); 428 | 429 | //GLKMatrix4 mViewMatrix = GLKMatrix4MakeLookAt(-2.0, 0.0, 0.0, -2.0, 0.0, -1.0, 0.0, 1.0, 0.0); 430 | //GLKMatrix4 matrix = GLKMatrix4Multiply(mViewMatrix, modelViewMatrix); 431 | //self.modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, matrix); 432 | 433 | glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, GL_FALSE, self.modelViewProjectionMatrix.m); 434 | } 435 | 436 | #pragma mark - GLKViewDelegate 437 | 438 | - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 439 | // [self refreshTexture]; 440 | 441 | glClear(GL_COLOR_BUFFER_BIT); 442 | glDrawElements(GL_TRIANGLES, self.numIndices, GL_UNSIGNED_SHORT, 0); 443 | } 444 | 445 | #pragma mark - OpenGL Program 446 | 447 | - (void)buildProgram { 448 | self.program = [[GLProgram alloc] 449 | initWithVertexShaderFilename:@"Shader" 450 | fragmentShaderFilename:@"Shader"]; 451 | 452 | [self.program addAttribute:@"position"]; 453 | [self.program addAttribute:@"texCoord"]; 454 | 455 | if (![self.program link]) { 456 | self.program = nil; 457 | NSAssert(NO, @"Falied to link HalfSpherical shaders"); 458 | } 459 | 460 | self.vertexTexCoordAttributeIndex = [self.program attributeIndex:@"texCoord"]; 461 | 462 | uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = [self.program uniformIndex:@"modelViewProjectionMatrix"]; 463 | uniforms[UNIFORM_Y] = [self.program uniformIndex:@"SamplerY"]; 464 | uniforms[UNIFORM_UV] = [self.program uniformIndex:@"SamplerUV"]; 465 | uniforms[UNIFORM_COLOR_CONVERSION_MATRIX] = [self.program uniformIndex:@"colorConversionMatrix"]; 466 | } 467 | 468 | #pragma mark - Touch Event 469 | // 470 | //- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 471 | // if(self.isUsingMotion) return; 472 | // for (UITouch *touch in touches) { 473 | // [_currentTouches addObject:touch]; 474 | // } 475 | //} 476 | // 477 | //- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 478 | // if(self.isUsingMotion) return; 479 | // UITouch *touch = [touches anyObject]; 480 | // float distX = [touch locationInView:touch.view].x - [touch previousLocationInView:touch.view].x; 481 | // float distY = [touch locationInView:touch.view].y - [touch previousLocationInView:touch.view].y; 482 | // distX *= -0.005; 483 | // distY *= -0.005; 484 | // self.fingerRotationX += distY * self.overture / 100; 485 | // self.fingerRotationY -= distX * self.overture / 100; 486 | //} 487 | // 488 | //- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 489 | // if (self.isUsingMotion) return; 490 | // for (UITouch *touch in touches) { 491 | // [self.currentTouches removeObject:touch]; 492 | // } 493 | //} 494 | //- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 495 | // for (UITouch *touch in touches) { 496 | // [self.currentTouches removeObject:touch]; 497 | // } 498 | //} 499 | // 500 | //- (void)handlePinchGesture:(UIPinchGestureRecognizer *)recognizer { 501 | // self.overture /= recognizer.scale; 502 | // 503 | // if (self.overture > MAX_OVERTURE) { 504 | // self.overture = MAX_OVERTURE; 505 | // } 506 | // 507 | // if (self.overture < MIN_OVERTURE) { 508 | // self.overture = MIN_OVERTURE; 509 | // } 510 | //} 511 | // 512 | //- (void)handleSingleTapGesture:(UITapGestureRecognizer *)recognizer { 513 | // [self.videoPlayerController toggleControls]; 514 | //} 515 | 516 | @end 517 | -------------------------------------------------------------------------------- /全景_图片.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 792DCFA71D53609800749E84 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 792DCFA61D53609800749E84 /* main.m */; }; 11 | 792DCFAA1D53609800749E84 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 792DCFA91D53609800749E84 /* AppDelegate.m */; }; 12 | 792DCFB01D53609800749E84 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 792DCFAE1D53609800749E84 /* Main.storyboard */; }; 13 | 792DCFB21D53609800749E84 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 792DCFB11D53609800749E84 /* Assets.xcassets */; }; 14 | 792DCFB51D53609800749E84 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 792DCFB31D53609800749E84 /* LaunchScreen.storyboard */; }; 15 | 792DCFC01D53609800749E84 /* _____Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 792DCFBF1D53609800749E84 /* _____Tests.m */; }; 16 | 792DCFCB1D53609800749E84 /* _____UITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 792DCFCA1D53609800749E84 /* _____UITests.m */; }; 17 | 792DCFD91D5361C000749E84 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 792DCFD81D5361C000749E84 /* OpenGLES.framework */; }; 18 | 792DCFEE1D538E2400749E84 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 792DCFED1D538E2400749E84 /* ViewController.m */; }; 19 | 79B9EC091D55797A00E1F02C /* test3.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 79B9EC081D55797A00E1F02C /* test3.jpg */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 792DCFBC1D53609800749E84 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 792DCF9A1D53609800749E84 /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 792DCFA11D53609800749E84; 28 | remoteInfo = "全景_图片"; 29 | }; 30 | 792DCFC71D53609800749E84 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 792DCF9A1D53609800749E84 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 792DCFA11D53609800749E84; 35 | remoteInfo = "全景_图片"; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 792DCFA21D53609800749E84 /* 全景_图片.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "全景_图片.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 792DCFA61D53609800749E84 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 42 | 792DCFA81D53609800749E84 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 43 | 792DCFA91D53609800749E84 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 44 | 792DCFAF1D53609800749E84 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 45 | 792DCFB11D53609800749E84 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 46 | 792DCFB41D53609800749E84 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 47 | 792DCFB61D53609800749E84 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | 792DCFBB1D53609800749E84 /* 全景_图片Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "全景_图片Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 792DCFBF1D53609800749E84 /* _____Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "_____Tests.m"; sourceTree = ""; }; 50 | 792DCFC11D53609800749E84 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | 792DCFC61D53609800749E84 /* 全景_图片UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "全景_图片UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 792DCFCA1D53609800749E84 /* _____UITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "_____UITests.m"; sourceTree = ""; }; 53 | 792DCFCC1D53609800749E84 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 792DCFD81D5361C000749E84 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; 55 | 792DCFEC1D538E2400749E84 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 56 | 792DCFED1D538E2400749E84 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 57 | 792DCFEF1D538E7000749E84 /* Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Header.h; sourceTree = ""; }; 58 | 79B9EC081D55797A00E1F02C /* test3.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = test3.jpg; sourceTree = ""; }; 59 | /* End PBXFileReference section */ 60 | 61 | /* Begin PBXFrameworksBuildPhase section */ 62 | 792DCF9F1D53609800749E84 /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | 792DCFD91D5361C000749E84 /* OpenGLES.framework in Frameworks */, 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | 792DCFB81D53609800749E84 /* Frameworks */ = { 71 | isa = PBXFrameworksBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | 792DCFC31D53609800749E84 /* Frameworks */ = { 78 | isa = PBXFrameworksBuildPhase; 79 | buildActionMask = 2147483647; 80 | files = ( 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | /* End PBXFrameworksBuildPhase section */ 85 | 86 | /* Begin PBXGroup section */ 87 | 792DCF991D53609800749E84 = { 88 | isa = PBXGroup; 89 | children = ( 90 | 792DCFD81D5361C000749E84 /* OpenGLES.framework */, 91 | 792DCFA41D53609800749E84 /* 全景_图片 */, 92 | 792DCFBE1D53609800749E84 /* 全景_图片Tests */, 93 | 792DCFC91D53609800749E84 /* 全景_图片UITests */, 94 | 792DCFA31D53609800749E84 /* Products */, 95 | ); 96 | sourceTree = ""; 97 | }; 98 | 792DCFA31D53609800749E84 /* Products */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 792DCFA21D53609800749E84 /* 全景_图片.app */, 102 | 792DCFBB1D53609800749E84 /* 全景_图片Tests.xctest */, 103 | 792DCFC61D53609800749E84 /* 全景_图片UITests.xctest */, 104 | ); 105 | name = Products; 106 | sourceTree = ""; 107 | }; 108 | 792DCFA41D53609800749E84 /* 全景_图片 */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 792DCFA81D53609800749E84 /* AppDelegate.h */, 112 | 792DCFA91D53609800749E84 /* AppDelegate.m */, 113 | 792DCFEC1D538E2400749E84 /* ViewController.h */, 114 | 792DCFED1D538E2400749E84 /* ViewController.m */, 115 | 792DCFEF1D538E7000749E84 /* Header.h */, 116 | 792DCFAE1D53609800749E84 /* Main.storyboard */, 117 | 792DCFB11D53609800749E84 /* Assets.xcassets */, 118 | 792DCFB31D53609800749E84 /* LaunchScreen.storyboard */, 119 | 792DCFB61D53609800749E84 /* Info.plist */, 120 | 792DCFA51D53609800749E84 /* Supporting Files */, 121 | ); 122 | path = "全景_图片"; 123 | sourceTree = ""; 124 | }; 125 | 792DCFA51D53609800749E84 /* Supporting Files */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 79B9EC081D55797A00E1F02C /* test3.jpg */, 129 | 792DCFA61D53609800749E84 /* main.m */, 130 | ); 131 | name = "Supporting Files"; 132 | sourceTree = ""; 133 | }; 134 | 792DCFBE1D53609800749E84 /* 全景_图片Tests */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 792DCFBF1D53609800749E84 /* _____Tests.m */, 138 | 792DCFC11D53609800749E84 /* Info.plist */, 139 | ); 140 | path = "全景_图片Tests"; 141 | sourceTree = ""; 142 | }; 143 | 792DCFC91D53609800749E84 /* 全景_图片UITests */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 792DCFCA1D53609800749E84 /* _____UITests.m */, 147 | 792DCFCC1D53609800749E84 /* Info.plist */, 148 | ); 149 | path = "全景_图片UITests"; 150 | sourceTree = ""; 151 | }; 152 | /* End PBXGroup section */ 153 | 154 | /* Begin PBXNativeTarget section */ 155 | 792DCFA11D53609800749E84 /* 全景_图片 */ = { 156 | isa = PBXNativeTarget; 157 | buildConfigurationList = 792DCFCF1D53609800749E84 /* Build configuration list for PBXNativeTarget "全景_图片" */; 158 | buildPhases = ( 159 | 792DCF9E1D53609800749E84 /* Sources */, 160 | 792DCF9F1D53609800749E84 /* Frameworks */, 161 | 792DCFA01D53609800749E84 /* Resources */, 162 | ); 163 | buildRules = ( 164 | ); 165 | dependencies = ( 166 | ); 167 | name = "全景_图片"; 168 | productName = "全景_图片"; 169 | productReference = 792DCFA21D53609800749E84 /* 全景_图片.app */; 170 | productType = "com.apple.product-type.application"; 171 | }; 172 | 792DCFBA1D53609800749E84 /* 全景_图片Tests */ = { 173 | isa = PBXNativeTarget; 174 | buildConfigurationList = 792DCFD21D53609800749E84 /* Build configuration list for PBXNativeTarget "全景_图片Tests" */; 175 | buildPhases = ( 176 | 792DCFB71D53609800749E84 /* Sources */, 177 | 792DCFB81D53609800749E84 /* Frameworks */, 178 | 792DCFB91D53609800749E84 /* Resources */, 179 | ); 180 | buildRules = ( 181 | ); 182 | dependencies = ( 183 | 792DCFBD1D53609800749E84 /* PBXTargetDependency */, 184 | ); 185 | name = "全景_图片Tests"; 186 | productName = "全景_图片Tests"; 187 | productReference = 792DCFBB1D53609800749E84 /* 全景_图片Tests.xctest */; 188 | productType = "com.apple.product-type.bundle.unit-test"; 189 | }; 190 | 792DCFC51D53609800749E84 /* 全景_图片UITests */ = { 191 | isa = PBXNativeTarget; 192 | buildConfigurationList = 792DCFD51D53609800749E84 /* Build configuration list for PBXNativeTarget "全景_图片UITests" */; 193 | buildPhases = ( 194 | 792DCFC21D53609800749E84 /* Sources */, 195 | 792DCFC31D53609800749E84 /* Frameworks */, 196 | 792DCFC41D53609800749E84 /* Resources */, 197 | ); 198 | buildRules = ( 199 | ); 200 | dependencies = ( 201 | 792DCFC81D53609800749E84 /* PBXTargetDependency */, 202 | ); 203 | name = "全景_图片UITests"; 204 | productName = "全景_图片UITests"; 205 | productReference = 792DCFC61D53609800749E84 /* 全景_图片UITests.xctest */; 206 | productType = "com.apple.product-type.bundle.ui-testing"; 207 | }; 208 | /* End PBXNativeTarget section */ 209 | 210 | /* Begin PBXProject section */ 211 | 792DCF9A1D53609800749E84 /* Project object */ = { 212 | isa = PBXProject; 213 | attributes = { 214 | LastUpgradeCheck = 0720; 215 | ORGANIZATIONNAME = H; 216 | TargetAttributes = { 217 | 792DCFA11D53609800749E84 = { 218 | CreatedOnToolsVersion = 7.2.1; 219 | DevelopmentTeam = 9LY5F86E2S; 220 | }; 221 | 792DCFBA1D53609800749E84 = { 222 | CreatedOnToolsVersion = 7.2.1; 223 | TestTargetID = 792DCFA11D53609800749E84; 224 | }; 225 | 792DCFC51D53609800749E84 = { 226 | CreatedOnToolsVersion = 7.2.1; 227 | TestTargetID = 792DCFA11D53609800749E84; 228 | }; 229 | }; 230 | }; 231 | buildConfigurationList = 792DCF9D1D53609800749E84 /* Build configuration list for PBXProject "全景_图片" */; 232 | compatibilityVersion = "Xcode 3.2"; 233 | developmentRegion = English; 234 | hasScannedForEncodings = 0; 235 | knownRegions = ( 236 | en, 237 | Base, 238 | ); 239 | mainGroup = 792DCF991D53609800749E84; 240 | productRefGroup = 792DCFA31D53609800749E84 /* Products */; 241 | projectDirPath = ""; 242 | projectRoot = ""; 243 | targets = ( 244 | 792DCFA11D53609800749E84 /* 全景_图片 */, 245 | 792DCFBA1D53609800749E84 /* 全景_图片Tests */, 246 | 792DCFC51D53609800749E84 /* 全景_图片UITests */, 247 | ); 248 | }; 249 | /* End PBXProject section */ 250 | 251 | /* Begin PBXResourcesBuildPhase section */ 252 | 792DCFA01D53609800749E84 /* Resources */ = { 253 | isa = PBXResourcesBuildPhase; 254 | buildActionMask = 2147483647; 255 | files = ( 256 | 792DCFB51D53609800749E84 /* LaunchScreen.storyboard in Resources */, 257 | 792DCFB21D53609800749E84 /* Assets.xcassets in Resources */, 258 | 792DCFB01D53609800749E84 /* Main.storyboard in Resources */, 259 | 79B9EC091D55797A00E1F02C /* test3.jpg in Resources */, 260 | ); 261 | runOnlyForDeploymentPostprocessing = 0; 262 | }; 263 | 792DCFB91D53609800749E84 /* Resources */ = { 264 | isa = PBXResourcesBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | ); 268 | runOnlyForDeploymentPostprocessing = 0; 269 | }; 270 | 792DCFC41D53609800749E84 /* Resources */ = { 271 | isa = PBXResourcesBuildPhase; 272 | buildActionMask = 2147483647; 273 | files = ( 274 | ); 275 | runOnlyForDeploymentPostprocessing = 0; 276 | }; 277 | /* End PBXResourcesBuildPhase section */ 278 | 279 | /* Begin PBXSourcesBuildPhase section */ 280 | 792DCF9E1D53609800749E84 /* Sources */ = { 281 | isa = PBXSourcesBuildPhase; 282 | buildActionMask = 2147483647; 283 | files = ( 284 | 792DCFAA1D53609800749E84 /* AppDelegate.m in Sources */, 285 | 792DCFA71D53609800749E84 /* main.m in Sources */, 286 | 792DCFEE1D538E2400749E84 /* ViewController.m in Sources */, 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | 792DCFB71D53609800749E84 /* Sources */ = { 291 | isa = PBXSourcesBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | 792DCFC01D53609800749E84 /* _____Tests.m in Sources */, 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | 792DCFC21D53609800749E84 /* Sources */ = { 299 | isa = PBXSourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | 792DCFCB1D53609800749E84 /* _____UITests.m in Sources */, 303 | ); 304 | runOnlyForDeploymentPostprocessing = 0; 305 | }; 306 | /* End PBXSourcesBuildPhase section */ 307 | 308 | /* Begin PBXTargetDependency section */ 309 | 792DCFBD1D53609800749E84 /* PBXTargetDependency */ = { 310 | isa = PBXTargetDependency; 311 | target = 792DCFA11D53609800749E84 /* 全景_图片 */; 312 | targetProxy = 792DCFBC1D53609800749E84 /* PBXContainerItemProxy */; 313 | }; 314 | 792DCFC81D53609800749E84 /* PBXTargetDependency */ = { 315 | isa = PBXTargetDependency; 316 | target = 792DCFA11D53609800749E84 /* 全景_图片 */; 317 | targetProxy = 792DCFC71D53609800749E84 /* PBXContainerItemProxy */; 318 | }; 319 | /* End PBXTargetDependency section */ 320 | 321 | /* Begin PBXVariantGroup section */ 322 | 792DCFAE1D53609800749E84 /* Main.storyboard */ = { 323 | isa = PBXVariantGroup; 324 | children = ( 325 | 792DCFAF1D53609800749E84 /* Base */, 326 | ); 327 | name = Main.storyboard; 328 | sourceTree = ""; 329 | }; 330 | 792DCFB31D53609800749E84 /* LaunchScreen.storyboard */ = { 331 | isa = PBXVariantGroup; 332 | children = ( 333 | 792DCFB41D53609800749E84 /* Base */, 334 | ); 335 | name = LaunchScreen.storyboard; 336 | sourceTree = ""; 337 | }; 338 | /* End PBXVariantGroup section */ 339 | 340 | /* Begin XCBuildConfiguration section */ 341 | 792DCFCD1D53609800749E84 /* Debug */ = { 342 | isa = XCBuildConfiguration; 343 | buildSettings = { 344 | ALWAYS_SEARCH_USER_PATHS = NO; 345 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 346 | CLANG_CXX_LIBRARY = "libc++"; 347 | CLANG_ENABLE_MODULES = YES; 348 | CLANG_ENABLE_OBJC_ARC = YES; 349 | CLANG_WARN_BOOL_CONVERSION = YES; 350 | CLANG_WARN_CONSTANT_CONVERSION = YES; 351 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 352 | CLANG_WARN_EMPTY_BODY = YES; 353 | CLANG_WARN_ENUM_CONVERSION = YES; 354 | CLANG_WARN_INT_CONVERSION = YES; 355 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 356 | CLANG_WARN_UNREACHABLE_CODE = YES; 357 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 358 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 359 | COPY_PHASE_STRIP = NO; 360 | DEBUG_INFORMATION_FORMAT = dwarf; 361 | ENABLE_STRICT_OBJC_MSGSEND = YES; 362 | ENABLE_TESTABILITY = YES; 363 | GCC_C_LANGUAGE_STANDARD = gnu99; 364 | GCC_DYNAMIC_NO_PIC = NO; 365 | GCC_NO_COMMON_BLOCKS = YES; 366 | GCC_OPTIMIZATION_LEVEL = 0; 367 | GCC_PREPROCESSOR_DEFINITIONS = ( 368 | "DEBUG=1", 369 | "$(inherited)", 370 | ); 371 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 372 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 373 | GCC_WARN_UNDECLARED_SELECTOR = YES; 374 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 375 | GCC_WARN_UNUSED_FUNCTION = YES; 376 | GCC_WARN_UNUSED_VARIABLE = YES; 377 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 378 | MTL_ENABLE_DEBUG_INFO = YES; 379 | ONLY_ACTIVE_ARCH = YES; 380 | SDKROOT = iphoneos; 381 | TARGETED_DEVICE_FAMILY = "1,2"; 382 | }; 383 | name = Debug; 384 | }; 385 | 792DCFCE1D53609800749E84 /* Release */ = { 386 | isa = XCBuildConfiguration; 387 | buildSettings = { 388 | ALWAYS_SEARCH_USER_PATHS = NO; 389 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 390 | CLANG_CXX_LIBRARY = "libc++"; 391 | CLANG_ENABLE_MODULES = YES; 392 | CLANG_ENABLE_OBJC_ARC = YES; 393 | CLANG_WARN_BOOL_CONVERSION = YES; 394 | CLANG_WARN_CONSTANT_CONVERSION = YES; 395 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 396 | CLANG_WARN_EMPTY_BODY = YES; 397 | CLANG_WARN_ENUM_CONVERSION = YES; 398 | CLANG_WARN_INT_CONVERSION = YES; 399 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 400 | CLANG_WARN_UNREACHABLE_CODE = YES; 401 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 402 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 403 | COPY_PHASE_STRIP = NO; 404 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 405 | ENABLE_NS_ASSERTIONS = NO; 406 | ENABLE_STRICT_OBJC_MSGSEND = YES; 407 | GCC_C_LANGUAGE_STANDARD = gnu99; 408 | GCC_NO_COMMON_BLOCKS = YES; 409 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 410 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 411 | GCC_WARN_UNDECLARED_SELECTOR = YES; 412 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 413 | GCC_WARN_UNUSED_FUNCTION = YES; 414 | GCC_WARN_UNUSED_VARIABLE = YES; 415 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 416 | MTL_ENABLE_DEBUG_INFO = NO; 417 | SDKROOT = iphoneos; 418 | TARGETED_DEVICE_FAMILY = "1,2"; 419 | VALIDATE_PRODUCT = YES; 420 | }; 421 | name = Release; 422 | }; 423 | 792DCFD01D53609800749E84 /* Debug */ = { 424 | isa = XCBuildConfiguration; 425 | buildSettings = { 426 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 427 | CODE_SIGN_IDENTITY = "iPhone Developer"; 428 | DEVELOPMENT_TEAM = 9LY5F86E2S; 429 | INFOPLIST_FILE = "全景_图片/Info.plist"; 430 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 431 | PRODUCT_BUNDLE_IDENTIFIER = "wushuputi.-----"; 432 | PRODUCT_NAME = "$(TARGET_NAME)"; 433 | }; 434 | name = Debug; 435 | }; 436 | 792DCFD11D53609800749E84 /* Release */ = { 437 | isa = XCBuildConfiguration; 438 | buildSettings = { 439 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 440 | CODE_SIGN_IDENTITY = "iPhone Developer"; 441 | DEVELOPMENT_TEAM = 9LY5F86E2S; 442 | INFOPLIST_FILE = "全景_图片/Info.plist"; 443 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 444 | PRODUCT_BUNDLE_IDENTIFIER = "wushuputi.-----"; 445 | PRODUCT_NAME = "$(TARGET_NAME)"; 446 | }; 447 | name = Release; 448 | }; 449 | 792DCFD31D53609800749E84 /* Debug */ = { 450 | isa = XCBuildConfiguration; 451 | buildSettings = { 452 | BUNDLE_LOADER = "$(TEST_HOST)"; 453 | INFOPLIST_FILE = "全景_图片Tests/Info.plist"; 454 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 455 | PRODUCT_BUNDLE_IDENTIFIER = "wushuputi.-----Tests"; 456 | PRODUCT_NAME = "$(TARGET_NAME)"; 457 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/全景_图片.app/全景_图片"; 458 | }; 459 | name = Debug; 460 | }; 461 | 792DCFD41D53609800749E84 /* Release */ = { 462 | isa = XCBuildConfiguration; 463 | buildSettings = { 464 | BUNDLE_LOADER = "$(TEST_HOST)"; 465 | INFOPLIST_FILE = "全景_图片Tests/Info.plist"; 466 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 467 | PRODUCT_BUNDLE_IDENTIFIER = "wushuputi.-----Tests"; 468 | PRODUCT_NAME = "$(TARGET_NAME)"; 469 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/全景_图片.app/全景_图片"; 470 | }; 471 | name = Release; 472 | }; 473 | 792DCFD61D53609800749E84 /* Debug */ = { 474 | isa = XCBuildConfiguration; 475 | buildSettings = { 476 | INFOPLIST_FILE = "全景_图片UITests/Info.plist"; 477 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 478 | PRODUCT_BUNDLE_IDENTIFIER = "wushuputi.-----UITests"; 479 | PRODUCT_NAME = "$(TARGET_NAME)"; 480 | TEST_TARGET_NAME = "全景_图片"; 481 | USES_XCTRUNNER = YES; 482 | }; 483 | name = Debug; 484 | }; 485 | 792DCFD71D53609800749E84 /* Release */ = { 486 | isa = XCBuildConfiguration; 487 | buildSettings = { 488 | INFOPLIST_FILE = "全景_图片UITests/Info.plist"; 489 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 490 | PRODUCT_BUNDLE_IDENTIFIER = "wushuputi.-----UITests"; 491 | PRODUCT_NAME = "$(TARGET_NAME)"; 492 | TEST_TARGET_NAME = "全景_图片"; 493 | USES_XCTRUNNER = YES; 494 | }; 495 | name = Release; 496 | }; 497 | /* End XCBuildConfiguration section */ 498 | 499 | /* Begin XCConfigurationList section */ 500 | 792DCF9D1D53609800749E84 /* Build configuration list for PBXProject "全景_图片" */ = { 501 | isa = XCConfigurationList; 502 | buildConfigurations = ( 503 | 792DCFCD1D53609800749E84 /* Debug */, 504 | 792DCFCE1D53609800749E84 /* Release */, 505 | ); 506 | defaultConfigurationIsVisible = 0; 507 | defaultConfigurationName = Release; 508 | }; 509 | 792DCFCF1D53609800749E84 /* Build configuration list for PBXNativeTarget "全景_图片" */ = { 510 | isa = XCConfigurationList; 511 | buildConfigurations = ( 512 | 792DCFD01D53609800749E84 /* Debug */, 513 | 792DCFD11D53609800749E84 /* Release */, 514 | ); 515 | defaultConfigurationIsVisible = 0; 516 | defaultConfigurationName = Release; 517 | }; 518 | 792DCFD21D53609800749E84 /* Build configuration list for PBXNativeTarget "全景_图片Tests" */ = { 519 | isa = XCConfigurationList; 520 | buildConfigurations = ( 521 | 792DCFD31D53609800749E84 /* Debug */, 522 | 792DCFD41D53609800749E84 /* Release */, 523 | ); 524 | defaultConfigurationIsVisible = 0; 525 | defaultConfigurationName = Release; 526 | }; 527 | 792DCFD51D53609800749E84 /* Build configuration list for PBXNativeTarget "全景_图片UITests" */ = { 528 | isa = XCConfigurationList; 529 | buildConfigurations = ( 530 | 792DCFD61D53609800749E84 /* Debug */, 531 | 792DCFD71D53609800749E84 /* Release */, 532 | ); 533 | defaultConfigurationIsVisible = 0; 534 | defaultConfigurationName = Release; 535 | }; 536 | /* End XCConfigurationList section */ 537 | }; 538 | rootObject = 792DCF9A1D53609800749E84 /* Project object */; 539 | } 540 | --------------------------------------------------------------------------------