【问题标题】:rendering a UIImage using openGL使用 openGL 渲染 UIImage
【发布时间】:2016-05-05 09:50:45
【问题描述】:

我使用以下代码使用 openGL 渲染 UIImage。 Texture2D 类来自 Apple,所以我认为它是正确的。图像不显示。我只是得到 glClearColor 产生的背景颜色。我的应用程序基于 Apple 的 GLpaint 示例代码,因此设置正确,我可以使用 openGL 画线就好了。

下面这个渲染代码是不是漏掉了什么?

- (void) render:(UIImage *)image
{
[EAGLContext setCurrentContext:context];
glViewport(0, 0, backingWidth, backingHeight);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// texturing will need these
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_TEXTURE_2D);

glOrthof(0, backingWidth, 0, backingHeight, -1, 1);

glMatrixMode(GL_MODELVIEW);

glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

Texture2D *texture = [[Texture2D alloc] initWithImage:image];

[texture drawInRect: self.frame];


// This application only creates a single color renderbuffer which is already bound at this point.
// This call is redundant, but needed if dealing with multiple renderbuffers.
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER];
}

【问题讨论】:

  • 不是您问题的答案,但请注意,通过在每一帧调用 [[Texture2D alloc] initWithImage:image] 而不释放它,您会泄漏大量内存。
  • @hanno ARC 可能已启用,在这种情况下它不会泄漏。虽然,如果每帧都使用它,那么可能有更好的方法来缓存返回值,而不是每次调用都创建一个新值。

标签: ios objective-c opengl-es


【解决方案1】:

更新:用实际代码替换原始答案中损坏的链接。

这是对我有用的代码:

-(void) mergeWithImage:(UIImage*) image
{
if(image==nil)
{
    return;
}
glPushMatrix();
glColor4f(256,
          256,
          256,
          1.0);
GLuint stampTexture; // = texture.id;

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glGenTextures(1, &stampTexture);
glBindTexture(GL_TEXTURE_2D, stampTexture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

GLuint imgwidth = CGImageGetWidth(image.CGImage);
GLuint imgheight = CGImageGetHeight(image.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc( imgheight * imgwidth * 4 );
CGContextRef context2 = CGBitmapContextCreate( imageData, imgwidth, imgheight, 8, 4 * imgwidth, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
CGContextTranslateCTM (context2, 0, imgheight);
CGContextScaleCTM (context2, 1.0, -1.0);
CGColorSpaceRelease( colorSpace );
CGContextClearRect( context2, CGRectMake( 0, 0, imgwidth, imgheight ) );
CGContextTranslateCTM( context2, 0, imgheight - imgheight );
CGContextDrawImage( context2, CGRectMake( 0, 0, imgwidth, imgheight ), image.CGImage );

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgwidth, imgheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

CGContextRelease(context2);

free(imageData);

static const GLfloat texCoords[] = {
    0.0, 1.0,
    1.0, 1.0,
    0.0, 0.0,
    1.0, 0.0
};

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

/*
 These arrays would need to be changed if the size of the paintview changes. You must make sure that all image imput is 64x64, 256x256, 512x512 or 1024x1024.  Here we are using 512, but you can use 1024 as follows:

 use the numbers:
 {
 0.0, height, 0.0,
 1024, height, 0.0,
 0.0, height-1024, 0.0,
 1024, height-1024, 0.0
 }
 */

NSLog(@"height of me: %f", self.bounds.size.height);

static const GLfloat vertices[] = {
    0.0,  643, 0.0,
    1024,  643, 0.0,
    0.0, -381, 0.0,
    1024, -381, 0.0
};

static const GLfloat normals[] = {
    0.0, 0.0, 1024,
    0.0, 0.0, 1024,
    0.0, 0.0, 1024,
    0.0, 0.0, 1024
};


glBindTexture(GL_TEXTURE_2D, stampTexture);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glPopMatrix();

glDeleteTextures( 1, &stampTexture );

// Display the buffer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];

}



-(void) addImageToView{
UIImage* imageToAdd= [UIImage imageNamed:@"IMAGE_TO_ADD_TO_GL_VIEW.png"];


//     all images added to the paining view MUST be 512x512.
//     You can also add smaller images (even transformed ones) using this method - just add it to a UIView and then get it's graphics context

UIView* imageView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 512, 512)];



UIImageView* subView   = [[UIImageView alloc] initWithImage:imageToAdd];


[imageView addSubview:subView];
UIImage* blendedImage =nil;

UIGraphicsBeginImageContext(imageView.frame.size);

[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];

blendedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

[self mergeWithImage: blendedImage ];

【讨论】:

  • 链接无效。请提供解决方案,而不仅仅是一个链接
  • 死链接。无用的回答者
  • 我已经用代码替换了断开的链接。请考虑撤消反对票,以免阻止人们使用该代码。
猜你喜欢
  • 2013-01-06
  • 1970-01-01
  • 1970-01-01
  • 2013-12-13
  • 2011-09-11
  • 2023-03-23
  • 2019-10-12
  • 2014-04-06
  • 1970-01-01
相关资源
最近更新 更多