羅大柚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




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章