SSU Development Thread (3.0 to 4.0)

DaveS

Addon Developer
Addon Developer
Donator
Beta Tester
Joined
Feb 4, 2008
Messages
9,434
Reaction score
688
Points
203
Not too hard, but still, you should remember that we also produce a dependency that way directly to DirectX. Not good for portability and compatibility with rendering clients.
Aren't we already directly tied to DX by being dependent on Orbiter? Orbiter isn't going away from DX anytime soon. And the only OGL client died a long time ago.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,604
Reaction score
2,324
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Aren't we already directly tied to DX by being dependent on Orbiter? Orbiter isn't going away from DX anytime soon. And the only OGL client died a long time ago.

Yes, but also on a specific DirectX version, should anything change underneath. Remember: 9 is not fully compatible to 11 and 11 not fully compatible to 12, thanks to the implementation freedom.

If we could be DirectX-agnostic, it would be better, but I see little chances there to also be fast than.

I believe it would be better if we implement any such rendering extension in a separate DLL and use late linking, so using different DLLs for different versions is possible. Maybe we can later replace such a extension DLL more and more by functions of a rendering client.
 

Poscik

Addon Developer
Addon Developer
Joined
Mar 28, 2008
Messages
512
Reaction score
3
Points
18
Location
Sulejówek
I like the ADI part... we could then do the yaw without breaking a sweat, and that would allow the ATT REF PB to be used (after some kind of IMU is implemented). The HSI would also be easier. I know nothing about the D2D and/or D3D, except they are faster than GDI, but how hard can it be to draw lines and numbers after the initial setup is done? :shrug:

Well, in D2D it's relatively easy:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd756653(v=vs.85).aspx

But I'm wondering if it's possible to obtain rendering surface from mfd surface handle given by orbiter API.

---------- Post added at 01:22 PM ---------- Previous post was at 01:12 PM ----------

Yes, but also on a specific DirectX version, should anything change underneath. Remember: 9 is not fully compatible to 11 and 11 not fully compatible to 12, thanks to the implementation freedom.

If we could be DirectX-agnostic, it would be better, but I see little chances there to also be fast than.

I believe it would be better if we implement any such rendering extension in a separate DLL and use late linking, so using different DLLs for different versions is possible. Maybe we can later replace such a extension DLL more and more by functions of a rendering client.

Exactly. Separate DLL with exposed interface that wraps all the rendering stuff. Then such interface can be obtained as a return of exported function using GetProcAddress. Module can be loaded using GetModuleHandle('module.dll'), thus rendering module can be specified in config.

But I'm also wondering how much imprevement can be achieved this way.
 
Last edited:

GLS

Well-known member
Orbiter Contributor
Addon Developer
Joined
Mar 22, 2008
Messages
5,914
Reaction score
2,908
Points
188
Website
github.com
I'm tied up with other things at the moment, but in 2 weeks or so I could do p.e. the APU/HUD display in the new format, to compare with the current format. Somebody else needs to make the rest though...
I'd say the A/E PFD will be faster (I'm sold on the ADI anyway), the DPS display is simple enough that it will not matter much, so I think the 3 MEDS displays (OMS/MPS, APU/HYD and SPI) will be a good benchmark. We could branch off the Orbiter 2016 branch for this. It would need some changes to the VC mesh, as currently the MDU screen is split in 2: display and menu :uhh:.

One thing I should probably "make public", even though I haven't really started it, is that I'm planning on making the famous "DEU font" from scratch. I've already gathered some dozens of photos of the displays, so I just need time to start drawing.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,604
Reaction score
2,324
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
One thing I should probably "make public", even though I haven't really started it, is that I'm planning on making the famous "DEU font" from scratch. I've already gathered some dozens of photos of the displays, so I just need time to start drawing.

The 7 bit font encoding for the DEU font is in the HAL/S FC manual (Its plain ASCII with small changes).
 

GLS

Well-known member
Orbiter Contributor
Addon Developer
Joined
Mar 22, 2008
Messages
5,914
Reaction score
2,908
Points
188
Website
github.com
The 7 bit font encoding for the DEU font is in the HAL/S FC manual (Its plain ASCII with small changes).

I think that's easy to change once it's done, but first I have to put my OCD to work and make the letters/numbers. :lol:
 

Poscik

