Antialiasing with transparent background

  • Follow


I have problem for rendering antialiasing lines in a 2D application. The 
rendering output is a picture.

First, I set the background totally transparent (I need this 
transparency for latter use of the result)
Second, I render a filled polygone in white, the commands are put in a 
display list.
Third, I reuse the display list to render a polyline in grey. The 
problem is that the antialiased pixels are blended with the transparent 
background, not the filled polygone.

I tried many things, even with depth test enable, and the polyline 
rendered above the polygone, I always have the same problem

I also have another problem with the antialiasing, that I think is 
related to first one. If I render without transparency, the line are 
clearly visible, with the transparency, they are very light (I see that 
the antialiasing, in this case, is done on the color AND on the alpha 
channel).
I was able to have a better result with setting the line widther of 1 
pixel if the transparency is used. This work fine for black lines, the 
result is very similar with and without transparency. But for a blue 
line, the blue is very light for some pixel, thus the line isn't as 
visible than without transparency.

Anybody who can helps me?

Thanks
0
Reply PBY 9/16/2005 9:57:02 AM

PBY wrote:
> I have problem for rendering antialiasing lines in a 2D application. The 
> rendering output is a picture.
> 
> First, I set the background totally transparent (I need this 
> transparency for latter use of the result)
> Second, I render a filled polygone in white, the commands are put in a 
> display list.
> Third, I reuse the display list to render a polyline in grey. The 
> problem is that the antialiased pixels are blended with the transparent 
> background, not the filled polygone.
> 

What's your blending function?   glBlendFunc(???)



-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again.  They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful.  But it happens
every day.  I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address

0
Reply fungus 9/16/2005 1:27:53 PM


I use glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


fungus wrote:
> PBY wrote:
> > I have problem for rendering antialiasing lines in a 2D application. The
> > rendering output is a picture.
> >
> > First, I set the background totally transparent (I need this
> > transparency for latter use of the result)
> > Second, I render a filled polygone in white, the commands are put in a
> > display list.
> > Third, I reuse the display list to render a polyline in grey. The
> > problem is that the antialiased pixels are blended with the transparent
> > background, not the filled polygone.
> >
>
> What's your blending function?   glBlendFunc(???)
>
>
>
> --
> <\___/>
> / O O \
> \_____/  FTB.    For email, remove my socks.
>
> In science it often happens that scientists say, 'You know
> that's a really good argument; my position is mistaken,'
> and then they actually change their minds and you never
> hear that old view from them again.  They really do it.
> It doesn't happen as often as it should, because scientists
> are human and change is sometimes painful.  But it happens
> every day.  I cannot recall the last time something like
> that happened in politics or religion.
> 
> - Carl Sagan, 1987 CSICOP keynote address

0
Reply PBY 9/19/2005 6:47:13 AM

PBY wrote:
> I use glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
> 
> 

To be honest I don't think this is going to work.
It sounds like it ought to ... but in practice I bet
you'll never get it right.


If you tell us what you're really trying to do (I
bet it isn't "draw a single white square on a black
background") then we might be able to suggest
something.


-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again.  They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful.  But it happens
every day.  I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address

0
Reply fungus 9/19/2005 1:35:06 PM

I try to draw a city map, with some big part transparent, to put on top 
of other picture.

All is working fine, expect of the antialiasing when transparency is 
actived.

But, without antialiasing, the picture are not very nice.

I think it's a specific case, but it's strange that nobody has never 
tried to use transparency and antialiasing.

For the problem of width of the lines, I tested every blend functions. 
Only one other was usable, in fact it was better, but the rendering was 
not working for some other cases.

I thinked of using the glAccum, to render first the polygone and after 
the polyline. But I have fear that it will take more time than before to 
render. And the rendering process is already too long.




fungus wrote:
> PBY wrote:
> 
>> I use glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
>>
>>
> 
> To be honest I don't think this is going to work.
> It sounds like it ought to ... but in practice I bet
> you'll never get it right.
> 
> 
> If you tell us what you're really trying to do (I
> bet it isn't "draw a single white square on a black
> background") then we might be able to suggest
> something.
> 
> 
0
Reply PBY 9/19/2005 2:49:40 PM

