我对 OpenGL ES 很陌生,但我要做的就是glDrawElements
在Character
类中使用绘制索引顶点。我在GLKViewController
课堂上之前已经让这个工作了,但是当我尝试创建一个Character
可以执行自己的渲染的类时,除了 BAD_ACCESS 什么都没有。这是我的Character
课:
#import "Character.h"
@interface Character()
{
GLuint _vertexBuffer;
GLuint _indexBuffer;
GLuint _vertexArray;
}
@property(nonatomic, weak) GLKBaseEffect *effect;
@end
typedef struct {
float Position[3];
float Color[4];
} Vertex;
const Vertex Vertices[] = {
{{1, -1, 0}, {1, 0, 0, 1}},
{{1, 1, 0}, {0, 1, 0, 1}},
{{-1, 1, 0}, {0, 0, 1, 1}},
{{-1, -1, 0}, {0, 0, 0, 1}}
};
const GLushort Indices[] = {
0, 1, 2,
2, 3, 0
};
@implementation Character
- (id)initWithEffect:(GLKBaseEffect *)effect
{
if (self = [super init])
{
self.effect = effect;
[self setupGL];
}
return self;
}
- (void)setupGL
{
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Color));
glBindVertexArrayOES(0);
}
- (void)teardownGL
{
glDeleteBuffers(1, &_vertexBuffer);
glDeleteBuffers(1, &_indexBuffer);
}
- (void)render
{
self.effect.transform.modelviewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, self.position.x, self.position.y, self.position.z);
self.effect.transform.modelviewMatrix = GLKMatrix4Rotate(self.effect.transform.modelviewMatrix, self.rotation, 0.0f, 0.0f, 1.0f);
[self.effect prepareToDraw];
glBindVertexArrayOES(_vertexArray);
glDrawElements(GL_TRIANGLES, sizeof(Indices) / sizeof(Indices[0]), GL_UNSIGNED_SHORT, 0);
}
@end
然后在ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
GLKView *view = (GLKView *)self.view;
view.context = self.context;
character = [[Character alloc] initWithEffect:self.effect];
character.position = GLKVector3Make(self.view.bounds.size.width / 2, self.view.bounds.size.height / 2, 0.0f);
[self setupGL];
}
使用:
- (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);
[character render];
}
我知道这并不像错误计算字节大小或其他东西那么简单,因为我已经在这个问题上待了几天了。