Addon Developer
Addon Developer
Joined
Mar 28, 2008
Messages
512
Reaction score
3
Points
18
Location
Sulejówek
Just made some research. As I see, HDC handle for surface can be obtained, so It can be binded to D2DRenderTarget. I'm not sure if the same thing is possible with D3D. I think the best solution here is to draw displays to D2D resources, then copy content to fill HDC surface. D2D will draw it's shapes veeery fast, and then simple memory copy should be enough to paint on HDC. I think that's faster than drawing each shape on HDC surface.
 

jarmonik

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 28, 2008
Messages
2,666
Reaction score
795
Points
128
It's hard to imagine that how a rendering of any MFDs could be a performance problem. A lag from MFD updates is likely due to a collision of a resource use in a multi-threaded environment.

For an example DirectX 9 is multi-threaded. When we execute a draw call it will return immediately and the draw order is placed in a queue which is then executed by worker threads. The queue is long enough to hold 3 frames worth of drawing commands. Most resources those are placed in a queue cannot be modified by CPU while being in the queue. So, the CPU needs to wait that D3D is done using it until a lock can be issued. Which can be very long wait in the worst cases.

The easiest way to avoid collisions like that is not to mix GPU and CPU based drawing commands. oapiBlt() qualifies as GPU based. Whether oapiBlt is placed in the draw queue too is something that I don't know yet. Right now my guess is that it is.

D3D9 has implemented a CPU tracker in the statistics panel (Shift + Ctrl + C). If the orange bar is high then a resource collision has occurred. Currently, CPU is idling a lot in Present() waiting DirectX worker threads and render hardware to catch up (Red bar).

There is also "PresentLocation" parameter in D3D9Client.cfg:

- If set to '1' then client allows other task to be performed (Orbiter core update, vessel updates) before finishing the frame to buy more time for DX worker threads and graphics hardware to do the rendering. This also increases a change of resource collision.

- If set to '0' then the client waits that the frame is finished before allowing any other tasks to be performed. As far as I can tell, this doesn't mean that the draw queue is flushed empty since multiple frames can be queued.


Some other thoughts:

Mixing two GPU based systems like D2D and D3D with HDC based middle layer doesn't sound a good idea.

In D3D9 the Sketchpad is using DirectX so it's queued with the rest of the rendering calls and shouldn't cause lag. Trying to improve Sketchpad's usefulness could be more productive.
 

DaveS

Addon Developer
Addon Developer
Donator
Beta Tester
Joined
Feb 4, 2008
Messages
9,434
Reaction score
688
Points
203
This is how the D3D9Client statistics screen looks for me:

D3D9Client_beta_statistics.jpg
 

GLS

Well-known member
Orbiter Contributor
Addon Developer
Joined
Mar 22, 2008
Messages
5,914
Reaction score
2,908
Points
188
Website
github.com
I get +/- the same numbers (it varies and the blue bar is smaller in the outside view). I tried the stats in Orbiter 2010 and there are no bars, but the times shown have about 50% of the frame in the HUD, MFDs and panels category.
 

jarmonik

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 28, 2008
Messages
2,666
Reaction score
795
Points
128
This is how the D3D9Client statistics screen looks for me:

Looks good to me, nothing alarming there. Is there MFD based performance problem occurring in that screen shot ?
 

DaveS

Addon Developer
Addon Developer
Donator
Beta Tester
Joined
Feb 4, 2008
Messages
9,434
Reaction score
688
Points
203
Looks good to me, nothing alarming there. Is there MFD based performance problem occurring in that screen shot ?
Yes. All 9 MFDs on the forward panels (2xCDR, 4xcenter, 2xPLT) are powered up and displaying data.
 

jarmonik

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 28, 2008
Messages
2,666
Reaction score
795
Points
128
I get +/- the same numbers (it varies and the blue bar is smaller in the outside view). I tried the stats in Orbiter 2010 and there are no bars, but the times shown have about 50% of the frame in the HUD, MFDs and panels category.

All scene related including the HUD, MFDs and panels are included in the green part of the bar. It would seem that I don't remember at which point the actual MFD updates are done/called by orbiter.

As far as I can tell the GPU should be running with 100% duty cycle.

---------- Post added at 14:54 ---------- Previous post was at 14:52 ----------

Yes. All 9 MFDs on the forward panels (2xCDR, 4xcenter, 2xPLT) are powered up and displaying data.

