Apenas surgiu com o pensamento - você precisa encontrar algum tipo de hobby. Caso contrário, você pode sair das bobinas. E como sou uma pessoa muito inútil, que não pode fazer nada além de apertar botões, o hobby será esse: pelo menos uma vez por semana, organize um fluxo com a escrita de um brinquedo. Após um fluxo, o registro é publicado no Habré. (Você pode tentar postar ao vivo no Habr, mas é muito mais difícil).
Escrever é muito orientado pelo feedback - se alguém precisar de uma explicação, posso explicar como posso. Se houver sugestões - vou tentar levar em conta. No habr, todos os comentários são lidos até o fim, em outros lugares - como vai.
A primeira panqueca é irregular aqui:
Sob a cena - uma descrição da tese para aqueles que estão justamente sem dinheiro para passar meia hora vendo.
Ideias orientadoras
O primeiro aspecto interessante é que você deseja escrever tudo sem noivos. Como é que um javista regular faz? Há um problema - você descobre uma melancolia, dependendo dela, e resolve o problema para você. O preço disso é que, devido a esses porcos, o projeto se transforma em um chiqueiro, e ninguém pode determinar exatamente o que está acontecendo. Eu gostaria de tentar escrever sem esta fazenda de porcos, limpa e arrumada. Talvez isso não seja possível - informe-nos nos comentários.
O segundo aspecto. Eu tenho codificado Java e PHP a vida toda. Havia experiência no desenvolvimento de brinquedos, mas apenas na parte do servidor, com uma resposta pela rede e nunca - um aplicativo de desktop real em C ++. Portanto, em essência, este será um show de horrores - uma pessoa que não entende o assunto tentará de alguma forma descrever com suas próprias palavras o que está acontecendo.
Não, tudo isso não tem valor prático. Isso é para não sair da bobina e motivar os tios barbudos adultos a pegar o teclado e cortar alguns brinquedos também.
Rotina atinge um níquel
Infelizmente, a programação nunca começa com entretenimento fácil e agradável. Inicialmente, há um período de escavação dolorosa nas configurações do ambiente e do IDE.
A primeira coisa que entendi sobre o Visual Studio é uma ótima ferramenta para um profissional, mas causa uma impressão muito frustrante para um iniciante. Depois do Eclipse e do IntelliJ IDEA, tudo, você sabe, é algum tipo de fútil pouco natural e lilás com uma reinscrição. O ponto não é, de forma alguma, o VS, o ponto sou eu :-)
E com plugins, sempre há algum tipo de problema.

Portanto, por decisão deliberada, abandonamos Vizhualka e vemos o que mais é. O Vim, o Emacs e outros editores que não entendem a estrutura de origem são enviados pela floresta. A primeira tentativa de usar o Eclipse falhou, portanto a ferramenta foi escolhida CLion .
O problema com o CLion é que ele ainda não pode funcionar totalmente com o compilador do Visual Studio. Se você tentar fazer algo nele, ficará assim:

É claro que haveria um fio para encontrar os goshniks e começar a gritar com uma voz aguda que haveria impressões de depuração suficientes para todos. Mas não vamos ouvi-los, é claro.
Portanto, você precisa do que o CLion pode fazer bem, e esse é o MinGW.
Escolhendo o MinGW
Há uma tabela de versão grande.

E mostra que faz sentido olhar apenas para Cygwin e Msys2. O Msys2 é meio estranho - ele tem poucos committers, os pacotes estão no github pessoal de um dos autores. Por outro lado, é muito legal - há um compilador novo e um monte de pacotes. Isto é crucial.
A instalação consiste em chamar next-next-ok e, em seguida, executar repetidamente o comando update ( pacman -Syu
, como no Archlinux), reiniciando o terminal Msys2 até dizer que tudo acabou da melhor maneira possível.
Se você simplesmente instalar o Msys2 de acordo com as instruções e tentar adicioná-lo ao CLion, nenhuma cadeia de ferramentas será encontrada. Você precisa instalá-lo, isso é feito pelo comando pacman -S mingw-w64-x86_64-toolchain
.
Depois de instalar este pacote, o CLion lança o helloworld (que é gerado automaticamente ao criar um novo projeto) e a depuração funciona nele.
Verificação de recursos # 1: uma janela simples
Em primeiro lugar, quero entender se pelo menos algum aplicativo de desktop será iniciado. Ainda assim, este não é o PlatformSDK nativo, mas o MinGW.
Para isso, é adequado um programa simples que desenha uma janela usando vinapi.
E sim, com o MinGW, ele começa. Mas com a cadeia de ferramentas do Visual Studio, ela gera algum tipo de erro, mas não lidei com eles, porque - mas por que, se a plataforma de destino já funciona para nós?
Verificação de recurso # 2: Triângulo com sombreador
É claro que, para escrever algo viável, não basta exibir pixels na janela. É uma frenagem, desconfortável, não há coisas sofisticadas. Em resumo, precisamos do DirectX.
A questão principal sobre o CLion + MinGW é essa. Se eles não puderem usar o DirectX, serão enviados para o lixo.
Para o teste, um tutorial muito curto foi pesquisado, consistindo em apenas dois arquivos: em um, todo o código C ++, no outro, um shader. O desafio é fazê-lo funcionar.
Além da natureza do arquivo único, este tutorial é muito bom, pois informa aos dedos como funciona. Talvez este artigo deva ser transferido para Habr (escreva nos comentários).
O resultado final é aqui no GitHub . Aqui vou descrever quais problemas foram encontrados.
Pequenas coisas e lixo
Muitas linhas L tornaram-se apenas strings. Você pode excluir as letras L. Em muitos lugares, você precisa substituir NULL por 0 para que não caia.
Apesar do set(CMAKE_CXX_STANDARD 17)
, nada de interessante aconteceu nesse aspecto, nada se desfez.
Cabeçalhos e Libs
O fato, é claro, é que esse exemplo é muito antigo, escrito muito antes do Windows 10. O DirectX não está mais em um SDK do DirectX separado como nos dias de nossa polêmica juventude, mas é inserido diretamente no SDK do Windows.
Portanto, a primeira coisa a fazer é executar o instalador do Visual Studio e verificar se a versão mais recente do Windows SDK está instalada.
A segunda pergunta está nas manchetes.
#include <d3d11.h> #include <d3dx11.h> #include <d3dx10.h>
Eles não são mais, você precisa de algo como:
#include <d3d9.h> #include <d3d10.h> #include <d3d11.h> #include <dxgi.h>
E, em CMakeLists, adicione uma pesquisa a eles no final do arquivo:
set(LIBS d3d9 d3d11 d3dcompiler_43) target_link_libraries(src ${LIBS})
APIs ausentes
Anteriormente, havia essa estrutura :
typedef struct D3DXCOLOR { FLOAT r; FLOAT g; FLOAT b; FLOAT a; } D3DXCOLOR, *LPD3DXCOLOR;
E ela não existe mais. No entanto, em todos os locais em que era realmente necessário, acabou substituindo D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f)
por {0.0f, 0.2f, 0.4f, 1.0f}
.
O problema acabou sendo mais interessante com o D3DX11CompileFromFile
. Ela não existe mais!
No artigo Vivendo sem D3DX, foi proposto substituí-lo por D3DCompileFromFile
.

