Question

Whenever I add vertices to my vertex array, my application crashes.

Here is the code:

const GLKVector3 Vertices[] = {


//8,9,0
LASH_BOTTOM_LEFT,
LASH_BOTTOM_RIGHT,
RECT_BOTTOM_L,


//9,1,0
LASH_BOTTOM_RIGHT,
RECT_BOTTOM_R,
RECT_BOTTOM_L,


//2,6,7
RECT_TOP_R,
LASH_TOP_RIGHT,
LASH_TOP_LEFT,

//3,2,7
RECT_TOP_L,
RECT_TOP_R,
LASH_TOP_LEFT,

//0,1,3
RECT_BOTTOM_L,
RECT_BOTTOM_R,
RECT_TOP_L,

//1,2,3
RECT_BOTTOM_R,
RECT_TOP_R,
RECT_TOP_L,

//2,5,3
RECT_TOP_R,
BACK_RIGHT,
RECT_TOP_L,

//3,5,4
RECT_TOP_L,
BACK_RIGHT,
BACK_LEFT,


//0,1,5
RECT_BOTTOM_L,
RECT_BOTTOM_R,
BACK_RIGHT,

//5,4,0
BACK_RIGHT,
BACK_LEFT,
RECT_BOTTOM_L,


};

Setting it up:

- (void)setupGL {


    [EAGLContext setCurrentContext:self.myContext];

    self.effect = [[GLKBaseEffect alloc] init];
    self.layer.contentsScale = 2.0;

    // Create default framebuffer object.
    glGenFramebuffers(1, &defaultFrameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFrameBuffer);


    ViewToMap *view = [[ViewToMap alloc]initWithFrame:CGRectMake(0, 0, 320, 80)];
    view.layer.shadowOffset = CGSizeMake(1, 1);
    view.layer.masksToBounds = NO;
    view.layer.shadowRadius = 1;
    view.layer.shadowOpacity = 0.02;

    GLfloat coordToPixScale = 1.0;//[UIScreen mainScreen].scale;


    /*********************
     MAPPING UIVIEW ONTO THE FACE
     ****************/

    self.effect.texture2d0.enabled = true;



    // make space for an RGBA image of the view
    GLubyte *pixelBuffer = (GLubyte *)malloc(
                                             4 *
                                             view.bounds.size.width * coordToPixScale *
                                             view.bounds.size.height * coordToPixScale);

    // create a suitable CoreGraphics context
    CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context =
    CGBitmapContextCreate(pixelBuffer,
                          view.bounds.size.width*coordToPixScale, view.bounds.size.height*coordToPixScale,
                          8, 4*view.bounds.size.width *coordToPixScale,
                          colourSpace,
                          kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colourSpace);

    // draw the view to the buffer
    [view.layer renderInContext:context];

    // upload to OpenGL
    glTexImage2D(GL_TEXTURE_2D, 0,
                 GL_RGBA,
                 view.bounds.size.width * coordToPixScale, view.bounds.size.height * coordToPixScale, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer);

    BOOL repeatX = NO;
    BOOL repeatY = NO;

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeatX ? GL_REPEAT
                    : GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeatY ? GL_REPEAT
                    : GL_CLAMP_TO_EDGE);



    glGenBuffers(1, &texArray);
    glBindBuffer(GL_ARRAY_BUFFER, texArray);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glBufferData(GL_ARRAY_BUFFER, sizeof(TexCoords), TexCoords, GL_STATIC_DRAW);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0,0);

    /**************************
     ******************************************/

    // clean up
    CGContextRelease(context);
    free(pixelBuffer);

    glGenRenderbuffers(1, &depthBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, view.bounds.size.width * coordToPixScale, view.bounds.size.height * coordToPixScale);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);

    glEnable(GL_DEPTH_TEST);

    glGenBuffers(1, &vertexArray);
    glBindBuffer(GL_ARRAY_BUFFER, vertexArray);
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(GLKVertexAttribPosition,3,GL_FLOAT,GL_FALSE,0,0);



    self.effect.transform.projectionMatrix = GLKMatrix4MakePerspective(45.0f,0.9f, 0.01f, 1.0f);

    rotMatrix = GLKMatrix4Translate(self.effect.transform.modelviewMatrix,0,0,-2);
    self.effect.transform.projectionMatrix =          GLKMatrix4Translate(self.effect.transform.projectionMatrix, 0, 0, 1.2);


}

If I add 1 more vertex, everything seems OK but if I add another one it crashes (with no regards as to how their coordinates are and I think the vertex coordinates are perfectly OK).

What I get is a bad access error.

Draw call:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {


    self.opaque = NO;

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    [self.effect prepareToDraw];

    glDrawArrays(GL_TRIANGLES, 0, sizeof(Vertices));
}
Was it helpful?

Solution

Okay, I have a hunch about this, but involves the driver being buggy (I can explain a crash, i.e. sudden program termination) in your case only with a buggy driver.

That adding a vertex position breaks your code is no surprise though. A vertex is the whole tuple of position, texture coordinates and the other attributes. So when you add positions, you also must add the other attributes. If you were using client side vertex arrays, this would explain the crash, but VBOs should catch this.

Anyway, you have those calls (annotated them).

glBufferData(GL_ARRAY_BUFFER, buf_size_t = sizeof(TexCoords), TexCoords, GL_STATIC_DRAW);
glVertexAttribPointer(GLKVertexAttribTexCoord0, attrib_elements_t = 2, GL_FLOAT, GL_FALSE, 0,0);

and

glBufferData(GL_ARRAY_BUFFER, buf_size_p = sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glVertexAttribPointer(GLKVertexAttribPosition, attrib_elements_p = 3, GL_FLOAT, GL_FALSE, 0, 0);

You must make sure that

buf_size_t / (attrib_elements_t * sizeof(GLfloat)) 

    ==

buf_size_p / (attrib_elements_p * sizeof(GLfloat))

if this equality is not met, things will break in some form.

Update due to question edit

And finally the cause of the root of the problem:

 glDrawArrays(GL_TRIANGLES, 0, sizeof(Vertices));
                               ^^^^^^
                                     \--- This

glDrawArrays expects the number of vertices to draw (and not the size of the vertex array buffer).

The sizeof operator doesn't tell you the number of vertices in the array, but its size in units of char. You have to replace this with sizeof(Vertices) / ( sizeof(GLfloat) * attrib_elements_p ), attrib_elements_p = 3 in your case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top