Preparando o ambiente de desenvolvimento
Antes de começarmos a desenvolver aplicativos com Vulkan e Qt, precisamos fazer alguns preparativos. Primeiro, precisamos instalar o Vulkan SDK. Para fazer isso, devemos acessar https://vulkan.lunarg.com/, baixar o arquivo que corresponde ao nosso sistema operacional em uso e executar ou descompactar esse arquivo. Precisamos examinar o arquivo Getting_Started.html na pasta de instalação para ver se devemos executar alguma ação adicional.
Em seguida, precisamos de uma compilação do Qt com o suporte Vulkan; deve ser Qt 5.10 ou posterior. Se o sistema operacional em uso for macOS, precisaremos do Qt 5.12 ou posterior. Se foi instalada a versão mais recente disponível através do instalador, ela já pode ser adequada.
O primeiro passo para desenvolver um aplicativo com o Qt Creator é criar um projeto usando um dos modelos fornecidos pela IDE.
No menu File do Qt Creator, escolhemos New File or Project ou clicamos no botão + New Project na janela principal. Existem vários tipos de projetos para escolher. Iremos seguir as etapas fornecidas para criar um projeto Qt Desktop:
1. Iremos criar um aplicativo baseado em widget1, para isso, escolhemos o grupo Application e o template Qt Widgets Application, conforme mostrado na figura a seguir:

1 Um widget é um fragmento da interface do usuário com aparência e comportamento específicos. O Qt fornece muitos widgets integrados que são amplamente utilizados em aplicativos: rótulos, caixas de texto, caixas de seleção, botões e assim por diante. Cada um desses widgets é representado como uma instância de uma classe C++ derivada de
QWidget
e fornece métodos para ler e gravar o conteúdo do widget. Também podemos criar nossos próprios widgets com conteúdo e comportamento personalizados.
2. O próximo passo é escolher um nome e local para o nosso novo projeto:

3. Vamos criar um aplicativo Vulkan simples, então nomearemos nosso projeto
myqtvkproject
e forneceremos um local apropriado para ele.
4. Em seguida, precisamos selecionar o kit (ou vários kits) que desejamos usar com o projeto. Devemos selecionar o kit Desktop Qt correspondente à versão do Qt 5.10 ou superior:

5. Agora seremos apresentados com a opção de criar o primeiro widget para o nosso projeto. Queremos criar um widget que represente a janela principal do nosso aplicativo, portanto, selecionamos Base class como
QWidget
e alteramos o campo Class name para “MainWindow”. Nós também queremos o uso do editor de interface gráfica para editar o conteúdo da janela principal, portanto, o Generate form deve ser deixado marcado:

