• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

[C/C++] DIB Section with Transparent Background

Messages
531
Country
france
Hello,
My goal is to use GDI+ for a circular gauge, such as an analog altimeter. In order to do this, I need to use the IMAGE_CREATE_DIBSECTION drawing flag. The problem when using this drawing flag is that the whole rectangular area dedicated to the gauge is drawn black, even if IMAGE_USE_TRANSPARENCY is also used. It means I can not integrate my altimeter in the 2D panel where a circular bezel is drawn...

Does anyone have any clue to solve this problem?

Thanks,
Eric
 
Messages
531
Country
france
Yes, I knew about this solution, but I don't like it much because it works on FSX Acceleration only. I'd rather have something that works with FSX as well, but maybe I'm asking too much here :)

Eric
 

n4gix

Resource contributor
Messages
11,674
Country
unitedstates
Well, the actual "clues" might lie with those who responded to Susan's post. The ones who stated that they'd been "doing this for years..." :)

Maybe Jean-Luc's suggested NO_STATIC_BLENDING?
 
Messages
531
Country
france
As far as I understand, NO_STATIC_BLENDING is not used that way in fs9 as it used to be in fs8. I will test again but I am 99% sure it doesn't do the job. Regarding the people who say they can do transparent gauges for years, they are right, I also did it (see my good old F-16 panel), but these are not vector gauges that use GDI or GDI+ for drawing. This is what I am looking for.

Eric
 
Messages
240
Country
switzerland
Regarding the people who say they can do transparent gauges for years, they are right, I also did it (see my good old F-16 panel), but these are not vector gauges that use GDI or GDI+ for drawing.

I have used VECTOR gauges in GDI+ with partial transparencies, as in an analog altimeter that has a round background with needles drawn on top of it in GDI+ for years, since the MB339 and the Phantom, which were published by Cloud9 in 2005/2006. As far as I know, nobody else used this method so far, I never had the chance to use it after those two products, since the whole idea of 2D panels today is so old fashined (IMHO)...the way to go for an analog instrument is to draw every moving element in 3D and animate it.

In any case, you just can't do it with SDK alone, not without a some additional helper code.

You need to store the static background image in a memory area in its native pixel format (which, regardless of the source format used, it's *always* 16 bit 1555 or 32 bit 8888) then, at every frame during the _DRAW cycle, restore the background, then draw with GDI+ on top of it.

That's the basic concept, of course I've developed a C++ framework to use it so, I really can't put some source code, since it's really too much intertwined with the rest of framework infrastructure (which basically wraps GDI+ entirely). The key command to put a bitmap on screen as fast as possible in GDI+ is DrawCachedBitmap so, by looking at the GDI+ documentation for that command, you might be able to figure out a solution that works for you.

Don't waste your time trying to find a magical SDK flag that will do this automatically, because there's none, not at least for something that works in FS9 and FSX at the same time, otherwise you could use Susan's example, but that would be FSX/Acceleration or SP2 only.
 
Last edited:
Messages
531
Country
france
I understand what you're talking about and I will test it ASAP. I understand the concept and I should be able to code this. I agree with you, 2D panels are now out of date, but some people (including myself) still like 2D panels :)

Thanks for your help !!
Eric
 
Messages
2
Country
russia
In my experiments with GDI+ I faced the same issue of missing transparency. I tried to play with rotating compass card and obviously I wanted it to be round.

After digging into FS data structures (namely IMAGE) I examined image buffer ("image" structure member) and found that GDI+ drawing calls simply do not follow FS rule that RGB(0,0,0) color should be transparent and do not set alpha value to 0 where color is black.

Soliution I used was simple. When drawing using GDI+ is complete go through each pixel in drawing buffer and set alpha value to 0 if pixel color is RGB(0,0,0). Doing so requires knowlege of buffer format ("format" structure member) although in all my tests I was geting only IMG_15_BIT format irrespective of FS color settings.

My background static image had the following flags: IMAGE_CREATE_DIBSECTION | IMAGE_USE_TRANSPARENCY | IMAGE_NO_TRANSLATION

Hope this helps.
Sergei.
 
Messages
531
Country
france
Thank you Sergei, after digging into the problem I came to the same conclusion as you, but I didn't think about your idea. It looks simple and efficient, in my opinion the best way to make it work while keeping good performance.

I just have a question about the IMAGE_NO_TRANSLATION drawing flag, what is it for? Does it mean the color space of the gauge will not be transformed?

Thanks,
Eric
 
Messages
2
Country
russia
Hello Eric,

It looks like IMAGE_NO_TRANSLATION disables any further color space translations of an image making it look the same regardless of time of the day and lighting conditions. During my tests (FS9 and FSXA) I found that it behaves similar to IMAGE_USE_BRIGHT but I cannot confirm that these two flags are absolutely identical.

To be honest I didn't do much testing of this flag. But I remember that I've seen a discussion on Avsim back in 2004 where it was advised to use it together with IMAGE_CREATE_DIBSECTION.

Sergei.
 
Messages
531
Country
france
Hello Sergei,
I always use IMAGE_USE_BRIGHT with IMAGE_CREATE_DIBSECTION because since now I have been using GDI+ to simulate EFIS screens that are obviously bright whatever the exterior light. As far as I understand, IMAGE_USE_BRIGHT and IMAGE_NO_TRANSLATION are quite similar, not to say the same...

Thanks,
Eric
 
Messages
240
Country
switzerland
Solution I used was simple. When drawing using GDI+ is complete go through each pixel in drawing buffer and set alpha value to 0 if pixel color is RGB(0,0,0).

This is redundant and will result in an unnecessarily slow down.

although in all my tests I was geting only IMG_15_BIT format irrespective of FS color settings.

As I've said, FS will use two image formats: 1555 or 8888, if IMAGE_USE_ALPHA flag is set.

Have a look at this bit of code, it's part of a C++ class that does many other things, but it should be clear enough what it does:

Code:
GdiCachedBitmap::GdiCachedBitmap( Graphics& g, PELEMENT_STATIC_IMAGE element )
{
	IMAGE* final = element->image_data.final;
	mDimX = final->dim.x;
	mDimY = final->dim.y;
	mID = element->resource_id;

	int stride;
	int pf;
		
	if( final->format == IMG_15_BIT )
	{
		pf = PixelFormat16bppARGB1555;
		stride = 2;
	}
	else if ( final->format == IMG_32_BIT )
	{
		pf = PixelFormat32bppARGB;
		stride = 4;
	}
	else
	{
		throw std::runtime_error("Unknown pixelformat");
	}
	Bitmap bmp(mDimX, mDimY, (mDimX * stride + 3) & ~3, pf, reinterpret_cast<PBYTE>(final->image));
	mCachedBitmap.reset(new CachedBitmap(&bmp, &g));
}

This will be done only once, during PANEL_SERVICE_POST_INSTALL.

At each frame, during PANEL_SERVICE_PRE_DRAW, the DrawCachedBitmap GDI+ function will be called, that will restore the background, in the fastest possible way, since the image has been stored (see the previous CachedBitmap call ) in the native pixel format.
 
Top