Configuring and creating a GUI with ImGui and SFML in C++

n1njasec
6 min readDec 2, 2022

--

Estarei ensinando como fazer uma boa configuração do ImGui para criação de projetos C++. Esse artigo é para o público que utiliza Linux, portanto, não procure basear seu projeto no Windows utilizando este artigo!

Primeiro de tudo, é necessário que você esteja em um ambiente Linux e tenha o VsCode instalado ou qualquer outro editor de texto. (Pode ser Vim, Nano, Emacs…)

Primeiro de tudo, faça a instalação do SFML na sua máquina. Se o seu sistema operacional for baseado nas distribuições que eu coloquei, então utilize os comandos certos.

Debian/Ubuntu:
- sudo apt-get install libsfml-dev

Arch Linux:
- sudo pacman -S sfml

CentOS:
- yum install sfml

Perfeito! Depois de ter instalado o SFML, é hora de fazer a instalação do ImGui e ImGui-SFML. Para isso, instale o Git na sua máquina, mas caso já o tenha, é hora de criar o ambiente.

Siga os meus passos:

cd /home/$USER; mkdir CPProject; cd CPProject; mkdir Gui
git clone
https://github.com/eliasdaler/imgui-sfml
git clone
https://github.com/ocornut/imgui

Agora, dentro do diretório Gui que foi criado, crie um outro diretório chamado “includes” ou então copie o comando abaixo:

cd /home/$USER/CPProject/Gui; mkdir includes

Copie os seguintes arquivos e cole dentro do diretório “includes”.

Primeiros arquivos são do ImGui:

Os arquivos estão em cor verde.

Cole-os dentro do “includes” que foi criado dentro do diretório Gui.

Agora faça o mesmo para o ImGui-SFML. Entre no “imgui-sfml” e copie os seguintes arquivos:

Os arquivos estão em cor verde.

Cole-os dentro do diretório “Includes”.

  • O seu diretório includes deve ficar desse jeito:

Perfeito! Depois de ter configurado os arquivos dentro do diretório “includes”, é hora de criarmos o nosso Makefile.

Seu arquivo Makefile tem que ficar da mesma forma que o meu para que não tenha nenhum problema.

Código:

TARGET=particle
CXX=g++ -std=c++11
DEBUG=-g
OPT=-O0
WARN=-Wall
SFML=-lsfml-graphics -lsfml-window -lsfml-system
OPENGL=-lGL
CXXFLAGS=$(DEBUG) $(OPT) $(WARN) $(SFML) $(OPENGL)
LD=g++
OBJS= main.o gui.o imgui.o imgui_draw.o imgui-SFML.o imgui_tables.o imgui_widgets.o
all: $(OBJS)
$(LD) -o $(TARGET) $(OBJS) $(CXXFLAGS)
@rm *.o
@./$(TARGET)

main.o: main.cpp
$(CXX) -c $(CXXFLAGS) main.cpp -o main.o

gui.o: gui.cpp
$(CXX) -c $(CXXFLAGS) gui.cpp -o gui.o

imgui.o: includes/imgui.cpp
$(CXX) -c $(DEBUG) $(OPT) includes/imgui.cpp -o imgui.o

imgui_draw.o: includes/imgui_draw.cpp
$(CXX) -c $(DEBUG) $(OPT) includes/imgui_draw.cpp -o imgui_draw.o

imgui-SFML.o: includes/imgui-SFML.cpp
$(CXX) -c $(DEBUG) $(OPT) includes/imgui-SFML.cpp -o imgui-SFML.o

imgui_tables.o: includes/imgui_tables.cpp
$(CXX) -c $(DEBUG) $(OPT) includes/imgui_tables.cpp -o imgui_tables.o

imgui_widgets.o: includes/imgui_widgets.cpp
$(CXX) -c $(DEBUG) $(OPT) includes/imgui_widgets.cpp -o imgui_widgets.o


Agora vamos para a parte mais legal! Sim, vamos finalmente escrever o nosso programa :)

Bom, para isso, a minha recomendação é que você utilize o Visual Studio Code, mas cabe a você decidir o que é melhor para você.

  • Criando o Header File

Agora vá até o diretório Gui e crie os seguintes arquivos:
- gui.hpp — Header File
- gui.cpp — Functions File
- main.cpp — Main File

Ou então, copie e cole o comando seguinte no terminal:

cd /home/$USER/CPProject/Gui; touch gui.cpp gui.hpp main.cpp

Pronto, depois de ter configurado os arquivos, é hora de escrever o Header File. Você não precisa dar-se ao trabalho de escrever o Header File desse projeto, pois vou disponibilizar logo abaixo:

  • gui.hpp
#pragma once

#include "includes/imgui.h"
#include "includes/imgui-SFML.h"

#include <SFML/Graphics.hpp>
#include <memory>

class Gui {
public:
struct iGui {
sf::Vector2f velocity;
int lifetime;
};

std::shared_ptr<sf::RenderWindow> window;
std::vector<iGui> m_particles;
sf::VertexArray verticles;
sf::Color color;
float size, x, y;
std::size_t count;

void reset_gui_effect();
void reset_effect(std::size_t, bool);
void update();

Gui();
void run();
};

Apenas copie e cole este código dentro do arquivo gui.hpp

  • Criando o Functions File

