0

我对 GLKView 进行了子类化,我想围绕 x 轴旋转它。我尝试在 raywenderlich 的教程中应用该方法,但没有结果。不同之处在于,我有一个 GLKView,而他碰巧用 GLKViewController(+ 它的委托)做所有事情。所以我没有delegate之类的更新方法等。我对OpenGL几乎没有经验(刚开始),所以希望在这里能有所启发。

视图控制器.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];

}
4

3 回答 3

0

您似乎没有任何东西可以运行您的绘图循环。把它放在你的 viewDidLoad 中:

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

将 displayLink 定义为标题中的属性,并将 @selector(render:) 更改为您的渲染函数(不必是那个 glkview 函数,因为您没有使用 GLKViewController)。

于 2012-12-21T11:37:51.470 回答
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 的值,使用 max;对于 0.0,使用最小值;

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

于 2017-02-08T01:47:34.877 回答
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");
}

这些要求听起来有点可疑。但是,我向你保证,你不会以任何其他方式旋转它,并在所有方向和所有方面保持一致性。

于 2017-01-17T02:52:30.697 回答