本篇教程使用一種比較笨拙的方法來實現觸摸旋轉一個幾何體,這裏需要說明一下,我在之前有看過泰然網上面一片通過觸摸實現旋轉的文章,我只是用我的方式來實現了一下,嚴格的講是算抄襲的,但是這裏不做商業用途,所以特別說明一下,我在下一篇會使用四元數來實現旋轉,而在下一節課則是講紋理相關的知識,歡迎大家提出寶貴意見。
#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