Agora é hora de criar as funções do nosso projeto. Dentro do arquivo gui.cpp, copie e cole o código abaixo:

  • gui.cpp
#include "gui.hpp"

Gui::Gui() {
count = 1024;
size = 8;

window = std::make_shared<sf::RenderWindow>(
sf::VideoMode(1360, 768),
"Gui System Effect",
sf::Style::Titlebar | sf::Style::Close
);
window->setFramerateLimit(60);
window->setPosition(sf::Vector2i(0,0));
ImGui::SFML::Init(*window);

x = static_cast<float>(window->getSize().x) / 2;
y = static_cast<float>(window->getSize().y) / 2;

reset_gui_effect();
}

void Gui::reset_gui_effect() {
m_particles = std::vector<iGui>(count);
vertices = sf::VertexArray(sf::Quads, count * 4);

for(std::size_t i{}; i < m_particles.size(); ++i){
reset_effect(i, true);
}
}

void Gui::reset_effect(std::size_t index, bool start =false){
vertices[4 * index + 0 ].position = sf::Vector2f(x,y);
vertices[4 * index + 1 ].position = sf::Vector2f(x + size,y);
vertices[4 * index + 2 ].position = sf::Vector2f(x + size, y + size);
vertices[4 * index + 3 ].position = sf::Vector2f(x,y + size);

if(start){
color.a = 0;
}

for(std::size_t i{}; i < 4; ++i){
vertices[4 * index + i].color = color;
}

sf::Vector2f pos = {
static_cast<float>(rand()) / (float)RAND_MAX * 8 - 4,
static_cast<float>(rand()) / (float)RAND_MAX * 8 - 4
};

m_particles[index].velocity = pos;
m_particles[index].lifetime = 30 + rand() % 60;
}

void Gui::update() {
for(std::size_t i{}; i < m_particles.size(); ++i){
if(m_particles[i].lifetime == 0){
reset_effect(i);
}
vertices[4 * i + 0].position += m_particles[i].velocity;
vertices[4 * i + 1].position += m_particles[i].velocity;
vertices[4 * i + 2].position += m_particles[i].velocity;
vertices[4 * i + 3].position += m_particles[i].velocity;
--m_particles[i].lifetime;
}
}

void Gui::run() {
sf::Clock clock;
float imcolor[4] = { (float)0 / 255, (float)255 / 255, (float)64 / 255, (float)64 / 255 };
int imsize = size;
int imx = x, imy = y;
while(window->isOpen()){
sf::Event e;
while(window->pollEvent(e)) {
ImGui::SFML::ProcessEvent(*window, e);
if(e.type == sf::Event::Closed) {
window->close();
}
}

ImGui::SFML::Update(*window, clock.restart());

ImGui::Begin("Gui Effect System");
ImGui::Button("Particle System");
ImGui::ColorEdit4("Particle Color", imcolor);
ImGui::SliderInt("Size", &imsize, 2, 40);
ImGui::SliderInt("Position x", &imx, 0, 1360);
ImGui::SliderInt("Position y", &imy, 0, 768);
ImGui::End();

x = imx;
y = imy;
size = imsize;

color = sf::Color(
(int)(imcolor[0] * 255),
(int)(imcolor[1] * 255),
(int)(imcolor[2] * 255),
(int)(imcolor[3] * 255)
);

update();

window->clear(sf::Color::Black);
window->draw(vertices);
ImGui::SFML::Render(*window);
window->display();
}

ImGui::SFML::Shutdown();
}
  • Criando o Main File

Assim como tens feito com os códigos acima, faça o mesmo com o código da main:

#include "gui.hpp"

int main() {
auto eGui = std::make_shared<Gui>();
eGui->run();
return 0;
}

Bom, depois de ter feito tudo isso, chegou a hora de compilar o nosso programa! Antes de tudo, precisamos dar um último ajuste dentro do arquivo “imgui-SFML.cpp” que se encontra dentro do diretório “includes”.

Vá até faça a seguinte modificação:

Para:

Você apenas modificará o include removendo as <> e incluindo “” para não resultar em problemas na hora da compilação. Isso acontece porque a lib imgui não se encontra instalada no sistema, portanto o uso de <> resultará em erro.

Enfim, chegou a parte legal! É hora de compilar tudo e iniciar o nosso programa! Para isso, dentro do seu terminal, digite o comando make ou então copie e cole o seguinte comando abaixo:

cd /home/$USER/CPProject/Gui; make

O código será compilado e automaticamente o programa será aberto! Confira os prints :)

:D Sim, funcionou perfeitamente aqui e funcionará no seu também! Caso você conseguiu acompanhar este artigo sem ter algum problema para executar todos os passos, eu digo que você está apto para criar novos projetos utilizando o ImGui. Mas caso você não tenha conseguido acompanhar, não se sinta triste, eu preparei um script em bash para que você apenas execute-o em seu terminal e automágicamente todo esse processo será feito sozinho! (Sim, eu deixei você saber da existência desse script no final do artigo hahaha existem preguiçosos que não gostam de ler! :D)

Script: Repositório

  • Agradeço a todos por terem lido este artigo e espero que tenham adquirido bastante conhecimento! Vejo vocês no próximo post :)

#L1za left…

--

--

n1njasec
n1njasec

Written by n1njasec

Apenas um brasileiro apaixonado por hacking

No responses yet