Transparency Issue with MultipassBitmap in GeUserArea
-
Hello,
I'm encountering an issue with transparency when drawing a MultipassBitmap over a background in a custom GeUserArea. The transparent areas appear black unless I save the bitmap before drawing it.
Code Snippet:
// ARGBfbuf is a Float32 image buffer with ARGB data // w = width, h = height auto Bmp = MultipassBitmap::Alloc(w, h, COLORMODE::ARGBf); if (!Bmp) { // Handle allocation failure return; } Bmp->SetColorProfile(ColorProfile::GetDefaultSRGB()); // Set parameters for the MultipassBitmap Bmp->SetParameter(MPBTYPE_NAME, "bitmap"); Bmp->SetParameter(MPBTYPE_SAVE, FALSE); Bmp->SetParameter(MPBTYPE_SHOW, TRUE); // Add root alpha channel to the MultipassBitmap auto rootAlpha = Bmp->AddAlpha(nullptr, COLORMODE::GRAYf); if (!rootAlpha) { // Handle error return; } // Set parameters for the root alpha rootAlpha->SetParameter(MPBTYPE_NAME, "rootAlpha"); rootAlpha->SetParameter(MPBTYPE_SAVE, FALSE); rootAlpha->SetParameter(MPBTYPE_SHOW, TRUE); auto layer = Bmp->GetLayerNum(0); if (!layer) { // Handle error return; } // Set parameters for the layer layer->SetParameter(MPBTYPE_NAME, "layer0"); layer->SetParameter(MPBTYPE_SAVE, FALSE); layer->SetParameter(MPBTYPE_SHOW, TRUE); // Add alpha channel to the layer auto alpha = layer->AddAlpha(nullptr, COLORMODE::GRAYf); if (!alpha) { // Handle error return; } // Set parameters for the alpha layer alpha->SetParameter(MPBTYPE_NAME, "alpha0"); alpha->SetParameter(MPBTYPE_SAVE, FALSE); alpha->SetParameter(MPBTYPE_SHOW, TRUE); for (Int32 y = 0; y < h; ++y) { Float32* ptr = ARGBfbuf + (y * w * 4); // Copy image line to the layer layer->SetPixelCnt(0, y, w, reinterpret_cast<UChar*>(ptr), COLORBYTES_ARGBf, COLORMODE::ARGBf, PIXELCNT_0); // Copy alpha line to the alpha layer alpha->SetPixelCnt(0, y, w, reinterpret_cast<UChar*>(ptr), COLORBYTES_ARGBf, COLORMODE::GRAYf, PIXELCNT_0); } // In the GeUserArea render function: // Draw background image DrawBitmap(Background, 0, 0, GetWidth(), GetHeight(), 0, 0, Background->GetBw(), Background->GetBh(), BMP_NORMAL); // Draw bitmap with transparency DrawBitmap(Bmp, 0, 0, GetWidth(), GetHeight(), 0, 0, Bmp->GetBw(), Bmp->GetBh(), BMP_NORMAL | BMP_APPLY_COLORPROFILE | BMP_TRANSPARENTALPHA);
Issue:
Transparent areas (where alpha = 0.0f) appear black instead of showing the background.
Workaround:Saving the bitmap before drawing fixes the issue:
// Save and delete the file String path = GeGetStartupWritePath() + "/temp.tga"; Bmp->Save(path, FILTER_TGA, nullptr, SAVEBIT_ALPHA); GeFKill(path); // Then draw as before DrawBitmap(Bmp, ...);
Additional Information:
- I tried using BaseBitmap instead of MultipassBitmap, but BaseBitmap does not support floating-point color modes (COLORMODE::ARGBf), which I need for my application.
- Even when using BaseBitmap and saving the image, the transparency issue persists.
Questions:
- Why does saving the MultipassBitmap make the transparency work?
- How can I achieve proper transparency without saving the bitmap?
- Is there a way to handle floating-point ARGB data with transparency using BaseBitmap, or is MultipassBitmap the only option?
- Do the SetParameter calls on the Bmp, Layer, root alpha, and alpha layers have any effect on this issue, and am I using them correctly?
Any insights or solutions would be greatly appreciated!
-
Welcome to the Maxon developers forum and its community, it is great to have you with us!
Getting Started
Before creating your next postings, we would recommend making yourself accustomed with our forum and support procedures. You did not do anything wrong, we point all new users to these rules.
- Forum Overview: Provides a broad overview of the fundamental structure and rules of this forum, such as the purpose of the different sub-forums or the fact that we will ban users who engage in hate speech or harassment.
- Support Procedures: Provides a more in detail overview of how we provide technical support for APIs here. This topic will tell you how to ask good questions and limits of our technical support.
- Forum Features: Provides an overview of the technical features of this forum, such as Markdown markup or file uploads.
It is strongly recommended to read the first two topics carefully, especially the section Support Procedures: Asking Questions.
About your First Question
Hey, you did a great job for your first your topic(s), I assume you did read our forum rules - thanks. But you should really avoid having more than one question in a topic, because things tend to become very hard to answer then and our answers very long (as evident by my answer here). Try to find a singular main question you have. You can then optionally ask thematically closely related follow-up questions once the main question has been answered.
Before we go here into details, I would recommend having a look at the topic Overlapping images with transparency with BaseBitmap as it is quite tangential to what you seem to be trying to do.
The general problem is that this "writing multiple layers with embedded alpha values" scenario is not something the Cinema Image API (
BaseBitmap
,MultipassBitmap
) has been really geared for. The major use case for creating multiple layers with alpha values in the Cinema API, Bodypaint, is covered by cinema::PaintBitmap. But that is sort of its own eco-system.BaseBitmap
andMultipassBitmap
are meant for loading and displaying data.- The reasons why your code is likely not working, is because you do not write the master alpha of the multipass bitmap. That was also what I was struggling with in the other thread. You create the channel as
auto rootAlpha = Bmp->AddAlpha(nullptr, COLORMODE::GRAYf);
but never write to it. Probably in the assumption that this would happen automatically, but it does not. - That is probably due to the Maxon Image API image saver maxon::ImageSaverClasses::TGA or generally the switch to the underlying Image API (BaseBitmap::GetImageRef()) making some things snap into place there. You must understand that the Cinema API types
BaseBitmap
andMultipassBitmap
are just a shallow wrapper for the underlying Maxon Image API. - You could save into one of our in-memory UrlSchemes, e.g., an MFS or Ramdisk, when it is the disk activity you fear. When you want to avoid the general overhead of having to serialize and deserialize the image, and want to stay in the Cinema Image API, you will probably have to curate your master alpha channel manually. Or just do what I did in the other thread and manually blend things. There are also some options in the Maxon Image API, but my answer is getting longer and longer ...
- I don't think that this is true. Both
BaseBitmap
and the underlyingImageInterface
(which you usually encounter as anImageRef
in code) support floating point image data. They are defined under the Graphics label asmaxon:Pix...
- They are largely correct but neither necessary nor the cause (not sure why you set
MPBTYPE_SAVE
tofalse
though).
This topic is riddled a bit by too many questions. Let's try to take a more direct angle here and just try to solve what you are trying to do. I assume you want to have some form of UI that stacks multiple images with transparent areas, similar to what the Asset Browser is doing here to display overlay icons over its assets.
-
Thank you for your quick reply and guidance on using the forum.
I'm working on an existing plugin that needs to render an image in RGBAf format in real-time within the User Area. Currently, it achieves this by converting the buffer to ARGB, then to a BaseBitmap, and finally using DrawBitmap to display it on the User Area. This method is slow, and now I also need to add a background, which isn’t possible with BaseBitmap.
Following your guidance, I understand I should use the Maxon Image API (maxon::ImageRef) instead of BaseBitmap and use cinema::GeUserArea::DrawImageRef to display it in the User Area instead of DrawBitmap.
Is there a way to work directly with RGBAf format rather than converting to ARGBf to improve performance?
Thank you!