2012-07-06 95 views
1

借助OpenGL ES,我的图像处理存在一些问题。 我创建了一个纹理,负载着色器,并将其连接到程序,当我想呈现我 质感的UIImage,图像全黑:(OpenGL ES渲染为UIImage,图像为黑色

纹理初始化:

glActiveTexture(GL_TEXTURE0); 
glGenTextures(1, &_name); 
glBindTexture(self.format, _name); 
glTexParameteri(self.format, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(self.format, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(self.format, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(self.format, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glBindTexture(self.format, 0); 

纹理负载代码:

self.pixelSize = CGSizeMake(self.size.width * self.scale, self.size.height * self.scale); 

    BOOL shouldScale = NO; 

    if (self.limitedSize.width < self.pixelSize.width || 
     self.limitedSize.height < self.pixelSize.height) { 
     self.pixelSize = self.limitedSize; 
    } 

    if (shouldScale) { 
     CGFloat normalizedWidth = ceil(log2(self.pixelSize.width)); 
     CGFloat normalizedHeight = ceil(log2(self.pixelSize.height)); 

     self.pixelSize = CGSizeMake(pow(2.0, normalizedWidth), powf(2.0, normalizedHeight)); 
     self.data = (GLubyte *)calloc(1, self.bytes); 

     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
     CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst; 
     CGContextRef context = CGBitmapContextCreate(self.data, normalizedWidth, normalizedHeight, 8, normalizedWidth * 4, colorSpace, bitmapInfo); 
     CGContextDrawImage(context, CGRectMake(0, 0, normalizedWidth, normalizedHeight), image.CGImage); 
     CGContextRelease(context); 
     CGColorSpaceRelease(colorSpace); 
    } 
    else { 
     CFDataRef dataRef = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage)); 
     self.data = (GLubyte *)CFDataGetBytePtr(dataRef); 
     CFRelease(dataRef); 
    } 

    glBindTexture(self.format, self.name); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
    glTexImage2D(self.format, 0, GL_RGBA, self.pixelSize.width, self.pixelSize.height, 0, GL_BGRA, self.type, self.data); 
    glGenerateMipmap(GL_TEXTURE_2D); 

帧缓冲:

glActiveTexture(GL_TEXTURE1); 
glGenFramebuffers(1, &_buffer); 
glBindFramebuffer(GL_FRAMEBUFFER, _buffer); // self.format is GL_TEXTURE_2D 
glBindTexture(self.texture.format, self.texture.name); 
glTexImage2D(self.texture.format, 0, GL_RGBA, self.width, self.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, self.texture.format, self.texture.name, 0); 

GLint status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 
if (status != GL_FRAMEBUFFER_COMPLETE) { 
    NSLog(@"GLBuffer: Failed to make framebuffer object"); 
} 

glBindTexture(self.texture.format, 0); 

渲染:

[self.buffer bind]; 
[self.program use]; 

glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT); 

glActiveTexture(GL_TEXTURE2); 
[self.texture bind]; 

glUniform1i([self.texture uniformForKey:@"inputImageTexture"], 2); 
glUniform1f([self.texture uniformForKey:@"red"], 1.0); 
glUniform1f([self.texture uniformForKey:@"green"], 0.0); 
glUniform1f([self.texture uniformForKey:@"blue"], 0.0); 

glVertexAttribPointer([self.texture attributeForKey:@"position"], 2, GL_FLOAT, 0, 0, [self.texture vertices]); 
glEnableVertexAttribArray([self.texture attributeForKey:@"position"]); 

glVertexAttribPointer([self.texture attributeForKey:@"inputTextureCoordinate"], 2, GL_FLOAT, 0, 0, [self.texture coordinates]); 
glEnableVertexAttribArray([self.texture attributeForKey:@"inputTextureCoordinate"]); 

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

[self.buffer unbind]; 
[self.texture unbind]; 

纹理图像:

[self.buffer bind]; 
    GLubyte *rawPixels = (GLubyte *)malloc([self.texture bytes]); 

glReadPixels(0, 0, [self.texture width], [self.texture height], GL_RGBA, GL_UNSIGNED_BYTE, rawPixels); 
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rawPixels, [self.texture bytes], NULL); 

NSUInteger bytesPerRow = [self.texture pixelWidth] * 4; 
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaLast; 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

CGImageRef cgImage = CGImageCreate([self.texture pixelWidth], 
            [self.texture pixelHeight], 
            8, 
            32, 
            bytesPerRow, 
            colorSpace, 
            bitmapInfo, 
            dataProvider, 
            NULL, 
            NO, 
            kCGRenderingIntentDefault); 


UIImage *image = [UIImage imageWithCGImage:cgImage]; 

CGImageRelease(cgImage); 
CGDataProviderRelease(dataProvider); 
CGColorSpaceRelease(colorSpace); 

后从我的渲染方法除去glClear(GL_COLOR_BUFFER_BIT),纹理正确呈现模拟器上,但不能在实际设备。有什么建议么?

+0

只是一个快速评论 - 请避免'处理'标签,除非你真的在谈论www.processing.org – 2014-07-07 00:04:49

回答

2

转换质感的UIImage

`#pragma mark - Convert GL image to UIImage` 
-(UIImage *) glToUIImage 
{ 

    imageWidth = 702; 
    imageHeight = 962; 

    NSInteger myDataLength = imageWidth * imageHeight * 4; 


    // allocate array and read pixels into it. 
    GLubyte *buffer = (GLubyte *) malloc(myDataLength); 
    glReadPixels(0, 0, imageWidth, imageHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 

    // gl renders "upside down" so swap top to bottom into new array. 
    // there's gotta be a better way, but this works. 
    GLubyte *buffer2 = (GLubyte *) malloc(myDataLength); 
    for(int y = 0; y < imageHeight; y++) 
    { 
     for(int x = 0; x < imageWidth * 4; x++) 
     { 
      buffer2[((imageHeight - 1) - y) * imageWidth * 4 + x] = buffer[y * 4 * imageWidth + x]; 
     } 
    } 

    // make data provider with data. 
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL); 

    // prep the ingredients 
    int bitsPerComponent = 8; 
    int bitsPerPixel = 32; 
    int bytesPerRow = 4 * imageWidth; 
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; 
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; 

    // make the cgimage 
    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); 

    // then make the uiimage from that 
    UIImage *myImage = [UIImage imageWithCGImage:imageRef]; 
    return myImage; 
} 

通过调用此方法像这样只是让你的形象 -

UIImage *yourImage = [self glToUIImage]; 

源=http://www.bit-101.com/blog/?p=1861

+0

我的代码做同样的事情 – kenshin 2012-07-06 13:50:43

+0

我不明白你的代码.....但我的代码是工作代码....你试过吗? – TheTiger 2012-07-06 13:52:29

+0

我的代码和我的图片完全一样,我的图片也没有变化,即使有点 – kenshin 2012-07-06 13:56:17