We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpOpenGL and 3D Libraries › Probleme with alpha in GLGraphics OffScreen
Pages: 1 2 
Probleme with alpha in GLGraphics OffScreen (Read 4715 times)
Probleme with alpha in GLGraphics OffScreen
Nov 8th, 2009, 4:00pm
 
I'm joyous of GLGraphics library abilities, and I'm playing with it arroud free-hand painting. I use GLGraphicsOffScreen to store my painting and apply brush, than I image() the texture onto the screen before painting of GUI.

The problem is when I want to paint with alpha-blended brush into my offscreen. The texture of entire offscreen become transparent and do not cover the backgroud of the window.

For example:

Code:

import processing.opengl.*;
import codeanticode.glgraphics.*;
import codeanticode.protablet.*;

GLGraphicsOffScreen L1;

void setup()
{
size(1000, 600, GLConstants.GLGRAPHICS);
L1 = new GLGraphicsOffScreen(this, width, height, true, 4);
L1.beginDraw();
L1.background(128,255);
L1.noStroke();

// simulate my painting with non-100% papacity of brush
L1.fill(0,0,0,128);
L1.ellipse(100,100,50,50);

L1.endDraw();

//make some strips to see the problem
background(255,255);
stroke(0);
for(int i=0;i<width;i+=10){
line(i,0,i,height);
};

image(L1.getTexture(), 0, 0, width, height);
// Ops, theres a hole :(

}



How can I render my brush with alpha blending into offscreen, but not to change alpha-channel. I want 100%-opaque offscreen texture, and just alpha-blend something onto it (like Flow in photoshop).

it means alpha-channel of the painting should not be replaced by alpha-channel of brush (like ellipse in example) bud rather should build-up additively.

If I have 100%-transparent (alpha=0) offscreen texture at the beginning, I wan't each alpha-blended ellipse() to increase alpha by its the A in fill(R,G,B,A);

Naturaly I'd like to use as much of standard rendering tools of processing (like ellipse, line, quad ... ) as possible. I don't want to do any per-pixel operation if not necessary;
Re: Probleme with alpha in GLGraphics OffScreen
Reply #1 - Nov 9th, 2009, 7:42am
 
Hi, this is an interesting problem, and incidentally quite related (I think) to a recent post on the glgraphics forum on sourceforge (https://sourceforge.net/projects/glgraphics/forums/forum/813603/topic/3452510).


I think one solution to this problem would be to have a bunch of new methods in GLTexture allowing to manipulate individual color channels in a texture. For instance:

GLTexture.setAlphaChannel(int[] buffer);
GLTexture.setAlphaChannel(int value);

The first method would copy buffer to the alpha channel of GLTexture. The second one would write value to the alpha component of all the texels in the texture. Similar methods would be implemented for the red, green and blue channels.

How this methods could be useful for you? After you do the offscreen rendering to L1 (with all the proper alpha blending of your geometric primitives), then you write 255 to the alpha channel of L1:

Code:

...
L1.fill(0,0,0,128);  
L1.ellipse(100,100,50,50);
 
L1.endDraw();

// Setting the alpha channel of the offscreen
// texture to full opacity.
GLTexture tex = L1.getTexture();
tex.setAlphaChannel(255);

image(tex, 0, 0, width, height);


What do you think about this idea?
Re: Probleme with alpha in GLGraphics OffScreen
Reply #2 - Nov 9th, 2009, 2:12pm
 
Yes, operations with Channel would be sure very usefull. Especially
Copy just specific chanel from one texture to other, or divide one texture into four textures for each channel do something and than put it together. It would be usefull for operations like "quick mask" in Photoshop or "color to alpha" in GIMP and many other similar things.
I thing, now it's possible using user defined GLSL filter, but with new function it would be more confortable.

However, it is not the solution of this problem, consider:
1]I want to build up my brush (like using airbrush) of black circle on my texture white backgroud RGBA=(1.0,1.0,1.0,1.0)
2]I do this by repetitive rendering of RGBA=(0.0,0.0,0.0,a) circle onto the screen, where "a" is opacity (Flow) value of brush
3]However it would not build up, but replace pixels of my texture by (0.0,0.0,0.0,a)
4]Now I set alpha-channel to 1.0. I get texture which is white somewhere RGBA=(1.0,1.0,1.0,1.0), where I did not paint at all, and black RGBA=(0.0,0.0,0.0,1.0) everywhere I did;
5]this is not what I want. I want to finish with texture  gradually shaded like RGBA=(1-k*a,1-k*a,1-k*a,1.0) where "k" is number of strokes I had painted over this pixel.

what I need is to render ellipses, lines and polygons in other render mode.

instead of replace(RGBA):
result.RGBA=brush.RGBA