6. Em seguida, clicamos em Next e Finish.
O SDK Vulkan também exige que definamos algumas variáveis de ambiente, como VULKAN_SDK
, PATH
, LD_LIBRARY_PATH
e VK_LAYER_PATH
(nomes e valores exatos podem depender do sistema operacional, por isso devemos consultar a documentação do SDK). Podemos editar variáveis de ambiente para o nosso projeto, alternando para o painel Projects do Qt Creator e expandindo a seção Build Environment.
O Qt Creator criou um novo subdiretório no diretório que foi escolhido anteriormente para a localização do projeto. Esse novo diretório (o diretório do projeto) agora contém vários arquivos. Podemos usar o painel Edit em seguida selecionar Projects na parte superior para listar e abrir esses arquivos. Vamos entender cada um desses arquivos.
O arquivo main.cpp
contém uma implementação da função main()
, o ponto de entrada do aplicativo, como mostra o código a seguir:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
A função main()
cria uma instância da classe QApplication
e a fornece as variáveis contendo os argumentos da linha de comando. Em seguida, instancia nossa classe MainWindow
, chama seu método show()
e, finalmente, retorna um valor retornado pela função exec()
do objeto do aplicativo.
QApplication
é uma classe singleton que gerencia o aplicativo inteiro. Em particular, é responsável pelo processamento de eventos que vêm de dentro do aplicativo ou de fontes externas. Para que os eventos sejam processados, um loop de eventos precisa estar em execução. O loop aguarda os eventos de entrada e os envia para as rotinas apropriadas.
A chamada exec()
em QApplication
(ou, para ser mais específico, em sua classe base – QCoreApplication
) é responsável por inserir o loop de eventos principal do aplicativo. A função não retorna até que seu aplicativo solicite que o loop de eventos seja finalizado. Quando isso acontece, a função principal retorna e seu aplicativo é finalizado.
Os arquivos mainwindow.h
e mainwindow.cpp
implementam a classe MainWindow
. Por enquanto, quase não há código neles. A classe é derivada de QWidget
, portanto, herda muitos métodos e comportamentos de sua classe base. Na declaração desta classe, notamos a macro Q_OBJECT
do Qt. Esta macro é obrigatória para qualquer classe que implemente o conceito de sinais e slots (signals and slots) do Qt (trataremos sobre isso em uma seção futura). Ela também contém um campo Ui::MainWindow * ui
, que é inicializado no construtor e excluído no destrutor. O construtor também chama a função ui->setupUi(this)
.
Ui::MainWindow
é uma classe gerada automaticamente, portanto não há declaração dela no código fonte. Ela será criada no diretório de build
quando o projeto for compilado. O objetivo dessa classe é configurar nosso widget e preenchê-lo com conteúdo baseado em mudanças no editor de formulários. A classe gerada automaticamente não é um QWidget
. Na verdade, ela contém apenas dois métodos: setupUi
, que executa a configuração inicial e retranslateUi
, que atualiza o texto visível quando o idioma da interface do usuário é alterado. Todos os widgets e outros objetos adicionados no editor de formulários estão disponíveis como campos públicos da classe Ui::MainWindow
, para que possamos acessá-los a partir de um método de MainWindow
como ui->nomeDoObjeto
.
mainwindow.ui
é um arquivo de formulário que pode ser editado no editor de formulários. Se abrirmos esse arquivo no Qt Creator clicando duas vezes nele no painel Projects, o Qt Creator mudará para o modo Design. Se voltarmos ao modo Editor, veremos que esse arquivo é, na verdade, um arquivo XML contendo a hierarquia e as propriedades de todos os objetos editados no modo Design. Durante a compilação do projeto, uma ferramenta especial chamada User Interface Compiler converte esse arquivo XML para a implementação da classe Ui::MainWindow
usada na classe MainWindow
.
O último arquivo gerado é chamado myqtvkproject.pro
e é o arquivo de configuração do projeto. Ele contém todas as informações necessárias para compilar nosso projeto usando as ferramentas que o Qt fornece. Vamos analisar este arquivo (diretivas menos importantes são omitidas):
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = myqtvkproject
TEMPLATE = app
CONFIG += c++11
SOURCES += main.cpp mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
As duas primeiras linhas habilitam os módulos core
, gui
e widgets
do Qt. A variável TARGET
contém o nome do executável produzido (myqtvkproject
). A variável TEMPLATE
é usada para especificar que nosso arquivo de projeto descreve um aplicativo (em oposição a, por exemplo, uma biblioteca). A variável CONFIG
informa ao sistema de compilação para usar os recursos do C++11 (como expressões lambda, enumerações com escopo e for loops baseados em intervalo). Com isso, o compilador C++ receberá um sinalizador indicando que o suporte a C++11 deve ser ativado. As últimas três linhas listam todos os arquivos que devem ser usados para compilar o projeto.
Para verificar se a versão do Qt instalado tem suporte a Vulkan modificamos main.cpp
para o seguinte:
#include "mainwindow.h"
#include <QApplication>
#include <QVulkanInstance>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QVulkanInstance inst;
if (!inst.create())
qFatal("Failed to create Vulkan instance: %d", inst.errorCode());
MainWindow w;
w.show();
return a.exec();
}
Nesse código, criamos um objeto QVulkanInstance
e chamamos a função create()
que retorna true
se a criação da instância do Vulkan foi bem sucedida ou false
caso contrário. Se não for possível criar o objeto de instância usamos a macro qFatal
para imprimir uma mensagem de erro para stderr
e abortar a aplicação.
Por fim, clicamos no botão (Run). Se o projeto for compilado e executado com sucesso, nossa configuração estará completa.
Se o compilador não conseguir encontrar o cabeçalho vulkan/vulkan.h
, o SDK Vulkan não foi instalado corretamente ou seus cabeçalhos não estão localizados no caminho de inclusão padrão. Para isso, devemos verificar a documentação do SDK Vulkan para ver se esquecemos de algum passo na configuração do SDK. Também podemos mudar para o painel Projects do Qt Creator e editar as variáveis do ambiente de compilação do projeto para tornar visíveis os cabeçalhos instalados. Dependendo do compilador, pode ser necessário definir a variável de ambiente INCLUDEPATH
ou CPATH
com o caminho para a pasta include
da instalação do SDK Vulkan.
Se obtermos um erro de compilação correspondente ao cabeçalho QVulkanInstance
, significa que estamos usando uma versão do Qt anterior a 5.10. Devemos nos certificar de instalar uma versão mais recente e selecione o kit correto no painel Projects do Qt Creator.
No entanto, se a inclusão de QVulkanInstance
funcionar, mas a classe QVulkanInstance
ainda não estiver definida, isso significa que nossa compilação do Qt não possui suporte ao Vulkan. Nesse caso, primeiro devemos tentar instalar a versão mais recente usando o instalador oficial, caso isso ainda não tenha sido feito, devemos executar os seguintes passos:
- Fechar o Qt Creator;
- Iniciar o executável Maintenance Tool a partir do diretório de instalação do Qt;
- Selecionar Add or remove components;
- Selecionar a versão mais recente do Desktop Qt;
- Confirmar as alterações.
Após a conclusão da instalação, devemos abrir novamente o Qt Creator, alterar para o painel Projects e selecionar o novo kit para o projeto.
Se a classe QVulkanInstance
ainda não for reconhecida, devemos compilar o Qt a partir do código-fonte. Esse processo varia dependendo do sistema operacional e da versão do Qt, portanto, não abordaremos os detalhes neste trabalho. Para fazermos isso, devemos acessar a página https://doc.qt.io/qt-5/build-sources.html e seguir as instruções correspondentes ao nosso sistema operacional. Se o Vulkan SDK estiver instalado corretamente, a saída do comando configure
deverá conter Vulkan ... yes
, indicando que o suporte do Vulkan está habilitado. Depois de compilarmos o Qt, devemos abrir o diálogo de opções do Qt Creator e configurar uma versão do Qt e um kit. Por fim, precisamos selecionar o novo kit para o projeto no painel Projects.
Se fizermos tudo corretamente, o projeto deve compilar e executar com sucesso.