Estou usando Objective-C e Metal para renderizar em uma janela, porém todo o código do meu aplicativo está escrito em C++. Portanto, toda a manipulação dos dados internos da CPU MTLBuffer
é feita em C++. Isso é feito passando o conteúdo dos buffers (que é um void*
) para o código C++, onde ele lança o ponteiro do conteúdo para MyVertex*
gravar novos dados de vértice. No meu arquivo de cabeçalho, apenas adicionei condições do compilador para digitar as estruturas de vértice corretamente.
#ifdef __IN_OBJC__
#define V2 vector_float2
#define V4 vector_float4
#endif
#ifdef __IN_CPP__
#define V2 vec2
#define V4 vec4
#endif
typedef struct {
V2 position;
V4 color;
} MyVertex;
Aqui vec2
estão vec4
basicamente estruturas de 2, 4 carros flutuantes implementadas em meu código C++. Mas neste exemplo, Objective-C e C++ pensam que MyVertex
são de tamanhos diferentes. Estou compilando com clang e clang++. E o compilador Objective-C deseja preencher a estrutura para que ela tenha tamanho 32, enquanto C++ diz que a estrutura é de tamanho 24. Atualmente, corrigi isso com #pragma pack
, mas parece uma solução fraca. Na verdade, eu preferiria que minha implementação C++ fosse preenchida em vez de compactada para otimizar melhor os buffers nos shaders. Mas não posso preencher deliberadamente uma estrutura como posso empacotar uma.
Devo tornar meus próprios vetores ( vec2
…) compatíveis com Objective-C? No momento, eles são escritos como classes. Dessa forma, não terei que fazer declarações condicionais. Eu preferiria que a solução otimizasse melhor o desempenho do buffer no shader.
Como o Objective-C espera que cada campo da sua estrutura se alinhe em um limite de 16 bytes (4 flutuantes), você pode pedir ao C++ para fazer o mesmo com
alignas(16)
Isso ajustará os deslocamentos e o tamanho resultante de
MyVertex
: