罗大柚OpenGL ES教程系列_LessonThree(Part 1)_使用Touch来实现旋转

本篇教程使用一种比较笨拙的方法来实现触摸旋转一个几何体,这里需要说明一下,我在之前有看过泰然网上面一片通过触摸实现旋转的文章,我只是用我的方式来实现了一下,严格的讲是算抄袭的,但是这里不做商业用途,所以特别说明一下,我在下一篇会使用四元数来实现旋转,而在下一节课则是讲纹理相关的知识,欢迎大家提出宝贵意见。

#import "ViewController.h"

 

#defineBUFFER_OFFSET(i) ((char *)NULL + (i))

 

typedef struct {

    float Position[3];

    float Color[4];

    float TexCoord[2];

}Vertex;

 

const VertexVertices[] = {

    // 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 GLubyteIndices[] = {

    // 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(@"Failedto 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的像素数据的OpenGL ES 纹理缓存

    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 per vertex

                          GL_FLOAT,            // data is floating point

                          GL_FALSE,            // no fixed point scaling

                          sizeof(Vertex),                    // no gaps in data

                          (const GLvoid *) offsetof(Vertex, Position));               // NULLtells GPU to start at

   

    glEnableVertexAttribArray(      // STEP 4

                              GLKVertexAttribColor);

   

    glVertexAttribPointer(         // STEP 5

                          GLKVertexAttribColor,

                          4,                   // three components per vertex

                          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 start at

   

   

    glEnableVertexAttribArray(      // STEP 4

                              GLKVertexAttribTexCoord0);

   

    glVertexAttribPointer(         // STEP 5

                          GLKVertexAttribTexCoord0,

                          2,                   // three components per vertex

                          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 start at

 

   

    //索引

    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 and GLKViewControllerdelegate 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 inside touchBegan

- (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);

   

    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);

}

 

- (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/7007875




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值