2012-07-06 103 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