PBY wrote:
> I have problem for rendering antialiasing lines in a 2D application. The 
> rendering output is a picture.
> 
> First, I set the background totally transparent (I need this 
> transparency for latter use of the result)
[...]

Hi,
I have had similar problems while blending to a transparent destination.
The answer is to use glBlendFuncSeparate...

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 
GL_ONE_MINUS_DST_ALPHA, GL_ONE);

The resulting image will be premultiplied, so you might have to 
postdivide it (multiply each component of each pixel by 255/alpha).

Jonno


0
Reply Jonno 9/19/2005 3:39:03 PM

Thanks a lot, it seems to be a solution.

Unfortunalty, I can not use it for the moment, when I get the gl 
extensions, I only have:

GL_WIN_swap_hint GL_EXT_bgra GL_EXT_paletted_texture

I tested with another program, and this time, I have a lot of 
extensions, including glBlendFuncSeparate

The big difference between the two programs is that mine don't render on 
screen.

But, it's the first time I used these opengl extensions, so it's a good 
possibility that I miss something when setting the context.

Currently, I'm on windows, but I will also test on Linux after.

I will try to find difference between the two program's context, but if 
somebody have an idea, it will be very usefull.

PBY

Jonno wrote:
> PBY wrote:
> 
>> I have problem for rendering antialiasing lines in a 2D application. 
>> The rendering output is a picture.
>>
>> First, I set the background totally transparent (I need this 
>> transparency for latter use of the result)
> 
> [...]
> 
> Hi,
> I have had similar problems while blending to a transparent destination.
> The answer is to use glBlendFuncSeparate...
> 
> glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 
> GL_ONE_MINUS_DST_ALPHA, GL_ONE);
> 
> The resulting image will be premultiplied, so you might have to 
> postdivide it (multiply each component of each pixel by 255/alpha).
> 
> Jonno
> 
> 
0
Reply PBY 9/20/2005 7:44:26 AM

PBY wrote:
> Thanks a lot, it seems to be a solution.
> 
> Unfortunalty, I can not use it for the moment, when I get the gl 
> extensions, I only have:
> 
> GL_WIN_swap_hint GL_EXT_bgra GL_EXT_paletted_texture
> 
> I tested with another program, and this time, I have a lot of 
> extensions, including glBlendFuncSeparate
> 
> The big difference between the two programs is that mine don't render on 
> screen.
[...]

I guess you're calling ChoosePixelFormat with the PFD_DRAW_TO_BITMAP flag?
This means you will get the Microsoft Software implementation - slow, 
and no extensions.
If you want to use hardware to render to a bitmap, you'll need to use a 
P-buffer instead.

Jonno.
0
Reply Jonno 9/20/2005 8:35:11 AM

Many thanks!

Yes, I use PFD_DRAW_TO_BITMAP.
I will change my code to use the P-buffer

Thanks

PBY


Jonno wrote:
> PBY wrote:
> 
>> Thanks a lot, it seems to be a solution.
>>
>> Unfortunalty, I can not use it for the moment, when I get the gl 
>> extensions, I only have:
>>
>> GL_WIN_swap_hint GL_EXT_bgra GL_EXT_paletted_texture
>>
>> I tested with another program, and this time, I have a lot of 
>> extensions, including glBlendFuncSeparate
>>
>> The big difference between the two programs is that mine don't render 
>> on screen.
> 
> [...]
> 
> I guess you're calling ChoosePixelFormat with the PFD_DRAW_TO_BITMAP flag?
> This means you will get the Microsoft Software implementation - slow, 
> and no extensions.
> If you want to use hardware to render to a bitmap, you'll need to use a 
> P-buffer instead.
> 
> Jonno.
0
Reply PBY 9/20/2005 8:38:56 AM

Hi Jonno,

I found the same solution, but .. how to postdivide quickly in OpenGL ?

Mik
--


"Jonno" <a@a.com> ha scritto nel messaggio 
news:rYAXe.18984$hQ4.3013@newsfe4-win.ntli.net...
> PBY wrote:
>> I have problem for rendering antialiasing lines in a 2D application. The 
>> rendering output is a picture.
>>
>> First, I set the background totally transparent (I need this transparency 
>> for latter use of the result)
> [...]
>
> Hi,
> I have had similar problems while blending to a transparent destination.
> The answer is to use glBlendFuncSeparate...
>
> glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 
> GL_ONE_MINUS_DST_ALPHA, GL_ONE);
>
> The resulting image will be premultiplied, so you might have to postdivide 
> it (multiply each component of each pixel by 255/alpha).
>
> Jonno 


0
Reply Michele 9/20/2005 9:41:25 AM

Michele Puccini wrote:

> I found the same solution, but .. how to postdivide quickly in OpenGL ?

Unfortunately I could not find a way to do this.
I ended up doing it on the CPU.
But if you are using your premultiplied target as a texture, then I 
*think* you can use glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE) when you 
use the texture.
I have not tested this though.

Jonno
0
Reply Jonno 9/20/2005 10:27:00 AM

 > "Jonno" <a@a.com> ha scritto nel messaggio
 >
 >>The resulting image will be premultiplied, so you might have to postdivide
 >>it (multiply each component of each pixel by 255/alpha).

Michele Puccini replied:
> Hi Jonno,
> 
> I found the same solution, but .. how to postdivide quickly in OpenGL ?


Why would you need to postdivide? Why not keep the colors as weighted colors?
They are better for processing that way.

--
Andy V
0
Reply Andy 9/21/2005 12:28:19 AM

Jonno wrote:
> Michele Puccini wrote:
> 
>> I found the same solution, but .. how to postdivide quickly in OpenGL ?
> 
> 
> Unfortunately I could not find a way to do this.
> I ended up doing it on the CPU.
> But if you are using your premultiplied target as a texture, then I 
> *think* you can use glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE) when you 
> use the texture.
> I have not tested this though.
> 
> Jonno

The proper blend mode for pre-weighted back-to-front is GL_ONE, GL_ONE_MINUS_SRC_ALPHA.

--
Andy V
0
Reply Andy 9/21/2005 12:39:00 AM

>> But if you are using your premultiplied target as a texture, then I 
>> *think* you can use glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE) when 
>> you use the texture.

> The proper blend mode for pre-weighted back-to-front is GL_ONE, 
> GL_ONE_MINUS_SRC_ALPHA.

OK, that makes more sense :)
0
Reply Jonno 9/21/2005 7:25:22 AM

Imagine you want to save your result to a PNG file..

Mik
--

"Andy V" <Nobody@nowhere.net> ha scritto nel messaggio 
news:Ob6dnc5bDL6-NK3eRVn-ig@comcast.com...
> > "Jonno" <a@a.com> ha scritto nel messaggio
>
> Why would you need to postdivide? Why not keep the colors as weighted 
> colors?
> They are better for processing that way.
>
> --
> Andy V 


0
Reply Michele 9/21/2005 8:55:44 AM

 > "Andy V" <Nobody@nowhere.net> ha scritto nel messaggio
 >>Why would you need to postdivide? Why not keep the colors as weighted
 >>colors?
 >>They are better for processing that way.

Michele Puccini replied:

> Imagine you want to save your result to a PNG file..

I did not realize that the PNG spec requires unweighted colors -- I've been saving
weighted colors in PNG files for many years.

Yes, when writing a correct PNG file it is necessary to convert (back) to unweighted
colors.

--
Andy V
0
Reply Andy 9/21/2005 11:09:50 PM

Thanks to all.

Now, these antialiasing don't create anymore some artifact. But I
didn't divide the color before saving in png, the colors are correct
like that.

Now, I have just another problem, it seems that glClearColor don't work
anymore. I can change the clear color and nothing change.

For using the gl extentions, I change my code to create a window, which
isn't show. This part replace the bitmap used before. In fact, I use
the code from Nehe site. all work correctly, expect this glClearColor.

When I don't use the transparency, the background is now white. As a
workaround, I first render a white quad (not a good way, but it's
working). But, with the transparency, I cannot do that. In the general
case, it's ok. But I need also to render some filled polygone with some
amount of transparency. the filled part with alpha are more darker than
expected (in fact, all are gray, but the input color are like yelow,
blue...) I expect that this is coming from the black background : the
blending of filled part with some alpha on the transparent but black
background. Therefore, I want to test with a transparent but white
background.

Is this the good way? Somebody have any clue for the glClearColor?

Thanks,

PBY

0
Reply PBY 9/30/2005 6:28:44 AM

PBY wrote:
> 
> Is this the good way? Somebody have any clue for the glClearColor?
> 

It would help a lot if you post that piece of code...



-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again.  They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful.  But it happens
every day.  I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address

0
Reply fungus 9/30/2005 8:24:53 AM

PBY wrote:
> Now, I have just another problem, it seems that glClearColor don't work
> anymore. I can change the clear color and nothing change.

I assume you are also calling glClear? :)
glClearColor just sets the clearing colour, glClear actually clears the 
buffer.

Jonno
0
Reply Jonno 9/30/2005 8:44:28 AM

Here some parts of my code. For the glClear:

if (transparent)
{
	blend();  //glBlendFunc or glBlendFuncSeparate
         glEnable (GL_ALPHA_TEST);
	glClearColor (1.0, 1.0, 1.0, 0.0);
}
else
{
	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glClearColor (red / 255.0, green / 255.0, blue / 255.0, 1.0);
}
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


the creation of the window (from nehe):

GT_Bool oglWinContext::create (GT_Int32 width, GT_Int32 height)
{
	GLuint		PixelFormat;						// Holds The Results After Searching For A Match
	WNDCLASS	wc;							// Windows Class Structure
	DWORD		dwExStyle;						// Window Extended Style
	DWORD		dwStyle;						// Window Style
	
	RECT WindowRect;							// Grabs Rectangle Upper Left / Lower Right Values
	WindowRect.left=(long)0;						// Set Left Value To 0
	WindowRect.right=(long)width;						// Set Right Value To Requested Width
	WindowRect.top=(long)0;							// Set Top Value To 0
	WindowRect.bottom=(long)height;						// Set Bottom Value To Requested 
Height

	hInstance		= GetModuleHandle(NULL);			// Grab An Instance For Our Window
	wc.style		= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;		// Redraw On Move, And 
Own DC For Window
	wc.lpfnWndProc		= (WNDPROC) WndProc;				// WndProc Handles Messages
	wc.cbClsExtra		= 0;						// No Extra Window Data
	wc.cbWndExtra		= 0;						// No Extra Window Data
	wc.hInstance		= hInstance;					// Set The Instance
	wc.hIcon		= LoadIcon(NULL, IDI_WINLOGO);			// Load The Default Icon
	wc.hCursor		= LoadCursor(NULL, IDC_ARROW);			// Load The Arrow Pointer
	wc.hbrBackground	= NULL;						// No Background Required For GL
	wc.lpszMenuName		= NULL;						// We Don't Want A Menu
	wc.lpszClassName	= "OpenGL";					// Set The Class Name

	if (!RegisterClass(&wc))						// Attempt To Register The Window Class
	{
		//MessageBox(NULL,"Failed To Register The Window 
Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							// Exit And Return FALSE
	}
	dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			// Window Extended Style
	dwStyle=WS_OVERLAPPEDWINDOW;					// Windows Style
	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);		// Adjust 
Window To True Requested Size
	if (!(hWnd=CreateWindowEx(	dwExStyle,				// Extended Style For The Window
					"OpenGL",				// Class Name
					"OpenGL",					// Window Title
					WS_CLIPSIBLINGS |			// Required Window Style
					WS_CLIPCHILDREN |			// Required Window Style
					dwStyle,				// Selected Window Style
					0, 0,					// Window Position
					WindowRect.right-WindowRect.left,	// Calculate Adjusted Window Width
					WindowRect.bottom-WindowRect.top,	// Calculate Adjusted Window Height
					NULL,					// No Parent Window
					NULL,					// No Menu
					hInstance,				// Instance
					NULL)))					// Don't Pass Anything To WM_CREATE
	{
		KillGLWindow();							// Reset The Display
		//MessageBox(NULL,"Window Creation 
Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							// Return FALSE
	}
	PIXELFORMATDESCRIPTOR pfd;
	memset (&pfd, 0, sizeof (pfd));
     pfd.nSize      = sizeof (pfd);
     pfd.nVersion   = 1;
     pfd.dwFlags    = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | 
