我已经将GLKView子类化,我想围绕x轴旋转它。我试图在raywenderlich的教程中应用该方法,但没有结果。不同的是,我有一个GLKView,他碰巧用GLKViewController(+它的委托)做了一切。所以我没有委托等的更新方法等。我几乎没有使用OpenGL的经验(刚刚开始),所以我希望我在这里遇到一些启示。
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 :(得分:0)
你似乎没有任何东西可以运行你的绘制循环。把它放在你的viewDidLoad:
中displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)];
displayLink.frameInterval = 2;
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
将displayLink定义为标题中的属性,并将@selector(render :)更改为渲染函数(因为你不使用GLKViewController,所以不必是glkview)。
答案 1 :(得分: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");
}
这些要求可能听起来有点怀疑;但是,我保证你不会以任何其他方式轮换它,并保持所有方向和所有方面的一致性。
答案 2 :(得分: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中使用它,例如:
使用self.bounds.size
代替self.presentationRect.size
,这样无论轮换如何,输出都会填满整个屏幕:
CGRect vertexSamplingRect = AVMakeRectWithAspectRatioInsideRect(self.bounds.size, self.eaglLayer.bounds);
对于值1.0,请使用max;对于0.0,使用min;
GLfloat quadTextureData [] = { CGRectGetMaxX(textureSamplingRect),CGRectGetMinY(textureSamplingRect), CGRectGetMaxX(textureSamplingRect),CGRectGetMaxY(textureSamplingRect), CGRectGetMinX(textureSamplingRect),CGRectGetMinY(textureSamplingRect), CGRectGetMinX(textureSamplingRect),CGRectGetMaxY(textureSamplingRect) };