2013-02-28 42 views
1

我爲this question使用OpenGL的

同樣的要求,我現在的情況,我設置的UIImage在我的OpenGL視圖上的圖像畫面與模糊效果。 下面是我用來設置uiimage的完整代碼。還包括繪圖代碼。 使用下面的代碼我可以設置圖像和繪圖。

當我不設置圖像背景中它可以讓我畫模糊和平滑的描畫

,但如果我設置背景圖片它吸引的固體描繪

我想在背景圖像平滑的描畫。

我已經使用蘋果的一些GLPaint代碼進行繪製。

- (id)initWithCoder:(NSCoder*)coder 
{ 
    CGImageRef  brushImage; 
    CGContextRef brushContext; 
    GLubyte   *brushData; 
    size_t   width, height; 

    if ((self = [super initWithCoder:coder])) 
    { 
     CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; 
     eaglLayer.opaque = NO; 
     eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: 
             [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, 
             kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, 
             nil]; 

     _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; 
     if (!_context || ![EAGLContext setCurrentContext:_context]) 
     { 
      return nil; 
     } 

     { 
      brushImage = [UIImage imageNamed:@"Brush.png"].CGImage; 

      width = CGImageGetWidth(brushImage); 
      height = CGImageGetHeight(brushImage); 

      if(brushImage) { 
       brushData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte)); 
       brushContext = CGBitmapContextCreate(brushData, width, width, 8, width * 4, CGImageGetColorSpace(brushImage), kCGImageAlphaPremultipliedLast); 
       CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); 
       CGContextDrawImage(brushContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), brushImage); 
       CGContextRelease(brushContext); 
       glGenTextures(1, &brushTexture); 
       glBindTexture(GL_TEXTURE_2D, brushTexture); 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, brushData); 
       free(brushData); 
      } 
     } 

     // Setup OpenGL states 
     glMatrixMode(GL_PROJECTION); 
     CGRect frame = self.bounds; 
     glOrthof(0, frame.size.width, 0, frame.size.height, -1, 1); 
     glViewport(0, 0, frame.size.width , frame.size.height); 
     glMatrixMode(GL_MODELVIEW); 

     glDisable(GL_DITHER); 
     glEnable(GL_TEXTURE_2D); 
     glEnableClientState(GL_VERTEX_ARRAY); 

     glEnable(GL_BLEND); 
     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

     glEnable(GL_POINT_SPRITE_OES); 
     glTexEnvf(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE); 
     glPointSize(10); 

    } 
    return self; 
} 



    - (void)layoutSubviews 
    { 
     [EAGLContext setCurrentContext:_context]; 
     [self destroyFramebuffer]; 
     [self createFramebuffer]; 

     if (texture) { 
      [self _updateContent]; 
      glDeleteTextures(1, &texture); 
      texture = 0; 
     } 
    } 


    - (void)_updateContent { 
     NSUInteger width = self.frame.size.width; 
     NSUInteger height = self.frame.size.height; 

     CGFloat texWidth = (1.0 * width)/TEX_SIZE; 
     CGFloat texHeight = (1.0 * height)/TEX_SIZE; 

     GLfloat verts[12] = { 
      0, height, 
      width, height, 
      width, 0, 
      0, height, 
      0, 0, 
      width, 0 
     }; 

     GLfloat txcoord[12] = { 
      0, texHeight, 
      texWidth, texHeight, 
      texWidth, 0, 
      0, texHeight, 
      0, 0, 
      texWidth, 0 
     }; 

     [EAGLContext setCurrentContext:_context]; 
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, _viewFramebuffer); 
     glVertexPointer(2, GL_FLOAT, 0, verts); 
     glTexCoordPointer(2, GL_FLOAT, 0, txcoord); 
     glDrawArrays(GL_TRIANGLES, 0, 6); 

     glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

     glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); 
     [_context presentRenderbuffer:GL_RENDERBUFFER_OES]; 

     glDisable(GL_TEXTURE_2D); 
     glDisable(GL_BLEND); 

    } 


    - (void)setContent:(UIImage*)image 
{ 

    if (image) { 
     //  self.isNotEmpty = YES; 
     CGImageRef contentImage = image.CGImage; 

     [EAGLContext setCurrentContext:_context]; 

     CGFloat w = CGImageGetWidth(contentImage); 
     CGFloat h = CGImageGetHeight(contentImage); 

     GLubyte *data = (GLubyte *)calloc(TEX_SIZE * TEX_SIZE * 4, sizeof(GLubyte)); 

     CGContextRef ctx = CGBitmapContextCreate(data, TEX_SIZE, TEX_SIZE, 8, TEX_SIZE * 4, CGImageGetColorSpace(contentImage), kCGImageAlphaPremultipliedLast); 
     CGContextScaleCTM(ctx, 1, -1); 
     CGContextTranslateCTM(ctx, 0, -TEX_SIZE); 
     CGContextDrawImage(ctx, CGRectMake(0, 0, w, h), contentImage); 
     CGContextRelease(ctx); 

     if (!texture) { 
      glGenTextures(1, &texture); 
     } 
     glBindTexture(GL_TEXTURE_2D, texture); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 
     free(data); 
    } 
    [self setNeedsLayout];   
    glDisable(GL_VERTEX_ARRAY); 
} 

