Este é o primeiro devlog deste projeto comentando sobre tudo que há na versão 0.1-alpha.
Primeiro de tudo o meu foco é atingir o máximo de jogadores possível, isso pode ser observado na classe DisplayManager, no momento da criação do contexto eu setei para o jogo utilizar no máximo a implementação 3.3 Core do OpenGL.
Porém, é possível observar eu utilizando técnicas presentes na implementação 4.2 Core, futuramente irei adicionar checagens para determinar se uma determinada implementação contém as extensões necessárias para a renderização mais moderna.
Um desses momentos é quando uso a extensão ‘GL_ARB_shading_language_420pack’ que permite o uso de Layout Classifiers no GLSL e outras coisas interessantes como a função ‘bindTextureUnit’ e o Layout Classifier ‘binding’ que facilitam a manipulação de texturas.
A classe Engine é o coração do jogo, é onde está o Main Game Loop e onde está inicialização de diversos componentes necessários para utilização da mesma. No momento a classe está com diversos códigos que não deveriam estar lá como o carregamento de entidades e assets. O carregamento de assets deve ser feito por um callback futuramente ou alguma outra forma de carregar os assets.
No momento o método ‘render(StaticShader)’ da classe Renderer não deveria aceitar aquele shader ali. Tenho planos de fazer uma função genérica que identifica qual entidade está sendo adicionada e faz ela ser atribuída ao Renderer correspondente ao Shader necessário.
Já falando sobre a classe Renderer, a mesma utiliza uma técnica chamada Batch Rendering, onde você inibe a necessidade de fazer chamadas de binding para o mesmo VAO centenas de vezes. Resumindo, você binda o VAO e itera sobre a lista de entidades somente atualizando seus materiais e posições criando um efeito de múltiplos objetos, sendo que atualmente somente um VAO está sendo usado! Isto gera um aumento de eficiência absurdo (fiz uns benchmarks em outro projeto, onde eu renderizei 15 000 cubos, com e sem essa técnica, mais disso em outro post).
Sobre as classes Material, Texture e Model creio que seja tudo bem auto explicativo. Essas classes são como esqueletos, somente um agregado de IDs e vetores que o OpenGL usa para renderização.
Creio que as duas classes mais interessantes são a MeshLoader e a ShaderProgram, vou começar pela MeshLoader.
Esta classe serve para transformar dados crus em dados atualmente legíveis pelo OpenGL, indicar sua estrutura e enviar os mesmos para a GPU! Isto é feito com o uso de VBOs. São utilizados dois tipos de VBOs, VERTEX_ARRAY_BUFFER e ELEMENT_ARRAY_BUFFER; consecutivamente, para armazenar dados como posições, coordenadas de texturas, normais e cores, o outro para os índices.
No código é possível observar que no caso dos VBOs gerados com VERTEX_ARRAY_BUFFER dou um unbind e não no que usa ELEMENT_ARRAY_BUFFER, faço isto porque diferente dos outros VBOs o ELEMENT_ARRAY_BUFFER tem um espaço reservado no VAO sendo assim ele não precisa ter sua estrutura de dados especificada muito menos ser unbinded.
A classe ShaderProgram é uma classe abstrata que serve de modelo para todos os shaders do projeto. Essa classe, carrega, compila e testa shaders e então junta tudo em um programa que é utilizado para renderização.
Essa classe também define funções para manipular Uniform Variables do GLSL.
Note que em praticamente todas as classes onde há geração de objetos OpenGL há uma função exit! Isto é de extrema importância, isso limpa toda a memória alocada manualmente, que é muito mais eficiente que simplesmente fechar o programa e esperar o GC trabalhar (isso quando ele trabalha). Caso eu estivesse programando em C++ não limpar a memória poderia causar todo tipo de falha satânica que deixa o seu InvocationTargetException parecer brincadeira de criança.
No final do dia o que temos? Uma telinha fofa com 2 sirenes cabulosas (texturas em um plano) sendo renderizadas na metade esquerda da tela.