PFD_DOUBLEBUFFER;
     pfd.iPixelType = PFD_TYPE_RGBA;
     pfd.cColorBits = 32;
	pfd.cRedBits   = 8;
     pfd.cGreenBits = 8;
     pfd.cBlueBits  = 8;
     pfd.cAlphaBits = 8;
     pfd.cDepthBits = 8;
     pfd.iLayerType = PFD_MAIN_PLANE;

	
	if (!(hDC=GetDC(hWnd)))							// Did We Get A Device Context?
	{
		KillGLWindow();							// Reset The Display
		//MessageBox(NULL,"Window Creation 
Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							// Return FALSE
	}
	if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))				// Did Windows Find 
A Matching Pixel Format?
	{
		KillGLWindow();							// Reset The Display
		//MessageBox(NULL,"Can't Find A Suitable 
PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							// Return FALSE
	}
	if(!SetPixelFormat(hDC,PixelFormat,&pfd))				// Are We Able To Set The 
Pixel Format?
	{
		KillGLWindow();							// Reset The Display
		//MessageBox(NULL,"Can't Set The 
PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							// Return FALSE
	}
	if (!(hRC=wglCreateContext(hDC)))					// Are We Able To Get A Rendering 
Context?
	{
		KillGLWindow();							// Reset The Display
		//MessageBox(NULL,"Can't Create A GL Rendering 
Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							// Return FALSE
	}
	if(!wglMakeCurrent(hDC,hRC))						// Try To Activate The Rendering Context
	{
		KillGLWindow();							// Reset The Display
		//MessageBox(NULL,"Can't Activate The GL Rendering 
Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;							// Return FALSE
	}

     validI = GT_TRUE;
	return GT_TRUE;
}


and for drawing filled polygon, we use gluTess* functions

Thanks,
PBY

Jonno wrote:
> PBY wrote:
> 
>> Now, I have just another problem, it seems that glClearColor don't work
>> anymore. I can change the clear color and nothing change.
> 
> 
> I assume you are also calling glClear? :)
> glClearColor just sets the clearing colour, glClear actually clears the 
> buffer.
> 
> Jonno
0
Reply PBY 9/30/2005 11:58:15 AM

PBY wrote:
> Here some parts of my code. For the glClear:
> 
> if (transparent)
> {
>     blend();  //glBlendFunc or glBlendFuncSeparate
>         glEnable (GL_ALPHA_TEST);
>     glClearColor (1.0, 1.0, 1.0, 0.0);
> }
> else
> {
>     glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
>     glClearColor (red / 255.0, green / 255.0, blue / 255.0, 1.0);
> }
> glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> 

Looks ok.

The only things which could stop it working*
are glScissor() and glColorMask(). Are you
using either of these functions?


[*] Or not calling wglMakeCurrent()...

-- 
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again.  They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful.  But it happens
every day.  I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address

0
Reply fungus 9/30/2005 1:19:43 PM

No, I don't use these functions. And wglMakeCurrent is called.
It must come from the window, because if I show it, the background is of 
the good color (expect where the taskbar was over the window)


I tested with creating a white transparent quad before, it's not helping.

Maybe the problem of semi-transparent filled poly is not comming from 
this black background.

I have tested some workaround, in which I add 100 (of 255) at the color 
for this case. The result is strange, in Gimp, just one color changed of 
value, and not of 100.

In fact, the double values that I pass to the glColor4f seem ok, but in 
the result image, I have completly different values (more darker).

Something must go wrong because of the transparent background, because 
with a opaque white background, it's ok.

Thanks,
PBY


fungus wrote:
> Looks ok.
> 
> The only things which could stop it working*
> are glScissor() and glColorMask(). Are you
> using either of these functions?
> 
> 
> [*] Or not calling wglMakeCurrent()...
> 
0
Reply PBY 9/30/2005 2:33:32 PM

21 Replies
450 Views

(page loaded in 0.193 seconds)

Similiar Articles:






7/23/2012 4:03:43 PM


Reply: