Você está na página 1de 46

1

OPENGL: ANÁLISE DE PERFORMANCE DE RENDERIZAÇÃO DE SPRITES 2D EM


BATCH RENDERING
Mateus Freitas da Costa*
Maicon Vinicius Ribeiro**

RESUMO
No mundo moderno, a tecnologia tem tido um espaço cada vez mais proeminente na
vida das pessoas. Uma das ferramentas que mudaram a forma como as pessoas
lidam com dados computacionais e com a indústria do entretenimento é a área da
computação gráfica. Assim, o seguinte trabalho pretende fazer um experimento de
performance de uma técnica usada na computação gráfica, o qual pode ser utilizada
em diversos programas, como jogos e outros programas desktop de interface gráfica.
O software desenvolvido é um simples sandbox que busca realizar diversos testes
sobre a técnica batch rendering 2d na API gráfica OpenGL, e assim, comparar o
tempo de renderização de diversos sprites 2d utilizando a técnica em questão, e a da
técnica comum. Feito os experimentos, concluiu-se que o batch rendering apresenta
uma performance significantemente superior à da técnica comum, principalmente em
aplicações mais pesadas que renderizam um alto número de objetos ao mesmo
tempo.

Palavras-Chave: Computação gráfica; OpenGL; Batch Rendering.

ABSTRACT
In the modern world, technology has taken an increasingly prominent place in people's
lives. One of the tools that changed the way people deal with computational data and
the entertainment industry is the area of computer graphics. Thus, the following work
intends to make a performance experiment of a technique used in computer graphics,
which can be used in several programs, such as games and other graphical interface
desktop programs. The developed software is a simple sandbox that seeks to perform
several tests on the 2d batch rendering technique in the OpenGL graphics API, and
this way, compare the rendering time of several 2d sprites using the technique in
question, as well the common technique. After the experiments, it was concluded that
batch rendering presents a significantly superior performance than the common
technique, which is more easily observed in heavier applications that render a high
number of objects at the same time.

Keywords: Computer Graphics; OpenGL; Batch Rendering.


* Rede de Ensino Doctum – Unidade Caratinga – aluno.mateus.costa1@doctum.edu.br – Graduando em
Ciência da Computação
** Rede de Ensino Doctum – Unidade Caratinga – maicon.ribeiro@doctum.edu.br – Professor
especialista em Ciência da Computação – Maicon Vinicius Ribeiro.
2

1 - Introdução
Ao longo da história da humanidade, um dos aspectos que esteve sempre
presente foi o lazer, que, nas suas mais diferentes formas, permite que o homem se
entretenha e descanse de seus afazeres e trabalhos diários. Caminhar, exercícios,
esportes, cozinhar, ler, e diferentes tipos de jogos são parte da vida cotidiana de
pessoas de praticamente todas as culturas e regiões do mundo.
Tendo origem no ano de 1958, no auge da guerra fria, pelo físico William
Higinbotham, do projeto Manhattan, que, com o objetivo de atrair visitantes para o
Brookhaven National Laboratories, sediado em Nova York, e exibir o potencial nuclear
dos Estados Unidos, desenvolveu um simples jogos de tênis usando gráficos simples, o
qual chamou de Tennis Programming ou Tennis for Two (SANTANA, c2006-2022) , os
videogames se tornaram uma das mais proeminentes formas de lazer do mundo
tecnológico, tendo presença na vida de três quartos dos brasileiros (TADEU E
TORTELLA, 2022).
Da mesma maneira que os jogos fazem parte do imaginário de boa parte dos
jovens1, e principalmente, daqueles aficionados em tecnologia, o seu desenvolvimento
atrai a atenção de muitas pessoas. Só na plataforma de jogos Steam, há registro de
44.000 de desenvolvedores que anunciaram ou publicaram pelo menos um jogo
(KONTUS, 2022).
Tendo isto em vista, o seguinte trabalho se propõe a analisar uma simples
técnica de programação gráfica, um algoritmo que pode ser utilizado em uma das mais
utilizadas APIs de computação gráfica, o OpenGL, e assim, fornecer resultados
experimentais para os estudantes que desejam ingressar no desenvolvimento de jogos
e que buscam entender como os mecanismos de baixo nível funcionam, ou ainda,
aqueles que querem desenvolver suas aplicações utilizando ferramentas mais simples,
sem ter de recorrer a complexas game engines.

1.1 – Objetivos

1 Com média acima da mundial, 28% dos jovens brasileiros fazem uso abusivo de videogames,
diz pesquisa da USP, 2022, disponível em <https://g1.globo.com/saude/noticia/2022/07/31/uso-
excessivo-de-videogames-e-maior-entre-adolescentes-brasileiros-diz-pesquisa.ghtml>
3

O objetivo deste projeto é desenvolver um simples software sandbox em


