試圖爲iPhone寫一個簡單的繪畫程序,並且我使用Apple的glPaint樣本作爲指南。唯一的問題是,繪畫不適用於白色背景,因爲白+顏色=白。我已經嘗試了不同的混合功能,但是無法使用正確的設置和/或畫筆組合來完成這項工作。我已經看到類似的帖子關於這個問題,但沒有答案。有誰知道這可能如何工作?基於Apple的'glPaint'在白色背景上的OpenGL繪圖程序 - 如何混合?
編輯:
我甚至不真透明效果,在這一點上,如果我能畫實線與圓端我會很高興。
試圖爲iPhone寫一個簡單的繪畫程序,並且我使用Apple的glPaint樣本作爲指南。唯一的問題是,繪畫不適用於白色背景,因爲白+顏色=白。我已經嘗試了不同的混合功能,但是無法使用正確的設置和/或畫筆組合來完成這項工作。我已經看到類似的帖子關於這個問題,但沒有答案。有誰知道這可能如何工作?基於Apple的'glPaint'在白色背景上的OpenGL繪圖程序 - 如何混合?
編輯:
我甚至不真透明效果,在這一點上,如果我能畫實線與圓端我會很高興。
而不是將顏色添加到混合,你可以減去其相反?這大概是油漆和燈光在現實生活中的工作方式,應該提供正確的功能。
例如:如果用戶在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
正如你所看到的,這導致在一個不錯的紫色,這是藍色的組合和紅色。您可以調整添加劑的比例以減去邏輯來模擬油漆混合的程度。
希望有幫助! =)
我碰到類似的東西。下面的混合函數調用爲我解決了它,而沒有任何複雜的數學。
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
在你的glDraw調用之前添加它,你應該可以使用任何紋理作爲畫筆繪製。
這是否在白色背景上工作?我嘗試了這些設置,並且遇到了同樣的問題,那就是我只是在白色的頂部添加了一種顏色,而這種顏色變成了白色。 – Adam 2010-05-30 20:06:05
是的,我做了一個glClear設置一切爲白色,然後這些設置讓我在任何顏色的白色背景上繪製,而不與白色合併。 – 2010-06-02 20:08:35
我用這個代碼。也許我的畫筆紋理不好,但在我的情況下,我的畫筆紋理周圍有灰色的輪廓..你能告訴我,你用什麼樣的畫筆紋理?正如我所瞭解的白色背景畫筆紋理在透明背景上應該是白色的。這樣對嗎? – OgreSwamp 2010-07-06 10:09:12
其實這部作品甚至更好:
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
你可以向我發送代碼嗎?我嘗試了這兩個,但它仍然沒有工作......要麼它只是白色的,或刷子的邊緣是錯誤的,我已經嘗試了100個組合:( – Adam 2010-06-14 05:11:09
爲什麼不發佈你的代碼,讓我們調試我的代碼是在NDA下使用的。 – 2010-06-22 19:50:17
示例代碼GLPaint用於glBlendFunc(GL_SRC_ALPHA, GL_ONE)
和功能- (id)initWithCoder:(NSCoder*)coder
。所以當顏色爲白色glBlendFunc(GL_SRC_ALPHA, GL_ONE)
模式,所有其他的顏色不會被看到。 我也想解決它。
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
這是最好的答案。你必須充電刷圖片。圖片必須是一個阿爾法背景,而橢圓。
是的,我有同樣的問題。刷子的邊緣比他們應該是黑暗的。事實證明,蘋果的api預先將α乘以rgb頻道。
所以我通過在Photoshop中製作灰度畫筆,只用rgb值並且沒有alpha通道。這應該看起來像你想要你的畫筆用白色代表全色色素,黑色代表沒有色素沉着。 我按照在蘋果的glPaint示例代碼中完成的方式加載該筆刷。然後我將R通道(或G或B通道,因爲它們都相等)複製到紋理的Alpha通道中。之後,我將刷子紋理的所有像素的R-G-B值設置爲最大值。
所以,現在你的畫筆有一個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);
}
回報brushTexture; }
可以通過改變這條線來修正預乘問題嗎?brushContext = CGBitmapContextCreate(brushData,width,width,8,width * 4,CGImageGetColorSpace(brushImage),kCGImageAlphaPremultipliedLast); – Adam 2012-06-12 23:18:16
我工作白色背景(使用默認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];
}
默認的混合功能,刷的圖像似乎只是工作。
這是glClearColor(1.0,1.0,1.0,0.0); – 2011-04-14 15:01:20
這對我不起作用......默認的混合功能就像添加光源一樣工作,所以白色+任何顏色=白色 – Adam 2012-06-12 23:05:16
不錯的想法...我已經嘗試過,但無法讓它工作,例如,如果我用100%不透明度的紅色(255,0,0)繪製,然後用藍色(0,0,255),你會期望它是藍色的,但它實際上是黑色的(0,0,0) – Adam 2010-05-08 03:36:20
@Adam:嗯。這是真的。我將編輯。 – 2010-05-08 05:09:27
又一個好主意!我也玩過這個,但是opengl畫筆很有趣 - 在形狀區域之外被解釋爲黑色,50%的白色背景+ 50%的黑色=灰色框內的漂亮的形狀。我會繼續試驗和更新,如果我找到合適的組合......但理論上我認爲這是一個很好的答案,所以我會給你一個大複選標記 – Adam 2010-05-08 06:10:10