Escolar Documentos
Profissional Documentos
Cultura Documentos
Análise de Performance de Batch Rendering para Sprites 2D em OpenGl
Análise de Performance de Batch Rendering para Sprites 2D em OpenGl
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.
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.
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
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
2 - Referencial Teórico
2.1 – Computação Gráfica
A computação gráfica é definida como:
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):
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)
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.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:
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.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
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.1- Renderer2D
13
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.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:
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.
Fonte: O autor
16
Fonte: O Autor
17
Fonte: O Autor
18
Fonte: O Autor
19
Fonte: O Autor
20
Fonte: O Autor
21
Fonte: O Autor
22
Fonte: O Autor
23
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
Fonte: O Autor
26
Fonte: O Autor
27
Fonte: O Autor
28
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
Fonte: O Autor
31
Fonte: O Autor
32
Fonte: O Autor
Fonte: O Autor
35
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
Fonte: O Autor
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
10 10 216
50 50 252
Renderer Renderer2D
Slots de Textura 16
10 10 273
50 50 252
Renderer BatchRenderer2D
Quantidade de Texturas 1
Slots de Textura 16
10 1 196
50 1 178
200 1 187
1000 1 175
5000 5 206
Renderer BatchRenderer2D
Slots de Textura 16
10 1 177
50 4 185
200 13 218
1000 63 365
Renderer Renderer2D
Quantidade de Texturas 1
Slots de Textura 32
10 10 198
50 50 253
Renderer Renderer2D
Slots de Textura 32
10 10 274
50 50 255
Renderer BatchRenderer2D
Quantidade de Texturas 1
Slots de Textura 32
10 1 198
50 1 175
200 1 180
1000 1 176
5000 5 209
Renderer BatchRenderer2D
Slots de Textura 32
10 1 178
50 2 181
200 7 203
1000 32 298
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
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
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.
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.
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.
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.