New Release D3D9Client Development

I removed all the redraw except the mfd. No issues. the only thing in the log is:
000000.000: D3D9: [Scene Initialized] 000000.000: Finished initialising panels 000061.245: D3D9: [Session Closed. Scene deleted.] 000061.245: D3D9: [Destroy Render Window Called] D3D9: ERROR: [Failed to Reset DirectX Device] (Likely blocked by undeleted resources) 000061.245: **** Closing simulation session
void Atlantis::RedrawPanel_MFDButton(SURFHANDLE surf, int mfd) { oapi::Font* font = oapiCreateFont(-11, true, "Arial"); //g_Param.font[0] = CreateFont (-11, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Arial"); oapi::Sketchpad* skp = oapiGetSketchpad(surf); //skp->SetTextColor(BBGGRR) skp->SetFont(font); skp->SetTextColor(0x00FF00); skp->SetTextAlign(oapi::Sketchpad::CENTER); if (oapiGetMFDMode(mfd) == MFD_NONE) { RECT r = { 0, 0, 255, 13 }; skp->Rectangle(0, 0, 255, 13); } else { // MFD powered on const char* label; int x = 24; for (int bt = 0; bt < 5; bt++) { if (label = oapiMFDButtonLabel(mfd, bt)) { skp->Text(x, 1, label, strlen(label)); x += 42; } else break; } skp->Text(234, 1, "PG", 2); } oapiReleaseSketchpad(skp); }
 
Last edited:
C++:
void Atlantis::RedrawPanel_MFDButton(SURFHANDLE surf, int mfd)
{
    oapi::Font* font = oapiCreateFont(-11, true, "Arial");
    //g_Param.font[0] = CreateFont (-11, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Arial");
    oapi::Sketchpad* skp = oapiGetSketchpad(surf);
    //skp->SetTextColor(BBGGRR)
    skp->SetFont(font);
    skp->SetTextColor(0x00FF00);
    skp->SetTextAlign(oapi::Sketchpad::CENTER);
    
    if (oapiGetMFDMode(mfd) == MFD_NONE) {
        RECT r = { 0, 0, 255, 13 };
        skp->Rectangle(0, 0, 255, 13);
    }
    else { // MFD powered on
        const char* label;
        int x = 24;
        for (int bt = 0; bt < 5; bt++) {
            if (label = oapiMFDButtonLabel(mfd, bt)) {
                skp->Text( x, 1, label, strlen(label));
                x += 42;
            }
            else break;
        }
        skp->Text(234, 1, "PG", 2);
    }
    oapiReleaseSketchpad(skp);
}

I see no reason why this code should lockup in D3D9. But there is a memory leak due to oapiCreateFont(). Fonts should be created during vessel initialization not in a "Draw" routines.

Code:
D3D9: ERROR: D3D9ClientSurface: GetDC() Failed
D3D9: ERROR: Surface name is clbkCreateSurface Handle=0xF58D8E0 (256,36)
D3D9: ERROR: Surface Has a Texture Interface
D3D9: ERROR: Surface Has a Surface Interface
D3D9: ERROR: Surface is in a DefaultPool
D3D9: ERROR: Surface has DYNAMIC usage
D3D9: ERROR: Surface Format is 22
D3D9: ERROR: Surface Has 1 MipMaps
D3D9: ERROR: ActiveFlags( )

Once again there appears to be no visible reason for the failure. It should work under the conditions listed in the error report. Do you have any co-developers those could test the code on a different computer.

Do you have a binary package available that I could run on my computer to see what happens ? Or possibly a source code ?
How hard it is to produce the errors do they occur every time.

D3D9: ERROR: [Failed to Reset DirectX Device] (Likely blocked by undeleted resources)
This is nothing to worry about.
 
Now how to do this is sketchpad? this is what I have.
void Atlantis::RedrawPanel_MFDButton(SURFHANDLE surf, int mfd) { oapi::Font* font = oapiCreateFont(-11, true, "Arial"); //g_Param.font[0] = CreateFont (-11, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Arial"); oapi::Sketchpad* skp = oapiGetSketchpad(surf); //skp->SetTextColor(BBGGRR) skp->SetFont(font); skp->SetTextColor(0x00FF00); skp->SetTextAlign(oapi::Sketchpad::CENTER); if (oapiGetMFDMode(mfd) == MFD_NONE) { RECT r = { 0, 0, 255, 13 }; skp->Rectangle(0, 0, 255, 13); } else { // MFD powered on
BUt this is from Atlantis.
void Atlantis::RedrawPanel_MFDButton (SURFHANDLE surf, int mfd) { HDC hDC = oapiGetDC (surf); // D. Beachy: BUGFIX: if MFD powered off, cover separator lines and do not paint buttons if (oapiGetMFDMode(mfd) == MFD_NONE) { RECT r = { 0,0,255,13 }; FillRect(hDC, &r, (HBRUSH)GetStockObject(BLACK_BRUSH));

How to fill the rectangle with a black box?
 
There is a documentation for Sketchpad in OrbiterSDK/doc/API_Reference.chm

so, somewhere in vessel initialization:
gBlackBrush = oapiCreateBrush(0x000000);

and in a drawing routine:
C++:
skp->SetBrush(gBlackBrush);      // Enable shape filling
auto Old = skp->SetPen(NULL);     // Disable outline
skp->Rectangle(0, 0, 255, 13);
skp->SetBrush(NULL);             // Disable shape filling
skp->SetPen(Old);                 // Restore previous pen

If the FillRect is common then you could create a sub rotine
C++:
inline void FillRect(RECT *r, Brush *pBrush)
{
skp->SetBrush(pBrush);      // Enable shape filling
auto Old = skp->SetPen(NULL);     // Disable outline
skp->Rectangle(r->left,....);
skp->SetBrush(NULL);             // Disable shape filling
skp->SetPen(Old);                 // Restore previous pen
}
 
Last edited:
Thanks. This is only in one area. The one issue is the
gBlackBrush = oapiCreateBrush(0x000000);
does "gBlackBrush" need to be defined?
 
Last edited:
I started back adding in my panel redraw.
void Atlantis::RedrawPanel_EVENTstatus(SURFHANDLE surf, int part) { char cbuf[20]; oapi::Font* font = oapiCreateFont(70, true, "Arial"); oapi::Sketchpad* skp = oapiGetSketchpad(surf); skp->SetFont(font); skp->SetTextColor(0x000000); skp->SetTextAlign(oapi::Sketchpad::LEFT); sprintf(cbuf, "%d", Minutes4set); skp->Text(5, 85, cbuf, strlen(cbuf)); sprintf(cbuf, "%d", Minutes3set); skp->Text(70, 85, cbuf, strlen(cbuf)); sprintf(cbuf, "%d", Minutes2set); skp->Text(145, 85, cbuf, strlen(cbuf)); sprintf(cbuf, "%d", Minutes1set); skp->Text(220, 85, cbuf, strlen(cbuf)); oapiReleaseSketchpad(skp); }

it locks up. in the log is: 000000.000: D3D9: [Scene Initialized] 000000.000: Finished initialising panels 000019.844: D3D9: [Session Closed. Scene deleted.] 000019.844: D3D9: [Destroy Render Window Called] D3D9: ERROR: [Failed to Reset DirectX Device] (Likely blocked by undeleted resources) 000019.844: **** Closing simulation session D3D9: ERROR: 25997 un-released fonts!
 
gattispilot!
Maybe offtopic, but remember what jarmonic said few posts ago:
But there is a memory leak due to oapiCreateFont(). Fonts should be created during vessel initialization not in a "Draw" routines.

Problem is here:
Code:
void Atlantis::RedrawPanel_MFDButton(SURFHANDLE surf, int mfd)
{
    oapi::Font* font = oapiCreateFont(-11, true, "Arial");
}
 
Thanks. So what should I do?

I did this all the create font are here:
Atlantis::Atlantis (OBJHANDLE hObj, int fmodel) : VESSEL4 (hObj, fmodel) {.... oapi::Font* font1 = oapiCreateFont(50, true, "*Seven Segment"); oapi::Font* font2 = oapiCreateFont(40, true, "*Seven Segment"); oapi::Font* font3 = oapiCreateFont(-11, true, "Arial");

then in the redraw:
void Atlantis::RedrawPanel_PANELRCSstatus(SURFHANDLE surf, int part) { char cbuf[20]; // oapi::Font* font1 = oapiCreateFont(50, true, "*Seven Segment"); oapi::Sketchpad* skp = oapiGetSketchpad(surf); skp->SetFont(font1); skp->SetTextColor(0x0000FF); skp->SetTextAlign(oapi::Sketchpad::LEFT); sprintf(cbuf, "%2.0f", RCSQTY); skp->Text(0, 100, cbuf, strlen(cbuf)); skp->Text(210, 100, cbuf, strlen(cbuf)); skp->Text(105, 100, cbuf, strlen(cbuf)); oapiReleaseSketchpad(skp); }
but now font1 is undefined
 
Last edited:
I have experience only with arduino C/C++ code, so, don't take my comment to serious, but what about changing this:
Code:
skp->SetFont(font1);
to this:
Code:
skp->SetFont(Atlantis::font1);

Looks like font1 is local for one function. You need to make it "more global" and visible for other functions.
Maybe you even need to put font1 in in Atlantis.h file class declaration private section. Hope you got an idea.
 
Thanks. But I guess I don't get what to define Font1,.... in the H.
I have looked at some code for examples. like the DG and ShuttleA
 
I am looking in DeltaGlider.cpp source code. It comes with stock Orbiter 2016.
Font creation happen in PaintMarkings function
PaintMarkings fuction is called from void DeltaGlider::clbkPostCreation ()

But... front is released in the same PaintMarkings function. :(

What about delralring forn in Atrlantis.h file private section in following way:
Code:
private:
    oapi::Font *font;

Then use font where you need in following way:

Code:
Atlantis::Atlantis (OBJHANDLE hObj, int fmodel) {
Atlantis::font1 = oapiCreateFont(50, true, "*Seven Segment");
}

void Atlantis::RedrawPanel_PANELRCSstatus(SURFHANDLE surf, int part) {
skp->SetFont(Atlantis::font1);
}

Do not forget to release font resource when deinitialisin Atlantis:
Code:
Atlantis::Atlantis () {
oapiReleaseFont (Atlantis::font1);
}
 
Thanks.
on in the h:
private: oapi::Font* font, font1, font2, font3;

on the CPP
// -------------------------------------------------------------- // Constructor // -------------------------------------------------------------- Atlantis::Atlantis (OBJHANDLE hObj, int fmodel) : VESSEL4 (hObj, fmodel) { #ifdef _DEBUG // D. Beachy: for BoundsChecker debugging GrowStack(); #endif Atlantis::font1 = oapiCreateFont(50, true, "*Seven Segment"); int i; plop = new PayloadBayOp (this); ...}

but it has issues:
Severity Code Description Project Path File Line Suppression State
Error C2679 binary '=': no operator found which takes a right-hand operand of type 'oapi::Font *' (or there is no acceptable conversion) SPACESHUTTLE2016EARLYMET D:\Orbiter2016\Orbitersdk\samples\SPACESHUTTLE2016E4evaearlyvccammoveEVAnewmfd MET D:\Orbiter2016\Orbitersdk\samples\SPACESHUTTLE2016E4evaearlyvccammoveEVAnewmfd MET\Atlantis.cpp 319
 
cpp
void Atlantis::Createfonts() { oapi::Font* font1 = oapiCreateFont(50, true, "*Seven Segment"); oapi::Font* font2 = oapiCreateFont(40, true, "*Seven Segment"); oapi::Font* font3 = oapiCreateFont(-11, true, "Arial"); }
h:
private: oapi::Font* font, font1, font2, font3; void Createfonts();

But when i go to the drawing part I get errors
void Atlantis::RedrawPanel_MFDButton(SURFHANDLE surf, int mfd) { // oapi::Font* font3 = oapiCreateFont(-11, true, "Arial"); //g_Param.font[0] = CreateFont (-11, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Arial"); oapi::Sketchpad* skp = oapiGetSketchpad(surf); //skp->SetTextColor(BBGGRR) skp->SetFont(Atlantis::font3); skp->SetTextColor(0x00FF00); skp->SetTextAlign(oapi::Sketchpad::CENTER); if (oapiGetMFDMode(mfd) == MFD_NONE) { RECT r = { 0, 0, 255, 13 }; //skp->Rectangle(0, 0, 255, 13); //skp->SetBrush(gBlackBrush); // Enable shape filling auto Old = skp->SetPen(NULL); // Disable outline skp->Rectangle(0, 0, 255, 13); skp->SetBrush(NULL); // Disable shape filling skp->SetPen(Old); }
Severity Code Description Project Path File Line Suppression State
Error C2664 'oapi::Font *oapi::Sketchpad::SetFont(oapi::Font *) const': cannot convert argument 1 from 'oapi::Font' to 'oapi::Font *' SPACESHUTTLE2016EARLYMET D:\Orbiter2016\Orbitersdk\samples\SPACESHUTTLE2016E4evaearlyvccammoveEVAnewmfd MET D:\Orbiter2016\Orbitersdk\samples\SPACESHUTTLE2016E4evaearlyvccammoveEVAnewmfd MET\Atlantis.cpp 7705

the other error I get is this:
Severity Code Description Project Path File Line Suppression State
Error C2512 'oapi::Font': no appropriate default constructor available SPACESHUTTLE2016EARLYMET D:\Orbiter2016\Orbitersdk\samples\SPACESHUTTLE2016E4evaearlyvccammoveEVAnewmfd MET D:\Orbiter2016\Orbitersdk\samples\SPACESHUTTLE2016E4evaearlyvccammoveEVAnewmfd MET\Atlantis.cpp 312
 
I redid the code and it compiles. but CTD. When running the debug I get a break on the release in the mfd code.
in the h: private: oapi::Font *font, *font1, *font2, *font3;

in the post creation:
void Atlantis::clbkPostCreation () { oapi::Font* font1 = oapiCreateFont(50, true, "*Seven Segment"); oapi::Font* font2 = oapiCreateFont(40, true, "*Seven Segment"); oapi::Font* font3 = oapiCreateFont(-11, true, "Arial");

And the mfd buttons:
void Atlantis::RedrawPanel_MFDButton(SURFHANDLE surf, int mfd) { // oapi::Font* font3 = oapiCreateFont(-11, true, "Arial"); //g_Param.font[0] = CreateFont (-11, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Arial"); oapi::Sketchpad* skp = oapiGetSketchpad(surf); //skp->SetTextColor(BBGGRR) skp->SetFont(Atlantis::font3); skp->SetTextColor(0x00FF00); skp->SetTextAlign(oapi::Sketchpad::CENTER); if (oapiGetMFDMode(mfd) == MFD_NONE) { RECT r = { 0, 0, 255, 13 }; //skp->Rectangle(0, 0, 255, 13); //skp->SetBrush(gBlackBrush); // Enable shape filling auto Old = skp->SetPen(NULL); // Disable outline skp->Rectangle(0, 0, 255, 13); skp->SetBrush(NULL); // Disable shape filling skp->SetPen(Old); } else { // MFD powered on const char* label; int x = 24; for (int bt = 0; bt < 5; bt++) { if (label = oapiMFDButtonLabel(mfd, bt)) { skp->Text(x, 1, label, strlen(label)); x += 42; } else break; } skp->Text(234, 1, "PG", 2); } oapiReleaseFont(Atlantis::font3); oapiReleaseSketchpad(skp); }
 

Attachments

  • debugerrors.jpg
    debugerrors.jpg
    63.8 KB · Views: 5
You are almost THERE!

Font releasing happens in wrong function.
Code:
oapiReleaseFont(Atlantis::font3);

The idea is following:
1) When you initialize your vessel Atlantis you also initialize additional resources including font. Than is reason why oapiCreateFont() happen in function clbkPostCreation()
2) Then you use this font in RedrawPanel_MFDButton(). This is called on every frame update. You don't need to allocate/deallocate/create/destroy/release font resource here.
3) When you don't need font anymore you must release/destroy it. Let me see in what function you need to release unneeded font.
So far I suggest to release font here (Atlantis class destructor):
Code:
Atlantis::~Atlantis () {
oapiReleaseFont (Atlantis::font1);
}

But, maybe there is better place (function) where to deallocate/release/remove font. I will check it in sample code, but little later.
 
Thanks. now getting this in debug
yPprqCw.jpg

I have this:
void Atlantis::RedrawPanel_MFDButton(SURFHANDLE surf, int mfd) { // oapi::Font* font3 = oapiCreateFont(-11, true, "Arial"); //g_Param.font[0] = CreateFont (-11, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, "Arial"); oapi::Sketchpad* skp = oapiGetSketchpad(surf); //skp->SetTextColor(BBGGRR) skp->SetFont(Atlantis::font3); skp->SetTextColor(0x00FF00); skp->SetTextAlign(oapi::Sketchpad::CENTER); if (oapiGetMFDMode(mfd) == MFD_NONE) { RECT r = { 0, 0, 255, 13 }; //skp->Rectangle(0, 0, 255, 13); //skp->SetBrush(gBlackBrush); // Enable shape filling auto Old = skp->SetPen(NULL); // Disable outline skp->Rectangle(0, 0, 255, 13); skp->SetBrush(NULL); // Disable shape filling skp->SetPen(Old); } else { // MFD powered on const char* label; int x = 24; for (int bt = 0; bt < 5; bt++) { if (label = oapiMFDButtonLabel(mfd, bt)) { skp->Text(x, 1, label, strlen(label)); x += 42; } else break; } skp->Text(234, 1, "PG", 2); } oapiReleaseSketchpad(skp); } and this:
// -------------------------------------------------------------- // Destructor // -------------------------------------------------------------- Atlantis::~Atlantis () { // UnregisterMFDMode (ascapMfdId); // if (ascentApDlg) delete ascentApDlg; // delete ascap; delete plop; int i; for (i = 0; i < 6; i++) delete rms_anim[i]; oapiReleaseFont(Atlantis::font3); }
 
Wow! This is THE ERROR!

What about ExitModule from Orbiter2016/Orbitersdk/doc/API_Guide.pdf page 2:
Code:
DLLCLBK void ExitModule (HINSTANCE hModule)
{
// perform module cleanup here
oapiReleaseFont (Atlantis::font1);
}

or this from page3:
Code:
DLLCLBK void ovcExit (VESSEL *vessel)
{
if (vessel) delete (MyVessel*)vessel;

oapiReleaseFont (Atlantis::font1);
}

But do oapiReleaseFont (Atlantis::font1); only in one function and not in all.
 
Thanks.
so I did this:
DLLCLBK void ExitModule (HINSTANCE hModule) { oapiUnregisterCustomControls (hModule); oapiDestroySurface (g_Param.tkbk_label); // deallocate GDI resources DeleteObject (g_Param.font[0]); oapiReleaseFont(Atlantis::font3); }
but get this:
Severity Code Description Project Path File Line Suppression State Error C2597 illegal reference to non-static member 'Atlantis::font3' SPACESHUTTLE2016EARLYMET D:\Orbiter2016\Orbitersdk\samples\SPACESHUTTLE2016E4evaearlyvccammoveEVAnewmfd MET D:\Orbiter2016\Orbitersdk\samples\SPACESHUTTLE2016E4evaearlyvccammoveEVAnewmfd MET\Atlantis.cpp 9335
it says that font3 is inaccessible. Is this because it is private?

Not sure what you meant by do the release font in one function and not all. I think you mean but it in the destructor and not all the redraw functions?
 
// -------------------------------------------------------------- // Vessel cleanup // -------------------------------------------------------------- DLLCLBK void ovcExit (VESSEL *vessel) { if (vessel) delete (Atlantis*)vessel; oapiReleaseFont(Atlantis::font3); }

same font3 inaccessible
 
Back
Top