interface gráfica, e realizar diversos experimentos em cima da técnica de programação
Batch Rendering 2d, utilizando do OpenGl. Assim, pegar diversas estatísticas de tempo
e comparar o resultado com a técnica de renderização comum, para descobrir o nível
de vantagem em performance a técnica apresenta.

1.1.1 - Objetivos Específicos


Para realizar o objetivo geral, o seguinte deve ser feito:
o Criar um software capaz de abrir uma interface gráfica em janela num
sistema operacional qualquer.
o Inicializar a API OpenGL e exibir imagens 2D.
o Montar um esquema de batch rendering no OpenGL, que é capaz de
renderizar imagens 2D.
o Criar uma série de experimentos automáticos, a fim de cronometrar o
tempo em que o OpenGL demora para renderizar sprites 2D, utilizando
tanto o batch rendering como a técnica comum.

1.2 - Hipóteses
Tendo em vista o funcionamento do OpenGL, é esperado que a renderização em
batch rendering, por ser capaz de renderizar vários objetos de uma vez só numa única
chamada a GPU, tenha um considerável bônus de performance, principalmente num
número maior de sprites.
É esperado também que esta diferença seja ainda mais significante quando se
trata de renderizar apenas uma única textura, pois assim poderá fazer renderizar todos
os objetos numa única chamada, enquanto o renderizador normal terá de fazer o
mesmo número de chamadas que forem a quantidade de objetos.

1.3 – Justificativa
A justificativa do atual trabalho se dá pela curiosidade do autor em utilizar uma
técnica OpenGL, cuja implementação não é muito complexa, com o objetivo de verificar
4

o quão eficiente é possível escrever um renderizador de OpenGL que ofereça uma


performance viável para o desenvolvimento de aplicações gráficas, tais como jogos 2D,
e que possa até mesmo ultrapassar bibliotecas opensource mais utilizadas na área,
como o SDL.

1.4 – Classificação Metodológica


A metodologia a ser utilizada no projeto é de fim descritivo e quantitativo, isto é,
busca realizar diversos experimentos a fim de obter estatísticas em números, e assim,
comparar os resultados das técnicas utilizadas.

1.5 – Estrutura do Trabalho


Este trabalho é estruturado da seguinte forma: este capítulo contêm a introdução
e os objetivos do trabalho. O capítulo 2 contém o referencial teórico, dando uma base
sobre o assunto. O capítulo 3 possui a metodologia detalhada sobre como o projeto
será desenvolvido, evidenciando seus detalhes mais técnicos. O capítulo 4 apresenta o
desenvolvimento do programa e dos testes. O capítulo 5 contém os resultados que
foram objetivos a partir dos testes do projeto, e por fim, o capítulo 6 apresenta a
conclusão do que foi feito. O projeto termina no capítulo 7, com as referências
bibliográficas.

2 - Referencial Teórico
2.1 – Computação Gráfica
A computação gráfica é definida como:

A Computação Gráfica reúne um conjunto de técnicas que permitem a


geração de imagens a partir de modelos computacionais de objetos
reais, objetos imaginários ou de dados quaisquer coletados por
equipamentos na natureza. (SILVEIRA, 2018)

Dessa forma, entendemos que a computação gráfica é uma forma de


representar objetos, que podem ser derivados do mundo real ou imaginários, num
computador, assim gerando imagens que serão visualizadas por usuários, os quais
podem ter objetivos educacionais, corporativos, científicos, lúdicos, entre outros.
5

A história da computação gráfica tem origem na década de 1950, época no qual


pesquisadores do MIT foram capazes de criar um computador que podia processar
imagens em três dimensões. Mais tarde, nos anos 1970, Ivan Sutherland e David Evans
foram capazes de desenvolver um software que gerava e modelava gráficos.
Posteriormente, foram criados os modelos 3D, utilizados amplamente na indústria
cinematográfica, dando vida aos filmes da Disney e da Pixar. Outro grande marco a ser
mencionado é o lançamento do computador da Apple, Macintosh, em 1980.
(COUTINHO, 2021)

Devido ao alto custo que essa tecnologia demandava para ser utilizada,
inicialmente a CG estava limitada às estações gráficas que possuíam recursos
computacionais mais potentes, o que era caro. Foi nos anos 1990 que a evolução do
hardware e dos dispositivos gráficos permitiu o barateamento desses recursos. Assim,
acelerou-se o surgimento de ambientes que utilizavam da interface gráfica como o
sistema operacional Windows. (SIQUEIRA, [s.d])
A computação gráfica se divide, principalmente, em três subcategorias
(GONÇALVES, c2020-2021):

a) Síntese de imagens, que se refere a produção de imagens sintéticas, em duas


ou três dimensões;
b) Análise de imagens, que busca obter dados provenientes de uma imagem, e
traduzi-los em informações úteis para uma determinada função, como, por
exemplo, reconhecimento facial.
c) Processamento de imagens, o qual busca manipular uma determinada imagem
com ajustes de cor, brilho, aplicações de filtros, etc. Exemplos incluem o
Photoshop e os programas de edição de vídeo.

