From 2ffff9193f649750816dd22f640a8a65c9480a60 Mon Sep 17 00:00:00 2001 From: maj00r Date: Fri, 3 Jul 2026 21:49:43 +0200 Subject: [PATCH] fix: correct listener orientation broken by GLM aligned gentypes Enabling GLM_FORCE_DEFAULT_ALIGNED_GENTYPES makes glm::vec3 16 bytes (padded), but the listener orientation was passed to alListenerfv as reinterpret_cast(glm::vec3[2]). With the padding the six floats OpenAL reads are at.x, at.y, at.z, PAD, up.x, up.y - the 'up' vector is taken from padding garbage, corrupting the listener basis (right = at x up) and swapping left/right of every positional sound. Build the 6 floats explicitly instead of reinterpreting a padded vec3 array. --- audio/audiorenderer.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/audio/audiorenderer.cpp b/audio/audiorenderer.cpp index bd0a0e49..eceeb346 100644 --- a/audio/audiorenderer.cpp +++ b/audio/audiorenderer.cpp @@ -372,10 +372,14 @@ openal_renderer::update( double const Deltatime ) { auto cameraposition = Global.pCamera.Pos + glm::dvec3(Global.viewport_move * glm::mat3(cameramatrix)); cameramatrix = glm::dmat4(glm::inverse(Global.viewport_rotate)) * cameramatrix; auto rotationmatrix { glm::mat3{ cameramatrix } }; - glm::vec3 const orientation[] = { - glm::vec3{ 0, 0,-1 } * rotationmatrix , - glm::vec3{ 0, 1, 0 } * rotationmatrix }; - ::alListenerfv( AL_ORIENTATION, reinterpret_cast( orientation ) ); + // AL_ORIENTATION expects 6 tightly-packed floats (at, then up). Do NOT reinterpret a + // glm::vec3[2] here: with GLM_FORCE_DEFAULT_ALIGNED_GENTYPES a glm::vec3 is 16 bytes + // (padded), so the array is not 6 contiguous floats and the 'up' vector gets read from + // padding as garbage, corrupting the listener basis (left/right swapped). + auto const at { glm::vec3{ 0, 0,-1 } * rotationmatrix }; + auto const up { glm::vec3{ 0, 1, 0 } * rotationmatrix }; + ALfloat const orientation[ 6 ] = { at.x, at.y, at.z, up.x, up.y, up.z }; + ::alListenerfv( AL_ORIENTATION, orientation ); // velocity if( Deltatime > 0 ) { auto cameramove { cameraposition - cached_camerapos };