问题描述
我的要求与这个问题
我现在处于在opengl视图上设置UIImage的情况.以下是我用来设置uiimage的完整代码.还包括绘图代码.使用下面的代码,我可以设置图像并在其上绘图.
I am right now at situation where i set UIImage on my opengl view.Below is the complete code i used to set uiimage. Also it includes the drawing code.Using below code I am able to set image and drawing on it.
当我未在背景中设置图像时,它允许我绘制模糊且平滑的图形
when i do not set image in background it allows me to draw blur and smooth drawing
但是如果我设置背景图像,它将绘制实体图
but if i set background image it draws solid drawing
我要在背景图像上平滑绘制.
I want smooth drawing on background image.
我已经使用了苹果的GLPaint代码进行绘图.
I have used some of GLPaint code of apple for drawing.
- (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上调用
//Called on 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);
}
}
有什么解决方法可以做到这一点?我几乎可以实现我的目标,但是却被困在这里.任何帮助将不胜感激.
Any workaround to accomplish this?I am almost there to my goal but badly stuck here.Any help will be appreciated.
推荐答案
我找到了解决方法...
I got the solution...
剩下的事情是我需要在opengl视图中绘制UIImage之后设置我的opengl状态.我初始化画笔纹理时所做的同样的事情...
The thing remaining was I need to set my opengl states after i draw UIImage in opengl view. The same thing i did when i initialized brush texture...
我只是在_updateContent
方法之后在LayoutSubviews
方法中添加了以下代码
I just added below code in LayoutSubviews
method after _updateContent
method
// 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)
现在此代码运行正常..
and now this code is working perfectly..
这篇关于使用opengl对图像进行模糊处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!