2012-12-19 98 views
0

我有一個GLKView的子類,我想圍繞x軸旋轉它。我試圖在raywenderlich的教程中應用該方法,但沒有結果。不同的是,我有一個GLKView,他碰巧用GLKViewController(+它的委託)做所有事情。所以我沒有委託的更新方法等。我幾乎沒有OpenGL的經驗(剛開始),所以我希望我在這裏遇到一些啓發。如何圍繞x軸旋轉GLKView?

ViewController.m

EAGLContext * context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 
    BlogCell *view = [[BlogCell alloc] initWithFrame:CGRectMake(0, 200, 320, 80) context:context]; 
    view.drawableMultisample = GLKViewDrawableMultisample4X; 
    view.context = context; 
    view.delegate = view; 
    [view setupGL]; 
    [self.view addSubview:view]; 

MyGLKViewSubclass.m

- (void)setupGL { 

    [EAGLContext setCurrentContext:self.context]; 
    glEnable(GL_CULL_FACE); 


    self.effect = [[GLKBaseEffect alloc] init]; 

    NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys: 
           [NSNumber numberWithBool:YES], 
           GLKTextureLoaderOriginBottomLeft, 
           nil]; 

    NSError * error; 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"myImage" ofType:@"png"]; 
    GLKTextureInfo * info = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error]; 
    if (info == nil) { 
     NSLog(@"Error loading file: %@", [error localizedDescription]); 
    } 
    self.effect.texture2d0.name = info.name; 
    self.effect.texture2d0.enabled = true; 

    glGenVertexArraysOES(1, &vertexArray); 
    glBindVertexArrayOES(vertexArray); 

    glGenBuffers(1, &vertexBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); 


    glGenBuffers(1, &indexBuffer); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW); 

    glEnableVertexAttribArray(GLKVertexAttribColor); 
    glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Color)); 


    glEnableVertexAttribArray(GLKVertexAttribPosition); 
    glVertexAttribPointer(GLKVertexAttribPosition, 
          3,   
          GL_FLOAT, 
          GL_FALSE,  
          sizeof(Vertex), 
          (const GLvoid *) offsetof(Vertex, Position) 
         ); 

    glEnableVertexAttribArray(GLKVertexAttribTexCoord0); 
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, TexCoord)); 


    glBindVertexArrayOES(0); 

    rotMatrix = GLKMatrix4Identity; 

} 




- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 

    self.contentScaleFactor = 2.0; 
    self.opaque = NO; 
    self.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; 
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 

    glClear(GL_COLOR_BUFFER_BIT); 

    [self.effect prepareToDraw]; 

    glBindVertexArrayOES(vertexArray); 
    glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0); 


} 

這是我想給我的旋轉物體

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ 

    UITouch * touch = [touches anyObject]; 
    CGPoint location = [touch locationInView:[touch view]]; 
    CGPoint lastLoc = [touch previousLocationInView:[touch view]]; 
    CGPoint diff = CGPointMake(lastLoc.x - location.x, lastLoc.y - location.y); 

    float rotX = -1 * GLKMathDegreesToRadians(diff.y/2.0); 
    float rotY = -1 * GLKMathDegreesToRadians(diff.x/2.0); 

    GLKVector3 xAxis = GLKVector3Make(1, 0, 0); 
    rotMatrix = GLKMatrix4Rotate(rotMatrix, rotX, xAxis.x, xAxis.y, xAxis.z); 
    GLKVector3 yAxis = GLKVector3Make(0, 1, 0); 
    rotMatrix = GLKMatrix4Rotate(rotMatrix, rotY, yAxis.x, yAxis.y, yAxis.z); 
    [self update]; 

} 

回答

0

你似乎沒有任何東西來運行你的繪製循環。把這個在您的viewDidLoad中:

displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)]; 
displayLink.frameInterval = 2; 
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

DisplayLink的定義在你的頭一個屬性,改變@selector(渲染:)你的渲染功能(不必須是glkview之一,因爲你的arent使用GLKViewController)。

+0

謝謝你的回答。我嘗試了你的代碼,不幸的是無濟於事。當我需要重繪我的GLKView時,什麼對我有用就是使用'[self display ]'。順便說一下,我將委託設置爲GLKView本身,因此當我調用它的'display'方法時,它的委託方法將被調用。這是一個壞方法嗎? –

+0

