[<<] [<] Page 1 of 1 [>] [>>] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Drawing transparent bitmaps
From: "Uwe Klatt" ####@####.#### Date: 27 Feb 2007 08:48:49 +0000 Message-Id: <002301c75a4c$05e3ad90$081710ac@arnstein.miwe.de> Hello, today I modified the fb16 graphic driver for displaying transparent bitmaps. I want to know if somebody knows a "better" solution for this "problem". In my application I use bmp files for user interface and normally there is no transparency feature available for this file format. I decided to use WHITE (all Bits ON) for transparency. Then I used the existing ROP-Mode MWROP_SRC_OVER. This ROP is not used at the moment. I had to modify only two functions: linear16_blit and linear16_stretchblit You can find both in fblin16.c In linear16_blit I replaced applyOp(MWROP_TO_MODE(op), *src, dst, ADDR16); with if(op == MWROP_SRC_OVER) { if(*src != 0xFFFF) *dst = *src; } else applyOp(MWROP_TO_MODE(op), *src, dst, ADDR16); and in linear16_stretchblit I replaced *dst++ = pixel; with if((op == MWROP_SRC_OVER) && (pixel == 0xFFFF)) dst++; else *dst++ = pixel; Bye Uwe | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: [nanogui] Drawing transparent bitmaps
From: "Greg Haerr" ####@####.#### Date: 28 Feb 2007 02:58:18 +0000 Message-Id: <1b1301c75ae4$3471b920$0300a8c0@RDP> : today I modified the fb16 graphic driver for displaying transparent bitmaps. : I want to know if somebody knows a "better" solution for this "problem". Uwe - I would likely have implemented the solution the same way, as implementing it in the driver allows the fastest possible image drawing with no changes to the engine level. Since the engine doesn't support passing any additional values to the driver to identify the transparency value (other than stuffing it in the rightmost bits of 'op', which wouldn't work well for 32bpp framebuffers), picking an otherwise-unused ROP is probably fine. My only other thoughts would be exactly which ROP code to use, and documenting that, or adding a new one called say MWMODE_SRC_TRANS_WHITE = 26 and incrementing MWMODE_MAX to 26. Also, the applyOp macro is used in some other places, I think, so we may need to implement this capability in a macro...? Nonetheless, send a patch when you're done! Regards, Greg : : In my application I use bmp files for user interface and normally there is : no transparency feature available for this file format. : I decided to use WHITE (all Bits ON) for transparency. : : Then I used the existing ROP-Mode MWROP_SRC_OVER. : This ROP is not used at the moment. : : I had to modify only two functions: : linear16_blit and linear16_stretchblit : You can find both in fblin16.c : : In linear16_blit I replaced : : applyOp(MWROP_TO_MODE(op), *src, dst, ADDR16); : : with : : if(op == MWROP_SRC_OVER) { : if(*src != 0xFFFF) : *dst = *src; : } : else : applyOp(MWROP_TO_MODE(op), *src, dst, ADDR16); : : and in linear16_stretchblit I replaced : : *dst++ = pixel; : : with : : if((op == MWROP_SRC_OVER) && (pixel == 0xFFFF)) : dst++; : else : *dst++ = pixel; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: [nanogui] Drawing transparent bitmaps
From: Roberto ####@####.#### Date: 1 Mar 2007 20:07:19 +0000 Message-Id: <45E73227.7050006@tnw2000.org> Hi Uwe, I had a similar idea like you. My gain was to have a transparent color in order to be able to draw an invisible window with a transparent gif inside. Intention was to show only the visible part of the gif. I began in the fb driver like you but found out that the the clipping of the windows wont work with this mechanism since several windows may overlap each other. So I tried to introduce an "alpha map" which is added to each nanox window. If any drawing routine draws to the window, the alpha map is filled with the information which pixel is visible and which not. In the next step I modified the clipping functions to be able to calculate the visible/invisible pixels if several windows are overlapping. Greg already mentioned that the engine doesn't support any additional values to the driver, so I store this information in a global pointer which can be accessed by the fb drivers. I know this is a little bit dirty, but I had no idea how to solve this in a different way Anyway, with this modifications I was able to have several transparent gifs without any rectangular background overlapping each other. The application simply has to use the GR_ARGB macro to define the color, where A=0 means transparent and A=255 non-transparent. You may download what I described above (based on version 0.91) at ftp.tnw2000.org. But I concentrated in the Nano-X api. May be it does not work completely with the win32 api. Contact me if you have problems. bye roberto | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: [nanogui] Drawing transparent bitmaps
From: "Greg Haerr" ####@####.#### Date: 2 Mar 2007 17:14:34 +0000 Message-Id: <1e3c01c75ced$f8525ba0$0300a8c0@RDP> : I had a similar idea like you. My gain was to have : a transparent color in order to be able to draw an : invisible window with a transparent gif inside. : Intention was to show only the visible part of the gif. Roberto - I have several comments on your post, and am concerned about the proper way to implement what you've done. See comments below! : I began in the fb driver like you but found out that the : the clipping of the windows wont work with this mechanism : since several windows may overlap each other. Clipping should long have been handled above the driver layer, so I'm concerned as to why we're worried about clipping when we're talking about transparency. Is this because you want to implement non-rectangular windows and want alpha-blending outside the normal window frame? : : So I tried to introduce an "alpha map" which is added to each : nanox window. If any drawing routine draws to the window, : the alpha map is filled with the information which pixel : is visible and which not. This should already be able to be handled using 32bpp drawing with ARGB, such that the upper byte is the alpha channel, without adding any new maps. We would have to implement the ability to convert 32bpp ARGB to lower resolutions for systems with, say 16bpp, which isn't handled now, since nano-X always demands drawing in the native hardware format, except for the MWIMAGEHDR structure. In the next step I modified the clipping functions : to be able to calculate the visible/invisible pixels if several : windows are overlapping. Greg already mentioned that the : engine doesn't support any additional values to the driver, so : I store this information in a global pointer which can be accessed : by the fb drivers. I know this is a little bit dirty, : but I had no idea how to solve this in a different way This sounds like something to do with creating overlapped windows with an alpha channel, including the ability of the system to handle alpha blending outside of the interior (user) area? : Anyway, with this modifications I was able to have several transparent gifs : without any rectangular background overlapping each other. : The application simply has to use the GR_ARGB macro to : define the color, where A=0 means transparent and A=255 non-transparent. Was this for the window borders? : : You may download what I described above (based on version 0.91) : at ftp.tnw2000.org. But I concentrated in the Nano-X api. : May be it does not work completely with the win32 api. : Contact me if you have problems. I'll check it out Regards, Greg | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: [nanogui] Drawing transparent bitmaps
From: Roberto ####@####.#### Date: 4 Mar 2007 19:54:49 +0000 Message-Id: <45EB23B3.7020706@tnw2000.org> Hi Greg, sorry about so much text, but its a little bit complicated to explain my thoughts. > > Greg Haerr wrote: > >> : I had a similar idea like you. My gain was to have >> : a transparent color in order to be able to draw an >> : invisible window with a transparent gif inside. >> : Intention was to show only the visible part of the gif. >> >> Roberto - I have several comments on your post, and >> am concerned about the proper way to implement >> what you've done. See comments below! >> >> >> : I began in the fb driver like you but found out that the >> : the clipping of the windows wont work with this mechanism >> : since several windows may overlap each other. >> >> Clipping should long have been handled above the driver >> layer, so I'm concerned as to why we're worried about >> clipping when we're talking about transparency. Is this >> because you want to implement non-rectangular windows >> and want alpha-blending outside the normal window >> frame? >> >> Yes, my intention is to have a non-rectangular window (what do you mean with "outside the normal window frame"?) , but with fb drivers <32BPP. My Idea is to have a window with an invisible background. This means that the window is existing, it is causing an event if someone clicks into it, but it is not visible. If a gif (a gif with transparency parts, i.e. a circle) is drawn to this window, the only thing you can see is the visible part of this picture. Attachment1 should illustrate my desire. I know that there is already a way to do things like this, the tux example is a non-rectangular window. But the transparent parts of tux.gif are hard coded, you have to recompile the tux code when changing the gif. Generating the tuxmask at runtime in the application would mean that the gif is opened and read twice, one time by nanox, one time by the application to generate the mask. Now imagine that the application wants to draw an additional line across the window using GrLine. In this case, the mask array has to be changed again. I had the impression, that this technique is firstly complicated for the applications programmer, since he has to calculate the mask array each time his self, secondly, the work is done twice, one time in the application to generate the line mask, one time by nanox to draw the line. Looking forward to the performance, I think it is better to do this one time in the server/engine. Now to your question about the clipping. I try to explain my thought, please refer to attachment1. In attachment1 is a window named window3. window3 is rectangular and has transparent parts. window 3 is above window2 and below window4. If something changes in window3 (i.e. the gif should move some pixels to the left), it has to be redrawn. Now I had several thoughts about this: Following scenario : The screen driver (i.e. fb16) gets a 32bit value with alpha channel. With an alpha channel=255 the screen driver draws the pixel, with an alpha channel=0, this pixel is not drawn. One way for redrawing : Destroy window3 and draw it again. Without any modifications in the server/engine and without any mask as used in the tux example, this will cause a redraw of - the parts of window0 (=background picture) which are not covered by window2 and 4 - the visible parts of window2 which are covered by window3 -> the invisible parts of window2 which are covered by visible parts of window3 are are left. - no redraw of window 4 at all -> parts of window3 are left. When drawing window3 again, the part of window3 which is covered by window4 is not drawn since it is clipped out. Besides, clearing out window2 completely and redrawing it would cause flickering. I don't know any more why I discarded to use the same technique as used in the tux demo inside the server/engine, but there were some reasons. I always had problems that something wasn't redrawn correctly, at the wrong time or not at all. So I began to modify the code in the nanox and engine directory and tried following things: Way 2: Clear out every window with a transparent background and draw everything again beginning at window0. -> This works basically, but flickering is a real problem. This is no solution. Way 3: Don't clear out anything. Just redraw every window, beginning at window0, but only the part which is covered by window3. I modified GsSetClipWindow to ignore windows with a transparent background. I also used pixmaps which were set as background using GrSetBackgroundPixmap. The advantage here is that using the pixmaps as background will cause a blitting of the already (offscreen) painted pixmap to the screen. -> works better, but still flickers. Way 4: Like way3, but I modified GsSetClipWindow in a way that it does examine the alpha channel (of all overlapping windows with transparent background) and modifies the clipping region. I think this is what you mean with Clipping should long have been handled above the driver layer I tried it and basically this worked without flickering. But too slow. Generating the clipping regions and evaluating the the regions in GdBlit was too slow. Way5: Like way4, but I didn't used the clipping regions, but allocated a field of chars, each char representing the visibility of one pixel -> clipmap (255= visible, 0=invisible). The clipmap is only valid for the overlapping regions. Only for speed I decided to evaluate the clipmap in the driver. Finally I reviewed everything: 1.) every window (pixmaps, too) got an alpha map (as replacement for the missing alpha channel when using lower resolutions). The alpha map is filled by the higher level drawing functions. 2.) the alpha maps are evaluated by GsSetClipWindow in srvclip2.c only where needed (overlapping parts of windows with transparent background). Result is something I called "clipmap". 3.) The clipmap is evaluated in the driver. An invisible pixel means: don't draw it. 4.) When redrawing a window with a transparent background, the area below must be redrawn, too. Up to now this is working with a good performance and without flickering within an application window. The TNW++ example3 should demonstrate this. Moving transparent windows is currently only working within an application window using GrMove, but with flickering. You can check this out in example3 by clicking to the "Place in Runtime" label, then clicking to a widget and then use the arrow keys to move it. I also added a tux2 example which does not use an array for shaping. This works fine since GrMove is used here. With the window managers container windows I still have some problems. But I think the solution is not far away. >> : So I tried to introduce an "alpha map" which is added to each >> : nanox window. If any drawing routine draws to the window, >> : the alpha map is filled with the information which pixel >> : is visible and which not. >> >> This should already be able to be handled using >> 32bpp drawing with ARGB, such that the upper >> byte is the alpha channel, without adding any new >> maps. We would have to implement the ability to >> convert 32bpp ARGB to lower resolutions for >> systems with, say 16bpp, which isn't handled now, >> since nano-X always demands drawing in the native >> hardware format, except for the MWIMAGEHDR >> structure. >> >> > Yes, thats true, but if using i.e. GrLine, the information about visible and invisible pixels is lost for future redraw operations of other overlapping windows, since GrLine (respectively GdLine) directly calls the drivers drawing routines. If a window has a transparent line across, the windows below must be redrawn in this area. >> In the next step I modified the clipping functions >> : to be able to calculate the visible/invisible pixels if several >> : windows are overlapping. Greg already mentioned that the >> : engine doesn't support any additional values to the driver, so >> : I store this information in a global pointer which can be accessed >> : by the fb drivers. I know this is a little bit dirty, >> : but I had no idea how to solve this in a different way >> >> This sounds like something to do with creating overlapped >> windows with an alpha channel, including the ability >> of the system to handle alpha blending outside of the >> interior (user) area? >> > No, the only reason for the global pointer was to handle it over to the fb drivers in a simple way. > >> >> : Anyway, with this modifications I was able to have several transparent >> gifs >> : without any rectangular background overlapping each other. >> : The application simply has to use the GR_ARGB macro to >> : define the color, where A=0 means transparent and A=255 >> non-transparent. >> >> Was this for the window borders? >> >> > What I tried to say is that i.e. GrLine(...) with a prior call of GrSetGCForeground(...,GR_ARGB(0,x,x,x) will draw a transparent line. > >> : >> : You may download what I described above (based on version 0.91) >> : at ftp.tnw2000.org. But I concentrated in the Nano-X api. >> : May be it does not work completely with the win32 api. >> : Contact me if you have problems. >> >> I'll check it out > I would be very happy about your feedback. >> Regards, >> >> Greg >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: ####@####.#### >> For additional commands, e-mail: ####@####.#### >> >> >> >> > > > ------------------------------------------------------------------------ > > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[<<] [<] Page 1 of 1 [>] [>>] |