I need alpha-blend(RGB):
result.RGB=backgroud.RGB*(1-brush.A)+brush.RGB*brush.A
result.A = backgroud.A + brush.A

however, is it samehow possible to set?
Re: Probleme with alpha in GLGraphics OffScreen
Reply #3 - Nov 9th, 2009, 2:27pm
 
btw. If I can sugest something considering your proposed new methods of GLTexture, just one universal can does all this work and more:

GLTexture.blendChannelByChannel(
SoureTexture, // where I take sourceChannel?
sourceChannel, // R, G, B or A?
targetChannel, // R, G, B or A?
belndMode // add, substract, max, min, multiply or replace?
);
Re: Probleme with alpha in GLGraphics OffScreen
Reply #4 - Nov 10th, 2009, 4:31am
 
Ok, I think the solution is easier and involves properly implementing blending methods in both GLGraphicsOffscreen and GLGraphics.

The following sample code does in fact what you need:

Code:

// Enables blending in the offscreen surface using the BLEND mode.
L1.setBlendMode(BLEND);
L1.beginDraw();
...
L1.endDraw();

// We get the underlying GLGraphics renderer...
GLGraphics renderer = (GLGraphics)g;
//... in order to use its setBlendMode() method.
// The BACKGROUND_ALPHA mode keeps the alpha
// from the background, it is implemented internally
// in OpenGL with the following code:
// gl.glBlendColor(0.0f, 0.0f, 0.0f, 1.0f);
// gl.glBlendFunc(GL.GL_ONE, GL.GL_CONSTANT_COLOR);
renderer.setBlendMode(BACKGROUND_ALPHA);

image(L1.getTexture(), 0, 0);


BACKGROUND_ALPHA is just a possible name. All the blending modes to have in GLGraphics should come from examining the OpenGL  blending functions (glAlphaFunc, glBlendColor, glBlendEquation, glBlendEquationSeparate, glBlendFunc) and the blending constants already present in Processing (BLEND, ADD, SUBTRACT, LIGHTEST, DARKEST, DIFFERENCE, etc). I'm still not sure it is possible to reproduce all the blending modes in Processing using OpenGL...
Re: Probleme with alpha in GLGraphics OffScreen
Reply #5 - Nov 10th, 2009, 7:44am
 
Yes, that is exactly what is needed.

Your last code sample is just proposal? Because it print an error "The function setBlendMode() does not exist".

If so, is it somehow possible for now set render mode directly using underlaying OpenGL? I belive OpenGL is behind your library or not?

I tried to initialize OpenGL and call gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA); but it also did not work to solve this problem. I don't want to switch my renderer form your GLGraphics to OpenGL because I want this nice easy acess to GPGPU and GLSL functionality.

I think OpenGL's rendering capability in this area are superset of processing's.
Re: Probleme with alpha in GLGraphics OffScreen
Reply #6 - Nov 10th, 2009, 1:07pm
 
Hi, I just added the GLGraphics.setBlendMode() and GLGraphicsOffscreen.setBlendMode() to the trunk. There is still no official release with these new features, but you can try them out with this pre-release package:

http://users.design.ucla.edu/~acolubri/processing/glgraphics/glgraphics-20091110.zip

The following sketch should have the correct behavior in terms of blending, when using the pre-release glgraphics:

Code:

import processing.opengl.*;
import codeanticode.glgraphics.*;

GLGraphicsOffScreen glg1;

void setup()
{
 size(640, 480, GLConstants.GLGRAPHICS);
   
 glg1 = new GLGraphicsOffScreen(this, width, height);

 glg1.beginDraw();
 glg1.background(255);  
 glg1.noStroke();
 glg1.endDraw();
}

void draw()
{
 background(0);
 
 // In the off-screen surface 1, we draw random ellipses.
 glg1.setBlendMode(BLEND);
 glg1.beginDraw();
   glg1.fill(0, 50);
   glg1.ellipse(mouseX, mouseY, 50, 50);
 glg1.endDraw();  

 stroke(255);
 for(int i = 0; i < width; i += 10) line(i, 0, i, height);

 GLGraphics renderer = (GLGraphics)g;
 renderer.setBlendMode(GLConstants.BACKGROUND_ALPHA);  
 image(glg1.getTexture(), 10, 10, width - 20, height - 20);
}
Re: Probleme with alpha in GLGraphics OffScreen
Reply #7 - Nov 11th, 2009, 9:26am
 
Thank you a lot, now it works well.

Are there any other changes from last version? Especially I noticed some differences considering transforms (translate, scale... )
Some of my brushes which use transforms of PMatrix now render on different place than before. Also I used L1.scale(-1,1) to flip the painting horrizontally and vertically

Code:

if(key=='x'){
L1.beginDraw();
L1.scale(-1,1);
L1.image(L1.getTexture(), 0, 0, width*zoom, height*zoom);
L1.endDraw();
}


