Изменить позицию матриц (Старый OpenGL)

Есть вот такой код:

void Object::add()
{
    float projection[16]{};
    glGetFloatv(GL_PROJECTION_MATRIX, projection);
 
    float modelview[16]{};
    glGetFloatv(GL_MODELVIEW_MATRIX, modelview);
 
    Object::projection.insert(Object::projection.end(), begin(projection), end(projection));
    Object::modelview.insert(Object::modelview.end(), begin(modelview), end(modelview));
}

Он записывает данные матриц проекции и model-view в массив, для того чтобы потом я мог загрузить эти матрицы и дорисовать то что мне нужно.

Я попытался изменить этот код на

void Object::add(float offsetX, float offsetY, float offsetZ)
{
    float projection[16]{};
    glGetFloatv(GL_PROJECTION_MATRIX, projection);
 
    projection[12] = projection[12] + offsetX;
    projection[13] = projection[13] + offsetY;
    projection[14] = projection[14] + offsetZ;
 
    float modelview[16]{};
    glGetFloatv(GL_MODELVIEW_MATRIX, modelview);
 
    modelview[12] = modelview[12] + offsetX;
    modelview[13] = modelview[13] + offsetY;
    modelview[14] = modelview[14] + offsetZ;
 
    Object::projection.insert(Object::projection.end(), begin(projection), end(projection));
    Object::modelview.insert(Object::modelview.end(), begin(modelview), end(modelview));
}

Для того чтобы иметь возможность по желанию корректировать расположение перед сохранением в вектор, но это даёт странный результат. При движении камеры игрока, начинает изменяться и позиция: https://www.youtube.com/watch?v=VNHu2dAjv24.

Если менять только model-view, то получается примерно похожий эффект: https://youtu.be/nAHGmnqe3x4.

Я не могу использовать glTranslatef перед сохранением матриц, поскольку в таком случае изменится и позиция рисуемого на данный момент игрой объекта. Я мог бы добавить глобальные переменные со значениями смещения и уже после загрузки сохранённых матриц вызывать glTranslatef, но хотелось бы решить эту задачу без дополнительных переменных, редактируя сами массивы перед из записью в вектор. Как правильно сделать то что мне нужно?


Ответы (1 шт):

Автор решения: August Vishnevsky

Ответ дал пользователь zayats80888 на cyberforum

void translate(float * m, float x, float y, float z)
{
    float m3[4];
    for (int i = 0; i < 4; ++i)
        m3[i] = m[i] * x + m[i + 4] * y + m[i + 8] * z + m[i + 12];
    std::memcpy(m + 12, m3, sizeof(m3));
}
→ Ссылка