Atualmente, a computação gráfica é parte fundamental de diversos sistemas


computacionais, e se tornou uma ferramenta essencial na vida e cotidiano de muitas
pessoas. Entre os seus usos, incluem-se: interface de usuário de programas e sistemas
operacionais, visualização de gráficos, editoração eletrônica, CADS - Projeto assistido
6

por computador - (mecânico, civil, elétrico), simulações e animações, arte e comércio,


cartografia, e muitos outros. (PINHO, [s.d])

2.2 - OpenGL
Um dos grandes instrumentos utilizados na computação gráfica é o OpenGL,
que:
OpenGL, assim como Direct3D ou Glide, é uma API (Application
Programming Interface), termo usado para classificar uma biblioteca de
funções específicas disponibilizadas para a criação e desenvolvimento
de aplicativos em determinadas linguagens de programação. A OpenGL
foi produzida com C e C++ em mente, mas pode ser utilizada para
diversas outras com um alto nível de eficiência. (TECMUNDO, 2008)

Assim, entendemos que o OpenGL é uma API, uma especificação de funções


escritas na linguagem de programação C, que deve ser implementada pelos fabricantes
de placas de vídeo, criada para ser uma interface de programação para o
desenvolvimento de aplicações gráficas tais como jogos, CADs, sistemas operacionais,
programas de desenho e modelagem 3D, bibliotecas gráficas de alto nível, entre outros.
A história do OpenGL remonta a década de 1980, época no qual não havia uma
padronização comum das interfaces gráficas, fazendo com que os desenvolvedores do
período tivessem de produzir seus softwares para cada hardware diferente. Dessa
forma, uma empresa de nome Silicon Graphics Inc. (SGI) criou o IRIS GL, um padrão
gráfico que chamou a atenção da indústria. Mais tarde, devido ao interesse da empresa
em manter parte do código fonte como proprietário, a ramificação de código totalmente
aberto, o OpenGL, surgiu, estando em contínuo desenvolvimento até hoje, sendo
suportado por diversas empresas, como a AMD, Dell, HP, Intel, Nvídia, Sun (Oracle) e
outras. (CIPOLI, 2012)
O Opengl é independente da implementação de uma placa de vídeo específica,
assim, o programador apenas deve dizer apenas o que o computador deve fazer, e não
como. Possui 250 funções, utilizadas para controlar os desenhos que serão realizados
na tela do computador. Tem suporte a diversas primitivas, como pontos, linhas e
triângulos. A medida que as funções vão sendo chamadas pelo desenvolvedor, os
7

dados e comandos vão passando pelos buffers num esquema que damos o nome de
pipeline, nos quais são adicionados coordenadas, cores, texturas, iluminação e outros
efeitos, até chegar no frame buffer, do qual é enviado para a tela do computador.
(MANSSOUR, 2003)

2.3 - Renderização 2D
Uma tela de computador é composta por milhares de pixeis, pequenos
quadrados constituídos de três feixes de luz, um de cada cor, vermelho, verde e azul,
um padrão conhecido como RGB - Red Green Blue -. Assim, num processo complexo
de transformações, é possível determinar a luminosidade de cada feixe de luz para
cada pixel, o qual misturando as cores aditivamente, pode formar milhões de cores
diferentes, permitindo a criação de imagens complexas e realistas. (MEIRELLES, 2002)
Para determinar o local no qual os pixeis serão desenhados, é necessário um
sistema de coordenadas. Comumente, as bibliotecas gráficas contam os pixeis a partir
do canto superior esquerdo da tela do computador (ECK, 2021). Assim, numa tela de
1920 por 1080 pixeis, por exemplo, a coordenada (0, 1080) corresponde ao canto
inferior esquerdo, e a coordenada (1920, 1080), ao canto inferior direito.
Na OpenGL API, o sistema de coordenadas é 3D, ou seja, possui a dimensão da
profundidade. Para que então seja possível renderizar imagens no ecrã, uma
transformação dessas coordenadas se faz necessária. Dessa forma, primeiramente
convertemos as coordenadas 3D para 2D, e, posteriormente, o sistema de pipeline
junta as coordenadas, em conjunto com outras informações, e as converte em pixeis
coloridos, formando os desenhos que se deseja exibir. (VRIES, 2020)
O OpenGL é capaz apenas de desenhar simples formas primitivas, como pontos,
linhas e triângulos, sendo os últimos responsáveis pela maior parte dos gráficos que
vemos nos computadores (GORDON; CLEVENGER, c2021). A rendering pipeline
constitui-se de vários programas da GPU chamados shaders. Assim, enviamos os
dados para a GPU, os chamados buffers objects, e os shaders se encarregam de
desenhar estes dados no dispositivo, tendo o programador gráfico a responsabilidade
de prover o código fonte de dois deles, o vertex shader, responsável por controlar as
8