Now it does not work this way.

I can make it diferent way, I just want to know if this change is intended or some side effect. If I sould rewride the code according to this new behaviour or wait for release.
Re: Probleme with alpha in GLGraphics OffScreen
Reply #8 - Nov 11th, 2009, 9:46am
 
The changes come from some testing I'm currently doing with the latest source. But my intention is to return the original behavior once this new version is finished.
Re: Probleme with alpha in GLGraphics OffScreen
Reply #9 - Nov 12th, 2009, 12:44am
 
Ok, thanks.

btw. Have you an guess what is a best way how to apply GLSL filter inside (masked by) brush stroke?
I'd like to do this by rendering of brush stroke into different texture (like Lmask) first and than use GLSL filter with input of Lmask working on  L1. However, if I want to paint pictures of big resolution it could be slow to apply filter on the whole picture. It would be best to apply it only in the region where brush stroke is really rendered. But than I need tile the image and Lmask to smaller parts (tiles, this way it's made in gimp as I know). When however is my filter non-local (reads pixels from different location than pixel is rendered,like blur) than it would be a problem on the edge of tiles (I need transport information on the edge to neighbour tile). Also rendering of brush on tiled image is more complicated => I don't want to tile Smiley Have you any idea of better way how to apply GLSL filter just inside brush stroke
1]without wasting time on pixels where brush isn't rendered
2]without tiling of image.
Re: Probleme with alpha in GLGraphics OffScreen
Reply #10 - Nov 13th, 2009, 11:07am
 
Ok, one possible solution would be to constrain the filter to be applied to a rectangular region of the input texture. Say:

inputTex.filter(brushFilter, outputTex, brush.x, brush.y, brush.w, brush.h);

Would this take care of the non-locality issue you mention?
Re: Probleme with alpha in GLGraphics OffScreen
Reply #11 - Nov 13th, 2009, 2:57pm
 
yes, thats exactly what I search for. May be I just need to read the reference and example codes of glgraphics more deeply.

I found just
GLTexture.filter(GLTextureFilter texFilter, GLTexture destTex, float[]... values)
Applies filter texFilter using this texture as source and destTex as destination.

I'm not sure if these ", float[]... values)" can be used for the constrain?
or is inputTex.filter(brushFilter, outputTex, brush.x, brush.y, brush.w, brush.h); proposal of new function?

for slightly nonlocal interactions like covolution including  just neighbour pixels is rectangular constrain (+ smooth masking by brush texture "window") enought, for completly nonlocal interactions (like pixel[1566,336]=func(pixel[1,687],pixel[69,1549])) isn't GPU processing very efficient neither as I know.
Re: Probleme with alpha in GLGraphics OffScreen
Reply #12 - Nov 13th, 2009, 3:14pm
 
well, you could potentially use the float parameters of a filter to constrain the region where the filter is applied. However this will be highly inefficient, since it will involve rendering the whole input texture, and then having a conditional inside the pixel shader to process only those pixels inside the desired rect.

I think the efficient way of dealing with this problem would be to implement a new function along the lines of what I described in my previous message, so only the specified rectangular portion of the input texture gets rendered...

But here I have a question: is the input texture just the brush texture, or a larger texture with the brush already drawn in some specific area of it?
Re: Probleme with alpha in GLGraphics OffScreen
Reply #13 - Nov 14th, 2009, 10:13am
 
good question, my first idea was just texture of the brush (one iteration or frame of brush rendering), but recently I think that for some purposes it would be better render whole stroke (the trace of brush between MousePressed and MouseReleased event) separately, and than apply it to the picture as one-piece entity. This mode of rendering in photoshop (if you use "Opacity" instead of "Flow") enable some techniques of painting.
But this could be a problem, if I want to see effect interactivly, than I don't know the final size of affected area (size of one stroke), so I sould realocate updated stroke texture of larger and larger size in each call of "draw" event. My solution would be probably to make imediately at the begining overlay stroke-texture over the hole painting which is transparent everywhere but the pixels where brush stroke is already rendered and than call the filter with the rectangular constrain working with both (painting and stroke overlay) full-size textrures as imput but only in the constrained area. With this constrain it could be as fast as working with smaller textures of "just stroke"-size.
Re: Probleme with alpha in GLGraphics OffScreen
Reply #14 - Nov 16th, 2009, 2:45am
 
I see. This type of dynamic masking could be done using the stencil buffer. It requires some work though in order to implement properly. I added this to the feature tracker of glgraphics:

https://sourceforge.net/tracker/?func=detail&aid=2898381&group_id=225391&atid=10
64716

In a related not, I put online a newer version of the lib where the behavior of the offscreen renderer should not change in the final release:

http://users.design.ucla.edu/~acolubri/processing/glgraphics/glgraphics-20091116.zip
Pages: 1 2