Que vantagem o OpenGL, SFML e SDL têm sobre a renderização de software?

24

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.

user148013
fonte
11
mais tarde em sua série (por volta do episódio 220), ele usará o opengl. A razão pela qual ele faz isso é a velocidade.
catraca aberração
5
O truque é determinar o que desenhar na tela. Todo o material de textura / sombreamento da GPU, triângulos, projeções da câmera etc. precisam ser feitos primeiro para decidir qual a cor de cada pixel. Empurrar as cores dos pixels para a tela é a parte mais fácil.
User14146
2
Para o registro, SDL e OpenGL não são mutuamente exclusivos. O SDL é uma "camada de abstração de hardware" que também lida com janelas, eventos e entradas, em vez de ser apenas uma biblioteca de gráficos. O SDL também tem suporte para ser usado em conjunto com o OpenGL, para que o SDL possa fazer todo o material não-gráfico enquanto o OpenGL lida com os gráficos. Observe também que, na maioria das vezes, o OpenGL trabalha diretamente com a GPU, enquanto o SDL pode ou não, dependendo da versão e do sistema que está sendo compilado.
Pharap
O SFML usa o OpenGL para renderização; portanto, tudo o que o SFML faz é fornecer uma interface mais simples para o uso do OpenGL.
Cornstalks
2
O técnico que Casey está fazendo ainda está usando uma biblioteca de gráficos. A biblioteca é chamada GDI e, embora faça parte da API principal do sistema operacional, ainda é tecnicamente uma biblioteca de gráficos.
Pharap

Respostas:

41

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).

Richard Greenlees
fonte
12
O OpenGL conhece termos como pontos, linhas e triângulos. Na maioria das vezes, você trabalha com triângulos. Para aprender a trabalhar com o OpenGL , recomendo o opengl-tutorial.org . Para saber o que OpenGL não sob o capô uma olhada no wiki oficial: opengl.org/wiki/Rendering_Pipeline_Overview
tkausl
11
Eu estava marcando +1, mas não gosto de "reinventar a roda" porque sinto que isso dá uma impressão errada em termos da história da computação. A renderização de bitmap veio em primeiro lugar, portanto o OpenGL foi quem "reinventou a roda". Eles tinham dois bons motivos para fazer isso: 1) Padronização e 2) Aceleração da GPU. Reinventar a roda nem sempre é uma coisa ruim se a nova versão for uma melhoria (ou seja, rodas com pneus x rodas de carroça de madeira). O ponto-chave aqui não deve ser que a renderização de software está reinventando a roda; deve ser inferior à renderização da GPU.
Pharap
4
@Pharap, exceto que agora , escrever um renderizador de software absolutamente está reinventando a roda, independentemente de ter sido historicamente ou não.
Porglezomp 14/05
11
Isso é apenas meia resposta. A próxima resposta é a outra metade, mas uma resposta completa (incluindo uma explicação da diferença entre o OpenGL e as outras coisas que ele menciona) seria a resposta correta para essa pergunta.
Jasper
11
@ user148013 "O opengl conhece termos como ponto, linha, triângulo?" O OpenGL moderno lida exclusivamente com essas primitivas. Você não pode rasterizar nada além deles.
Nax 'vi-vim-nvim'
25

Minha pergunta é: por que se preocupar em usar algo como open gl, sfml, sdl quando tudo o que você precisa fazer é simplesmente alocar algum buffer, passar um bitmap e desenhá-lo na tela?

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.

tkausl
fonte
8
Ele está criando um jogo 2D, esse é outro tópico como o 3D. E quando digo lento , não significa necessariamente que tenha menos de 60 qps, mas significa que a placa gráfica fará o mesmo trabalho em uma fração do tempo que a CPU precisa, pelo menos no que diz respeito ao espaço 3D.
21416 Tinkerbell #
4
Bem, a razão pela qual as GPUs são melhores nisso é porque elas são configuradas para paralelizar as invocações do shader.
catraca aberração
4
@ user148013 Pelo que vi desse cara, eu diria que ele é exatamente o oposto de "muito sábio".
Bartek Banachewicz
4
Não é apenas mais lento para renderizar (o renderizador de software de Casey foi surpreendentemente rápido). É também um monte de dados para continuar passando da RAM geral para a RAM de vídeo. Enviar um bitmap gigante para a placa de vídeo, dependendo do tipo de barramento, pode levar um tempo significativo de um quadro. Usando a GPU, você pressiona as texturas ocasionalmente e as usa para quadros após quadros.
Adrian McCarthy
2
@ user148013 Há uma diferença entre uma programação chamativa e boa. Eles podem se sobrepor, mas geralmente estão em conflito. Eu colocaria "Eu posso renderizar em software [como o MESA pode ...]" sob chamativo e certamente não é bom .
11

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.

Bálint
fonte
A renderização de software também é possível no OS X? Porque parece que tudo o que tem a ver com gráficos foi feito pelo OpenGl agora Metal.
User148013
2
@ user148013 Você tem alguns mal-entendidos. O OpenGL é uma API multiplataforma, para que possa ser executado no OS X, de fato, pode ser executado em tudo com uma GPU "moderna" (pós-2000). O Metal é uma API separada apenas para dispositivos Apple. A renderização de software também é uma coisa separada dos dois, e sim, também pode ser feita no OS X. É basicamente apenas definir pixels manualmente na tela com a CPU.
Bálint
Foi exatamente por isso que perguntei, porque, até onde eu sei, a renderização de software não pode ser feita no OS X. O Cocoa alcança o OpenGl, Quarz usa o OpenGl, o Core Framework usa o OpenGl. Todos agora usam o Metal como seu caminho mais rápido. Mas eu não encontrei uma única função que atraia um buffer para a tela sem o uso da GPU (OpenGl, Metal).
User148013
11
@ user148013 Porque não é específico para um SO nem implementações. Digamos que você queira implementá-lo em java, porque é uma escolha famosa para o desenvolvimento de várias plataformas. Com o java, você pode fazer isso primeiro criando uma janela (JFrame) e, em vez de desenhá-la diretamente, desenha uma imagem e coloca essa imagem no quadro. No entanto, não conhecerá os termos "triângulo" ou "linha". Apenas cores. Você precisa implementar isso com um algoritmo de rasterização. É por isso que preferimos o OpenGL, é mais rápido e um pouco mais fácil de usar. É basicamente uma API de rasterização.
Bálint 13/05
2
@ user148013 Por que eles não podiam? Se eles podem abrir uma janela e desenhar uma imagem nela sem uma API, eles podem.
Bálint
8

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!

erich8
fonte
2
Eu acho que essa é uma boa resposta, porque afirma por que usar estruturas é bom sem menosprezar a idéia de reinventar a roda para fins educacionais.
Pharap
3

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.

Uri Popov
fonte
3

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.

Aiman ​​Al-Eryani
fonte
0

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 :

O hardware gráfico Genesis consiste em 2 planos roláveis. Cada avião é composto de peças. Cada bloco é um quadrado de 8x8 pixels com 4 bits por pixel. Cada pixel pode ter 16 cores. Cada bloco pode usar 1 de 4 tabelas de cores; portanto, na tela, você pode obter 64 cores de uma só vez, mas apenas 16 em qualquer bloco específico. Os blocos requerem 32 bytes. Há 64K de memória gráfica. Isso permitiria 2048 blocos únicos se a memória fosse usada para mais nada.

pjc50
fonte
-2

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 .

SmugLispWeenie
fonte