Mas aqui está o problema, o D3DCompileFromFile
também está indisponível por algum motivo!
Uma pequena investigação mostrou que a documentação da Microsoft sugere o uso de uma versão muito nova da API:

E o MinGW nos envia de volta ao passado por vários anos:

No entanto, na versão de 32 bits, há um cabeçalho mais recente, mas não entendi como adicioná-lo a 64 bits. 32 bits, provavelmente, nas FIGs não desistiram.
Por um lado, isso é muito triste, porque pressagia uma hemorragia em um relacionamento com o MinGW no futuro. Eu me pergunto quem são os modos de todos esses assuntos.
Por outro lado, se pegarmos o D3DCompile
ausente e o presente D3DCompileFromFile
:
HRESULT WINAPI D3DCompileFromFile( in LPCWSTR pFileName, in_opt const D3D_SHADER_MACRO pDefines, in_opt ID3DInclude pInclude, in LPCSTR pEntrypoint, in LPCSTR pTarget, in UINT Flags1, in UINT Flags2, out ID3DBlob ppCode, out_opt ID3DBlob ppErrorMsgs );
HRESULT WINAPI D3DCompile( in LPCVOID pSrcData, in SIZE_T SrcDataSize, in_opt LPCSTR pSourceName, in_opt const D3D_SHADER_MACRO pDefines, in_opt ID3DInclude pInclude, in_opt LPCSTR pEntrypoint, in LPCSTR pTarget, in UINT Flags1, in UINT Flags2, out ID3DBlob ppCode, out_opt ID3DBlob ppErrorMsgs );
verifica-se que há apenas a diferença no seguinte:
in LPCWSTR pFileName,
contra
in LPCVOID pSrcData, in SIZE_T SrcDataSize, in_opt LPCSTR pSourceName,
Infelizmente, como não conheço C ++, contei como pude: acabei de adicionar subtração de arquivo e redirecionar esses dados para o D3DCompile
.
void WINAPI D3DCompileFromFile(const char *filename, const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages) { SIZE_T data_size; char* buffer; ifstream infile; infile.open(filename, ios::binary); infile.seekg(0, ios::end); data_size = infile.tellg(); infile.seekg(0, ios::beg); buffer = new char[data_size]; infile.read(buffer, data_size); infile.close(); D3DCompile(buffer, data_size,filename, defines, include,entrypoint, target, sflags, eflags, shader, error_messages); }
A única diferença importante entre o D3DX11CompileFromFile
e o D3DCompileFromFile
criado por D3DCompileFromFile
é a ausência do ID3DX11ThreadPump
como parâmetro na nova API. Isso é algo para assincronia, talvez algum tipo de pool de threads? No entanto, ele não foi usado no tutorial, existem 0 em seu lugar.
Sumário
Um monte de DirectX + MinGW + Msys2 + CLion é viável o suficiente para fazer um jogo simples. Há uma oportunidade não apenas de usar o vinapi básico, mas também de desenhar e até com shaders.
Em geral, isso é tudo. Lembro que o resultado simples está no GitHub .
Lembre-se de que este não é o meu código, mas um texto modificado do tutorial - no entanto, espero que seu uso seja honesto e direcionado. Mas, no entanto, é por isso que não há licença normal lá .

Comentários
Por favor, escreva seus comentários e sugestões nos comentários. Por isso, tudo está feito, ouça o que você diz. Especialmente se você é um programador de jogos experiente, apenas um bisonte, um bisonte e não se encaixa em um tópico por tamanho. Certifique-se de entrar e escrever algo.
Lembro que, como qualquer outro blogueiro, como gostos e designs. Quanto mais violentamente você tocar a seta para cima nesta postagem, maior será a probabilidade da próxima postagem e do fluxo.
© Alexander Raevsky