Привет, я пытался дать шейдеру массив, например, точечных положений света. Но этот шейдер хочет, чтобы vec3 были выровнены по 16 байтам, а не по 12 байтам от glm. Для одного vec3 проблем не было, можно было просто поставить перед ним "alignas(16)". Но для массива С++ просто считает, что весь массив должен быть выровнен по 16, а не его отдельные элементы.
struct Scene {
alignas(16) glm::vec3 lights[2];
};
int main() {
Scene scene;
scene.lights[0] = { 1,2,3 };
scene.lights[1] = { 4,5,6 };
}
Я также просмотрел отладчик памяти в Visual Studio, и байты просто плотно упакованы без каких-либо дополнений.
Скриншот отладчика памяти Visual Studio
Единственное решение, которое я могу придумать, это одно: изменить исходный код glm на выравнивание 16 (что не очень хорошая идея)
два: создать новую структуру типа "16ByteAlignedVec3" , содержащую vec3, и установить для этой структуры выравнивание 16. А затем использовать это как тип массива.
и третий: использование указателя для доступа к данным массива и увеличение его на 16 байт, если вы хотите получить доступ, например, к индексу 1.
🤔 А знаете ли вы, что...
Язык C++ активно применяется в разработке приложений для научных вычислений и искусственного интеллекта.
Но для массива С++ просто считает, что весь массив должен быть выровнен по 16, а не его отдельные элементы.
Действительно. Вот что означает указание alignas
для массива. Выравнивание массива затронуто; не выравнивание элементов.
два: создать новую структуру типа "16ByteAlignedVec3", которая содержит vec3, и установить для этой структуры выравнивание 16
Это разумный подход. Вы можете заставить класс вести себя так же, как если бы он был glm::vec3, используя наследование вместо члена:
struct Scene {
struct alignas(16) 16ByteAlignedVec3 : glm::vec3 {};
aligned_vec3 lights[2];
};