How does the graph change when the MFDs are shutdown ?
 

DaveS

Addon Developer
Addon Developer
Donator
Beta Tester
Joined
Feb 4, 2008
Messages
9,434
Reaction score
688
Points
203
All scene related including the HUD, MFDs and panels are included in the green part of the bar. It would seem that I don't remember at which point the actual MFD updates are done/called by orbiter.

As far as I can tell the GPU should be running with 100% duty cycle.

---------- Post added at 14:54 ---------- Previous post was at 14:52 ----------



How does the graph change when the MFDs are shutdown ?
This is with the MFDs powered off:

D3D9Client_beta_statistics_MFDs_off.jpg
 

jarmonik

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 28, 2008
Messages
2,666
Reaction score
795
Points
128
This is with the MFDs powered off:

I guess that answered to the question of where the MFD update is done. Is that due to heavy math or graphics ?

That would also suggest that GPU isn't working 100% of the time. Unless the "PresentLocation" was change to zero.

Also, the client displays a mean value measured during one second. Peak impact could be higher than shown on the screen.

Do you have a timer there showing where the performance disappears ?
 

GLS

Well-known member
Orbiter Contributor
Addon Developer
Joined
Mar 22, 2008
Messages
5,914
Reaction score
2,908
Points
188
Website
github.com
The non-client part decreases.... I guess that is our drawing code (but not "graphics", i.e. code to decide what to show), that doesn't run with the MDUs off.

---------- Post added at 01:42 PM ---------- Previous post was at 01:25 PM ----------

I guess that answered to the question of where the MFD update is done. Is that due to heavy math or graphics ?

Most displays don't have a lot of math, other than what is needed to convert a parameter value to a number of pixels to draw a rectangle. There are also some ifs to select which colors to use based on the parameter values displayed, so there are also lots of SelectObject() calls... I don't think it could be optimized much further.
Then there's the monster A/E PFD that has tons of stuff and is clearly the hog, and that has with some trigonometry. I optimized it to reduce those sin() and cos() calls to a minimum. The ADI is drawn from scratch everytime and must be rotated as needed, etc :facepalm: (I don't think the projected ball mesh idea from Poscik could be slower that what we have now, and it would do more.)
 

DaveS

Addon Developer
Addon Developer
Donator
Beta Tester
Joined
Feb 4, 2008
Messages
9,434
Reaction score
688
Points
203
I guess that answered to the question of where the MFD update is done. Is that due to heavy math or graphics ?

That would also suggest that GPU isn't working 100% of the time. Unless the "PresentLocation" was change to zero.

Also, the client displays a mean value measured during one second. Peak impact could be higher than shown on the screen.

Do you have a timer there showing where the performance disappears ?
This is my D3D9Client.cfg:

Code:
FrameRate = 200
EnableLimiter = 0
CustomCamMode = 1
PlanetPreloadMode = 0
PlanetTexLoadFreq = 20
Anisotrophy = 16
SceneAntialias = 8
SketchpadMode = 0
SketchpadFont = 1
PreLoadBaseVisuals = 0
EnableNormalMapping = 1
EnablePBR = 0
NearClipPlaneMode = 0
RwyLightAnimate = 1
RwyLightAngle = 120
RwyBrightness = 1
NightLightsAngle = 10
BumpMapAmplitude = 1
PlanetGlow = 1.25
EnvMapSize = 256
EnvMapMode = 2
EnvMapFaces = 3
ShadowMapMode = 1
ShadowMapSize = 1024
EnableGlass = 1
EnableMeshDbg = 1
TileMipmaps = 0
TextureMips = 2
TileDebug = 0
StereoSeparation = 65
StereoConvergence = 0.2
DebugLvl = 1
VCNearPlane = 0.1
LightSourcesInUse = 12
DisableDrvMgm = 0
NVPerfHUD = 0
DebugLineFontSize = 18
DisableVisualHelperReadout = 0
LODBias = -2
MeshRes = 1
MicroMode = 2
MicroFilter = 2
BlendMode = 1
MicroBias = 3
PostProcess = 0
SolCfg = Sol
DebugLineFont = Fixed

The performance loss is instant, no delay at all. I experience it as soon as the sim has finished loading. Normal FPS is 120 and dt/F is 0.008 (V-synch is on) but as you can see in the first screenshot with the MFDs on, my FPS is around 77 and dt/F is 0.013.
 