//調用上touchedMoved

- (void) renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end 
{ 
    glEnable(GL_BLEND); 
    if(1){ 
     sharedDelegate = [AppDelegate appDelegate]; 

     static GLfloat*  vertexBuffer = NULL; 
     static NSUInteger vertexMax = 64; 
     NSUInteger   vertexCount = 0, 
     count, 
     i; 
     GLenum err; 

     glColor4f(1.0, 0.0, 1.0, 1.0); 

     // Convert locations from Points to Pixels 
     CGFloat scale = self.contentScaleFactor; 
     start.x *= scale; 
     start.y *= scale; 
     end.x *= scale; 
     end.y *= scale; 

     // Allocate vertex array buffer 
     if(vertexBuffer == NULL) 
      vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat)); 

     // Add points to the buffer so there are drawing points every X pixels 
     count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y))/kBrushPixelStep), 1); 
     for(i = 0; i < count; ++i) { 
      if(vertexCount == vertexMax) { 
       vertexMax = 2 * vertexMax; 
       vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat)); 
      } 

      vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i/(GLfloat)count); 
      vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i/(GLfloat)count); 
      vertexCount += 1; 
     } 

     if(sharedDelegate.boolIsEraser) 
     { 
      glColor4f(1.0, 1.0, 1.0, 0.5); 
      glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); 
     } 
     // Render the vertex array 
     glVertexPointer(2, GL_FLOAT, 0, vertexBuffer); 
     glDrawArrays(GL_POINTS, 0, vertexCount); 

     if(sharedDelegate.boolIsEraser){ 
      // at last restore the mixed-mode 
      glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 
     } 

     glBindRenderbufferOES(GL_RENDERBUFFER_OES, _viewRenderbuffer); 
     [_context presentRenderbuffer:GL_RENDERBUFFER_OES]; 

     err = glGetError(); 
     if (err != GL_NO_ERROR) 
      NSLog(@"Error in frame. glError: 0x%04X", err); 

    } 
} 

任何解決辦法做到這一點? 我幾乎在那裏我的目標,但嚴重卡住here.Any幫助將不勝感激。

回答

1

我得到了解決?

剩下的東西是我需要在opengl視圖中繪製UIImage後設置我的opengl狀態。我沒有當我初始化刷質地同樣的事情...

我剛添加以下代碼LayoutSubviews方法之後_updateContent方法

 // Setup OpenGL states 
     glMatrixMode(GL_PROJECTION); 
     CGRect frame = self.bounds; 
     glOrthof(0, frame.size.width, 0, frame.size.height, -1, 1); 
     glViewport(0, 0, frame.size.width , frame.size.height); 
     glMatrixMode(GL_MODELVIEW); 

     glDisable(GL_DITHER); 
     glEnable(GL_TEXTURE_2D); 
     glEnableClientState(GL_VERTEX_ARRAY); 

     glEnable(GL_BLEND); 
     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

     glEnable(GL_POINT_SPRITE_OES); 
     glTexEnvf(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE) 

現在這個代碼工作完美..

1

您可以嘗試將陰影顏色設置爲與筆觸顏色相同,並將筆觸模糊半徑設置爲從想要延伸模糊的筆觸邊緣指出多處。您可能需要將陰影偏移設置爲CGSizeZero

+0

CGContextSetShadowWithColor(CTX ,CGSizeZero,15,outerColor); 我已經嘗試過這一點,我幾乎在那裏,但它顯示在我的Cap(CGContextSetLineCap(UIGraphicsGetCurrentContext(),kCGLineCapRound);)的開始,而不是在它的兩側的陰影。是否有任何方式給雙方(左,右)的陰影? – Heena 2013-02-28 10:58:56

0

您可以使用 CGContextSetBlendMode(背景下,kCGBlendModeClear)IKE真正的橡皮效果

+0

我在代碼中提到我使用的是CGContextSetBlendMode代碼,但這並沒有給出我的模糊效果 – Heena 2013-03-04 04:33:11

+0

您可以發送所需繪圖效果的快照還是不提供特定效果的代碼的一部分。 – Undertaker 2013-03-04 06:25:41

1

您可以從This Link

嘗試openGL的代碼或嘗試這種

CGSize offset; 
float blur;//set this variable as per your requirement 
offset.width = 10; 
offset.height = -10; 

CGContextSetShadow(context, offset, blur); 
+0

我在我的問題中提到我使用蘋果的GLPaint代碼。 – Heena 2013-03-14 04:17:36

+0

此代碼可以正常工作。 – 2013-03-14 07:57:09

+0

您是否嘗試過在opengl視圖上使用背景圖像? – Heena 2013-03-14 10:15:54