こんにちは、Habr!
この記事は、私の記事をロシア語に無料で翻訳したもので、若干の変更と改良が加えられています。 SFMLでImGuiを使用することがいかにシンプルで便利かを示したいと思います。 始めましょう。
はじめに
ゲームを開発する場合、コンテンツの作成(レベルのエディター、リソースなど)とデバッグのための優れたツールを持つことが非常に重要です。 これらのものがあると、生産性と創造性が向上します。 バグをキャッチし、すでに見つかっているものを修正するのははるかに簡単です。さまざまな変数の値を表示し、それらを変更するウィジェットを作成して、特定の値でゲームがどうなるかを確認するのは簡単です。 変数を変更するためのウィジェットは、ゲームプレイを洗練するためにも非常に便利です。 たとえば、キャラクターの速度、武器のリロードの速度などを簡単に変更できます。
ゲーム用に ImGuiを使用して作成したツールは次のとおりです。
レベルエディター
Luaコンソール
アニメーションエディター
ご覧のとおり、ImGuiには便利で便利なインターフェイスを作成するのに十分な数のウィジェットがあります。
ImGuiと即時GUIコンセプト
即時モードGUIは 、 保持モードGUIと呼ばれる従来のインターフェイスプログラミング手法とは少し異なります 。 ImGuiウィジェットは、ゲームループのすべてのフレームで作成および描画されます。 ウィジェット自体は、自身の状態を内部に保存しません。または、通常はプログラマから隠されている、絶対に必要な最小値を保存します。
ボタンを作成するQtとは異なり、 QPushButton
オブジェクトを作成し、押されたときに呼び出されるコールバック関数に関連付ける必要がありますが、 QPushButton
ではすべてがはるかに簡単です。 コードを記述するだけで十分です。
if (ImGui::Button("Some Button")) { ... // , }
このコードは、ユーザーがこのボタンを使用できるようにするゲームサイクルの各反復で呼び出す必要があります。
最初は、この概念は奇妙で非常に効率が悪いように見えるかもしれませんが、他のコードと比較して非常に高速に動作するため、複雑なインターフェースでもゲームのパフォーマンスに大きな変更を加えません。
このテクニックについてもう少し知りたい場合は、ImGuiについてのこのケーシームラトリビデオをご覧ください。
ImGuiの利点は何ですか?
- MITライセンス
- 非常に高速で、ほとんどメモリを占有しない
- 絶えず更新および拡張
- 動的な割り当て/割り当て解除はほとんどありません(これは、ImGuiが必要なメモリを受け取る方法を設定することで制御できます)
- 非常に移植性が高い:さまざまなライブラリおよびプラットフォーム用の多くのバインダーがあります
- 既存のウィジェットに基づいて、またはゼロから作成された新しいウィジェットを作成することにより、非常に簡単に拡張できます。
カスタマイズ
それでは始めましょう
- 空のウィンドウを表示する簡単なSFMLプログラムを作成します。 これをまだ行っていない場合は、 チュートリアルを使用できます。
- ImGuiをダウンロードします 。
- ImGui SFMLバインディングをダウンロードし、ImGuiをダウンロードしたフォルダーに入れます。
重要 : imconfig-SFML.hの内容をimconfig.hに追加します - ImGuiフォルダーをプロジェクトのincludeディレクトリーに追加します
次のファイルをプロジェクトビルドに追加します。
- imgui.cpp
- imgui_draw.cpp
- imgui-sfml.cpp
- imgui_demo.cpp
- リンクエラーが発生した場合は、OpenGLをプロジェクトにリンクしてください。
ImGuiウィンドウを作成し、背景色とウィンドウタイトルを変更できるコードの小さな例を次に示します。 何が起こっているかの説明が続きます。
#include "imgui.h" #include "imgui-sfml.h" #include <SFML/Graphics/RenderWindow.hpp> #include <SFML/System/Clock.hpp> #include <SFML/Window/Event.hpp> int main() { sf::RenderWindow window(sf::VideoMode(640, 480), ""); window.setVerticalSyncEnabled(true); ImGui::SFML::Init(window); sf::Color bgColor; float color[3] = { 0.f, 0.f, 0.f }; // char. // std::string , char windowTitle[255] = "ImGui + SFML = <3"; window.setTitle(windowTitle); sf::Clock deltaClock; while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { ImGui::SFML::ProcessEvent(event); if (event.type == sf::Event::Closed) { window.close(); } } ImGui::SFML::Update(window, deltaClock.restart()); ImGui::Begin("Sample window"); // // if (ImGui::ColorEdit3("Background color", color)) { // , // bgColor.r = static_cast<sf::Uint8>(color[0] * 255.f); bgColor.g = static_cast<sf::Uint8>(color[1] * 255.f); bgColor.b = static_cast<sf::Uint8>(color[2] * 255.f); } ImGui::InputText("Window title", windowTitle, 255); if (ImGui::Button("Update window title")) { // , // // if(ImGui::InputText(...)) window.setTitle(windowTitle); } ImGui::End(); // end window window.clear(bgColor); // ImGui::SFML::Render(window); window.display(); } ImGui::SFML::Shutdown(); }
次のようなものが表示されるはずです。
何かを変えてみてください。 RGBフィールドの1つをダブルクリックすると、対応する値を入力できます。 フィールドの1つをプルすると、現在の入力値をスムーズに変更できます。 入力フィールドでは、ボタンをクリックした後、ウィンドウのタイトルを変更できます。
では、どのように機能するかを見てみましょう。
ImGui ImGui::SFML::Init
呼び出すと、ImGuiが初期化されます。呼び出されると、 sf::RenderWindow
ウィンドウへのリンクが関数に渡されます。 現在、標準フォントも作成されており、今後使用されます。 (他のフォントの使用方法については、imgui-sfmlの説明の「フォントの使用方法」セクションを参照してください)。
プログラムを終了するとき、ImGuiが使用するリソースを解放するImGui::SFML::Shutdown
関数を呼び出すことが重要です。
ImGuiのゲームサイクルには、更新とレンダリングの2つのフェーズがあります。
更新は、イベント処理、ImGuiのステータスの更新、およびウィジェットの更新/作成で構成されます。 イベント処理は、 ImGui::SFML::ProcessEvent
呼び出しを通じて発生します。 ImGuiは、キーボード、マウス、フォーカス、ウィンドウサイズのイベントを処理します。 ImGuiの状態はImGui::SFML::Update
、デルタ時間(2つの更新間の時間)を送信します。これはImGuiがウィジェットの状態(アニメーションなど)を更新するために使用します。 また、この関数では、 ImGui::NewFrame
、その呼び出しの後、新しいウィジェットを作成することがすでに可能です。
ImGui レンダリングは 、 ImGui::SFML::Render
呼び出すことで実行されます。 ImGui::SFML::Update
とImGui::SFML::Render
呼び出しの間にウィジェットを作成/更新することが非常に重要です。そうしないと、ImGuiは状態の違反を誓います。
入力とゲームを更新するよりも頻繁にレンダリングしない場合は、更新の各反復の終わりに、 ImGui::EndFrame
も呼び出す必要があります。
while (gameIsRunning) { while (updateIsNeeded()) { updateGame(dt); ImGui::SFML::Update(window, dt); ImGui::EndFrame(); } renderGame(); }
ウィジェットは、適切な関数( ImGui::InputInt
またはImGui::Button
)を呼び出すことで作成されます。 ImGui::ShowTestWindow
を呼び出すと、 ImGui::ShowTestWindow
の使用例が多数表示されます 。すべてのコードはimgui_demo.cppにあります。
SFMLの便利な関数オーバーロード
いくつかの関数オーバーロードがバインダーのSFML用に作成されました。たとえば、 ImGui::Image
およびImGui::ImageButton
sf::Sprite
およびsf::Texture
スローできます。
おわりに
以下にそのようなライブラリを示します。使いやすく構成しやすく、ツールの作成やデバッグに非常に便利です。 素敵な使い方をしてください!
PS興味があれば、チュートリアルの2番目の部分を翻訳できます。これは、ImGuiを最新のC ++および標準ライブラリとともに使用することについて説明しています。 ImGuiを使用する(または既に使用している)ことに注意することをお勧めします。ImGuiの主な問題を解決し、C ++ 03で行うよりも簡単で安全なものにすることがどれほど簡単かを示しています。