Jump to content
Sign in to follow this  
WarpD

Gauge with Bitmaps

Recommended Posts

Guest WarCow

Hi,I am programming a gauge that makes heavy use of bitmaps with rotation. GDI+ seems very slow for bitmap processing. Is there a better library to use for bitmap calculations?

Share this post


Link to post
Share on other sites
Guest Patrick_Waugh

>Hi,>>I am programming a gauge that makes heavy use of bitmaps with>rotation. Programming in what langauge with what API?>GDI+ seems very slow for bitmap processing. Is there>a better library to use for bitmap calculations?Slow relative to what?What are you trying to do? Why are you not just using the standard methods using the gauge macros provided in the gauges.h?

Share this post


Link to post
Share on other sites
Guest WarCow

I use C++ currently with GDI+And I'd like to rotate bitmaps as fast as possible. GDI+ is just slow compared to what I think would be fast :DThe gauges macros are not flexible enough.

Share this post


Link to post
Share on other sites
Guest Patrick_Waugh

>I use C++ currently with GDI+>>And I'd like to rotate bitmaps as fast as possible. GDI+ is>just slow compared to what I think would be fast :DWhat exactly are you rotating/doing?>The gauges macros are not flexible enough.Are you sure? I have not run across a single case yet where they could not be used. If you are rotating only use MAKE_NEEDLE, but if you are needing to both rotate and translate then you'll need to use MAKE_MOVING. If ACES can do it, so can you. ;)You could also look into use AGG (http://antigrain.com) which is what ACES used (in part) for the terrain. Without more details, it is really hard to say. You might want to look at Boost (Google it).

Share this post


Link to post
Share on other sites

>>What exactly are you rotating/doing?>GDI+ bitmap rotation can indeed be rather slow.>>You could also look into use AGG (http://antigrain.com) which>is what ACES used (in part) for the terrain. >Where did you get the information they used AGG? Also, the current version of AGG is no longer suitable for commercial use to do licensing restrictions.


Ed Wilson

Mindstar Aviation
My Playland - I69

Share this post


Link to post
Share on other sites

Hi,I have been using the default FSX MACROS but also want to get away from those. One of the biggest problems I see it that the needles, movings, sliders etc... are only updated now and again. The PRE_DRAW event in the main gauge callback, doesn't happen each tick (as you would expect) but only every 4-5 ticks at best and even only every 20 ticks at worst. This is probably due to some resource optimizing done by FSX but in my case this means that almost none of the needles are moving smoothly but rather in discrete steps, which of course has a major negative impact on the realism effect.I've done tests on the speed gauge for instance, the needle callback is called every tick and I see the return value increasing in very small decimal increments. The PRE_DRAW event in the main gauge callback however is only called every so often and by then the AIRSPEED value has increased in steps of around 1 knots (not exactly 1 knot btw). I thought that maybe the needle element only takes the integer part of return value or the gauge would only update when it considers the changes to be "significant" so as a test I multiplied the airspeed by 10 and off course updated the non-linearity table likewise. That didn't have any effect ! In stead of incrementing in 1 knot steps the needle was now updated in around 10 unit steps.Another test that I did was to reduce the number of elements inside a gauge. For that I tested my RMI gauge. I removed all the elements but for the static and 1 needle ==> no effect whatsover, still get the same lousy update rates...So to put your results into perspective, the actual update rates for some of the gauges using standard MACROS is approx 5-1x per second. Not sure what you get using GDI+ but I can't imagine it being that bad !


simcheck_sig_banner_devteam.jpg

 

Bj

Share this post


Link to post
Share on other sites
Guest Patrick_Waugh

>Hi,>>I have been using the default FSX MACROS but also want to get>away from those. One of the biggest problems I see it that the>needles, movings, sliders etc... are only updated now and>again. The PRE_DRAW event in the main gauge callback, doesn't>happen each tick (as you would expect) but only every 4-5>ticks at best and even only every 20 ticks at worst. This is>probably due to some resource optimizing done by FSX but in my>case this means that almost none of the needles are moving>smoothly but rather in discrete steps, which of course has a>major negative impact on the realism effect.Which is why the PRE_DRAW event is not used in the way you are attempting. If you choose to attempt to program in C++, your gauges performance is going to be GREATLY affected by your skill and knowledge in how to code it "correctly". You will note other C gauges on your system do not have this problem, and this is why.>I've done tests on the speed gauge for instance, the needle>callback is called every tick and I see the return value>increasing in very small decimal increments. The PRE_DRAW>event in the main gauge callback however is only called every>so often and by then the AIRSPEED value has increased in steps>of around 1 knots (not exactly 1 knot btw). I thought that>maybe the needle element only takes the integer part of return>value or the gauge would only update when it considers the>changes to be "significant" so as a test I multiplied the>airspeed by 10 and off course updated the non-linearity table>likewise. That didn't have any effect ! In stead of>incrementing in 1 knot steps the needle was now updated in>around 10 unit steps.Yeap, it doesn't work that way.>Another test that I did was to reduce the number of elements>inside a gauge. For that I tested my RMI gauge. I removed all>the elements but for the static and 1 needle ==> no effect>whatsover, still get the same lousy update rates...Again, this is because the lousy update rate is due to how you are programming, not the SDK's fault.>So to put your results into perspective, the actual update>rates for some of the gauges using standard MACROS is approx>5-1x per second. Not sure what you get using GDI+ but I can't>imagine it being that bad !Well, not sure how you are doing things, but if you are getting only 1-5 updates per second (and not intending to do so) then you are doing things wrong. :DIf anything, I have to go back and slow gauges down that do not need to be updated so many times per second. You might want to consider asking what others are doing to accomplish whatever you are trying to do in the gauge callback.Patrick

Share this post


Link to post
Share on other sites

Patrick,"Which is why the PRE_DRAW event is not used in the way you are attempting. If you choose to attempt to program in C++, your gauges performance is going to be GREATLY affected by your skill and knowledge in how to code it "correctly". You will note other C gauges on your system do not have this problem, and this is why."You speak in riddles, what do you mean by this ? Here's a for instance, I have a NEEDLE macro that uses the AIRSPEED variable as input. The NEEDLE callback simply reads:if ( rvalue < 60 ) rvalue = 60;if ( rvalue > 450) rvalue = 450;return rvalue;That's it... nothing in the PRE_DRAW callback or anything. I've also tried:MODULE_VAR_NONE in the NEEDLE MACRO and then rvalue = AIRSPEED.var_value.n ;if ( rvalue < 60 ) rvalue = 60;if ( rvalue > 450) rvalue = 450;return rvalue;Same thing happens, the NEEDLE CALLBACK is called every tick, PRE_DRAW skips a few ticks.How would you code this ? You are right, I am probably doing something wrong, but I can't find what it could be. Kind regards,Bj


simcheck_sig_banner_devteam.jpg

 

Bj

Share this post


Link to post
Share on other sites

Patrick,I may have missed your point but are you saying the problem is related to using C++ vs C or a mixture of both ?Bj


simcheck_sig_banner_devteam.jpg

 

Bj

Share this post


Link to post
Share on other sites
Guest Patrick_Waugh

What are you computer specs? What FPS are you getting with your current display settings?Try PRE_UPDATE instead of PRE_DRAW.Are you using C++ (.cpp vs. .c)? Which compiler are you using? Let's see your entire MAKE_NEEDLE callback function. Is this for FSX?To help you we need more info, that is why it seems like riddles.

Share this post


Link to post
Share on other sites
Guest Patrick_Waugh

No, but if you are coding for FSX you should be using C++ entirely now.

Share this post


Link to post
Share on other sites

Patrick,- The "problem" has been seen by various users with all kinds of specs so it is not PC related. I get 15-20fps on the ground in the 2D panel view- I am not using PRE_DRAW nor any other event in the main gauge callback, so I'm not entirely sure why switching to another event would change anything and what would need to be switched...- I am using mixed cpp and c files since this panel was originally developed for FS2004 and is now used in FSX (after lots and lots and lots of changes though). The main gauge file (its a multigauge setup with approx 97 subgauges inside) is a cpp file. I think (but I don't have access to my PC now so I'm not 100% certain) this particular airspeed gauge file is a .c file. Will change the file extension just in case.- I am using VC2005- Will need to get to my PC for the complete callback functionI have browsed through the SDK again and noticed that in many samples no main gauge callback is used at all. Maybe that has something to do with it ?Will do some tials this evening (time permitting) and let you know the results.Bj


simcheck_sig_banner_devteam.jpg

 

Bj

Share this post


Link to post
Share on other sites

Patrick,Here is some code for the airspeed gauge...Needle callback:FLOAT64 FSAPI CBAirspeed( PELEMENT_NEEDLE pelement){lookup_var(&AIRSPEEDvar);float rvalue=AIRSPEEDvar.var_value.n;if ( rvalue < 60 ) { rvalue = 60 ; } if ( rvalue > 450 ) { rvalue = 450 ; } if ( lights_on == 1 ) { LIGHT_IMAGE(pelement) ; } else { DARKEN_IMAGE(pelement) ; } return rvalue;}This is the needle MAKROMAKE_NEEDLE(NeedleASI,RecourceASNeedle,&ElementList6ASI,fail1ASI,IMAGE_USE_ERASE | IMAGE_USE_TRANSPARENCY | BIT7,0,149,149,12,12,MODULE_VAR_NONE,CBAirspeed,NonlinASI,0)I have now changed the file extension to .cpp and I have removed the main gauge callback. I also tried adding the AIRSPEED var to the NEEDLE macro. But this all has no effect whatsoever on the smoothness of the gauge. One of the strange things is that the AIRSPEED value itself doesn't change continuously but rather in descrete steps.I don't see anything wrong with this code so if you can make this needle move smoother, please let me know !Bj


simcheck_sig_banner_devteam.jpg

 

Bj

Share this post


Link to post
Share on other sites
Guest Patrick_Waugh

Bjorn, (hey, how do I do the cool o thingy?)>Needle callback:>>FLOAT64 FSAPI CBAirspeed( PELEMENT_NEEDLE pelement)>{>lookup_var(&AIRSPEEDvar);>>float rvalue=AIRSPEEDvar.var_value.n;>>if ( rvalue < 60 ) { rvalue = 60 ; } >if ( rvalue > 450 ) { rvalue = 450 ; } >if ( lights_on == 1 ) { LIGHT_IMAGE(pelement) ; } else {>DARKEN_IMAGE(pelement) ; } >>return rvalue;}Ok, you have a few problems with the above code. First, you should not have the lookup_var() in the callback. Why? Because, instead of MODULE_VAR_NONE in the MAKE_NEEDLE macro below, you should have AIRSPEED. The MODULE_VAR is then sent as the pelement to the callback, making it available for you to modify, which is the point of the callback function. Next, your way of coding the test conditions with an extra local variable makes it hard to see what the code is doing. Also, you are forcing a lot of automatic conversions in the above code which slow things down even more.This is the way to make it clear:FLOAT64 FSAPI AirspeedNeedle_cb(PELEMENT_NEEDLE pelement){ static short maxIAS = 150; if (pelement->source_var.var_value.n > maxIAS) { return maxIAS; } else if(pelement->source_var.var_value.n < 15) { return 15; } return pelement->source_var.var_value.n;}Note the difference between the top if() and the bottom. The top makes it clear that you are checking to see if the airspeed is greater than the maxIAS the indicator can display. The bottom does not make it clear that the "magic" number 15 is the minIAS the indicator can display, and so will be harder to maintain later when you have forgotten what you were doing. Do it the first way. As an exercise you can convert this code to the "proper" way. Read "Code Complete" for more tips like this.Also, note that the above uses the variable directly which is faster than creating an rvalue which then also requires another conversion.>This is the needle MAKRO>>MAKE_NEEDLE(NeedleASI,RecourceASNeedle,&ElementList6ASI,fail1ASI,>IMAGE_USE_ERASE | IMAGE_USE_TRANSPARENCY | BIT7,>0,149,149,12,12,MODULE_VAR_NONE,CBAirspeed,NonlinASI,0)As stated above, MODULE_VAR_NONE should only be used when there is no FS var for what you are after, or you really want to ignore it. In your case it should be AIRSPEED. Also, you don't need the BIT7, and the final 0 could really be like 6, but zero is fine.Generally, you should code MACROs to look like this:#pragma region AIRSPEEDMAKE_NEEDLE( airspeedNeedle, BMP_NEEDLE_AIRSPEED, NULL, airspeed_fail, IMAGE_USE_TRANSPARENCY | IMAGE_USE_ERASE | IMAGE_USE_LUMINOUS, 0, 128, 128, // Needle center on BG 41, 10, // Center position on Needle AIRSPEED, AirspeedNeedle_cb, airspeed_nonLinearity, 6)PELEMENT_HEADER airspeedNeedle_list[] = { &airspeedNeedle.header, NULL };#pragma endregion /*Needle*/>I have now changed the file extension to .cpp and I have>removed the main gauge callback. I also tried adding the>AIRSPEED var to the NEEDLE macro. But this all has no effect>whatsoever on the smoothness of the gauge. One of the strange>things is that the AIRSPEED value itself doesn't change>continuously but rather in descrete steps.Also, if you really do need to use a lookup_var(), I would put that code in PRE_UPDATE, to ensure it gets updated each tick.>I don't see anything wrong with this code so if you can make>this needle move smoother, please let me know !That's why when you ask a question, it is best to post code. =)Glad I could help you.Patrick

Share this post


Link to post
Share on other sites

Hi Patrick,I had in fact used AIRSPEED in the MACRO but I was hoping the doing an explicit lookup_var() would force a new value. Anyway, I tried all the suggestions that you made but they absolutely no effect whatsoever.When I follow the AIRSPEED variable in the debugger it increments in distinct steps and not continuously with each tick or call to the NEEDLE callback. If its any comfort, I just checked and the airspeed needle in the default C172 in FSX also moves in steps and not smoothly.Bj


simcheck_sig_banner_devteam.jpg

 

Bj

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Tom Allensworth,
    Founder of AVSIM Online


  • Flight Simulation's Premier Resource!

    AVSIM is a free service to the flight simulation community. AVSIM is staffed completely by volunteers and all funds donated to AVSIM go directly back to supporting the community. Your donation here helps to pay our bandwidth costs, emergency funding, and other general costs that crop up from time to time. Thank you for your support!

    Click here for more information and to see all donations year to date.
×
×
  • Create New...