coordenadas dos vértices, e o fragment shader, que controla a cor final dos pixeis.
(SHREINER et al., c2013)
Dentro os buffers objects que são mandados para a GPU, situa-se também as
texturas dos objetos que serão desenhados. No entanto, diferente dos vértices, que
podem ser enviados em grandes quantidades, e, dessa forma, permitem uma única
chamada de desenho do OpenGL, as texturas têm um número bem limitado de slots, ou
seja, num único frame, para desenhar todos os possíveis objetos que a aplicação
deseja, se faz necessário executar o comando de desenho múltiplas vezes (VRIES,
2020). Em busca de reduzir o número de chamadas ao mínimo possível, usa-se a
técnica de batch rendering - renderização em lotes -, que procura desenhar o máximo
de objetos possíveis em uma única chamada, usando todos os slots de texturas de uma
determinada GPU, reduzindo assim o overhead de trocar os dados da GPU para cada
objeto a ser desenhado. (KRZEMINSKI, 2014)

3 – Metodologia
3.1 – Contexto
Em vista de coletar informações sobre uma técnica de renderização de imagens
2D, o batch rendering, que pode ser utilizada em diversos softwares dependentes de
interface gráfica, sobretudo jogos, os quais necessitam, diversas vezes, de exibir uma
grande quantidade de imagens na tela de computador em um curto período de tempo,
será feito uma série de experimentos com o propósito de medir a performance de um
programa que a utiliza, e assim compará-la com a renderização padrão, sem o batch
rendering.
Para isso, será desenvolvido pelo autor um simples software sandbox, na
linguagem de programação C++, que, utilizando de algumas bibliotecas necessárias
para a criação de janela e inicialização da API OpenGL, realizará uma série de testes
utilizando a técnica batch rendering, e assim, utilizando os artifícios da biblioteca padrão
do C++, calcular o tempo que esta técnica utiliza, bem como de sua contraparte, e
assim, fazer um comparativo estatístico entre as duas.

3.1.1 – Batch Rendering


9

Tendo em vista que no OpenGL, os dados de posição e tamanho podem ser


enviados em gigante quantidade a GPU, assim, não possuem muitos limites práticos, o
número de texturas armazenadas na GPU tem uma quantidade limitada de slots, o que
significa que se deseja desenhar um número de objetos, que, em conjunto, utilizem
mais texturas do que a GPU é capaz de armazenar, mais de uma chamada de desenho
deve ser executada. A renderização em lotes tem o objetivo de reduzir estas chamadas
ao mínimo.
Isso é feito da seguinte forma: um cliente que deseja utilizar o batch rendering
para desenvolver sua aplicação, um jogo, por exemplo, utiliza da classe responsável
por abstrair as chamadas diretas ao OpenGL, o qual daremos o nome de Renderer. O
cliente fará diversas chamadas a esta classe em cada quadro de seu jogo, e em cada
chamada, utilizará um objeto diferente, com sua posição, tamanho e textura. O
Renderer, ao invés de realizar o desenho imediatamente na chamada do cliente, irá
armazenar as informações desta chamada, e, somente quando o limite de texturas da
GPU chegar ao seu limite, ou quando o cliente indicar o fim do quadro, o Renderer vai
renderizar todos os objetos armazenados, iniciando um novo lote.
Dessa forma, se o cliente, por exemplo, tiver 16 texturas como limite de GPU,
mas quiser renderizar 500 objetos de uma vez, todos com a mesma textura, o Renderer
conseguirá renderizar tudo num único lote. No entanto, se o cliente tiver 17 objetos com
texturas diferentes, 2 lotes serão necessários.

3.2 - Ferramentas
Para a criação de janela e do contexto OpenGL, necessário para o
funcionamento do software, será utilizada uma simples biblioteca multiplataforma SDL.
Para acessar as funções do OpenGl, uma biblioteca de carregamento, a biblioteca
GLEW. Ainda, para o carregamento de imagens que serão utilizadas como texturas
pelo programa, a biblioteca STB_IMAGE. Por fim, a biblioteca GLM, que contêm
funções matemáticas e de manipulação de matrizes, necessárias para transformas as
coordenadas do programa em coordenadas da GPU e possam ser, assim, exibidas na
tela do computador. Todas as bibliotecas foram escritas em linguagem C e C++ e
possuem seus códigos-fonte disponíveis para download online.
10

3.3 - Ambiente
Os testes serão realizados num único computador, de processador AMD Ryzen
5 5500 (12 CPUs) ~3.6GHz, de placa de vídeo NVIDIA GeForce GTX 1660 SUPER, de
memória RAM 16384MB DDR4, e sistema operacional Windows 11 Home 64 bits. Será
utilizada a versão 4.5 do OpenGL (GLSL 450).

3.4 - Fundamentos
Os experimentos, com o objetivo de produzir um resultado confiável e útil, tem os
seguintes fundamentos:

● Serão realizados um grande número de testes em sequência para cada análise,


