同样的, LessonTwo的第三部分我们采用了VAO,但是我们觉得在part 2中那中为创建一个Cube而重复大量顶点数据的方式并不完美,于是我们很自然的想到了用index,part 3就是采用了VAO和index创建的Cube, 这似乎也减少了我们的体力的输出,程序员很幸苦,除了每天要耗费大量的脑力外, 还需要敲打那么多个字符,所以我们尽量的让代码变得简单一点吧,对自己好一点。好了, 代码端上来:
#import "ViewController.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
typedef struct {
floatPosition[3];
}Vertex;
const Vertex Vertices[] = {
{0.5f, -0.5f, 0.0f},
{0.5f, 0.5f, 0.0f},
{-0.5f, 0.5f, 0.0f},
{-0.5f, -0.5f, 0.0f},
{0.5f, -0.5f, -0.5f},
{0.5f, 0.5f, -0.5f},
{-0.5f, 0.5f, -0.5f},
{-0.5f, -0.5f, -0.5f}
};
const GLubyte Indices[] = {
// Front
0,1, 2,
2,3, 0,
// Back
4,5, 6,
6,7, 4,
// Left
4,5, 1,
1,0, 4,
// Right
7,6, 2,
2, 3, 7,
// Top
5,6, 2,
2,1, 5,
// Bottom
4,7, 3,
3,0, 4,
};
@interface ViewController ()
{
float_rotation;
GLuint _vertexArray;
GLuint vertexBufferID;
GLuint indexBufferID;
}
@property (strong, nonatomic) EAGLContext *context;
@property (strong, nonatomic) GLKBaseEffect *effect;
- (void)setupGL;
- (void)tearDownGL;
@end
@implementation ViewController
- (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];
self.effect.useConstantColor = GL_TRUE;
self.effect.constantColor = GLKVector4Make(
1.0f, // Red
0.0f, // Green
0.0f, // Blue
1.0f);// Alpha
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
NULL); // 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);
}
//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, 1.0f, 1.0f, 1.0f);
self.effect.transform.modelviewMatrix = modelViewMatrix;
_rotation += self.timeSinceLastUpdate * 0.5f;
}
- (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.effectprepareToDraw];
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]),
GL_UNSIGNED_BYTE, 0);
}
- (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/6987135