2

iPhone 用の簡単なペイント プログラムを作成しようとしており、Apple の glPaint サンプルをガイドとして使用しています。唯一の問題は、白 + 色 = 白であるため、白い背景ではペイントが機能しないことです。さまざまなブレンド機能を試しましたが、これを機能させるための設定やブラシの適切な組み合わせを見つけることができませんでした。この問題に関する同様の投稿を見たことがありますが、答えはありません。これがどのように機能するか知っている人はいますか?

編集:
私は実際には透明効果さえありません。この時点で、端が丸い実線を描くことができれば幸いです。

4

7 に答える 7

3

消去メソッドでクリアカラーを変更するだけで、(デフォルトの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];
}

デフォルトのブレンド機能とブラシ画像はうまく機能しているようです。

于 2011-01-12T16:53:58.997 に答える
2

ブレンドに色を追加するのではなく、反対の色を差し引くことはできますか? これは、ペイントとライトが実際にどのように機能するかを大まかに示したものであり、正しい機能を提供するはずです。

例: ユーザーが でペイントしている場合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

ご覧のとおり、これにより、青と赤の組み合わせである美しい紫色が得られます。加法ロジックと減法ロジックの比率を微調整して、塗料がどれだけうまく混ざるかをシミュレートできます。

それが役立つことを願っています! =)

于 2010-05-08T03:08:42.730 に答える
2

はい、同じ問題がありました。ブラシのエッジが本来よりも暗くなっています。Apple の API pre がアルファを RGB チャネルに乗算することがわかりました。

そこで、Photoshop で RGB 値のみを使用し、アルファ チャネルを使用しないグレースケール ブラシを作成することで、これに対抗しました。これは、フルカラーの色素沈着を表す白と色の色素沈着がないことを表す黒を使用して、ブラシを希望どおりに表示する必要があります。そのブラシを、Apple の glPaint サンプル コードで行った方法でロードします。次に、R チャネル (または G または B チャネルはすべて等しいため) をテクスチャのアルファ チャネルにコピーします。次に、ブラシ テクスチャのすべてのピクセルの RGB 値を最大に設定します。

これで、ブラシには、ブラシがどのように見えるかのデータを含むアルファ チャネルができました。そして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);
}

ブラシテクスチャを返します。}

于 2010-07-16T21:20:57.223 に答える
1

私は似たようなことに遭遇しました。次のブレンディング関数呼び出しは、複雑な計算なしで解決しました。

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

これを glDraw 呼び出しの前に追加すると、任意のテクスチャをブラシとして描画できるようになります。

于 2010-05-28T19:08:18.410 に答える
0
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);

これがベストアンサーです。そして、ブラシ絵をチャージする必要があります。

于 2010-07-13T08:38:27.420 に答える
0

実際、これはさらにうまく機能します:

glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
于 2010-06-09T19:57:46.103 に答える
0

サンプル コード GLPaint が使用され、関数内glBlendFunc(GL_SRC_ALPHA, GL_ONE)でモードになっているため、色が白である間、他のすべての色は表示されません。私も解決したいです。glBlendFunc(GL_SRC_ALPHA, GL_ONE)- (id)initWithCoder:(NSCoder*)coder

于 2010-07-04T06:44:58.283 に答える