class Configurando o Ambiente : public 🥾 OpenGL

Configurando o Ambiente

Na semana passada vimos um pouco do OpenGL, mas não colocamos a mão na massa! Nesse post vou fazer a configuração de ambiente, e no próximo post embarcamos então a nossa aplicação em OpenGL.

Eu disse que gosto de fazer as coisas do jeito mais difícil não é, o meu setup para esse estudo é Neovim + Cmake + VSCPP Compiler. Você não precisa seguir nesse setup, o mais comum é Usar o Visual Studio e configurar tudo nele ~se estiver no Windows claro~.

CMake

Logo CMake

CMake é uma família de ferramentas para build, testes e “empacotamento” de aplicações.1

Eu vejo duas grandes vantagens em usar o CMake, primeiro ele é cross-platform o que significa que eu posso carregar as configurações para “qualquer” plataforma que estiver usando, e assim o CMake gera um projeto que eu consigo trabalhar naquela plataforma em específico.

E também o arquivo de configuração dele ser um simples arquivo de texto, fácil de ler e com todas as informações necessárias em um lugar só (se o projeto for muito complexo pode ser que existam configurações específicas em mais de um lugar, mas eu prefiro isso a ter que ficar decorando onde ficam as configurações da IDE x, y ou z)

Bibliotecas externas

Além de utilizarmos o CMake para gerenciar a criação do projeto e builds, como explicado no primeiro post dessa serie precisamos de algumas bibliotecas externas para trabalhar com o OpenGL, e serão:

GLFW para gerenciar contextos, janelas e a I/O.2

GLEW para fazer o carregamento dos módulos OpenGL.3

Estrutura do Projeto

Estou utilizando uma estrutura de pastas comum quando trabalhamos com CMake

📂 Projeto
+--📂Source
+--📂Build

Dentro da pasta Soure ainda criei uma pasta ExternalLibs, e é nesta pasta que colocarei as bibliotecas que iremos utilizar. Você pode encontra os pré-compilados das GLFW e GLEW em seus respectivos sites, apenas fique atento para fazer o download para a plataforma que estiver trabalhando.

Dentro de ExternalLibs Crio uma pasta para cada uma das bibliotecas e extraio o arquivo zip delas em suas respectivas pastas.

Algumas bibliotecas são especificas para a versão do compilador que você estiver utilizando, fique atento para extrair a pasta lib correta

No caso do meu projeto estou usando o compilador do Visual Studio 2019

Feito tudo isso, o projeto deve ter ficado como abaixo

📂 Projeto
+--📂 Source
|  +--📂 ExternalLibs
|     +--📂 GLEW
|     |  +--📂 bin
|     |  +--📂 include
|     |  +--📂 lib
|     |
|     +--📂 GLFW
|        +--📂 include
|        +--📂 lib_vc2019
|
+--📂 Build

CMakeLists.txt

Para gerar os os arquivos de projeto, com as configurações necessárias para o compilador precisamos escrever um arquivo CmakeLists.txt que é o arquivo que o CMake vai ler e montar o projeto.

Crie um arquivo CMakeLists.txt na sua pasta Source

# Defino qual versão mínima do CMake necessária 
CMAKE_MINIMUM_REQUIRED(VERSION 3.20 FATAL_ERROR)

# Defino o nome do projeto e linguagem utilizada
# Depois do Build o executável será LeOpenGL nesse caso
PROJECT(LeOpenGL LANGUAGES CXX)

# Crio uma variável ExternalLibs
SET(ExternalLibs ${CMAKE_CURRENT_SOURCE_DIR}/ExternalLibs)

# Adiciono os diretórios para o linker procurar os arquivos 
# necessários de ambas as bibliotecas
LINK_DIRECTORIES(${ExternalLibs}/GLFW/lib_vc2019)
INCLUDE_DIRECTORIES(${ExternalLibs}/GLFW/include)