jarmonik

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 28, 2008
Messages
2,666
Reaction score
795
Points
128
I optimized it to reduce those sin() and cos() calls to a minimum. The ADI is drawn from scratch everytime and must be rotated as needed, etc :facepalm: (I don't think the projected ball mesh idea from Poscik could be slower that what we have now, and it would do more.)

If this code is disabled then does the performance problem go away ? Drawing rectangles can't be a problem.

Rendering a user supplied mesh to a MFD screen can be easily arranged in the sketchpad, technically almost everything is already there.
 

GLS

Well-known member
Orbiter Contributor
Addon Developer
Joined
Mar 22, 2008
Messages
5,914
Reaction score
2,908
Points
188
Website
github.com
If this code is disabled then does the performance problem go away ? Drawing rectangles can't be a problem.

Rendering a user supplied mesh to a MFD screen can be easily arranged in the sketchpad, technically almost everything is already there.

Here's the FPS I get in that KSC scenario:
baseline: 35
no ADI & HSI: 42
no ADI: 41
no HSI: 36

The ADI takes the cake on this one. Here's the current code:
Code:
void MDU::ADI( HDC hDC, double pitch, double roll, double yaw )
	{
		// center (122,94) r = 57
		// view r = 49, ball r = 49 * sqrt( 2 )
		// 90º pitch/yaw "FOV"

		// apply roll
		XFORM WTroll;
		WTroll.eM11 = (FLOAT)cos( roll * RAD );
		WTroll.eM12 = (FLOAT)(-sin( roll * RAD ));
		WTroll.eM21 = -WTroll.eM12;
		WTroll.eM22 = WTroll.eM11;
		WTroll.eDx = (FLOAT)(50 * (1 - WTroll.eM11 - WTroll.eM21));
		WTroll.eDy = (FLOAT)(50 * (1 - WTroll.eM11 + WTroll.eM21));
		SetGraphicsMode( hDC_ADI, GM_ADVANCED );
		SetWorldTransform( hDC_ADI, &WTroll );

		if (pitch > 180) pitch -= 360;// TODO get rid of this

		// 0º pitch line/labels
		double sinpitch = sin( pitch * RAD );
		double cospitch = cos( pitch * RAD );
		int hP;
		double hP2;
		SetTextColor( hDC_ADI, CR_BLACK );
		SetBkColor( hDC_ADI, CR_WHITE );
		if (fabs( pitch ) <= 45)
		{
			hP = Round( 69.296 * sinpitch );
			if (pitch < 0)
			{
				SelectObject( hDC_ADI, WhiteBrush );
				SelectObject( hDC_ADI, WhitePen );
				Rectangle( hDC_ADI, 0, 0, 100, 50 );
				SelectObject( hDC_ADI, LightGrayBrush );
				SelectObject( hDC_ADI, LightGrayPen );
				Chord( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
				Rectangle( hDC_ADI, 0, 50, 100, 100 );
				SelectObject( hDC_ADI, BlackPen );
				Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
			}
			else
			{
				SelectObject( hDC_ADI, LightGrayBrush );
				SelectObject( hDC_ADI, LightGrayPen );
				Rectangle( hDC_ADI, 0, 50, 100, 100 );
				SelectObject( hDC_ADI, WhiteBrush );
				SelectObject( hDC_ADI, WhitePen );
				Chord( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
				Rectangle( hDC_ADI, 0, 0, 100, 50 );
				SelectObject( hDC_ADI, BlackPen );
				Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
			}
			hP = 46 + Round( 66.935245 * sinpitch );
			TextOut( hDC_ADI, 31, hP, "0", 1 );
			TextOut( hDC_ADI, 67, hP, "0", 1 );
		}
		else if (pitch > 0)
		{
			SelectObject( hDC_ADI, WhiteBrush );
			Rectangle( hDC_ADI, 0, 0, 100, 100 );
		}
		else
		{
			SelectObject( hDC_ADI, LightGrayBrush );
			Rectangle( hDC_ADI, 0, 0, 100, 100 );
		}

		// pitch lines/labels for +30º/+60º/+90º/+120º/+150º
		SelectObject( hDC_ADI, DarkGrayPen );
		// +30º
		if (fabs( pitch - 30 ) <= 45)
		{
			hP2 = sinpitch * 60.012499 - cospitch * 34.648232;//hP = 69.296 * sin( (pitch - 30) * RAD );
			hP = Round( hP2 );
			if (pitch < 30) Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
			else Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
			hP = 46 + Round( hP2 * 0.965926 );
			TextOut( hDC_ADI, 31, hP, "3", 1 );
			TextOut( hDC_ADI, 67, hP, "3", 1 );
		}
		// +60º
		if (fabs( pitch - 60 ) <= 45)
		{
			hP2 = sinpitch * 34.648232 - cospitch * 60.012499;
			hP = Round( hP2 );
			if (pitch < 60) Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
			else Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
			hP = 46 + Round( hP2 * 0.965926 );
			TextOut( hDC_ADI, 31, hP, "6", 1 );
			TextOut( hDC_ADI, 67, hP, "6", 1 );
		}
		// +90º
		if (fabs( pitch - 90 ) <= 45)
		{
			hP2 = 69.296465 * (-cospitch);
			hP = Round( hP2 );
			if (pitch < 90) Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
			else Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
			hP = 46 + Round( hP2 * 0.965926 );
			TextOut( hDC_ADI, 31, hP, "9", 1 );
			TextOut( hDC_ADI, 67, hP, "9", 1 );
		}
		// +120º
		if (fabs( pitch - 120 ) <= 45)
		{
			hP2 = (-sinpitch) * 34.648232 - cospitch * 60.012499;
			hP = Round( hP2 );
			if (pitch < 120) Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
			else Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
			hP = 46 + Round( hP2 * 0.965926 );
			TextOut( hDC_ADI, 30, hP, "12", 2 );
			TextOut( hDC_ADI, 66, hP, "12", 2 );
		}
		// +150º
		if (fabs( pitch - 150 ) <= 45)
		{
			hP2 = (-sinpitch) * 60.012499 - cospitch * 34.648232;
			hP = Round( hP2 );
			if (pitch < 150) Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
			else Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
			hP = 46 + Round( hP2 * 0.965926 );
			TextOut( hDC_ADI, 30, hP, "15", 2 );
			TextOut( hDC_ADI, 66, hP, "15", 2 );
		}

		// pitch lines/labels for -30º/-60º/-90º/-120º/-150º
		SelectObject( hDC_ADI, WhitePen );
		SetTextColor( hDC_ADI, CR_WHITE );
		SetBkColor( hDC_ADI, CR_LIGHT_GRAY );
		// -30º
		if (fabs( pitch + 30 ) <= 45)
		{
			hP2 = sinpitch * 60.012499 + cospitch * 34.648232;
			hP = Round( hP2 );
			if (pitch < -30) Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
			else Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
			hP = 46 + Round( hP2 * 0.965926 );
			TextOut( hDC_ADI, 30, hP, "33", 2 );
			TextOut( hDC_ADI, 66, hP, "33", 2 );
		}
		// -60º
		if (fabs( pitch + 60 ) <= 45)
		{
			hP2 = sinpitch * 34.648232 + cospitch * 60.012499;
			hP = Round( hP2 );
			if (pitch < -60) Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
			else Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
			hP = 46 + Round( hP2 * 0.965926 );
			TextOut( hDC_ADI, 30, hP, "30", 2 );
			TextOut( hDC_ADI, 66, hP, "30", 2 );
		}
		// -90º
		if (fabs( pitch + 90 ) <= 45)
		{
			hP2 = 69.296 * cospitch;
			hP = Round( hP2 );
			if (pitch < -90) Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
			else Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
			hP = 46 + Round( hP2 * 0.965926 );
			TextOut( hDC_ADI, 30, hP, "27", 2 );
			TextOut( hDC_ADI, 66, hP, "27", 2 );
		}
		// -120º
		if (fabs( pitch + 120 ) <= 45)
		{
			hP2 = (-sinpitch) * 34.648232 + cospitch * 60.012499;
			hP = Round( hP2 );
			if (pitch < -120) Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
			else Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
			hP = 46 + Round( hP2 * 0.965926 );
			TextOut( hDC_ADI, 30, hP, "24", 2 );
			TextOut( hDC_ADI, 66, hP, "24", 2 );
		}
		// -150º
		if (fabs( pitch + 150 ) <= 45)
		{
			hP2 = (-sinpitch) * 60.012499 + cospitch * 34.648232;
			hP = Round( hP2 );
			if (pitch < -150) Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, 119, 50, -19, 50 );
			else Arc( hDC_ADI, -19, 50 - hP, 119, 50 + hP, -19, 50, 119, 50 );
			hP = 46 + Round( hP2 * 0.965926 );
			TextOut( hDC_ADI, 30, hP, "21", 2 );
			TextOut( hDC_ADI, 66, hP, "21", 2 );
		}

		// TODO yaw
		// HACK
		// "central plane"
		SelectObject( hDC_ADI, WhiteBrush );
		SelectObject( hDC_ADI, BlackPen );
		Rectangle( hDC_ADI, 48, 0, 52, 100 );
		SelectObject( hDC_ADI, DarkGrayPen );
		MoveToEx( hDC_ADI, 50, 0, NULL );
		LineTo( hDC_ADI, 50, 100 );

		SelectObject( hDC_ADI, DarkGrayPen );
		// yaw line 30º (above horizon)
		MoveToEx( hDC_ADI, 85, 0, NULL );
		LineTo( hDC_ADI, 85, 50 + Round( 60.012096 * sinpitch ) );
		// yaw line 330º (above horizon)
		MoveToEx( hDC_ADI, 15, 0, NULL );
		LineTo( hDC_ADI, 15, 50 + Round( 60.012096 * sinpitch ) );
		SelectObject( hDC_ADI, WhitePen );
		// yaw line 30º (below horizon)
		MoveToEx( hDC_ADI, 85, 100, NULL );
		LineTo( hDC_ADI, 85, 50 + Round( 60.012096 * sinpitch ) );
		// yaw line 330º (below horizon)
		MoveToEx( hDC_ADI, 15, 100, NULL );
		LineTo( hDC_ADI, 15, 50 + Round( 60.012096 * sinpitch ) );

		// TODO yaw labels

		// roll triangle
		SelectObject( hDC_ADI, LightGreenPen );
		SelectObject( hDC_ADI, LightGreenBrush );
		POINT tri[3];
		tri[0].x = 50;
		tri[0].y = 1;
		tri[1].x = 46;
		tri[1].y = 9;
		tri[2].x = 54;
		tri[2].y = 9;
		Polygon( hDC_ADI, tri, 3 );
		
		// clean up
		ModifyWorldTransform( hDC_ADI, &WTroll, MWT_IDENTITY );
		SetGraphicsMode( hDC_ADI, GM_COMPATIBLE );

		// flight director
		SelectObject( hDC_ADI, LightGreenThickPen );
		Arc( hDC_ADI, 44, 44, 56, 57, 44, 50, 56, 50 );
		SelectObject( hDC_ADI, LightGreenPen );
		SelectObject( hDC_ADI, LightGreenBrush );
		Rectangle( hDC_ADI, 49, 33, 51, 67 );
		Rectangle( hDC_ADI, 33, 49, 67, 51 );

		// digital RPY
		if (pitch < 0) pitch += 360;// TODO get rid of this
		SetTextColor( hDC, CR_WHITE );
		char cbuf[8];
		sprintf_s( cbuf, 8, "%03.0f", roll );
		TextOut( hDC, 180, 25, cbuf, strlen( cbuf ) );
		sprintf_s( cbuf, 8, "%03.0f", pitch );
		TextOut( hDC, 180, 32, cbuf, strlen( cbuf ) );
		sprintf_s( cbuf, 8, "%03.0f", yaw );
		TextOut( hDC, 180, 39, cbuf, strlen( cbuf ) );

		BitBlt( hDC_ADI, 0, 0, 100, 100, hDC_ADIMASK, 0, 0, SRCAND );
		BitBlt( hDC, 72, 44, 100, 100, hDC_ADI, 0, 0, SRCPAINT );
		return;
	}

I don't think SetWorldTransform() is to blame here as the HSI calls it, not once but several times, and it doesn't seem to "eat" as much time as the ADI.
 

DaveS

Addon Developer
Addon Developer
Donator
Beta Tester
Joined
Feb 4, 2008
Messages
9,434
Reaction score
688
Points
203
Here's the FPS I get in that KSC scenario:
baseline: 35
no ADI & HSI: 42
no ADI: 41
no HSI: 36
For me the FPS doesn't return until all the MFDs have been turned off, not just the ADI/HSI. So it isn't the heaviness of the ADI and HSI that is the true culprit of the FPS reduction.
 
Top