罗大柚OpenGL ES教程系列_LessonThree(Part 2)_本地坐标系中旋转
2014-03-08 17:40
591 查看
上一篇我们是使立方体在世界坐标系统绕X轴和Y轴旋转,而这一篇我们将把绕世界坐标系的中轴线的旋转转换为绕本地坐标系中的轴线旋转,废话不多说,代码奉上:
#import "ViewController.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
typedef
struct {
float Position[3];
float Color[4];
float TexCoord[2];
} Vertex;
const
Vertex Vertices[] = {
// Front
{{1, -1, 1},{1, 0, 0, 1}, {1, 0}},
{{1, 1, 1}, {0,1, 0, 1}, {1, 1}},
{{-1, 1, 1},{0, 0, 1, 1}, {0, 1}},
{{-1, -1, 1},{0, 0, 0, 1}, {0, 0}},
// Back
{{1, 1, -1},{1, 0, 0, 1}, {0, 1}},
{{-1, -1, -1},{0, 1, 0, 1}, {1, 0}},
{{1, -1, -1}, {0, 0, 1, 1}, {0, 0}},
{{-1, 1, -1},{0, 0, 0, 1}, {1, 1}},
// Left
{{-1, -1, 1},{1, 0, 0, 1}, {1, 0}},
{{-1, 1, 1},{0, 1, 0, 1}, {1, 1}},
{{-1, 1, -1},{0, 0, 1, 1}, {0, 1}},
{{-1, -1, -1},{0, 0, 0, 1}, {0, 0}},
// Right
{{1, -1, -1},{1, 0, 0, 1}, {1, 0}},
{{1, 1, -1},{0, 1, 0, 1}, {1, 1}},
{{1, 1, 1}, {0,0, 1, 1}, {0, 1}},
{{1, -1, 1},{0, 0, 0, 1}, {0, 0}},
// Top
{{1, 1, 1}, {1,0, 0, 1}, {1, 0}},
{{1, 1, -1},{0, 1, 0, 1}, {1, 1}},
{{-1, 1, -1},{0, 0, 1, 1}, {0, 1}},
{{-1, 1, 1},{0, 0, 0, 1}, {0, 0}},
// Bottom
{{1, -1, -1},{1, 0, 0, 1}, {1, 0}},
{{1, -1, 1},{0, 1, 0, 1}, {1, 1}},
{{-1, -1, 1},{0, 0, 1, 1}, {0, 1}},
{{-1, -1, -1},{0, 0, 0, 1}, {0, 0}}
};
const
GLubyte Indices[] = {
// Front
0, 1, 2,
2, 3, 0,
// Back
4, 6, 5,
4, 5, 7,
// Left
8, 9, 10,
10, 11, 8,
// Right
12, 13, 14,
14, 15, 12,
// Top
16, 17, 18,
18, 19, 16,
// Bottom
20, 21, 22,
22, 23, 20
};
@interface
ViewController ()
{
GLuint _vertexArray;
GLuint vertexBufferID;
GLuint indexBufferID;
GLKMatrix4 _rotMatrix;
}
@property (strong,
nonatomic) EAGLContext *context;
@property (strong,
nonatomic) GLKBaseEffect *effect;
- (void)setupGL;
- (void)tearDownGL;
@end
@implementationViewController
- (void)viewDidLoad
{
[super
viewDidLoad];
self.context = [[EAGLContext
alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!self.context) {
NSLog(@"Failed to create ES context");
}
GLKView *view = (GLKView *)self.view;
view.context =
self.context;
//
view.drawableDepthFormat =
GLKViewDrawableDepthFormat24;
[self
setupGL];
}
- (void)setupGL
{
[EAGLContext
setCurrentContext:self.context];
self.effect = [[GLKBaseEffect
alloc] init];
//设置纹理
CGImageRef imageRef1 = [[UIImage
imageNamed:@"floor.png"]
CGImage];
//接受一个CGImgaeRef并创建一个新的包含CGImageRef的像素数据的OpenGLES
纹理缓存
GLKTextureInfo *textureInfo1 = [GLKTextureLoader
textureWithCGImage:imageRef1
options:nil error:NULL];
self.effect.texture2d0.name = textureInfo1.name;
self.effect.texture2d0.target = textureInfo1.target;
glEnable(GL_DEPTH_TEST);
//设置VAO
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1,
// STEP 1
&vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER,
// STEP 2
vertexBufferID);
glBufferData(GL_ARRAY_BUFFER,
sizeof(Vertices),
Vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(
// STEP 4
GLKVertexAttribPosition);
glVertexAttribPointer(
// STEP 5
GLKVertexAttribPosition,
3,
// three components pervertex
GL_FLOAT,
// data is floating point
GL_FALSE,
// no fixed point scaling
sizeof(Vertex),
// no gaps in data
(const
GLvoid *) offsetof(Vertex,
Position));
// NULL tells GPU to startat
glEnableVertexAttribArray(
// STEP 4
GLKVertexAttribColor);
glVertexAttribPointer(
// STEP 5
GLKVertexAttribColor,
4,
// three components pervertex
GL_FLOAT,
// data is floating point
GL_FALSE,
// no fixed point scaling
sizeof(Vertex),
// no gaps in data
(const
GLvoid *)offsetof(Vertex,
Color));
// NULL tells GPU to startat
glEnableVertexAttribArray(
// STEP 4
GLKVertexAttribTexCoord0);
glVertexAttribPointer(
// STEP 5
GLKVertexAttribTexCoord0,
2,
// three components pervertex
GL_FLOAT,
// data is floating point
GL_FALSE,
// no fixed point scaling
sizeof(Vertex),
// no gaps in data
(const
GLvoid *)offsetof(Vertex,
TexCoord));
// NULL tells GPU to startat
//索引
glGenBuffers(1, &indexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(Indices),
Indices, GL_STATIC_DRAW);
//
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArrayOES(0);
_rotMatrix =
GLKMatrix4Identity;
}
//tear down 卸载;卸载GL
- (void)tearDownGL
{
[EAGLContext
setCurrentContext:self.context];
glDeleteBuffers(1, &vertexBufferID);
glDeleteBuffers(1, &indexBufferID);
glDeleteVertexArraysOES(1, &_vertexArray);
self.effect =
nil;
}
#pragma mark - GLKView andGLKViewController delegate methods
//更新函数
- (void)update
{
float aspect =
fabsf(self.view.bounds.size.width /
self.view.bounds.size.height);
GLKMatrix4 projectionMatrix =
GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 4.0f,10.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 modelViewMatrix =
GLKMatrix4MakeTranslation(0.0f, 0.0f, -7.0f);
// modelViewMatrix =GLKMatrix4Rotate(modelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix,
_rotMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
// _rotation += self.timeSinceLastUpdate *1.0f;
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT);
glBindVertexArrayOES(_vertexArray);
// Render the object with GLKit
[self.effect
prepareToDraw];
glDrawElements(GL_TRIANGLES,
sizeof(Indices)/sizeof(Indices[0]),
GL_UNSIGNED_BYTE, 0);
}
//Remove everything insidetouchBegan
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches
anyObject];
CGPoint location = [touch
locationInView:self.view];
CGPoint lastLocation = [touch
previousLocationInView:self.view];
CGPoint diff =
CGPointMake(lastLocation.x - location.x, lastLocation.y - location.y);
//角度转换为弧度,用户在屏幕上每移动一个像素,立方体旋转1/2度,这里要注意方向
float rotX = -1*GLKMathDegreesToRadians(diff.y/2.0);
float rotY = -1*GLKMathDegreesToRadians(diff.x/2.0);
//////////////////////////////////////////////////////////////
// _rotMatrix *object Vector = world Vector
// 两边同时乘以(_rotMatrix)^(-1)(旋转矩阵的逆矩阵)
// (_rotMatrix)^(-1) * _rotMatrix * object Vector = (_rotMatrix)^(-1) *world Vector
// 由于(_rotMatrix)*(-1)*_rotMatrix= 1
// object Vector = (_rotMatrix)^(-1)*world Vector
//
/////////////////////////////////////////////////////////////
bool isInvertible;
GLKVector3 xAxis =
GLKMatrix4MultiplyVector3(GLKMatrix4Invert(_rotMatrix, &isInvertible),
GLKVector3Make(1, 0, 0));
_rotMatrix =
GLKMatrix4Rotate(_rotMatrix, rotX, xAxis.x, xAxis.y,xAxis.z);
GLKVector3 yAxis =
GLKMatrix4MultiplyVector3(GLKMatrix4Invert(_rotMatrix, &isInvertible),
GLKVector3Make(0, 1, 0));
_rotMatrix =
GLKMatrix4Rotate(_rotMatrix, rotY, yAxis.x, yAxis.y,yAxis.z);
}
- (void)didReceiveMemoryWarning
{
[super
didReceiveMemoryWarning];
if ([self
isViewLoaded] && ([[self
view] window] ==
nil)) {
self.view =
nil;
[self
tearDownGL];
if ([EAGLContext
currentContext] == self.context) {
[EAGLContext
setCurrentContext:nil];
}
self.context =
nil;
}
}
- (void)dealloc
{
[self
tearDownGL];
if ([EAGLContext
currentContext] == self.context) {
[EAGLContext
setCurrentContext:nil];
}
}
@end
源码下载: http://download.csdn.net/detail/luozhonglan/7010291
#import "ViewController.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
typedef
struct {
float Position[3];
float Color[4];
float TexCoord[2];
} Vertex;
const
Vertex Vertices[] = {
// Front
{{1, -1, 1},{1, 0, 0, 1}, {1, 0}},
{{1, 1, 1}, {0,1, 0, 1}, {1, 1}},
{{-1, 1, 1},{0, 0, 1, 1}, {0, 1}},
{{-1, -1, 1},{0, 0, 0, 1}, {0, 0}},
// Back
{{1, 1, -1},{1, 0, 0, 1}, {0, 1}},
{{-1, -1, -1},{0, 1, 0, 1}, {1, 0}},
{{1, -1, -1}, {0, 0, 1, 1}, {0, 0}},
{{-1, 1, -1},{0, 0, 0, 1}, {1, 1}},
// Left
{{-1, -1, 1},{1, 0, 0, 1}, {1, 0}},
{{-1, 1, 1},{0, 1, 0, 1}, {1, 1}},
{{-1, 1, -1},{0, 0, 1, 1}, {0, 1}},
{{-1, -1, -1},{0, 0, 0, 1}, {0, 0}},
// Right
{{1, -1, -1},{1, 0, 0, 1}, {1, 0}},
{{1, 1, -1},{0, 1, 0, 1}, {1, 1}},
{{1, 1, 1}, {0,0, 1, 1}, {0, 1}},
{{1, -1, 1},{0, 0, 0, 1}, {0, 0}},
// Top
{{1, 1, 1}, {1,0, 0, 1}, {1, 0}},
{{1, 1, -1},{0, 1, 0, 1}, {1, 1}},
{{-1, 1, -1},{0, 0, 1, 1}, {0, 1}},
{{-1, 1, 1},{0, 0, 0, 1}, {0, 0}},
// Bottom
{{1, -1, -1},{1, 0, 0, 1}, {1, 0}},
{{1, -1, 1},{0, 1, 0, 1}, {1, 1}},
{{-1, -1, 1},{0, 0, 1, 1}, {0, 1}},
{{-1, -1, -1},{0, 0, 0, 1}, {0, 0}}
};
const
GLubyte Indices[] = {
// Front
0, 1, 2,
2, 3, 0,
// Back
4, 6, 5,
4, 5, 7,
// Left
8, 9, 10,
10, 11, 8,
// Right
12, 13, 14,
14, 15, 12,
// Top
16, 17, 18,
18, 19, 16,
// Bottom
20, 21, 22,
22, 23, 20
};
@interface
ViewController ()
{
GLuint _vertexArray;
GLuint vertexBufferID;
GLuint indexBufferID;
GLKMatrix4 _rotMatrix;
}
@property (strong,
nonatomic) EAGLContext *context;
@property (strong,
nonatomic) GLKBaseEffect *effect;
- (void)setupGL;
- (void)tearDownGL;
@end
@implementationViewController
- (void)viewDidLoad
{
[super
viewDidLoad];
self.context = [[EAGLContext
alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!self.context) {
NSLog(@"Failed to create ES context");
}
GLKView *view = (GLKView *)self.view;
view.context =
self.context;
//
view.drawableDepthFormat =
GLKViewDrawableDepthFormat24;
[self
setupGL];
}
- (void)setupGL
{
[EAGLContext
setCurrentContext:self.context];
self.effect = [[GLKBaseEffect
alloc] init];
//设置纹理
CGImageRef imageRef1 = [[UIImage
imageNamed:@"floor.png"]
CGImage];
//接受一个CGImgaeRef并创建一个新的包含CGImageRef的像素数据的OpenGLES
纹理缓存
GLKTextureInfo *textureInfo1 = [GLKTextureLoader
textureWithCGImage:imageRef1
options:nil error:NULL];
self.effect.texture2d0.name = textureInfo1.name;
self.effect.texture2d0.target = textureInfo1.target;
glEnable(GL_DEPTH_TEST);
//设置VAO
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1,
// STEP 1
&vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER,
// STEP 2
vertexBufferID);
glBufferData(GL_ARRAY_BUFFER,
sizeof(Vertices),
Vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(
// STEP 4
GLKVertexAttribPosition);
glVertexAttribPointer(
// STEP 5
GLKVertexAttribPosition,
3,
// three components pervertex
GL_FLOAT,
// data is floating point
GL_FALSE,
// no fixed point scaling
sizeof(Vertex),
// no gaps in data
(const
GLvoid *) offsetof(Vertex,
Position));
// NULL tells GPU to startat
glEnableVertexAttribArray(
// STEP 4
GLKVertexAttribColor);
glVertexAttribPointer(
// STEP 5
GLKVertexAttribColor,
4,
// three components pervertex
GL_FLOAT,
// data is floating point
GL_FALSE,
// no fixed point scaling
sizeof(Vertex),
// no gaps in data
(const
GLvoid *)offsetof(Vertex,
Color));
// NULL tells GPU to startat
glEnableVertexAttribArray(
// STEP 4
GLKVertexAttribTexCoord0);
glVertexAttribPointer(
// STEP 5
GLKVertexAttribTexCoord0,
2,
// three components pervertex
GL_FLOAT,
// data is floating point
GL_FALSE,
// no fixed point scaling
sizeof(Vertex),
// no gaps in data
(const
GLvoid *)offsetof(Vertex,
TexCoord));
// NULL tells GPU to startat
//索引
glGenBuffers(1, &indexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(Indices),
Indices, GL_STATIC_DRAW);
//
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArrayOES(0);
_rotMatrix =
GLKMatrix4Identity;
}
//tear down 卸载;卸载GL
- (void)tearDownGL
{
[EAGLContext
setCurrentContext:self.context];
glDeleteBuffers(1, &vertexBufferID);
glDeleteBuffers(1, &indexBufferID);
glDeleteVertexArraysOES(1, &_vertexArray);
self.effect =
nil;
}
#pragma mark - GLKView andGLKViewController delegate methods
//更新函数
- (void)update
{
float aspect =
fabsf(self.view.bounds.size.width /
self.view.bounds.size.height);
GLKMatrix4 projectionMatrix =
GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 4.0f,10.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 modelViewMatrix =
GLKMatrix4MakeTranslation(0.0f, 0.0f, -7.0f);
// modelViewMatrix =GLKMatrix4Rotate(modelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix,
_rotMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
// _rotation += self.timeSinceLastUpdate *1.0f;
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT);
glBindVertexArrayOES(_vertexArray);
// Render the object with GLKit
[self.effect
prepareToDraw];
glDrawElements(GL_TRIANGLES,
sizeof(Indices)/sizeof(Indices[0]),
GL_UNSIGNED_BYTE, 0);
}
//Remove everything insidetouchBegan
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches
anyObject];
CGPoint location = [touch
locationInView:self.view];
CGPoint lastLocation = [touch
previousLocationInView:self.view];
CGPoint diff =
CGPointMake(lastLocation.x - location.x, lastLocation.y - location.y);
//角度转换为弧度,用户在屏幕上每移动一个像素,立方体旋转1/2度,这里要注意方向
float rotX = -1*GLKMathDegreesToRadians(diff.y/2.0);
float rotY = -1*GLKMathDegreesToRadians(diff.x/2.0);
//////////////////////////////////////////////////////////////
// _rotMatrix *object Vector = world Vector
// 两边同时乘以(_rotMatrix)^(-1)(旋转矩阵的逆矩阵)
// (_rotMatrix)^(-1) * _rotMatrix * object Vector = (_rotMatrix)^(-1) *world Vector
// 由于(_rotMatrix)*(-1)*_rotMatrix= 1
// object Vector = (_rotMatrix)^(-1)*world Vector
//
/////////////////////////////////////////////////////////////
bool isInvertible;
GLKVector3 xAxis =
GLKMatrix4MultiplyVector3(GLKMatrix4Invert(_rotMatrix, &isInvertible),
GLKVector3Make(1, 0, 0));
_rotMatrix =
GLKMatrix4Rotate(_rotMatrix, rotX, xAxis.x, xAxis.y,xAxis.z);
GLKVector3 yAxis =
GLKMatrix4MultiplyVector3(GLKMatrix4Invert(_rotMatrix, &isInvertible),
GLKVector3Make(0, 1, 0));
_rotMatrix =
GLKMatrix4Rotate(_rotMatrix, rotY, yAxis.x, yAxis.y,yAxis.z);
}
- (void)didReceiveMemoryWarning
{
[super
didReceiveMemoryWarning];
if ([self
isViewLoaded] && ([[self
view] window] ==
nil)) {
self.view =
nil;
[self
tearDownGL];
if ([EAGLContext
currentContext] == self.context) {
[EAGLContext
setCurrentContext:nil];
}
self.context =
nil;
}
}
- (void)dealloc
{
[self
tearDownGL];
if ([EAGLContext
currentContext] == self.context) {
[EAGLContext
setCurrentContext:nil];
}
}
@end
源码下载: http://download.csdn.net/detail/luozhonglan/7010291
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- js判断客户端是iOS还是Android等移动终端的方法
- IOS开发环境windows化攻略
- 探讨Android与iOS,我们将何去何从?
- IOS 身份证校验详细介绍及示例代码
- iOS NSDate中关于夏令时的坑
- iOS内存错误EXC_BAD_ACCESS的解决方法
- 从 Auto Layout 的布局算法谈性能
- 浅谈 MVC、MVP 和 MVVM 架构模式
- 深入解析 ObjC 中方法的结构
- 你真的了解 load 方法么?
- 从源代码看 ObjC 中消息的发送
- vm安装mac os x 10.7 lion
- objective-c(一)
- objective-c(三)
- objective-c(四)-基本数据类型以及循环和选择结构
- objective-c(六)文件分离,合成存取方法,方法多参数,局部变量,self使用(未完成)