Pular para o conteúdo principal

SDL3 com Visual Studio, git submodule, e GitHub Workflow

· 11 min para ler

Após minha graduação em Ciência da Computação, iniciei uma pós-graduação em Produção e Programação de Jogos com o objetivo de mudar minha carreira e entrar na indústria de jogos. Isso foi em 2009, e uma das primeiras ferramentas de desenvolvimento de jogos que tive contato foi o SDL2, onde fiz o meu primeiro projeto de game com SDL e C++ em uma disciplina da pós-graduação. De lá pra cá utilizei o SDL em diversos projetos, principalmente game jams e para aprender a programar homebrew para Nintendo DS e PSP, e sempre foi um framework fácil de usar e bem completo para jogos 2D.

Criar um projeto novo utilizando Visual Studio e configurar o SDL2 era um pouco mais trabalhoso, e inclusive escrevi este tutorial pra mim mesmo por que eu sempre esquecia de algum passo. Alguns meses atrás, o SDL3 foi oficialmente lançado, e trouxe algumas mudanças para simplificar o desenvolvimento de jogos e sua configuração. Neste post vou mostrar como criar um projeto novo no Visual Studio, adicionar o SDL3 como uma dependência usando git submodule, configurar o projeto para compilar um Hello World, e como automatizar builds em cada commit utilizando GitHub Workflows.

SDL como dependência usando git submodule

A parte mais importante de todo este post é este primeiro passo, pois aqui vamos configurar o projeto como um repositório git e adicionar o SDL3 como um submodule. Existem diversos conteúdos muito bons sobre git, então não vou alongar muito com uma introdução, e vamos direto ao ponto. Caso não tenha git na sua máquina, você pode instalar aqui.

Primeiro, precisamos criar um repositório local. Os comandos abaixo são os mesmos em qualquer sistema operacional, mas como vamos utilizar o Visual Studio neste tutorial, pode assumir que estou utilizando Windows. Criei um novo diretório no seu computador com o nome HelloWorldSDL3. Após criar o diretório, abra o prompt de comandos do Windows (cmd ou power shell), nave até a nova pasta criada e, dentro dela, execute o comando abaixo:

git init

Este commando vai criar uma pasta invisível chamada .git. Caso algum erro aconteça, como comando não encontrado, certifique-se que o git foi instalado e está adicionado no path do Windows. Em seguida, vamos adicionar o repositório do SDL como um submodule usando os comandos abaixo:

git submodule add https://github.com/libsdl-org/SDL.git SDL

Este comando vai adicionar um arquivo .gitmodules com uma referência do SDL no repositório local, e baixar o projeto em uma pasta chamada SDL. Se tudo der certo, seu diretório deverá estar com esta estrutura abaixo:

HelloWorldSDL3/
├── .git/
├── SDL/
└── .gitmodules

Neste momento você pode criar um repositório no GitHub (necessário criar uma conta gratuita se não tiver). No meu exemplo abaixo, estou criando um repositório público com o nome hello-world-sdl, e não selecionei nenhuma opção para inicializar o repositório com algum arquivo.

Depois de criar o repositório, volte para o prompt de comandos e digite os seguintes comandos (substitua USERNAME pelo seu usuário no github):

git add .
git commit -m "SDL submodule"
git branch -M main
git remote add origin https://github.com/USERNAME/hello-world-sdl.git
git push -u origin main

E, após executar os comandos acima com sucesso, o seu repositório estará parecido com o meu na imagem abaixo:

Isso é tudo que precisamos por agora, mas vamos voltar ao github no final deste post para configurar a automação de compilação no GitHub Workflow.

Criação de um projeto no Visual Studio

O SDL3 tem uma documentação bem simples e fácil de seguir. A configuração do projeto no Visual Studio pode ser vista aqui, porém vou adicionar os passos em português abaixo com algumas modificações que fiz.

A principal diferença é que, ao invés de fazer o download do código fonte, nós vamos usar o submodule que configuramos no passo anterior em nosso repositório git.

Novo projeto no Visual Studio

O Visual Studio 2022 (ou mais novo) pode ser baixado aqui, e a versão Community é gratuita para desenvolvedores solo, uso acadêmico, ou projetos open source. Siga os passos do instalador e lembre de marcar as opções para adicionar Desktop Development with C++ (você também pode marcar as opções de Unity e game development mas não são necessárias para o SDL).

