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)
|