Формальный параметр с __declspec (align ('16 ')) не будет выровнен

Я пытаюсь создать функцию для настройки шейдерной формы, но когда я пытаюсь ее скомпилировать, я получаю эту ошибку:

Ошибка 2 ошибки C2719: 'значение': формальный параметр с __declspec (align ('16 ')) не будет выровнен

Вот код функции:

void Shader::setUniform(std::string name, const glm::mat4 value){
    GLint uniform = glGetUniformLocation(m_program, name.c_str());
    glUniformMatrix4fv(uniform, 1, GL_FALSE, (GLfloat*)&value);
}

Я использую Visual studio 2013.

Ответ 1

Из документации Microsoft об этой ошибке:

The align __declspec modifier is not permitted on function parameters.

Не копируйте параметр в положение без выравнивания. Передайте постоянную ссылку на существующие, выровненные данные.

void Shader::setUniform(const std::string &name, const glm::mat4 & value)
//                                               ^^^^^           ^

Ответ 2

Я не уверен в реализации glm:: mat4, но он не настроен таким образом, что помещает данные в него в полное "слово" в памяти или создается в несогласованном месте ( вы читаете из файла? Выполняете некоторые арифметические трюки указателя где-то?)

http://virtrev.blogspot.com/2010/09/memory-alignment-theory-and-c-examples.html

Если вы хотите взломать "заставить его работать", вы можете попробовать:

void Shader::setUniform(std::string name, const glm::mat4 value){
    // This assumes your copy constructor works correctly
    glm::mat4 alignedMat = value;
    GLint uniform = glGetUniformLocation(m_program, name.c_str());
    glUniformMatrix4fv(uniform, 1, GL_FALSE, (GLfloat*)&value);
}

Я использовал этот трюк для принудительного выравнивания данных раньше. Вы также можете сделать memcpy в alignedMat, чтобы заставить элементы выравнивания время от времени. НЕ ПРИНИМАЙТЕ, что это правильный способ сделать это. Вы должны создавать элементы с правильным выравниванием. Это просто для того, чтобы увидеть, что не соответствует настройке, тестированию и отладке.

Также, если вы используете модификатор __declspec для параметра в определении метода. Не делайте этого.

Ответ 3

Передайте ваш параметр по ссылке (здесь это трехмерный вектор с именем "color"), чтобы избавиться от ошибки выравнивания:

void SetColor(btVector3 color) { m_color = color; }   // does give the error

void SetColor(btVector3 &color) { m_color = color; }  // does not