XCODE 4 IOS 4.3.3 glClear(GL_COLOR_BUFFER_BIT)EXC_BAD_ACCESS

时间:2011-07-21 15:29:17

标签: iphone ios opengl-es exc-bad-access

我正在开发一个多层次的游戏。如果我从级别1或级别2开始,初始级别运行正常无关紧要。在代码中,根据用户的分数加载下一级别。我正在使用游戏状态管理器来解除初始级别并加载下一级别。在IOS 4.2中,此代码运行时没有错误。但是,在IOS 4.3.3中,当在下一级的Rendder方法中调用glClear(GL_COLOR_BUFFER_BIT)行时,我得到一个EXC_BAD_ACCESS错误。

  • 我没有任何僵尸
  • 分析不会返回任何更改
  • 我没有看到仪器中存在任何内存泄漏

其他帖子建议我在我的Render方法结尾处放置glBindBuffer(GL_ARRAY_BUFFER,0)和glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0),但是我得到了相同的EXC_BAD_ACCESS错误。我确信我访问了不良内存,但需要使用什么OpenGL来加载我的新级别w / o错误?

两个级别的渲染方法相同:

//clear anything left over from the last frame, and 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 get a nice boring white screen if you forget to swap buffers.
[self swapBuffers];

我有一个处理OpenGL设置的GLTexture类:

#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 a new texture id.  _name increases as more textures are loaded
        glGetIntegerv(GL_TEXTURE_BINDING_2D, &saveName); //generally, saveName==1.  gets existing bound texture, so we can restore it after load.
        glBindTexture(GL_TEXTURE_2D, _name); //start working with our new texture id
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        //associate pixel data with the 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 the 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 is 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 a mask image
        pixelFormat = kGLTexturePixelFormat_A8;


    imageSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));
    transform = CGAffineTransformIdentity;

    width = imageSize.width;

    if((width != 1) && (width & (width - 1))) {
        i = 1;
        while((sizeToFit ? 2 * i : i) < width)
            i *= 2;
        width = i;
    }
    height = imageSize.height;
    if((height != 1) && (height & (height - 1))) {
        i = 1;
        while((sizeToFit ? 2 * i : i) < height)
            i *= 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" to "RRRRRGGGGGGBBBBB"
    if(pixelFormat == kGLTexturePixelFormat_RGB565) {
        tempData = malloc(height * width * 2);
        inPixel32 = (unsigned int*)data;
        outPixel16 = (unsigned short*)tempData;
        for(i = 0; i < 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, about screen origin.
    glScalef(scale, scale, scale);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glPopMatrix();
}

//note that if you clip too near to a drastic color change in the source texture, the color may bleed through on
//the edges due to anti-aliasing.
//draws align bottom-left, like 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, about 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

0 个答案:

没有答案