LINK_DIRECTORIES(${ExternalLibs}/GLEW/lib/release/x64)
INCLUDE_DIRECTORIES(${ExternalLibs}/GLEW/include)

# O CMake consegue achar a biblioteca do OpenGL nas configurações padrões da máquina
FIND_PACKAGE(OPENGL REQUIRED)

# Adiciono um arquivo Hello.cpp ao projeto
ADD_EXECUTABLE(LeOpenGL Hello.cpp)

# Adiciono o Link para as bibliotecas necessárias
TARGET_LINK_LIBRARIES(LeOpenGL glfw3 ${GLFW_LIBRARIES})
TARGET_LINK_LIBRARIES(LeOpenGL glew32 ${GLEW_LIBRARIES})
TARGET_LINK_LIBRARIES(LeOpenGL ${OPENGL_LIBRARIES})

Feito isso vamos criar o arquivo Hello.cpp apenas para verifica se nossas configurações estão corretas.

#include <iostream>

int main(void){
    std::cout << "Olar OpenGL" << std::endl;
    return EXIT_SUCCESS;
}

Assim podemos executar o seguinte comando na pasta raiz do projeto.

$ cmake -S Source -B Build

Ele que irá criar as configurações necessárias para executar o Build de nosso projeto.

CMake Criando o Projeto

E caso não haja nenhuma mensagem de erro podemos executar então

$ cmake --build Build\

CMake "buildando" o projeto E se tudo estiver certo podemos executar nosso arquivo de teste.

$ .\Build\Debug\LeOpenGL.exe

E se tudo deu certo teremos um programa do terminal que escreve Olar OpenGL no terminal

Execução do Hello

Neste post criamos a infra que iremos utilizar durante os estudos, no próximo post iremos criar uma janela com o GLFW

GLFW

Agora que sabemos que nosso ambiente está configurado e compilando, vamos utilizar o GLFW para criar uma janela. Como quero apenas fazer um teste para ver se está ok, vou copiar descaradamente o código da documentação do GLFW2

#include <iostream>
#include <GLFW/glfw3.h>

int main(void){
    GLFWwindow* window;

    if(!glfwInit()){
        return EXIT_FAILURE;
    }

    window = glfwCreateWindow(400, 300, "Hello GLFW", NULL, NULL);
    if(!window){
        glfwTerminate();
        return EXIT_FAILURE;
    }

    glfwMakeContextCurrent(window);

    while(!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);

        glfwSwapBuffers(window);

        glfwPollEvents();
    }

    glfwTerminate();

    return EXIT_SUCCESS;

}

Se tudo deu certo, ao compilar e executar esse código teremos uma janela aberta no tamanho que definimos.

Vamos entender linha a linha o que está acontecendo no código que acabamos de fazer:

GLFWwindow* window;

Criamos uma referência (ponteiro) para a estrutura GLFWwindow do GLFW, esse objeto encapsula as operações de janela e de contexto do OpenGl em uma unica abstração.

if(!glfwInit()){

Antes de utilizarmos as funções do GLFW precisamos garantir sua inicialização correta. Se algum erro occorrer irá retornar GLFW_FALSE e caso isso ocorra finalizamos o programa.

window = glfwCreateWindow(400, 300, "Hello GLFW", NULL, NULL);

Aqui criamos uma Janela e um Contexto OpenGL, seus parametros são largura (width) em pixels, altura(height) em pixels e título da janela. Os dois ultimos parametros ficarão nulos (NULL), e não entraremos em detalhes pois são opções mais avançasdas. Mas são os parametros de Tela GLFWmonitor e o ultimo outro GLFWwindow.

As proximas duas linhas basicamente verificam se a janela conseguiu ser criada e caso contrario finaliza o GLFW glfwTerminate(), ou seja, libera os recursos que foram alocados pela glfwInit();

Referências

  1. CMake 

  2. GLFW: An OpenGL Library  2

  3. The OpenGL Extension Wrangler Library 

class Configurando o Ambiente : public 🥾 OpenGL