a fim de pegar uma média dos resultados como amostra e reduzir as possíveis
interferências. Neste projeto, o número escolhido foi 100.

● Tendo em vista que a técnica batch rendering se fundamenta na necessidade de


reduzir os custos do hardware ao renderizar um grande número de objetos na
tela do computador, serão feitos testes utilizando números diferentes de objetos,
que será 10, 50, 200, 1000 e 5000.

● Uma vez que a performance do batch rendering depende da quantidade de


texturas que farão parte dos objetos, os testes se dividirão no tipo que utilizam
apenas uma textura, assim permitindo uma performance maior, o melhor caso,
com apenas uma chamada de desenho, ou lote, e no tipo que utiliza uma
quantidade de texturas maior que o limite da GPU, com um objeto tendo uma
textura diferente do anterior de forma a esgotar os slots da GPU o mais rápido
possível, assim elevando o número de lotes ou chamadas ao máximo possível, o
pior caso. Para o Renderer normal, isso é irrelevante, uma vez que terá sempre
de fazer uma chamada por sprite.
11

● O OpenGL coloca como quantidade mínima de slots de texturas disponíveis para


serem utilizadas ao mesmo tempo o número 16, no entanto algumas placas de
vídeo conseguem utilizar um número maior que este. Assim, no seguinte projeto,
serão realizados testes assumindo um limite de 16, e outros que assumirão o
limite 32.

4 - Desenvolvimento do Projeto
As técnicas de desenvolvimento do software a seguir são inspiradas nos tutoriais
de Yan Chernikov, que possui um canal de youtube “The Cherno”, no qual publica
diversos tutoriais envolvendo programação em C++, OpenGL e game engines.2
Este capítulo é organizado da seguinte maneira: os subcapítulos contêm os
módulos e classes do software desenvolvido, com explicações acerca dos mesmos. No
fim de do capítulo há uma lista de figuras contendo os headers das classes, e das
implementações de definições mais pertinentes em relação a este projeto. Para a
criação das figuras de código fonte, foi utilizado o site Carbon3.

4.1 – Módulos do Programa


4.1.1 - OpenGL Data
Este módulo trata das classes responsáveis por encapsular os objetos que
contêm dados brutos no OpenGL, os quais serão utilizadas pelo módulo OpenGL
Rendering Tools.

4.1.1.1 - VertexBuffer
Trata-se da classe que contêm dados relacionados aos vértices que serão
enviados ao CPU. Estes dados podem coordenadas na tela, mapeamento de texturas,
cores e o index do slot de textura da GPU a ser renderizado.

4.1.1.2 - BufferLayout

2 https://www.youtube.com/watch?v=Th4huqR77rI&list=PLlrATfBNZ98f5vZ8nJ6UengEkZUMC4fy5
3 https://carbon.now.sh/
12

Age como um complemento ao VertexBuffer, especificando a configuração e


ordem em que cada dado estará organizado na memória do computador.

4.1.1.3 - ElementBuffer
Se refere ao objeto que contém indexes, que se referindo aos vertexes do
VertexBuffer, indicam a ordem em que serão processados pela GPU, e assim, permite
formar as geometrias, como triângulos ou quadrados.

4.1.1.4 - VertexArray
Esta classe é necessária nas versões modernas do OpenGL, e atua como um
mediador, que guarda o BufferLayout e sua relação com um determinado VertexBuffer.
Também pode estar ligado a um ElementBuffer.

4.1.1.5. - Shader
Responsável por armazenar uma shader, isto é, o programa que será
processado diretamente na GPU.

4.1.1.6 -Texture
Encapsula o objeto do OpenGL de textura, que é a imagem que será renderizada
na tela. Esta classe, através da biblioteca STB_IMAGE, é capaz de carregar arquivos
de imagens do computador e transformá-la nos BYTES que constituirão os dados da
textura.

4.1.2 - OpenGL Rendering Tools


Este módulo contém as duas ferramentas de renderização que encapsulam as
funções do OpenGL, e fornecem uma interface simples ao cliente que deseja exibir
imagens no ecrã do computador através da função DrawQuad. São estas as classes
que, através de benchmarks de medições de tempo, serão comparadas uma com a
outra.

4.1.2.1- Renderer2D
13

Este é a classe do Renderer comum, isto é, o que contêm apenas um buffer de


vértices, e o transforma na hora em que a função DrawQuad é chamada, passando-o
para o OpenGL e exibindo a imagem no buffer imediatamente.

4.1.2.1 - BatchRenderer2D
O BatchRenderer2D, ao contrário do Renderer comum, contêm um imenso buffer
de vértices, e assim, consegue armazenar as chamadas de DrawQuad e que apenas
no fim, quando ou o limite de texturas da GPU se esgotar, ou o buffer de vértices se
tornar cheio, vai mandar esses dados para a GPU, e assim, renderizar uma quantidade
muito maior de imagens numa única chamada ao OpenGL.

