罗大柚OpenGL ES教程系列_LessonThree(Part 2)_本地坐标系中旋转

上一篇我们是使立方体在世界坐标系统绕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.youkuaiyun.com/detail/luozhonglan/7010291



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值