Question

I am creating a rectangle in OpenGL ES 2.0 using GLKit. This is working and I can fill up the rectangle with solid colour and a gradient.

Now I am trying to fill it up with a texture from an image, which is not working for me.

I am getting a EXC_BAD_ACCESS code=1 error on the glDrawElements line.

Here is what I have right now:

//Setup GKLView

EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; self.glkView = [[GLKView alloc] initWithFrame:self.bounds context:context]; _glkView.opaque = NO; _glkView.backgroundColor = [UIColor clearColor]; _glkView.delegate = self; [self addSubview:_glkView];

//Setup BaseEffect

self.effect = [[GLKBaseEffect alloc] init]; [EAGLContext setCurrentContext:_glkView.context]; GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(0, self.bounds.size.width, 0, self.bounds.size.height, 0.0, 1.0); self.effect.transform.projectionMatrix = projectionMatrix; GLKMatrix4 modelMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0.0, 0.0, -0.1); self.effect.transform.modelviewMatrix = modelMatrix;

//Load image

UIImage* image = ... CGImageRef cgImage = image.CGImage; NSError* error; self.textureInfo = [GLKTextureLoader textureWithCGImage:cgImage options:nil error:&error]; if (error) { NSLog(@"could not load texture"); } if (_textureInfo) { self.effect.texture2d0.envMode = GLKTextureEnvModeReplace; self.effect.texture2d0.target = GLKTextureTarget2D; self.effect.texture2d0.name = _textureInfo.name; } //Bind buffers

glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glGenBuffers(1, &_indexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer (GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position)); glEnableVertexAttribArray(GLKVertexAttribTexCoord0); glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0, _currentData.texCoordinates);

//Populate buffers

glBufferData(GL_ARRAY_BUFFER, (sizeof(Vertex) * _currentData.numberOfVertices), _currentData.vertices, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, (sizeof(GLubyte) * _currentData.numberOfIndices), _currentData.indices, GL_STATIC_DRAW);

[self.effect prepareToDraw]; [self.glkView display];

//Inside - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect; glDrawElements(GL_TRIANGLE_STRIP, (sizeof(GLubyte) * _currentData.numberOfIndices), GL_UNSIGNED_BYTE, 0);

The data for texture coordinates is:

    SimpleVertex* vertices1 = (SimpleVertex *)malloc(sizeof(SimpleVertex) * 4);
    vertices1[0].Position[0] = 0.0;
    vertices1[0].Position[1] = 0.0;

    vertices1[1].Position[0] = 0.0;
    vertices1[1].Position[1] = 1.0;

    vertices1[2].Position[0] = 1.0;
    vertices1[2].Position[1] = 1.0;

    vertices1[3].Position[0] = 1.0;
    vertices1[3].Position[1] = 0.0;

typedef struct
{
    GLfloat Position[2];
}
SimpleVertex;

As I said, I am sure the rectangle is being drawn correctly. I can check this by filling it up with gradient, it looks fine. Also the texture loader is loading the image correctly, I can check this in the debugger.

Can someone point out what I am missing or doing wrong here?

Was it helpful?

Solution

Ok I figured it out. The mistake was in the way I was passing texture co-ordinate data to openGL. I was passing the data for vertices and colour this way:

glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer (GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));

But for texture coordinates I created a separate structure and was passing a pointer to that data and not an offset to the already bonded vertices array:

glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0, _currentData.texCoordinates);

The solution then was obviously to include the data within the Vertex data structure and then give the offset like so:

glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, TexCoord));

I am still a newbie to OpenGL ES so there might have been a better way to solve this problem but this worked for me.

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