4.1.3 - Test Tools


Este módulo contém a classe responsável por fazer os testes e obter os
resultados dos de Benchmark das ferramentas de rendering.

4.1.3.1 -TestController
Esta é a classe de teste propriamente dito. Na sua função principal, ela recebe
uma lista de TestSpecifications do cliente, realiza cada teste de acordo com a
especificação, e cada um é realizado várias vezes a fim de calcular um resultado médio
e obter um resultado mais preciso. Por fim, devolve um TestResult ao cliente.

4.1.3.2 - TestUnitResult
Esta classe contém o resultado de um único teste realizado, o que inclui o
número de chamadas de renderização ao OpenGL, e o tempo em microsegundos
gastos por essas chamadas.

4.1.3.3 - TestSpecification
Especifica como um determinado teste deve ser feito. Seus membros são:

• Tipo do Renderizador – Se será utilizado o BatchRenderer2D ou o Renderer2D.


14

• O tipo de teste em relação a quantidade de texturas – Se será utilizada apenas


uma textura para todos os sprites, ou se será utilizado múltiplas texturas, um
número maior que a quantidade de slots na GPU, de modo a sobrecarregar o
BatchRenderer2D e exigir que ele faça o máximo de chamadas possível ao
OpenGL, o seu pior caso.

• A quantidade de sprites a serem exibidos na tela.

4.1.3.4 - TestResult
É o resultado final de todos os testes realizados pelo TestController. Contém o
número de repetições que foram feitas para cada teste e o número de testes feitos no
total.
Contém também uma lista com os resultados de cada teste, isto é, cada
TestSpecification e seu respectivo resultado TestUnit.

4.1.4 - Outros
Este módulo mostra as partes do programa que não se encaixam em outros
módulos.

4.1.4.1 - Main
A função main inicializa as bibliotecas, cria uma janela, chama o TestControlller,
recebe os resultados e os escreve num arquivo txt.

4.1.4.2 - Util
Contém uma única função, que transforma os dados de um arquivo em uma
string, utilizado para abrir o arquivo que contêm o código fonte das shaders.

4.1.4.3 - Config
Contém as variáveis e constantes globais.

4.2 - Código Fonte


15

Figura 1 - Classe VertexBuffer – Header

Fonte: O autor
16

Figura 2 - Classe BufferLayout - Header

Fonte: O Autor
17

Figura 3 - Classe ElementBuffer - Header

Fonte: O Autor
18

Figura 4 - Classe VertexArray - Header

Fonte: O Autor
19

Figura 5 - Classe Shader - Header

Fonte: O Autor
20

Figura 6 - Classe Texture - Header

Fonte: O Autor
21

Figura 7 - Struct RendererData - Dados estáticos para a classe Renderer2D

Fonte: O Autor
22

Figura 8 - Classe Renderer2D - Header

Fonte: O Autor
23

Figura 9 - Função Renderer2d::Initialize - Inicializa os dados iniciais

Fonte: O Autor
24

Figura 10 - Função Renderer2D::DrawQuad - Desenha um sprite com textura, tamanho e posição na tela
imediatamente

Fonte: O Autor
25

Figura 11 - Struct RendererData - Utilizado na classe BatchRenderer2D

Fonte: O Autor
26

Figura 12 - Classe BatchRenderer2D - Header

Fonte: O Autor
27

Figura 13 - Função BatchRenderer2D::Initialize - Inicializa os dados do RendererData e aloca memória


para o buffer de vertex interno

Fonte: O Autor
28

Figura 14 - Função BatchRenderer2d::DrawQuad - Prepara no Buffer interno a renderização de um objeto


com posição, textura e tamanho

Fonte: O Autor
29

Figura 15 - Funções Adicionais do BatchRenderer2D - Prepara o buffer interno antes do ínicio do frame, e
renderiza todos os objetos do buffer interno numa só chamada

Fonte: O Autor
30

Figura 16 - Classe TestController - Header

Fonte: O Autor
31

Figura 17 - Struct TestUnitResult e função TestController:InitializeTestSystem - Dados estáticos e função


de inicialização da classe estática

Fonte: O Autor
32

Figura 18 - Função TestController::RunAll - Roda todos os testes a partir de um vetor de


especificações.
33
34

Fonte: O Autor

Figura 19 - Função TestController::TestUnit - Realiza um único teste a partir de uma determinada


especificação e retorna um resultado

Fonte: O Autor
35

Figura 20 - Struct TestSpecification - Determina um tipo de teste

Fonte: O Autor
36

Figura 21 - Struct TestResult - Os Resultados de uma série de testes, com seus tipos e resultados

Fonte: O Autor
37

Figura 22 - Função Main - Inicializa bibliotecas SDL, OpenGL, abre uma janela, realiza os testes e guarda
os resultados num Log

Fonte: O Autor
38

Figura 23 - Função util::FromFile - Guarda os resultados de um arquivo de texto numa string

Fonte: O Autor