displayLink運行循環與GLKViewController/GLKView組合提供的運行循環相同。使用CADisplayLink,您可以查看自上次刷新以來發生的週期數的細化視圖;但是,這些信息與我認識的每個人都無關。使用GLKViewController,我可以設置給定視頻每秒的幀數;以15 fps播放的視頻不需要以60 fps渲染。能夠減少fps使得一個更快的應用程序比沒有。 –

0

有用於旋轉GLKView四個要求: 1.旋轉相關的代碼必須放置視圖控制器 2. 90°必須添加到旋轉爲橫長方向內 3.旋轉相關的代碼必須括在一個UIView動畫塊 4.度應以弧度來表示,並且爲負數

下面是我使用的代碼,成功:

在GLKViewController實現文件(.M):

static inline double radians (double degrees) { return degrees * M_PI/180; } 

。 。 。

if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]) || (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))) { 
    [UIView animateWithDuration:0.0 animations:^{ 
     ((PlayerView *)self.view).transform = CGAffineTransformMakeRotation(radians(-90.0)); 
     ((PlayerView *)self.view).frame = [[UIScreen mainScreen] bounds]; 
    } completion:^(BOOL finished) { }]; 
} else if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) || (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]))) { 
    [UIView animateWithDuration:0.0 animations:^{ 
     ((PlayerView *)self.view).transform = CGAffineTransformMakeRotation(radians(-180.0)); 
     ((PlayerView *)self.view).frame = [[UIScreen mainScreen] bounds]; 
    } completion:^(BOOL finished) { }]; 
} else { 
    NSLog(@"--------------------------- orientation could not be determined"); 
} 

這些要求聽起來有點可疑;但是,我保證你不會以任何其他方式旋轉它,並保持所有方向和各個方面的一致性。

0

甚至比旋轉視圖更好的是旋轉四邊形紋理座標;雖然它沒有在Apple的任何示例代碼或文檔中演示過,但他們的文檔確實建議通過旋轉GLKView來旋轉輸出。

這裏是所有四紋理座標排列設置:

static const GLfloat noRotationTextureCoordinates[] = { 
    0.0f, 0.0f, 
    1.0f, 0.0f, 
    0.0f, 1.0f, 
    1.0f, 1.0f, 
}; 

static const GLfloat rotateLeftTextureCoordinates[] = { 
    1.0f, 0.0f, 
    1.0f, 1.0f, 
    0.0f, 0.0f, 
    0.0f, 1.0f, 
}; 

static const GLfloat rotateRightTextureCoordinates[] = { 
    0.0f, 1.0f, 
    0.0f, 0.0f, 
    1.0f, 1.0f, 
    1.0f, 0.0f, 
}; 

static const GLfloat verticalFlipTextureCoordinates[] = { 
    0.0f, 1.0f, 
    1.0f, 1.0f, 
    0.0f, 0.0f, 
    1.0f, 0.0f, 
}; 

static const GLfloat horizontalFlipTextureCoordinates[] = { 
    1.0f, 0.0f, 
    0.0f, 0.0f, 
    1.0f, 1.0f, 
    0.0f, 1.0f, 
}; 

static const GLfloat rotateRightVerticalFlipTextureCoordinates[] = { 
    0.0f, 0.0f, 
    0.0f, 1.0f, 
    1.0f, 0.0f, 
    1.0f, 1.0f, 
}; 

static const GLfloat rotateRightHorizontalFlipTextureCoordinates[] = { 
    1.0f, 1.0f, 
    1.0f, 0.0f, 
    0.0f, 1.0f, 
    0.0f, 0.0f, 
}; 

static const GLfloat rotate180TextureCoordinates[] = { 
    1.0f, 1.0f, 
    0.0f, 1.0f, 
    1.0f, 0.0f, 
    0.0f, 0.0f, 
}; 

要在他們AVBasicVideo使用的GLKView內使用此...示例應用程序,例如:

  1. 使用self.bounds.size而不是self.presentationRect.size讓你的輸出,而不管其旋轉填滿整個屏幕:

    CGRect vertexSamplingRect = AVMakeRectWithAspectRatioInsideRect(self.bounds.size, self.eaglLayer.bounds); 
    
  2. 爲1.0,使用最高值;爲0.0,使用min;

    GLfloat quadTextureData [] = { CGRectGetMaxX(textureSamplingRect),CGRectGetMinY(textureSamplingRect) CGRectGetMaxX(textureSamplingRect),CGRectGetMaxY(textureSamplingRect) CGRectGetMinX(textureSamplingRect),CGRectGetMinY(textureSamplingRect) CGRectGetMinX(textureSamplingRect), CGRectGetMaxY(textureSamplingRect) };