As APIs: DirectX e OpenGL

Diferente dos processadores, que utilizam um conjunto comum de instruções (o x86), os chipsets de vídeo são regidos por uma certa anarquia, onde não existe uma interface padrão, especialmente entre chipsets de diferentes fabricantes.

Na época do MS-DOS, os jogos acessavam diretamente o frame-buffer e os demais recursos da placa de vídeo. Embora isso permitisse extrair o máximo de desempenho das placas limitadas da época, aumentava muito o trabalho dos programadores, que precisavam escrever rotinas separadas para cada modelo de placa disponível. Funcionava enquanto os jogos utilizavam gráficos 2D simples (como no caso do antigo Warcraft 2) e o número de placas diferentes era relativamente pequeno, mas se tornou inviável a partir do início da era 3D, devido à complexidade do trabalho e às diferenças de arquitetura entre os diferentes chipsets.

Surgiram então as APIs para a criação de gráficos 3D, que facilitam o trabalho do desenvolvedor, oferecendo um conjunto de comandos e recursos padronizados, que podem ser usados em qualquer placa 3D compatível. Passou então a ser responsabilidade dos fabricantes tornarem seus chipsets compatíveis com as APIs existentes e disponibilizar drivers, assegurando que os títulos existentes rodarão com um bom desempenho.

De certa forma, uma API lembra bastante uma linguagem de programação de alto nível, como o C++, onde você desenvolve os aplicativos usando as funções disponíveis e deixa que o compilador se encarregue de gerar o código de máquina que será executado pelo processador.

As funções disponíveis determinam diretamente o que é possível fazer, o que transforma a API em um potencial gargalo: uma API deficiente ou desatualizada pode limitar severamente o desenvolvimento, bloqueando o acesso a recursos disponíveis na GPU. Assim como tudo na informática, as APIs evoluem, incorporando novas funções e se moldando aos chipsets 3D existentes, mantendo a corrida de gato e rato.

A primeira API 3D para jogos a se tornar popular foi o Glide, criado pela antiga 3dfx para uso em suas próprias placas. Ele surgiu como uma versão reduzida do OpenGL, otimizada para a criação de gráficos em tempo real, cujas funções eram implementadas diretamente no hardware das placas. Essa abordagem tinha suas limitações (não era possível incluir novas funções sem modificar os chipsets e não era possível corrigir bugs ou atualizar as placas já disponíveis) mas ofereceria ganhos significativos de desempenho.

A combinação da API fácil de usar e do bom desempenho permitiu que a Voodoo (lançada em 1996) e a Voodoo 2 (1998) dominassem rapidamente o mercado, praticamente inventando o ramo das aceleradoras 3D para jogos.

