使用GLKit與CoreAnimation2種方式實現3D旋轉盒子

經常看到前端會寫出各種炫酷的盒子動畫融蹂,那iOS有沒有實現方式呢?答案當然是肯定的弄企,而且方式還有很多種超燃。今天我就用兩種方式來實現一個炫酷的旋轉盒子,話不多說拘领,先來看一下動畫效果圖吧~


炫酷的旋轉盒子

接下來說一下實現方式吧

方式一:GLKView實現

第1步:創(chuàng)建context意乓,初始化上下文時設置API版本,并設置當前context

EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

[EAGLContext setCurrentContext:context];

第2步:創(chuàng)建GLKView并設置代理

CGRect frame = CGRectMake(0, 100, self.view.frame.size.width, self.view.frame.size.width);

?self.glkView = [[GLKView alloc] initWithFrame:frame context:context];

?self.glkView.backgroundColor = [UIColor clearColor];

?self.glkView.delegate = self;

第3步:使用深度緩存

self.glkView.drawableDepthFormat = GLKViewDrawableDepthFormat24;

glDepthRangef(1, 0);

第4步:將GLKView 添加self.view 上

[self.view addSubview:self.glkView];

第5步:獲取紋理圖片

NSString *imagePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"kunkun.jpg"];

UIImage *image = [UIImage imageWithContentsOfFile:imagePath];

第6步:設置紋理參數

NSDictionary *options = @{GLKTextureLoaderOriginBottomLeft : @(YES)};

GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithCGImage:[image CGImage] options:options error:NULL];

第7步:使用baseEffect,開啟光照效果,漫反射顏色,光源位置

?self.baseEffect = [[GLKBaseEffect alloc] init];

?self.baseEffect.texture2d0.name = textureInfo.name;

?self.baseEffect.texture2d0.target = textureInfo.target;

self.baseEffect.light0.enabled = YES;?

self.baseEffect.light0.diffuseColor = GLKVector4Make(1, 1, 1, 1);

self.baseEffect.light0.position = GLKVector4Make(-0.5, -0.5, 5, 1);

第8步:?開辟頂點數據空間(數據結構SenceVertex 大小 * 頂點個數kCoordCount)

self.vertices = malloc(sizeof(CCVertex) * kCoordCount);

self.vertices[0] = (CCVertex){{-0.5, 0.5, 0.5}, {0, 1}, {0, 0, 1}};

...

開辟頂點緩存區(qū)

glGenBuffers(1, &_vertexBuffer);

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);

GLsizeiptr bufferSizeBytes = sizeof(CCVertex) * kCoordCount;

glBufferData(GL_ARRAY_BUFFER, bufferSizeBytes, self.vertices, GL_STATIC_DRAW);

頂點數據

glEnableVertexAttribArray(GLKVertexAttribPosition);

glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(CCVertex), NULL + offsetof(CCVertex, positionCoord));

?紋理數據

?glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

?glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(CCVertex), NULL + offsetof(CCVertex, textureCoord));

?法線數據

?glEnableVertexAttribArray(GLKVertexAttribNormal);

?glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(CCVertex), NULL + offsetof(CCVertex, normal));

第9步:設置旋轉角度

self.angle = (self.angle + 5) % 360;

修改baseEffect.transform.modelviewMatrix

self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeRotation(GLKMathDegreesToRadians(self.angle), 0.3, 1, 0.7);

重新渲染

?[self.glkView display];

第10步:開啟深度測試

?glEnable(GL_DEPTH_TEST);

?清除顏色緩存區(qū)&深度緩存區(qū)

?glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

?準備繪制

? [self.baseEffect prepareToDraw];

?繪圖

?glDrawArrays(GL_TRIANGLES, 0, kCoordCount);

方式二:CoreAnimation實現

第1步:添加6個面父View的layer圖層

CATransform3D perspective = CATransform3DIdentity;

perspective.m34= -1.0/500.0;

?perspective =CATransform3DRotate(perspective, -M_PI_4,1,0,0);

?perspective =CATransform3DRotate(perspective, -M_PI_4,0,1,0);

?self.containerView.layer.sublayerTransform = perspective;

cube face 1

CATransform3D transform = CATransform3DMakeTranslation(0, 0, 100);

?[self addFace:0 withTransform:transform];

?cube face 2

?transform =CATransform3DMakeTranslation(100, 0, 0);

?transform =CATransform3DRotate(transform,M_PI_2,0,1,0);

?[self addFace:1 withTransform:transform];

...

添加面的方法约素,獲取face視圖并將其添加到容器中

?UIView*face =self.faces[index];

?[self.containerView addSubview:face];

?將face視圖放在容器的中心

?CGSize containerSize = self.containerView.bounds.size;

?face.center=CGPointMake(containerSize.width/2.0, containerSize.height/2.0);

?添加transform

?face.layer.transform= transform;

第2步:計算并旋轉

self.angle = (self.angle + 5) % 360;

?floatdeg =self.angle* (M_PI/180);

?CATransform3D temp = CATransform3DIdentity;

?temp =CATransform3DRotate(temp, deg,0.3,1,0.7);

?self.containerView.layer.sublayerTransform = temp;

以上就是兩種方式實現的炫酷旋轉盒子~

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末届良,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子圣猎,更是在濱河造成了極大的恐慌士葫,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件送悔,死亡現場離奇詭異慢显,居然都是意外死亡,警方通過查閱死者的電腦和手機欠啤,發(fā)現死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門荚藻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洁段,你說我怎么就攤上這事鞋喇。” “怎么了眉撵?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵侦香,是天一觀的道長。 經常有香客問我纽疟,道長罐韩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任污朽,我火速辦了婚禮散吵,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己矾睦,他們只是感情好晦款,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著枚冗,像睡著了一般缓溅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赁温,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天坛怪,我揣著相機與錄音,去河邊找鬼股囊。 笑死袜匿,一個胖子當著我的面吹牛,可吹牛的內容都是我干的稚疹。 我是一名探鬼主播居灯,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼内狗!你這毒婦竟也來了怪嫌?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤其屏,失蹤者是張志新(化名)和其女友劉穎喇勋,沒想到半個月后缨该,有當地人在樹林里發(fā)現了一具尸體偎行,經...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年贰拿,在試婚紗的時候發(fā)現自己被綠了蛤袒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡膨更,死狀恐怖妙真,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情荚守,我是刑警寧澤珍德,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站矗漾,受9級特大地震影響锈候,放射性物質發(fā)生泄漏。R本人自食惡果不足惜敞贡,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一泵琳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦获列、人聲如沸谷市。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迫悠。三九已至,卻和暖如春溯壶,著一層夾襖步出監(jiān)牢的瞬間及皂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工且改, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留验烧,地道東北人。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓又跛,卻偏偏與公主長得像碍拆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子慨蓝,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359