diff --git a/OVP/D3D9Client/D3D9Client.cpp b/OVP/D3D9Client/D3D9Client.cpp index 69a148245..27838ec32 100644 --- a/OVP/D3D9Client/D3D9Client.cpp +++ b/OVP/D3D9Client/D3D9Client.cpp @@ -1427,14 +1427,6 @@ ParticleStream *D3D9Client::clbkCreateReentryStream (PARTICLESTREAMSPEC *pss, #pragma endregion -// ============================================================== - -ScreenAnnotation* D3D9Client::clbkCreateAnnotation() -{ - _TRACE; - return GraphicsClient::clbkCreateAnnotation(); -} - #pragma region Mesh functions // ============================================================== diff --git a/OVP/D3D9Client/D3D9Client.h b/OVP/D3D9Client/D3D9Client.h index 9109f8b85..3fe4d6190 100644 --- a/OVP/D3D9Client/D3D9Client.h +++ b/OVP/D3D9Client/D3D9Client.h @@ -517,14 +517,6 @@ class D3D9Client : public GraphicsClient ParticleStream *clbkCreateReentryStream (PARTICLESTREAMSPEC *pss, OBJHANDLE hVessel); // @} - /** - * \brief Create an annotation object for displaying on-screen text. - * \return Pointer to new screen annotation object. - * \default Dynamically allocates a 'ScreenAnnotation' instance and returns - * a pointer to it. - */ - ScreenAnnotation* clbkCreateAnnotation(); - /** * \brief Render window message handler * diff --git a/Orbitersdk/include/GraphicsAPI.h b/Orbitersdk/include/GraphicsAPI.h index 9c33af69c..bcc08a516 100644 --- a/Orbitersdk/include/GraphicsAPI.h +++ b/Orbitersdk/include/GraphicsAPI.h @@ -777,14 +777,6 @@ class OAPIFUNC GraphicsClient: public Module { OBJHANDLE hVessel); // @} - /** - * \brief Create an annotation object for displaying on-screen text. - * \return Pointer to new screen annotation object. - * \default Dynamically allocates a 'ScreenAnnotation' instance and returns - * a pointer to it. - */ - virtual ScreenAnnotation *clbkCreateAnnotation (); - /** * \brief Returns the handle of the main render window. */ diff --git a/Src/Orbiter/DlgMgr.cpp b/Src/Orbiter/DlgMgr.cpp index 4baf05a33..ad20f4bee 100644 --- a/Src/Orbiter/DlgMgr.cpp +++ b/Src/Orbiter/DlgMgr.cpp @@ -568,6 +568,11 @@ void DialogManager::ImGuiNewFrame() ImGui_ImplWin32_NewFrame(); ImGui::NewFrame(); + for(auto &annotation: annotations) { + annotation->Render(); + } + + RenderNotifications(); // We can't use a range-based loop here because Display() may unregister the current dialog @@ -599,6 +604,17 @@ void DialogManager::SetMainColor(COLORREF col) ApplyGlowTheme(color); } +void DialogManager::RegisterAnnotation(oapi::ScreenAnnotation *an) +{ + annotations.push_back(an); +} + +void DialogManager::UnregisterAnnotation(oapi::ScreenAnnotation *an) +{ + annotations.remove(an); +} + + ImGuiDialog::~ImGuiDialog(){ // Make sure this dialog is no longer referenced in the DialogManager oapiCloseDialog(this); @@ -918,7 +934,6 @@ namespace ImGui { return ret; } - DLLEXPORT void PushFont(ImGuiFont f, float scale) { ImGuiContext& g = *GImGui; diff --git a/Src/Orbiter/DlgMgr.h b/Src/Orbiter/DlgMgr.h index 367725111..1ee032cb0 100644 --- a/Src/Orbiter/DlgMgr.h +++ b/Src/Orbiter/DlgMgr.h @@ -182,6 +182,8 @@ class DialogManager { ImFont *GetFont(ImGuiFont f); void SetMainColor(COLORREF col); + void RegisterAnnotation(oapi::ScreenAnnotation *); + void UnregisterAnnotation(oapi::ScreenAnnotation *); private: void InitImGui(); void ShutdownImGui(); @@ -189,6 +191,7 @@ class DialogManager { ImFont *consoleFont; ImFont *monoFont; ImFont *manuscriptFont; + std::listannotations; }; INT_PTR OrbiterDefDialogProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); diff --git a/Src/Orbiter/DlgOptions.cpp b/Src/Orbiter/DlgOptions.cpp index 7ce37ed48..2d2f27cb6 100644 --- a/Src/Orbiter/DlgOptions.cpp +++ b/Src/Orbiter/DlgOptions.cpp @@ -499,7 +499,7 @@ void DlgOptions::DrawAxes() ImGui::BeginChild("##right"); ImGui::SeparatorText("Display"); ImGui::CheckboxFlags("Show negative axis", &prm.flagFrameAxes, FAV_NEGATIVE); - ImGui::BeginDisabled(!(prm.flagFrameAxes, FAV_NEGATIVE)); + ImGui::BeginDisabled(!(prm.flagFrameAxes & FAV_NEGATIVE)); ImGui::SliderFloat("Scale", &prm.scaleFrameAxes, 0.25, 4.0, "%0.2f", ImGuiSliderFlags_AlwaysClamp); ImGui::SliderFloat("Opacity", &prm.opacFrameAxes, 0.0, 1.0, "%0.2f", ImGuiSliderFlags_AlwaysClamp); ImGui::EndDisabled(); diff --git a/Src/Orbiter/GraphicsAPI.cpp b/Src/Orbiter/GraphicsAPI.cpp index 4681cfbe6..78609332d 100644 --- a/Src/Orbiter/GraphicsAPI.cpp +++ b/Src/Orbiter/GraphicsAPI.cpp @@ -168,13 +168,6 @@ ParticleStream *GraphicsClient::clbkCreateReentryStream (PARTICLESTREAMSPEC *pss // ====================================================================== -ScreenAnnotation *GraphicsClient::clbkCreateAnnotation () -{ - TRACENEW; return new ScreenAnnotation (this); -} - -// ====================================================================== - bool GraphicsClient::TexturePath (const char *fname, char *path) const { // first try htex directory @@ -796,15 +789,20 @@ ScreenAnnotation::ScreenAnnotation (GraphicsClient *_gc) buflen = 0; txtscale = 0; font = NULL; - //hFont = NULL; Reset(); + DialogManager *dlg = g_pOrbiter->DlgMgr(); + if(dlg) { + dlg->RegisterAnnotation(this); + } } ScreenAnnotation::~ScreenAnnotation () { + DialogManager *dlg = g_pOrbiter->DlgMgr(); + if(dlg) { + dlg->UnregisterAnnotation(this); + } if (txt) delete[]txt; - if (font) gc->clbkReleaseFont (font); - //DeleteObject (hFont); } void ScreenAnnotation::Reset () @@ -847,11 +845,9 @@ void ScreenAnnotation::SetSize (double scale) { if (scale != txtscale) { txtscale = scale; - hf = (int)(viewH*txtscale/35.0); - if (font) gc->clbkReleaseFont (font); - font = gc->clbkCreateFont (-hf, true, "Sans"); - //if (hFont) DeleteObject (hFont); - //hFont = CreateFont (-hf, 0, 0, 0, 400, 0, 0, 0, 0, 3, 2, 1, 49, "Arial"); + // The size in CreateFont was the cell size whereas in ImGui it's the glyph size + // We multiply by 1.15 for it to look about the same as before + hf = (int)(viewH*txtscale/35.0*1.15); } } @@ -860,24 +856,38 @@ void ScreenAnnotation::SetColour (const VECTOR3 &col) int r = min (255, (int)(col.x*256.0)); int g = min (255, (int)(col.y*256.0)); int b = min (255, (int)(col.z*256.0)); - txtcol = r | (g << 8) | (b << 16); - txtcol2 = (r/2) | ((g/2) << 8) | ((b/2) << 16); + // Reuse COLORREF since it's also 32bit and we don't want to change the API + txtcol = IM_COL32(r,g,b,255); + txtcol2 = IM_COL32(r/2,g/2,b/2,255); } void ScreenAnnotation::Render () { - if (!txtlen) return; - - Sketchpad *skp = gc->clbkGetSketchpad (0); - if (skp) { - skp->SetFont (font); - skp->SetTextColor (txtcol2); - skp->SetBackgroundMode (oapi::Sketchpad::BK_TRANSPARENT); - skp->TextBox (nx1+1, ny1+1, nx2+1, ny2+1, txt, txtlen); - skp->SetTextColor (txtcol); - skp->TextBox (nx1, ny1, nx2, ny2, txt, txtlen); - gc->clbkReleaseSketchpad (skp); - } + if (!txtlen) + return; + + ImGuiViewport* vp = ImGui::GetMainViewport(); + ImDrawList* draw = ImGui::GetBackgroundDrawList(vp); + ImFont* font = ImGui::GetFont(); + ImVec2 pos(vp->Pos.x + nx1, vp->Pos.y + ny1); + + // Outline (1px offset) + draw->AddText( + font, + hf, + ImVec2(pos.x + 1, pos.y + 1), + txtcol2, + txt, 0, nw + ); + + // Normal text + draw->AddText( + font, + hf, + pos, + txtcol, + txt, 0, nw + ); } // ====================================================================== diff --git a/Src/Orbiter/Orbiter.cpp b/Src/Orbiter/Orbiter.cpp index 101d4ccc3..7c3c525d1 100644 --- a/Src/Orbiter/Orbiter.cpp +++ b/Src/Orbiter/Orbiter.cpp @@ -166,6 +166,18 @@ int _matherr(struct _exception *except ) } +// Hacky class to handle playback annotations without breaking the old ABI +class PlaybackAnnotation: public ScreenAnnotation +{ + public: + PlaybackAnnotation(GraphicsClient *_gc): ScreenAnnotation(_gc) {} + void Render() override { + if(g_pOrbiter->Cfg()->CfgRecPlayPrm.bShowNotes) { + ScreenAnnotation::Render(); + } + } +}; + // ======================================================================= // WinMain() // Application entry containing message loop @@ -744,7 +756,7 @@ HWND Orbiter::CreateRenderWindow (Config *pCfg, const char *scenario) pDlgMgr->AddEntry(g_input); // playback screen annotation manager - snote_playback = gclient->clbkCreateAnnotation (); + snote_playback = new PlaybackAnnotation(gclient); } else { pDlgMgr = new DialogManager(this, m_pConsole->WindowHandle()); @@ -1581,7 +1593,7 @@ void Orbiter::EndPlayback () oapi::ScreenAnnotation *Orbiter::CreateAnnotation (bool exclusive, double size, COLORREF col) { if (!gclient) return NULL; - oapi::ScreenAnnotation *sn = gclient->clbkCreateAnnotation(); + oapi::ScreenAnnotation *sn = new ScreenAnnotation(gclient); if (!sn) return NULL; sn->SetSize (size); @@ -1597,22 +1609,6 @@ oapi::ScreenAnnotation *Orbiter::CreateAnnotation (bool exclusive, double size, snote = tmp; snote[nsnote++] = sn; return sn; - - //DWORD w = oclient->GetFramework()->GetRenderWidth(); - //DWORD h = oclient->GetFramework()->GetRenderHeight(); - - //ScreenNote *sn = new ScreenNote (this, w, h); - //sn->SetSize (size); - //sn->SetColour (col); - - //ScreenNote **tmp = new ScreenNote*[nsnote+1]; - //if (nsnote) { - // memcpy (tmp, snote, nsnote*sizeof(ScreenNote*)); - // delete []snote; - //} - //snote = tmp; - //snote[nsnote++] = sn; - //return sn; } bool Orbiter::DeleteAnnotation (oapi::ScreenAnnotation *sn) @@ -1742,11 +1738,6 @@ const Mesh *Orbiter::LoadMeshGlobal (const char *fname, LoadMeshClbkFunc fClbk) VOID Orbiter::Output2DData () { g_pane->Draw (); - if (g_pane) { - for (DWORD i = 0; i < nsnote; i++) - snote[i]->Render(); - if (snote_playback && pConfig->CfgRecPlayPrm.bShowNotes) snote_playback->Render(); - } } //-----------------------------------------------------------------------------