尝试为 iPhone 编写一个简单的绘图程序,我使用 Apple 的 glPaint 示例作为指南。唯一的问题是,绘画不适用于白色背景,因为白色 + 颜色 = 白色。我尝试了不同的混合功能,但无法找到正确的设置和/或画笔组合来完成这项工作。我看过关于这个问题的类似帖子,但没有答案。有谁知道这可能如何工作?
编辑:
我什至没有真正的透明效果,在这一点上,如果我能画出圆角的实线,我会很高兴。
我让白色背景工作(使用默认的 GLPaint 代码),只需更改擦除方法中的清除颜色,即,
- (void) erase
{
[EAGLContext setCurrentContext:context];
// Clear the buffer
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
//glClearColor(0.0, 0.0, 0.0, 0.0);
glClearColor(1.0, 1.0, 1.0, 0.0); // Change to white
glClear(GL_COLOR_BUFFER_BIT);
// Display the buffer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
默认的混合功能和画笔图像似乎可以正常工作。
您可以减去相反的颜色,而不是将颜色添加到混合中吗?这大致是油漆和灯光在现实生活中的工作方式,并且应该提供正确的功能。
例如:如果用户正在绘画Red:255 Green:0 Blue:100 Opacity:0.5
,您应该对像素执行此操作:
pixel.red -= (255-paint.red) * paint.opacity; //Subtract 0
pixel.green -= (255-paint.green) * paint.opacity; //Subtract 127.5
pixel.blue -= (255-paint.blue) * paint.opacity; //Subtract 77.5
编辑:正如您所指出的,这不是预期的,因为用全红色涂上全蓝色会变成黑色,因为它们相互减去。
一个可能的解决方法是结合加法和减法方法。
例如,如果您添加0.5*paint.colour
和减去0.5*paint.complementaryColour
,将全红色添加到全蓝色将导致:
newPixel.red -> 0 + 127.5 - 0 = 127.5
newPixel.green -> 0 + 0 - 127.5 = 0 //Cap it off, or invent new math =D
newPixel.blue -> 255 + 0 - 127.5 = 127.5
如您所见,这会产生漂亮的紫色,它是蓝色和红色的组合。您可以调整添加剂与减法逻辑的比例,以模拟油漆的混合效果。
希望有帮助!=)
是的,我有同样的问题。刷子的边缘比它们应该的要暗。事实证明,苹果的 api pre 将 alpha 乘以 rgb 通道。
所以我通过在 Photoshop 中制作一个只有 rgb 值且没有 alpha 通道的灰度画笔来反驳这一点。这应该看起来像您希望画笔的方式,白色代表全彩色色素沉着,黑色代表无色素沉着。我按照苹果的 glPaint 示例代码中的方式加载该画笔。然后我将 R 通道(或 G 或 B 通道,因为它们都相等)复制到纹理的 Alpha 通道中。之后,我将画笔纹理的所有像素的 RGB 值设置为最大值。
所以现在你的画笔有一个 alpha 通道,其中包含你的画笔外观的数据。并且RGB都是1。
最后我使用了混合功能:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
并且不要忘记在绘制之前设置颜色。
glColor4f(1.0f,0.0f,0.0f,1.0f); //red color
查看下面的代码,看看它是否适合您:
-(GLuint) createBrushWithImage: (NSString*)brushName
{
GLuint brushTexture;
CGImageRef brushImage;
CGContextRef brushContext;
GLubyte *brushData,*brushData1;
size_t width, height;
//initialize brush image
brushImage = [UIImage imageNamed:brushName].CGImage;
// Get the width and height of the image
width = CGImageGetWidth(brushImage);
height = CGImageGetHeight(brushImage);
//make the brush texture and context
if(brushImage) {
// Allocate memory needed for the bitmap context
brushData = (GLubyte *) calloc(width * height *4, sizeof(GLubyte));
// We are going to use brushData1 to make the final texture
brushData1 = (GLubyte *) calloc(width * height *4, sizeof(GLubyte));
// Use the bitmatp creation function provided by the Core Graphics framework.
brushContext = CGBitmapContextCreate(brushData, width, height, 8, width *4 , CGImageGetColorSpace(brushImage), kCGImageAlphaPremultipliedLast);
// After you create the context, you can draw the image to the context.
CGContextDrawImage(brushContext, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), brushImage);
// You don't need the context at this point, so you need to release it to avoid memory leaks.
CGContextRelease(brushContext);
for(int i=0; i< width*height;i++){
//set the R-G-B channel to maximum
brushData1[i*4] = brushData1[i*4+1] =brushData1[i*4+2] =0xff;
//store originally loaded brush image in alpha channel
brushData1[i*4+3] = brushData[i*4];
}
// Use OpenGL ES to generate a name for the texture.
glGenTextures(1, &brushTexture);
// Bind the texture name.
glBindTexture(GL_TEXTURE_2D, brushTexture);
// Set the texture parameters to use a minifying filter and a linear filer (weighted average)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Specify a 2D texture image, providing the a pointer to the image data in memory
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, brushData1);
// Release the image data; it's no longer needed
free(brushData1);
free(brushData);
}
返回画笔纹理;}
我遇到了类似的事情。以下混合函数调用为我解决了它,无需任何复杂的数学运算。
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
在您的 glDraw 调用之前添加它,您应该能够使用任何纹理作为画笔进行绘制。
实际上这效果更好:
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
示例代码 GLPaint 在函数中使用glBlendFunc(GL_SRC_ALPHA, GL_ONE)
和glBlendFunc(GL_SRC_ALPHA, GL_ONE)
模式。因此- (id)initWithCoder:(NSCoder*)coder
,当颜色为白色时,将看不到所有其他颜色。我也想解决。
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
这是最好的答案。而且你必须为画笔充电。图片必须是alpha背景和椭圆。