Figura 24 - Namespace Config - Contém as variáveis e constantes globais

Fonte: O Autor

5 - Experimento
Após o software ter sido desenvolvido e executado, os seguintes resultados
foram obtidos em logs de arquivos de texto:

5.1 – Tabelas
39

Renderer Renderer2D

Quantidade de Texturas 1

Slots de Textura 16

Sprites Chamadas à GPU Microsegundos

10 10 216

50 50 252

200 200 504

1000 1000 1894

5000 5000 8913

Renderer Renderer2D

Quantidade de Texturas Texturas Alternando

Slots de Textura 16

Sprites Chamadas à GPU Microsegundos

10 10 273

50 50 252

200 200 503

1000 1000 1906

5000 5000 8963


40

Renderer BatchRenderer2D

Quantidade de Texturas 1

Slots de Textura 16

Sprites Chamadas à GPU Microsegundos

10 1 196

50 1 178

200 1 187

1000 1 175

5000 5 206

Renderer BatchRenderer2D

Quantidade de Texturas Texturas Alternando

Slots de Textura 16

Sprites Chamadas à GPU Microsegundos

10 1 177

50 4 185

200 13 218

1000 63 365

5000 313 1255


41

Renderer Renderer2D

Quantidade de Texturas 1

Slots de Textura 32

Sprites Chamadas à GPU Microsegundos

10 10 198

50 50 253

200 200 509

1000 1000 1930

5000 5000 9063

Renderer Renderer2D

Quantidade de Texturas Texturas Alternando

Slots de Textura 32

Sprites Chamadas à GPU Microsegundos

10 10 274

50 50 255

200 200 506

1000 1000 1933

5000 5000 9090


42

Renderer BatchRenderer2D

Quantidade de Texturas 1

Slots de Textura 32

Sprites Chamadas à GPU Microsegundos

10 1 198

50 1 175

200 1 180

1000 1 176

5000 5 209

Renderer BatchRenderer2D

Quantidade de Texturas Texturas Alternando

Slots de Textura 32

Sprites Chamadas à GPU Microsegundos

10 1 178

50 2 181

200 7 203

1000 32 298

5000 157 808

5.2 - Observações
Vendo os gráficos acima, mostra-se evidente que a técnica de batch rendering é
significantemente superior ao rendering inormal, principalmente quando se trata de
renderizar um número maior que 200 de sprites num mesmo frame. Além disso,
algumas outras observações podem ser feitas:
43

Entre utilizar uma textura ou alterná-las continuamente para o rendering normal


não impactou a performance de modo algum, uma vez que o rendering normal sempre
faz um número de chamadas idêntico a quantidade de sprites.
O mesmo se aplica a despeito de terem 16 ou 32 slots disponíveis na GPU, nenhuma
diferença sendo notada.
Quando se utiliza apenas uma textura, sem alternar, seja no uso de 16 ou 32
slots, se mostrou consistente e muito superior ao rendering normal no seu tempo
mesmo quando se trata de um impressionante número de 5000 sprites na tela do
computador.
Na renderização de 5000 sprites, foi uma diferença de velocidade de 43,5 vezes,
enquanto no uso de 1000 sprites, uma diferença de 10 vezes.
A não ser que o usuário realmente queira realmente renderizar apenas uma
única textura, o que pode ser comum, quando se trata de um sistema de partículas de
um jogo, por exemplo, em cenário mais realistas, a diferença será menor, uma vez que
o batch rendering não conseguirá realizar tudo em apenas uma chamada. Por isso, no
cenário em que se utiliza texturas alternando, a diferença foi de apenas 7 vezes, para
5000 sprites 5 vezes, para 1000 e de 2.5 vezes para 200, se mantendo mais ou menos
no mesmo tempo quando se trata de um número inferior de sprites.
Quando imposto o limite de 32 slots, a diferença consegue ser de 11.25 vezes
para 5000 sprites, 6.4 vezes para 1000 sprites, e de 2.5 vezes para 200 sprites.

6 - Conclusão
O projeto desenvolvido tinha o objetivo de criar um simples programa de
computador sandbox que realizaria uma série de testes na API de computação gráfica
OpenGL, e assim, comparar os resultados de usar uma técnica comum de renderização
de objetos com uma técnica mais avançada chamada de batch rendering, que utiliza
melhor os recursos da GPU.
O programa foi desenvolvido com sucesso, e os testes foram realizados e seus
resultados foram gravados em arquivos de texto, com todos os dados necessários para
a comparação entre as duas técnicas.
44

Antes da execução do software, era esperado que a técnica avançada batch


rendering oferecesse uma performance consideravelmente superior a técnica comum,
sobretudo quando se tratava de renderizar uma quantidade grande de objetos num
mesmo frame.
Tendo os resultados em mãos, os resultados corresponderam às hipóteses
iniciais, indicando que o batch rendering possui uma performance consideravelmente
superior em quase todos os casos analisados, sendo uma técnica muito mais eficiente
quando se trata de renderizar objetos utilizando do OpenGL.
Assim, conclui-se que estudantes ou desenvolvedores que desejam utilizar o
OpenGL para seus projetos que utilizem gráficos 2D, terão grandes benefícios ao
utilizar a técnica apresentada.