Na época, a maioria dos jogos (Need for Speed II SE, Carmageddon, Tomb Raider, Virtua Fighter II, Resident Evil, MechWarrior, etc., etc. 🙂 podiam rodar também em modo de renderização via software (sem uma aceleradora 3D), mas nesse caso o desempenho era limitado e os gráficos ficavam muito mais simples.

m7a4f3962

m23969728

Need for Speed II SE com aceleração em Glide e uma Voodoo 1

O Glide era uma solução bastante elegante, que permitia criar jogos facilmente portáveis para outras plataformas. O lado negro era o fato de ele ser completamente fechado e proprietário, disponível apenas para as placas da própria 3dfx. Se ele tivesse prevalecido, a 3dfx teria um quase monopólio dos chipsets 3D, o que não seria uma boa coisa.

Embora tenha sido a API dominante nos primeiros anos, o Glide decaiu rapidamente entre 1998 e 2000 devido à queda de popularidade das placas da 3dfx, que passaram a perder mercado para as placas da Rendition, Matrox e S3, que logo deram lugar às placas da nVidia e da ATI.

Inicialmente, ambas tiveram dificuldades em concorrer com as placas da 3dfx devido à falta de suporte ao Glide, mas o uso de ciclos mais rápidos de desenvolvimento (sobretudo por parte da nVidia) combinados com preços mais competitivos e migrações mais rápidas para novas técnicas de fabricação, acabaram fazendo a balança tender para o lado oposto. No final, a 3dfx acabou indo à falência, depois de vender parte da propriedade intelectual para a nVidia.

É possível rodar jogos antigos, que utilizam o Glide em placas atuais utilizando os glide-wrappers, que são emuladores destinados a processar as instruções via software (simular uma Voodoo com seus 50 megapixels de throroughput não é problema para um processador atual) ou convertê-las em chamadas OpenGL. Dois bons exemplos são o OpenGlide (http://sourceforge.net/projects/openglide/) e o dgVoodo (http://www.freeweb.hu/dege/).

Com o Glide saindo de cena, foi aberto o caminho para o domínio do OpenGL e do Direct3D, dando início à era moderna. O Direct3D faz parte do DirectX, que é, na verdade, um conjunto de APIs, cada uma com uma função específica relacionada a multimídia. Entre elas, o Direct3D é a API específica para a geração de gráficos 3D.

O OpenGL é na verdade bem mais antigo que o Glide, em uma história que remonta às estações de trabalho da década de 80. Ele surgiu oficialmente em 1992 quando, pressionada pelos concorrentes, a SGI decidiu criar uma API aberta com base no IrisGL, usado em suas estações de trabalho. Embora o objetivo inicial fosse o uso em aplicativos profissionais de CAD e renderização 3D, o OpenGL logo passou a ser usado também em jogos, com os fabricantes de chipsets e placas 3D se esforçando para adicionar o suporte a ele em seus chipsets. Como comentei, o próprio Glide surgiu como uma versão reduzida do OpenGL, implementada via hardware.

Além do fato de ser um padrão aberto, desenvolvido por uma associação de fabricantes, uma das principais vantagens é o fato de o OpenGL ser uma API multiplataforma, o que permite que os aplicativos e jogos sejam portados para o Linux e outras plataformas sem muita dificuldade.

Um bom exemplo são os jogos da ID Software, que possuem todos versão Linux. Neles, a instalação é feita usando os mesmos CDs da versão Windows, você precisa apenas baixar o executável do jogo para Linux, disponível para download. A lista inclui o Doom3, que foi um dos últimos grandes lançamentos baseados no OpenGL:

m62327a54

Doom3, em versão Linux

O Direct3D, por sua vez, surgiu em 1995 quando percebendo que os jogos 3D seriam o futuro, a Microsoft decidiu incorporar uma API 3D no DirectX. Nas primeiras versões, o Direct3D era visto como uma API limitada, que era usada mais devido a incentivos e subsídios por parte da Microsoft do que por méritos próprios. Entretanto, as coisas começaram a mudar a partir do DirectX 7.0, que atingiu uma quase paridade de recursos com o OpenGL, ao mesmo tempo em que oferecia ferramentas de desenvolvimento mais fáceis de usar. Com exceção da ID Software, que continuou leal ao OpenGL, a maioria das software houses começaram a debandar para o DirectX.

A tendência foi reforçada com o lançamento do DirectX 8.0 (lançado no final de 2000), que trouxe o suporte a shaders, e com o 8.1 (final de 2001), que trouxe várias melhorias na interface de desenvolvimento.

Inicialmente, os shaders são foram tão usados pelos desenvolvedores de jogos, em parte devido à falta de familiaridade com o conceito e em parte devido às limitações do DirectX 8 e das GPUs da época. Entretanto, a adoção cresceu rapidamente com o DirectX 9.0 (lançado em dezembro de 2002), que trouxe o suporte ao Shader Model 2.0 e se solidificou com o DirectX 9.0c (2004) e a inclusão do Shader Model 3.0, que se tornou a plataforma comum da maioria dos títulos lançados entre 2005 e 2009.

O OpenGL, por outro lado, acabou ficando um longo tempo estagnado, com as inovações sendo introduzidas lentamente devido às divergências entre os membros do conselho. A própria SGI acabou saindo do mercado depois de ver suas estações de trabalho perderem espaço para placas das linhas Quadro FX da nVidia e FireGL/FirePro da ATI que, devido ao grande volume de produção das placas domésticas, são capazes de oferecer as soluções profissionais com preços muito mais competitivos.

m44462931

A diferença entre estas placas e as GeForce/Radeon domésticas não estão tanto no hardware (a Quadro FX 5600 é baseada no mesmo G80 que equipa a GeForce 8800 doméstica, a FirePro V8700 usa o mesmo RV770 da Radeon HD 4870 e assim por diante), mas sim nos drivers. Eles são desenvolvidos de forma independente dos drivers domésticos, passando pelos processos oficiais de certificação e ganhando otimizações que resultam em um desempenho consideravelmente superior em aplicativos profissionais, como o Maya, 3ds Max, AutoCAD, SolidWorks, ProEngineer, etc. O preço inclui também um plano de suporte, geralmente válido por um ano.

Voltando ao OpenGL, em 2007 a manutenção foi transferida para o Khronos Group e o anúncio do OpenGL 3.0 renovou as esperanças em torno de uma renovação. Entretanto, as melhorias relacionadas ao desenvolvimento de jogos foram gradualmente perdendo espaço ao longo do caminho, fazendo com que o OpenGL 3.0 acabasse trazendo apenas melhorias relacionadas ao uso em estações de trabalho, que passaram a ser o principal reduto da API.

Nesse ponto, o fato de o DirectX ser controlado pela Microsoft acabou se revelando uma vantagem, já que as decisões podiam ser tomadas mais rapidamente. O Direct3D é uma API destinada a jogos, que é otimizado para o uso em placas de dois fabricantes (nVidia e ATI), enquanto o OpenGL tem um escopo muito mais abrangente e uma carga de legado muito maior, o que torna a concorrência mais difícil.

Isso permitiu que a Microsoft desenvolvesse um quase monopólio dos jogos para PCs, com quase todos os títulos sendo lançados exclusivamente em versão Windows (o único sistema capaz de rodar nativamente o DirectX) e apenas alguns ganhando versões para MacOS X ou Linux. É possível também rodar jogos DirectX no Linux através do Wine e do CrossOver, mas neste caso a compatibilidade é limitada e existe quase sempre uma perda considerável de desempenho.

Continuando, cada nova versão do DirectX oferece mais chamadas e novos recursos de desenvolvimento, que possibilitam a criação de efeitos mais complexos e permitem acessar os recursos oferecidos pelas GPUs mais atuais, mas por outro lado quebram a compatibilidade com GPUs antigas, criando uma espécie de obsolescência programada.

Um dos principais fatores é o Shader Model, a API responsável pelo uso dos shaders, que tem se tornado um dos principais fatores relacionados à qualidade das imagens e efeitos. O DirectX 9.0 (lançado em 2002) inclui suporte ao Shader Model 2.0, o DirectX 9.0c (lançado em 2004) ao Shader Model 3.0, enquanto o DirectX 10 (lançado no início de 2007, juntamente com o Vista) oferece suporte ao Shader Model 4.0, que é diretamente otimizado para as unidades programáveis das placas atuais.

Com isso, a versão do DirectX suportada pela placa tornou-se uma especificação importante (sobretudo no caso das placas integradas, que são quase sempre baseadas em chipsets antigos), já que está diretamente relacionada com a compatibilidade da placa com os jogos atuais.

Placas como as GeForce 6 e GeForce 7 e as ATI X1000, baseadas nos chipsets da família R520, são limitadas aos títulos com suporte ao DirectX 9.0c, enquanto as placas da série GeForce 8xxx (NV80) e as Radeon HD 2xxx (R600) em diante, oferecem suporte ao DirectX 10, o que garante efeitos extras em muitos títulos atuais e a compatibilidade com pelo menos mais uma geração de jogos. As placas onboard com chipset Intel GMA X3000 também suportam o DirectX 10 no papel, mas na prática o desempenho é muito fraco.

A versão do DirectX usada pelos jogos não é uma decisão encravada em pedra. Os desenvolvedores podem optar por focar o desenvolvimento em uma versão específica (o DirectX 9.0c, por exemplo) e incluir camadas de funções que utilizem recursos do DirectX 10 ou DirectX 11 (ativadas apenas nos PCs compatíveis), ou mesmo funções adicionais para manter a compatibilidade com versões antigas. Ao ser executado, o jogo detecta quais são as versões suportadas pela placa e ativa automaticamente as funções apropriadas, variando o nível de detalhes de acordo com os recursos do hardware.

Em pleno final de 2009 ainda tínhamos uma predominância de jogos desenvolvidos primariamente para o DirectX 9, contra um número pequeno de títulos desenvolvidos exclusivamente para o DirectX 10, diferente do que tivemos nas versões anteriores, onde a migração foi muito mais rápida.

Existem vários motivos para isso. Um dos principais foi a decisão da Microsoft de amarrar o DirectX 10 ao Vista, esperando por uma rápida adoção do sistema, que no final não aconteceu. Ao olharem os números de usuários do XP e do Vista, os desenvolvedores chegavam à conclusão de que era melhor continuar desenvolvendo primariamente para o DirectX 9, adicionando apenas uma camada posterior de efeitos baseados no DirectX 10, que passavam longe de serem convincentes.

Outro motivo é a predominância de títulos portados, que são desenvolvidos primariamente para o Xbox 360 ou o PS3 e em seguida portados para os PCs. O Xbox 360 usa uma API baseada no DirectX 9, o que torna natural que ele seja utilizado também nos portes para PC. Com uma base cada vez mais fragmentada, o desenvolvimento de títulos para várias plataformas utilizando uma base de código comum, se tornou norma.

Um bom exemplo é o Call of Duty World at War, que apesar dos bons gráficos, é um título DirectX 9, que foi portado sem muitas modificações dos consoles para o PC:

726136f8

Essa dependência dos consoles é um fator que tem retardado a adoção de novas tecnologias, já que os consoles possuem configurações muito mais modestas que um PC high-end e são atualizados em um ritmo muito mais lento. Por um lado isso é bom, já que torna os desenvolvedores mais conservadores com relação ao uso de recursos (reduzindo a velocidade com que novas GPUs se tornam obsoletas), mas por outro lado atrapalha os sonhos de quem quer ver imagens fotorealísticas em jogos.

Hoje em dia, é possível renderizar imagens bastante realísticas com o OpenGL, usando uma combinação do ray-tracing, photon mapping e outras técnicas (como na imagem a seguir). O problema é que isso torna a renderização muito cara em termos de processamento, fazendo com que cada imagem demore vários minutos, ou mesmo horas para ser renderizada, muito longe dos 30 a 60 FPS que são esperados em jogos, onde são necessários algoritmos menos precisos, porém mais rápidos.

m5fd5fc0c

Isso explica grande parte do hype em torno do DirectX 11, que além de ser suportado pelo Windows 7 e Vista, será utilizado pela próxima geração de consoles. Não vai ser uma migração rápida (já que depende de os usuários migrarem para o Windows 7 ou Vista e atualizarem as GPUs), mas ele tem tudo para se tornar a próxima grande versão da API, finalmente substituindo o DirectX 9.0c.

Do ponto de vista dos desenvolvedores, um dos grandes atrativos é o fato de o DX 11 ser um superset das instruções disponíveis no DirectX 10, que simplesmente inclui novas funções, sem abandonar as funções disponíveis anteriormente. Isso permite uma migração mais suave, já que ao deixar de usar as novas funções é possível escrever código compatível com as duas versões, assegurando a compatibilidade com a grande base de placas compatíveis com o DirectX 10.

Naturalmente, novos recursos e melhores gráficos consomem mais processamento, o que torna necessário o uso de placas mais poderosas, recomeçando o ciclo. Se você ainda tem dúvidas sobre para onde vai todo o poder de processamento das GPUs atuais, basta ter em mente que o DirectX 11 introduz o suporte de texturas de até 16.384 x 16.384, expandindo o antigo limite de 4096 x 4096, que já era impensável há poucos anos atrás.

Se você parar por um momento para pensar sobre o poder de processamento necessário para processar cenas com texturas desse tamanho em tempo real, vai logo entender os motivos da corrida armamentista entre a nVidia, ATI e Intel: no fundo tudo se resume ao uso de mais polígonos, texturas maiores e efeitos mas realistas.

Sobre o Autor

Redes Sociais:

Deixe seu comentário

X