Comecei a assistir o stream Handmade Hero , onde Casey Muratori cria um mecanismo de jogo sem usar estruturas ou algo assim. Ontem cheguei à parte em que ele mostrou como uma imagem é desenhada na tela. Tanto quanto eu entendi, ele apenas alocou uma memória tão grande quanto o tamanho da tela que ele deseja desenhar. E então ele criou um bitmap que ele passou para a memória buffer que ele alocou e desenhou na tela usando uma função específica do sistema operacional.
Isso parece bastante direto. Eu usei o GameMaker, mudei para o Love2D, trabalhei um pouco com o Sprite Kit, mas sempre me perguntava o que realmente estava acontecendo sob essas camadas, às vezes confusas.
Dado isso, por que se preocupar em usar as bibliotecas gráficas (OpenGL, SFML, SDL,…) quando tudo o que você precisa fazer é simplesmente alocar algum buffer, passar um bitmap e desenhá-lo na tela?
Se você deseja desenhar coisas distintas para sua tela, basta escrevê-las no seu bitmap, que é passado para o buffer. Eu sou bastante novo em programação, mas isso me parece bastante simples. Por favor me corrija se eu estiver errado.
fonte
Respostas:
Não se trata apenas de velocidade de execução, mas também de simplicidade. Embora a renderização de software usada neste exemplo seja muito mais lenta que a aceleração de hardware (por exemplo, uma GPU), desenhar alguns bitmaps na tela é uma tarefa tão trivial que você não notaria a queda no desempenho.
No entanto, atividades de baixo nível, como rasterização de triângulo, classificação de profundidade e similares, são conceitos bem entendidos com os quais a GPU pode lidar implicitamente com alguns comandos. Reimplementar aqueles no modo de software é essencialmente reinventar a roda. Tudo bem, se você quiser entender de baixo nível como a renderização é feita, eu mesmo escrevi um renderizador de software 3D apenas para explorá-lo um pouco, mas na maioria das circunstâncias é uma perda de tempo quando o OpenGL pode fazê-lo mais rapidamente. a Caixa.
O exemplo que você deu parece extremamente básico, basta desenhar uma única imagem na tela; portanto, a implementação é fácil. Porém, quando você começa a estratificar a complexidade, fica cada vez mais complicado obter tudo da renderização correta. As coisas que as pessoas tinham que fazer nos dias de Quake na renderização de software 3D eram insanas, embora eu aprecie que você não esteja indo tão longe (ainda).
fonte
Curto: Por ser rápido (OpenGL, DirectX).
Grandes:
Você pode pensar que pode fazer isso sozinho. Desenhe pixels para uma tela. Você pode escrever uma pequena biblioteca para desenhar formas, como quads ou triângulos. Isso vai funcionar, é claro. Existem muitas bibliotecas por aí para fazer exatamente isso. Alguns deles até implementam a especificação OpenGL (então eles são como um lado do software para opengl), que fará exatamente o que Casey Muratori faz. Eles calculam tudo no lado do software, definem os pixels no lado do software e gravam o resultado na tela.
No entanto, isso é lento . A CPU que eventualmente executará todas essas coisas não foi feita para esse cenário. É para isso que servem as GPUs. O que o OpenGL faz (a menos que seja uma implementação de software, é claro) é levar tudo o que você manda fazer e enviar todos os dados, todas as chamadas de chamada, quase tudo para a placa gráfica e dizer à GPU para fazer o trabalho. A GPU é feita especificamente para esse tipo de trabalho. Multiplicando números de ponto flutuante (isso é o que você faz muito ao desenhar uma cena 3D) e executando shaders. E isso em paralelo. Apenas para ter uma noção da velocidade da GPU, pense em uma cena simples em 3D em tela cheia com 1920x1080 pixels. Estes são, multiplicados, 2.073.600 pixels para desenhar. Para cadapixel, a GPU executará o fragment-shader pelo menos uma vez , na maioria das vezes mais de uma vez. Agora, digamos que rodemos a 60 quadros por segundo. Isso significa que a GPU executa o fragmento-shader 2.073.600 * 60 = 124.416.000 vezes por segundo . Você acha que pode fazer algo assim na sua CPU? (Essa é uma explicação bastante simplificada, há muito mais coisas a considerar, como quantos pixels você extrai por objetos mais próximos, quanto MSAA você usa e assim por diante; no entanto, as 124.416.000 vezes por segundo são provavelmente as mais baixas que você pode obter e você facilmente terá muito mais que 60 qps com uma cena simples)
É o que o OpenGL e o Direct3D fazem, para quais mecanismos a resposta de @Uri Popovs.
fonte
O que ele faz é chamado renderização de software , o que o OpenGL faz é chamado renderização de GPU
Qual a diferença entre eles? Velocidade e memória.
A rasterização (preenchendo triângulos na tela) leva algum tempo. Se você faz isso na CPU, essencialmente dedica esse tempo à lógica do jogo, especialmente se ela não for otimizada.
E não importa, quão pequena é a imagem, ele precisa alocar certa quantidade de memória para ela. GPUs têm uma memória de vídeo para isso.
fonte
Embora as respostas de outras pessoas sejam mais corretas do que qualquer resposta que eu possa dar, quero salientar o mal-entendido fundamental sobre como funciona o desenvolvimento de software que, na minha opinião, é subjacente à sua pergunta. Embora seja sempre possível fazer as coisas "sozinho" sem uma estrutura, e geralmente há um grande benefício educacional, a realidade é que não é assim que o software moderno é criado.
Alguém criou o hardware e as linguagens de máquina que são executadas nele. Outra pessoa cria linguagens e compiladores, drivers e sistemas operacionais de nível superior, bibliotecas de gráficos e assim por diante. Cada um de nós constrói sobre o trabalho de nossos predecessores. Isso não é apenas "ok", é um requisito.
Você está traçando a linha do que é "aceitável" ou não em um ponto arbitrário na cadeia de ferramentas. Você poderia dizer com a mesma facilidade "por que usar C ++ quando você pode fazer a mesma coisa na montagem?" Ou "por que confiar nos drivers do teclado quando você pode facilmente ler as tensões saindo de seus fios e calculá-lo você mesmo?" Não há horas suficientes no dia ou anos na vida para que todos façam tudo sozinhos.
Isso não se aplica apenas ao desenvolvimento de software, mas à vida moderna em geral. Você já ouviu falar do cara que construiu uma torradeira, a partir do zero? http://www.thomasthwaites.com/the-toaster-project/ . Demorou muito tempo e muito esforço. Para uma torradeira. Tente criar tudo o que é necessário para atualizar um videogame fora do éter sozinho!
fonte
Os motores fazem muito mais do que apenas desenhar uma imagem na tela. Eles lidam com iluminação, sombras, entrada, detecção de colisão. Mesmo apenas a parte de renderização é muito mais complexa do que apenas colocar um buffer na tela. Especialmente em cenas 3D, é necessário fazer muitos cálculos em dados muito mais complexos do que um bitmap. Deixe-me fazer uma analogia com um carro: o que você descreve como simples é a exaustão do carro. Você apenas faz um cano com o tamanho certo e empurra o gás de uma ponta à outra. No entanto, isso está longe de ser a única coisa que acontece no mecanismo do carro.
fonte
As respostas acima são excelentes, mas nenhuma realmente aborda o motivo mais importante do motivo pelo qual o OpenGL e outros são os preferidos. O principal motivo é fazer uso de hardware dedicado projetado especialmente para trabalhar com renderizações de milhões de pixels em uma tela, a GPU .
Com a renderização do software, usando a CPU, o renderizador fará um loop, um por um, sobre todos os pixels em um bitmap e emitirá ordens para mostrar cada um na tela. Portanto, se você estiver renderizando uma imagem de 1000 x 1000, esses 1.000.000 de loops para a CPU passarem. Eles são projetados com o controle em mente, afinal; muitas condições, saltando de um conjunto de instruções para outro e uma direção estrita do fluxo de controle. No entanto, uma GPU é projetada com o conhecimento de que fará muitos ciclos semelhantes sobre pixels na tela.Uma GPU pegaria um loop for com 1000000 iterações e dividiria o trabalho sobre seu grande número de núcleos para que cada um trabalhasse ** em paralelo e independente um do outro **. Portanto, diferentemente da CPU, toda vez que uma GPU se depara com uma condição if-else, ela manipulará ambas as ramificações de código em dois núcleos de si mesma. resultado da ramificação desnecessária (é por isso que muitas condições if-else nos shaders da GPU são desaprovadas; elas sempre são responsáveis por um desperdício).
Então, sim, as GPUs são construídas em torno do paralelismo . Isso torna o trabalho em pixels muito mais rápido em comparação com as CPUs.
fonte
Consulte Preciso realmente usar uma API de gráficos?
Claro, você pode pedir um buffer, colocar alguns bits nele e gravá-lo na tela. Essa foi essencialmente a única maneira de programar gráficos no PC até a disponibilidade de aceleradores gráficos em meados dos anos 90 do 3DFX. Mesmo no Windows, o DirectX foi desenvolvido para fornecer acesso direto à memória de vídeo.
Porém, no hardware que não é o PC, nas máquinas de jogos dedicadas, sempre houve técnicas para acelerar os gráficos, descarregando o trabalho do processador. Até o Atari 2600 tinha "sprites de hardware", em parte porque não tinha RAM suficiente para um buffer de quadros.
Mais tarde (meados dos anos 80), os consoles de jogos foram otimizados para jogos de plataforma. Novamente, nenhum framebuffer; em vez disso, o programador pode especificar grades de blocos :
fonte
As CPUs modernas são rápidas o suficiente para executar qualquer jogo 2D no software; portanto, para gráficos 2D, o OpenGL / DirectX não oferece vantagens, além de adicionar mais uma dependência e uma camada de complexidade ao seu projeto, como, por exemplo, definir uma matriz de projeção 3D para desenhar um monte de sprites e upload de dados para a GPU.
O OpenGL também o forçaria a empacotar todos os seus sprites em texturas de 512x512 (um artefato de consoles antigos, como PSX, empacotando gráficos em páginas de memória de vídeo), exigindo que você escrevesse um código de empacotamento de sprites bastante complexo.
Por outro lado, se você estiver fazendo 3d, renderizando milhões de triângulos com sombreamento complexo, a GPU é inevitável. Há muito tempo, havia a versão 2D mais simples do Direct3d, chamada DirectDraw, que o GPU acelerava o desenho de sprites, mas agora a Microsoft não o suporta mais, possivelmente porque as CPUs são rápidas o suficiente para fazer o 2D sem aceleração, se você não se importa com economia de energia .
fonte