OpenGL - O que é?
Tags: braziliandevs, gamedev, cpp, opengl
Published: 2022-07-30 20:22:00

Nós devs sempre nos deparamos com esse nome no nosso dia a dia, seja um jogo, editor de vídeo, ferramenta de modelagem 3D, motor de jogos... E aliás quem nunca tentou baixar OpenGL?

OpenGL é uma API gráfica e a partir dela conseguimos gerar desenhos na tela de forma acelerada, ou seja, é ela quem se comunica diretamente com o driver da placa de vídeo. Todas as funções do OpenGL dependem da implementação do driver e. g Nvidia disponibiliza os drivers para suas GPUs, com isso é possível utilizar as funções do OpenGL compatíveis com o modelo.

OpenGL não é diferente de DirectX ou Vulkan, se formos olhar para o que cada uma faz visto que DirectX também conversa com a GPU, existe os mesmos conceitos que o OpenGL trabalha, afinal se trata de como o driver implementa e não dá API em especifico.

Existem diferentes versões do OpenGL, a comunidade caracterizou elas de duas formas: legacy e moderno; O motivo é pela descontinuação de algumas funções como `glBegin` `glEnd` `glVertex2f` `glPushMatrix` etc, nas versões iniciais do OpenGL você não podia alterar o que estava na GPU e só realocando novos buffers (reenviando dados para a GPU), mas isso foi resolvido com a implementação de mini-programas (shaders) que rodam dentro da GPU e podem ser totalmente programáveis, assim em diante as versões foram nomeadas OpenGL moderno pela comunidade.

Dentre as versões modernas são: `OpenGL ES2/3` que é feita para sistemas embarcados (sistemas Android, consoles etc) - Outra versão é a `WebGL`, uma API feita em `Java Script` e é usada em navegadores - Por fim temos a versão "desktop" `OpenGL 3/4`, a maioria dos sistemas e arquiteturas utilizam.

Se você buscar algum tutorial pela internet e ver as tais funções descontinuadas sendo usadas, acredite em mim é uma furada e perda de tempo. Para você programar com OpenGL você necessita de uma binding para a linguagem, em C++ as mais usadas são `GL`, `glew` e `glad` - em Java `LWJGL` - em Python `PyOpenGL`.

--

# GPU

Em computação gráfica, OpenGL e outras APIs gráficas são utilizadas, como eu tinha dito OpenGL desenha coisas na tela, a nossa GPU adora 3 tipos de primitivos: pontos, linhas e triangulo; Em versões legacy do OpenGL você tinha a possibilidade de renderizar `QUADS` e `POLYGONS`, isso foi descontinuado e atualmente as GPUs preferem trabalhar com apenas os 3 tipos.

`vertex buffer object` ou os chamados `VBO` são buffers (listas) que podem armazenar qualquer tipo de dado, desde que seja utilizado pela GPU. Toda vez que queremos desenhar algo na GPU precisamos preparar esses buffers, isso também é conhecido como `mesh`, mesh de vértices nada mais são do que `VBOs` prontos.

Aqui você vai ver como criarmos o `VBO`, mas só criarmos, isso não vai ter nenhum efeito se não dizermos para a GPU desenhar e nem se quisermos pelo fato de não termos alocados nada no buffer.

```c++
GLuint vertex_buffer_object;
glGenBuffers(1, &vertex_buffer_object);
```

É um exemplo simples, o foco aqui é entender o que é OpenGL e não como programar (talvez eu poste tutoriais aqui).

As shaders utilizam dos VBOs para obter dados da CPU (código que você criou) e o nome disso é alocar buffers, isso custa muito uso da CPU se você alocar toda hora, mas ai que entra conceitos como `batch`, `instanced rendering` etc. Esses conceitos são algoritmos  e features que resolvem esse problema de performance, em versões antigas legacy do OpenGL você podia também alocar poucas vezes, mas não existia a possibilidade de alterar os buffers de forma eficaz (a não ser realocar os buffers). As shaders usam dos `uniforms` que nada mais são do que variáveis globais que guardam um valor de forma dinâmica, ou seja, você defini o valor em um loop antes de desenhar um buffer.

```c++
// alocando o vbo etc, ativando a shader
// ...
shader.set_uniform("width", 50);

glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object);
glDrawArrays(GL_TRIANGLES, 0, 6); // desenha
```

Como eu disse, shaders são programáveis, elas são compiladas e guardadas dentro do runtime do seu programa e são executadas dentro da GPU, assim você pode manipular o que estiver na GPU acessando as shaders pela CPU.

```
#version 330 core

layout (location = 0) in vec2 attrib_pos;
uniform float width;

void main() {
   // código.
}
```

Entretanto você até agora não entendeu é nada, mas isso foi um pouco do que OpenGL é capaz, obviamente que existem inúmeras coisas que deixei passar nesse post, lembrando eu só quero mostrar o OpenGL e não ensinar a usar OpenGL.

Se você quiser aprender OpenGL em outros lugares, recomendo os sites [Nvidia GPU Gems](https://developer.nvidia.com/gpugems/gpugems/contributors) e também [Learn OpenGL](https://learnopengl.com/), a Nvidia também disponibiliza PDFs bem legais explicando funções do OpenGL, efeitos com shaders, etc.

# The End

Bom acabou, espero que goste de ter lido e se gostar posso trazer realmente tutorias sobre OpenGL moderno, conceitos utilizando OpenGL e também outras coisas relacionada a game-dev, até mesmo como criar sua API de GUI (isso mesmo sua do 0) em código de alta performance!

~hi bye

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m2ldv7qv7wxv2zuqmd3m.png)