Depois de instalado, selecione a opção Create a new project e procure por Empty Project com C++, como na imagem abaixo. Se você não estiver vendo essa opção, volte no instalador e veja se as opções de suporte ao C++ foram instaladas no Visual Studio.

Após selecionar Empty Project com C++, na próxima janela digite HelloGame em Project name, e no campo Location selecione o caminho em que está o repositório que criamos no início deste post. As configurações do novo projeto devem estar iguais a imagem abaixo.

Depois de criar o novo projeto no Visual Studio, esta é a estrutura do nosso repositório atualizada:

HelloWorldSDL3/
├── .git/
├── HelloGame/
├── SDL/
└── .gitmodules

Adicionando código

Agora que temos um projeto em branco, vamos adicionar um arquivo de C++ e configurar o projeto para utilizar o SDL que está no mesmo diretório. É importante adicionar um arquivo de código fonte em C++ antes de continuar por que isso vai habilitar as opções que vamos configurar mais pra frente.

Clique com o botão direito no projeto HelloGame e, em seguida, selecione a opção Add | New Item... e digite main.cpp. No novo arquivo criado, copie e cole o código abaixo. Não se preocupe com os erros de compilação agora, nós ainda vamos configurar o projeto para localizar o SDL e poder compilar com sucesso.

#define SDL_MAIN_USE_CALLBACKS 1
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>

static SDL_Window* window = NULL;
static SDL_Renderer* renderer = NULL;

SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[])
{
if (!SDL_CreateWindowAndRenderer("Hello World", 800, 600, SDL_WINDOW_MAXIMIZED, &window, &renderer)) {
SDL_Log("Couldn't create window and renderer: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
return SDL_APP_CONTINUE;
}

SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
{
if (event->type == SDL_EVENT_KEY_DOWN ||
event->type == SDL_EVENT_QUIT) {
return SDL_APP_SUCCESS;
}
return SDL_APP_CONTINUE;
}

SDL_AppResult SDL_AppIterate(void* appstate)
{
const char* message = "Hello World!";
int w = 0, h = 0;
float x, y;
const float scale = 4.0f;

SDL_GetRenderOutputSize(renderer, &w, &h);
SDL_SetRenderScale(renderer, scale, scale);
x = ((w / scale) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * SDL_strlen(message)) / 2;
y = ((h / scale) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) / 2;

SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderDebugText(renderer, x, y, message);
SDL_RenderPresent(renderer);

return SDL_APP_CONTINUE;
}

void SDL_AppQuit(void* appstate, SDL_AppResult result)
{
}

O código acima é uma variação do hello.c disponibilizado no repositório do SDL. As mudanças que fiz foram mudar a extensão para .cpp, remover os comentários para não ficar tão longo aqui, e configurar a janela usando SDL_WINDOW_MAXIMIZED (modo janela) ao invés do original que criava a janela em modo tela cheia.

Adicionando SDL como dependência

Agora vamos adicionar o SDL no Visual Studio junto com o nosso projeto. Para isso, clique com o botão direito na Solution 'HelloGame', selecione Add | Existing Project e, na nova janela navegue até SDL/VisualC/SDL (dentro do nosso repositório), e selecione o arquivo SDL.vcxproj. Depois de adicionar o projeto SDL junto ao nosso projeto HelloGame, você deve ter a estrutura abaixo no Visual Studio:

O próximo passo agora é adicionar o SDL como uma referência no projeto HelloGame. Cliquei com o botão direito no projeto HelloGame, selecione Add | Reference... e, na nova janela, selecione o projeto SDL e clique em OK. Isso vai garantir que o nosso projeto use o SDL como uma dependência para compilar o código.

Por fim, vamos adicionar os headers do SDL na configuração do nosso projeto. Para isso, clique com o botão direto no projeto HelloGame e selecione a opção Properties. Na nova janela, mude o filtro acima para All Configurations e All Platforms (se já não estiver assim). Em seguida, expanda a opção C/C++ no menu da esquerda, selecione General, e no primeiro campo Additional Include Directories, selecione Edit e adicione o caminho SDL/includes (dentro do nosso repositório).

A imagem baixo mostra como a configuração deste janela deve estar depois dos passos acima:

Rodando o projeto

Se tudo deu certo, agora basta rodar o projeto no Visual Studio utilizando o botão play verde ou pressionando F5, e você deverá ver a tela abaixo:

Caso encontre algum erro, dê uma revisada nos passos anteriores e compare as imagens que adicionei no post para ajudar. Se mesmo assim tiver dúvidas ou problemas, deixe um comentário que tentarei ajudar assim que possível.

Nós temos um repositório configurado no GitHub com o SDL adicionado como uma dependência e também o nosso projeto configurado para rodar no Visual Studio. O próximo passo agora é um extra, mas que com certeza vai ajudar o desenvolvimento ao médio e longo prazo.

Automação com GitHub Workflow

Automação é algo muito comum e essencial em empresas, não só em jogos. A automação pode ser desde rodar alguns testes unitários, compilar o projeto, e até rodar o jogo em um teste pré-definido. Para isso, muitas vezes precisamos de outras máquinas ou até servidores dedicados a rodar nosso projeto sempre que precisar de um teste, ou até mesmo a cada alteração.

É ai que entra o GitHub Workflow, onde podemos automatizar muita coisa no nosso repositório utilizando servidores Windows, Linux e macOS do GitHub. Existem alguns limites, mas mesmo uma conta gratuita tem o suficiente para bastante coisa em projetos pequenos e até médios. Você também pode registrar uma máquina sua como servidor e não se preocupar com limites (já fiz isso com um raspberry pi e funcionou bem para projetos pequenos!).

Não vou entrar em muitos detalhes sobre o GitHub Workflow em si, por que é algo muito grande e complexo de explicar tudo, mas recomendo dar uma olhada na documentação e pesquisar sobre também.

Para adicionar suporte a automação em nosso projeto, precisamos apenas adicionar um arquivo no repositório. No repositório, cria uma nova pasta .github e outra pasta dentro dela chamada workflows. Dentro da pasta workflows, adicione um novo arquivo chamado msbuild.yml. Seu repositório deve estar assim:

HelloWorldSDL3/
├── .git/
├── .github/workflows/msbuild.yml
├── HelloGame/
├── SDL/
└── .gitmodules

Por fim, abra o arquivo msbuild.yml em qualquer editor e copie e cole o conteúdo abaixo:

name: MSBuild

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
SOLUTION_FILE_PATH: ./HelloGame
BUILD_CONFIGURATION: Release

permissions:
contents: read

jobs:
build:
runs-on: windows-latest

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.0.2

- name: Restore NuGet packages
working-directory: ${{env.GITHUB_WORKSPACE}}
run: nuget restore ${{env.SOLUTION_FILE_PATH}}

- name: Build
working-directory: ${{env.GITHUB_WORKSPACE}}
run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}

- name: Upload a Build Artifact
uses: actions/upload-artifact@v4.6.2
with:
name: hellogame-x64-release
path: ./HelloGame/x64/Release/

O arquivo acima parece um pouco confuso, mas se você ler cada linha vai começar a fazer sentido:

  • Este workflow roda quando commits forem adicionados no branch main ou quando tiver um pull request para ele.
  • O nosso env está configurado com o caminho do projeto HelloGame e a build Release.
  • O job vai rodar em máquinas windows.
  • Estamos utilizando msbuild para compilar o projeto pela linha de comando (já que é um servidor sem interface).
  • Depois de compilar, a build do jogo vai ficar arquivada como um artefato deste workflow.

Assim que adicionarmos esse arquivo no repositório e fizermos um commit para o branch main, este workflow vai rodar em gerar uma build que podemos baixar e testar, e vai estar no menu Actions do repositório no GitHub.

Além disso, é possível ver todo o processo de compilação e os logs do servidor. Caso algum erro aconteça, é lá que você vai entender o por que.

Conclusão

Este post demorou um pouco mais do que planejei para escrever, e ficou mais longo do que imaginei, mas acho que no fim é uma boa introdução de como criar um projeto novo usando SDL3, configurar o Visual Studio, e ainda como usar git submodule e GitHub Workflows para automação.

Tudo que fiz neste post pode ser visto no meu repositório público hello-worlds-sdl3. Fique a vontade para usar este repositório como um template ou base para o seu projeto, este é um dos motivos que fiz para mim mesmo.

Muito obrigado se você leu até o final, e espero que tenha sido útil. Qualquer dúvida, problemas no passo-a-passo, ou sugestões deixe um comentário abaixo.