您的位置:首页 > 运维架构

罗大柚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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios opengl es GLkit Rotate