Transparent textures in OpenGL ES 1.1 for iOS

146 views Asked by At

I've read other posts regarding similar issues and seem to have tried everything that stood there, but still didn't manage to achieve the desired effect.

What I want is to display arrows on the screen to give the user the possibility to rotate the selected object by pressing on them. My idea was to create a couple of png files with a transparent background and to show them as textures.

The corresponding code is spread among several source files, but I think the relevant parts are as follows:

typedef struct {
    unsigned int width;
    unsigned int height;
    void *image;
} TextureData;


NSString *path = [[NSBundle mainBundle] pathForResource:arrowFile ofType:@"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:path];

TextureData *texData;
texData->width  = CGImageGetWidth(image.CGImage);
texData->height = CGImageGetHeight(image.CGImage);
texData->image = malloc(4*texData->height*texData->width);

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(texData->image, texData->width,
    texData->height, 8, 4*texData->width,colorSpace,
    kCGImageAlphaPremultipliedLast|kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextClearRect(context, CGRectMake(0, 0, texData->width, texData->height));
CGContextTranslateCTM(context, 0, texData->height - texData->height);
CGContextDrawImage(context, CGRectMake(0, 0, texData->width, texData->height),
    image.CGImage);
CGContextRelease(context);

[image release];

With the obtained TextureData structure the textures are generated

glBindTexture(GL_TEXTURE_2D, arrowTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texData->width, texData->height,
    0, GL_RGBA, GL_UNSIGNED_BYTE, texData->image);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

And during the rendering phase I proceed as follows:

vec2 texVertices[6];
vec3 vertices[6];

texVertices[0] = vec2(1.0f, -1.0f);
texVertices[1] = vec2(0.0f, -1.0f);
texVertices[2] = vec2(0.0f,  0.0f);
texVertices[3] = vec2(1.0f, -1.0f);
texVertices[4] = vec2(0.0f,  0.0f);
texVertices[5] = vec2(1.0f,  0.0f);

vertices[0] = vec3( 0.5f,  0.5f, 0.0f);
vertices[1] = vec3(-0.5f,  0.5f, 0.0f);
vertices[2] = vec3(-0.5f, -0.5f, 0.0f);
vertices[3] = vec3( 0.5f,  0.5f, 0.0f);
vertices[4] = vec3(-0.5f, -0.5f, 0.0f);
vertices[5] = vec3( 0.5f, -0.5f, 0.0f);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexPointer(3, GL_FLOAT, sizeof(vec3), &vertices[0]);
glTexCoordPointer(2, GL_FLOAT, sizeof(vec2), &texVertices[0]);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glBindTexture(GL_TEXTURE_2D, arrowTexture);
glDrawArrays(GL_TRIANGLES, 0, 6);

glDisable(GL_BLEND);
glEnable(GL_LIGHTING);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

The result that I see is my arrow on the black background, and I am quite puzzled about it. Would appreciate any help/ideas/suggestions on this, thank you beforehand.

1

There are 1 answers

0
user3211670 On

I managed to find out the root cause of why I was getting black background instead of correct blending. Just post it here, in case somebody faces the same issue: I forgot to render objects w.r.t to their distance, the farthest first, and as a result, OpenGL was blending my texture with glClearColor, which was black. Evident, when I look at it now, but it almost made me desperate. Another thing; glDisable(GL_LIGHTING) was not so important although it did make my arrows look nicer. The missing part was to switch off the depth testing with glDepthFunc(GL_ALWAYS).