3

I have an iPhone app in the making with GLKit. I load vertices in from a .obj file from Blender, and then I attempt to draw the vertices. It's the first time I've tried to do so using glDrawElements. I chose this because then I only need as many vertices as there are vertices in my object, and I can just render one triangle strip with the indices of those vertices.

Here is a simplified version of what I'm trying to do, which just highlights the fact that I'm trying to draw outside of the ViewController, the entire source code for this simplified version is here

#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, (const GLvoid*)0);

}

@end

Here is how the character is initialized in viewDidLoad of the ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    GLKView *view = (GLKView *)self.view;
    view.context = self.context;


    [self setupGL];
    character = [[Character alloc] initWithEffect:self.effect];
    character.position = GLKVector3Make(self.view.bounds.size.width / 2, self.view.bounds.size.height / 2, 0.0f);
}

And here is how the calls to the character's render method are made:

- (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];
}

Here is my project structure project structure :

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
michaelsnowden
  • 6,031
  • 2
  • 38
  • 83

1 Answers1

1

The warning means that you should use VBOs (Vertex Buffer Objects) for static data. From your code, I see you are creating the index buffer VBO using GL_ELEMENT_ARRAY_BUFFER which is correct, but you are not setting it when you call render.

VAO's do not store index buffer data, so you should not be doing the GL_ELEMENT_ARRAY_BUFFER work inside of the VAO creation code.

Just before you call [character render], call glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); and the warning should go away.

Muzza
  • 1,236
  • 9
  • 13
  • I'll give you the bounty, but I don't see this as a really great answer honestly. It's to the point, but I'd like a more thorough explanation. – michaelsnowden Mar 18 '14 at 07:10
  • I'm happy to add more information if there is something you are not clear about. Index buffers aren't allowed in VAO's therefore you weren't setting an index buffer in your code, therefore you were getting the warning about it. There really isn't more to it than that that I can see. – Muzza Mar 18 '14 at 08:33