iphone - XCODE 4 IOS 4.3.3 glClear(GL_COLOR_BUFFER_BIT) EXC_BAD_ACCESS -
i working on game multiple levels. initial level runs fine not matter if start level 1 or level 2. within code next level loaded based off user's score. using game state manager dealloc initial level , load next level. in ios 4.2 code runs without error. however, in ios 4.3.3 exc_bad_access error when glclear(gl_color_buffer_bit) line called in rendder method of next level.
- i not have zombies
- analyze not return changes
- i not see memory leaks in instruments
other posts suggested put glbindbuffer(gl_array_buffer, 0) , glbindbuffer(gl_element_array_buffer, 0) @ end of render method, same exc_bad_access error. sure access bad memory, opengl calls need made load new level w/o error?
render method same both levels:
//clear left on last frame, , set background color. glclearcolor(0xff/256.0f, 0x66/256.0f, 0x00/256.0f, 1.0f); glclear(gl_color_buffer_bit); [tileworld draw]; [super renderendgame]; //you nice boring white screen if forget swap buffers. [self swapbuffers];
i have gltexture class handles opengl setup:
#import <opengles/es1/glext.h> #import "gltexture.h" //constants: #define kmaxtexturesize 1024 //class implementations: @implementation gltexture @synthesize contentsize=_size, pixelformat=_format, pixelswide=_width, pixelshigh=_height, name=_name, maxs=_maxs, maxt=_maxt; @dynamic width, height; - (float) width { return self.contentsize.width; } - (float) height { return self.contentsize.height; } - (id) initwithdata:(const void*)data pixelformat:(gltexturepixelformat)pixelformat pixelswide:(nsuinteger)width pixelshigh:(nsuinteger)height contentsize:(cgsize)size { glint savename; if((self = [super init])) { glgentextures(1, &_name); //get new texture id. _name increases more textures loaded glgetintegerv(gl_texture_binding_2d, &savename); //generally, savename==1. gets existing bound texture, can restore after load. glbindtexture(gl_texture_2d, _name); //start working our new texture id gltexparameteri(gl_texture_2d, gl_texture_min_filter, gl_linear); //associate pixel data texture id. switch(pixelformat) { case kgltexturepixelformat_rgba8888: glteximage2d(gl_texture_2d, 0, gl_rgba, width, height, 0, gl_rgba, gl_unsigned_byte, data); break; case kgltexturepixelformat_rgb565: glteximage2d(gl_texture_2d, 0, gl_rgb, width, height, 0, gl_rgb, gl_unsigned_short_5_6_5, data); break; case kgltexturepixelformat_a8: glteximage2d(gl_texture_2d, 0, gl_alpha, width, height, 0, gl_alpha, gl_unsigned_byte, data); break; default: [nsexception raise:nsinternalinconsistencyexception format:@""]; } glbindtexture(gl_texture_2d, savename); //restore previous texture binding. //nslog(@"name %d, savename %d", _name, savename); _size = size; _width = width; _height = height; _format = pixelformat; _maxs = size.width / (float)width; _maxt = size.height / (float)height; } return self; } - (void) dealloc { if(_name) gldeletetextures(1, &_name); [super dealloc]; } - (nsstring*) description { return [nsstring stringwithformat:@"<%@ = %08x | name = %i | dimensions = %ix%i | coordinates = (%.2f, %.2f)>", [self class], self, _name, _width, _height, _maxs, _maxt]; } @end @implementation gltexture (image) - (id) initwithimage:(uiimage *)uiimage { nsuinteger width, height, i; cgcontextref context = nil; void* data = nil;; cgcolorspaceref colorspace; void* tempdata; unsigned int* inpixel32; unsigned short* outpixel16; bool hasalpha; cgimagealphainfo info; cgaffinetransform transform; cgsize imagesize; gltexturepixelformat pixelformat; cgimageref image; uiimageorientation orientation; bool sizetofit = no; image = [uiimage cgimage]; orientation = [uiimage imageorientation]; if(image == null) { [self release]; nslog(@"image null"); return nil; } info = cgimagegetalphainfo(image); hasalpha = ((info == kcgimagealphapremultipliedlast) || (info == kcgimagealphapremultipliedfirst) || (info == kcgimagealphalast) || (info == kcgimagealphafirst) ? yes : no); if(cgimagegetcolorspace(image)) { if(hasalpha) pixelformat = kgltexturepixelformat_rgba8888; else pixelformat = kgltexturepixelformat_rgb565; } else //note: no colorspace means mask image pixelformat = kgltexturepixelformat_a8; imagesize = cgsizemake(cgimagegetwidth(image), cgimagegetheight(image)); transform = cgaffinetransformidentity; width = imagesize.width; if((width != 1) && (width & (width - 1))) { = 1; while((sizetofit ? 2 * : i) < width) *= 2; width = i; } height = imagesize.height; if((height != 1) && (height & (height - 1))) { = 1; while((sizetofit ? 2 * : i) < height) *= 2; height = i; } while((width > kmaxtexturesize) || (height > kmaxtexturesize)) { width /= 2; height /= 2; transform = cgaffinetransformscale(transform, 0.5, 0.5); imagesize.width *= 0.5; imagesize.height *= 0.5; } switch(pixelformat) { case kgltexturepixelformat_rgba8888: colorspace = cgcolorspacecreatedevicergb(); data = malloc(height * width * 4); context = cgbitmapcontextcreate(data, width, height, 8, 4 * width, colorspace, kcgimagealphapremultipliedlast | kcgbitmapbyteorder32big); cgcolorspacerelease(colorspace); break; case kgltexturepixelformat_rgb565: colorspace = cgcolorspacecreatedevicergb(); data = malloc(height * width * 4); context = cgbitmapcontextcreate(data, width, height, 8, 4 * width, colorspace, kcgimagealphanoneskiplast | kcgbitmapbyteorder32big); cgcolorspacerelease(colorspace); break; case kgltexturepixelformat_a8: data = malloc(height * width); context = cgbitmapcontextcreate(data, width, height, 8, width, null, kcgimagealphaonly); break; default: [nsexception raise:nsinternalinconsistencyexception format:@"invalid pixel format"]; } cgcontextclearrect(context, cgrectmake(0, 0, width, height)); cgcontexttranslatectm(context, 0, height - imagesize.height); if(!cgaffinetransformisidentity(transform)) cgcontextconcatctm(context, transform); cgcontextdrawimage(context, cgrectmake(0, 0, cgimagegetwidth(image), cgimagegetheight(image)), image); //convert "rrrrrrrrrggggggggbbbbbbbbaaaaaaaa" "rrrrrggggggbbbbb" if(pixelformat == kgltexturepixelformat_rgb565) { tempdata = malloc(height * width * 2); inpixel32 = (unsigned int*)data; outpixel16 = (unsigned short*)tempdata; for(i = 0; < width * height; ++i, ++inpixel32) *outpixel16++ = ((((*inpixel32 >> 0) & 0xff) >> 3) << 11) | ((((*inpixel32 >> 8) & 0xff) >> 2) << 5) | ((((*inpixel32 >> 16) & 0xff) >> 3) << 0); free(data); data = tempdata; } self = [self initwithdata:data pixelformat:pixelformat pixelswide:width pixelshigh:height contentsize:imagesize]; cgcontextrelease(context); free(data); return self; } @end @implementation gltexture (drawing) - (void) drawatpoint:(cgpoint)point { glfloat coordinates[] = { 0, _maxt, _maxs, _maxt, 0, 0, _maxs, 0 }; glfloat width = (glfloat)_width * _maxs, height = (glfloat)_height * _maxt; glfloat vertices[] = { -width / 2.0f + point.x, -height / 2.0f + point.y, 0.0, width / 2.0f + point.x, -height / 2.0f + point.y, 0.0, -width / 2.0f + point.x, height / 2.0f + point.y, 0.0, width / 2.0f + point.x, height / 2.0f + point.y, 0.0 }; glbindtexture(gl_texture_2d, _name); glvertexpointer(3, gl_float, 0, vertices); gltexcoordpointer(2, gl_float, 0, coordinates); gldrawarrays(gl_triangle_strip, 0, 4); } - (void) drawatpoint:(cgpoint)point withrotation:(cgfloat)rotation withscale:(cgfloat)scale { glfloat coordinates[] = { 0, _maxt, _maxs, _maxt, 0, 0, _maxs, 0 }; glfloat width = (glfloat)_width * _maxs, height = (glfloat)_height * _maxt; glfloat vertices[] = { -width / 2.0f, -height / 2.0f, 0.0, width / 2.0f, -height / 2.0f, 0.0, -width / 2.0f, height / 2.0f, 0.0, width / 2.0f, height / 2.0f, 0.0 }; glbindtexture(gl_texture_2d, _name); glvertexpointer(3, gl_float, 0, vertices); gltexcoordpointer(2, gl_float, 0, coordinates); glpushmatrix(); gltranslatef(point.x, point.y, 0); glrotatef(rotation, 0, 0, 1); //in degrees, screen origin. glscalef(scale, scale, scale); gldrawarrays(gl_triangle_strip, 0, 4); glpopmatrix(); } //note if clip near drastic color change in source texture, color may bleed through on //the edges due anti-aliasing. //draws align bottom-left, opengl coordinates. - (void) drawinrect:(cgrect)dest withclip:(cgrect)src withrotation:(cgfloat)rotation { glfloat gx0 = src.origin.x/_width, gx1 = (src.origin.x+src.size.width)/_width, gy0 = src.origin.y/_height, gy1 = (src.origin.y+src.size.height)/_height; glfloat coordinates[] = { gx0, gy1, gx1, gy1, gx0, gy0, gx1, gy0 }; glfloat vertices[] = { -dest.size.width/2, -dest.size.height/2, 0.0, dest.size.width/2, -dest.size.height/2, 0.0, -dest.size.width/2, dest.size.height/2, 0.0, dest.size.width/2, dest.size.height/2, 0.0 }; glbindtexture(gl_texture_2d, _name); glvertexpointer(3, gl_float, 0, vertices); gltexcoordpointer(2, gl_float, 0, coordinates); glpushmatrix(); gltranslatef(dest.origin.x+dest.size.width/2, dest.origin.y+dest.size.height/2, 0); glrotatef(rotation, 0, 0, 1); //in degrees, screen origin. gldrawarrays(gl_triangle_strip, 0, 4); glpopmatrix(); } - (void) drawinrect:(cgrect)rect { glfloat coordinates[] = { 0, _maxt, _maxs, _maxt, 0, 0, _maxs, 0 }; glfloat vertices[] = { rect.origin.x, rect.origin.y, 0.0, rect.origin.x + rect.size.width, rect.origin.y, 0.0, rect.origin.x, rect.origin.y + rect.size.height, 0.0, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height, 0.0 }; glbindtexture(gl_texture_2d, _name); glvertexpointer(3, gl_float, 0, vertices); gltexcoordpointer(2, gl_float, 0, coordinates); gldrawarrays(gl_triangle_strip, 0, 4); } - (void) drawinvertices:(glfloat*) vertices { glfloat coordinates[] = { 0, _maxt, _maxs, _maxt, 0, 0, _maxs, 0 }; glbindtexture(gl_texture_2d, _name); glvertexpointer(3, gl_float, 0, vertices); gltexcoordpointer(2, gl_float, 0, coordinates); gldrawarrays(gl_triangle_strip, 0, 4); } @end
Comments
Post a Comment