7 – Referências
MEIRELLES, Adriano. Como funciona o LCD. Hardware, 2002. Disponível em:
https://www.hardware.com.br/livros/hardware-manual/como-funciona-lcd.html. Acesso
em: 25 nov. 2022.

GORDON, V; CLEVENGER, John. Computer Graphics Programming in OpenGL


with C++. Second Edition. Mercury Learning and Information, c2021. Disponível em:
https://terrorgum.com/tfox/books/
computergraphicsprogrammminginopenglusingcplusplussecondedition.pdf. Acesso em:
25 nov. 2022.

SIQUEIRA, Fernando. Conceitos de Computação Gráfica. Sites Google, [s.d].


Disponível em:
https://sites.google.com/site/profferdesiqueiracompgrafica/aulas/aula-1---conceitos-de-
computacao-grafica. Acesso em: 25 nov. 2022.

SANTANA, Ana. História do Videogame. Infoescola, c2006-2022. Disponível em:


45

https://www.infoescola.com/curiosidades/historia-do-videogame. Acesso em: 25 nov.


2022.

GONÇALVES, Júnior. Introdução a computação gráfica. HyperBytes, c2020-2021.


Disponível em:
https://www.hiperbytes.com.br/introducao-a-computacao-grafica. Acesso em: 25 nov.
2022.

MANSSOUR, Isabel. Introdução à OpenGL. Pucrs, Escola Politécnica, 2003.


Disponível em:
https://www.inf.pucrs.br/~manssour/OpenGL/Introducao.html. Acesso em: 25 nov. 2022.

ECK, David. Introduction do Computer Graphics, 2021. Disponível em:


https://math.hws.edu/graphicsbook/c2/s1.html. Acesso em: 25 nov. 2022.

VRIES, Joey. Learn OPENGL – Graphics Programming, 2020. Disponível em:


https://learnopengl.com/book/book_pdf.pdf. Acesso em: 25 nov. 2022.

KRZEMINSKI, Marek. OpenGL Batch Rendering. Gamedev, 2014. Disponível em:


https://www.gamedev.net/tutorials/programming/graphics/opengl-batch-rendering-
r3900/. Acesso em: 25 nov. 2022.

SILVA, Edson. Opengl completa três décadas de constante evolução. Diolinux,


2012. Disponível em:
https://diolinux.com.br/noticias/opengl-completa-tres-decadas.html. Acesso em: 25 nov.
2022.

SHREINER, Dave. Et al. OpenGl Programming Guide: The Official Guide to


Learning Opengl, Version 4.3. Eighty Edition. Michigan: Edwards Brothers Malloy in
Ann Arbor, 2003. Disponível em:
46

https://www.cs.utexas.edu/users/fussell/courses/cs354/handouts/
Addison.Wesley.OpenGL.Programming.Guide.8th.Edition.Mar.2013.ISBN.0321773039.
pdf. Acesso em: 25 nov. 2022.

SARROGLIA, Márcio. Origens da Computação Gráfica. Pucrs, Escola Politécnica,


[s.d]. Disponível em:
https://www.inf.pucrs.br/~pinho/CG/Aulas/Intro/introOLD.htm. Acesso em: 25 nov. 2022.

LUIZ, André. O que é Computação Gráfica. Ambiente DESIGN, 2018. Disponível em:
http://www.um.pro.br/index.php?c=/computacao/definicao. Acesso em: 25 nov. 2022.

COUTINHO, Thiago. O que é Computação Gráfica? Descubra as melhores


oportunidades na área!. Voitto, 2021. Disponível em:
https://www.voitto.com.br/blog/artigo/o-que-e-computacao-grafica. Acesso em: 25 nov.
2022.

Equipe NZN. O que é OpenGL. Tecmundo, 2008. Disponível em:


https://www.tecmundo.com.br/video-game-e-jogos/872-o-que-e-opengl-.htm. Acesso
em: 25 nov. 2022.

TADEU, Vinicius; TORTELLA, Tiago. Público gamer cresce e 3 em cada 4 brasileiros


consomem jogos eletrônicos. CNN Brasil, 2022. Disponível em:
https://www.cnnbrasil.com.br/tecnologia/publico-gamer-cresce-e-3-em-cada-4-
brasileiros-consomem-jogos-eletronicos/. Acesso em: 25 nov. 2022.

KONTUS, Karl. There are 44,000 game developers on Steam. Who are they?. Game
Developer, 2022. Disponível em: https://www.gamedeveloper.com/blogs/there-are-44-
000-game-developers-on-steam-who-are-they-. Acesso em: 25 nov. 2022.

Você também pode gostar