Browse Source

Added note that tangents are needed for normal mapping. Clean up SoundSource decoder handling to prepare for application-supplied sound stream.

Lasse Öörni 11 years ago
parent
commit
8bf5af9261
2 changed files with 38 additions and 37 deletions
  1. 2 0
      Docs/Reference.dox
  2. 36 37
      Source/Engine/Audio/SoundSource.cpp

+ 2 - 0
Docs/Reference.dox

@@ -902,6 +902,8 @@ Normal maps encode the tangent-space surface normal for normal mapping. There ar
 
 
 Make sure the normal map is oriented correctly: an even surface should have the color value R 0.5 G 0.5 B 1.0.
 Make sure the normal map is oriented correctly: an even surface should have the color value R 0.5 G 0.5 B 1.0.
 
 
+Models using a normal-mapped material need to have tangent vectors in their vertex data; the easiest way to ensure this is to use the switch -t (generate tangents) when using either AssetImporter or OgreImporter to import models to Urho3D format. If there are no tangents, the light attenuation on the normal-mapped material will behave in a completely erratic fashion.
+
 Specular maps encode the specular surface color as RGB. Note that deferred rendering is only able to use monochromatic specular intensity from the G channel, while forward and light pre-pass rendering use fully colored specular. DXT1 format should suit these textures well.
 Specular maps encode the specular surface color as RGB. Note that deferred rendering is only able to use monochromatic specular intensity from the G channel, while forward and light pre-pass rendering use fully colored specular. DXT1 format should suit these textures well.
 
 
 Textures can have an accompanying XML file which specifies load-time parameters, such as addressing, mipmapping, and number of mip levels to skip on each quality level:
 Textures can have an accompanying XML file which specifies load-time parameters, such as addressing, mipmapping, and number of mip levels to skip on each quality level:

+ 36 - 37
Source/Engine/Audio/SoundSource.cpp

@@ -372,59 +372,58 @@ void SoundSource::Mix(int* dest, unsigned samples, int mixRate, bool stereo, boo
     {
     {
         if (decoder_)
         if (decoder_)
         {
         {
-            // If Decoder already exists, decode new compressed audio
+            // If decoder already exists, decode new compressed audio
             bool eof = false;
             bool eof = false;
             unsigned currentPos = position_ - decodeBuffer_->GetStart();
             unsigned currentPos = position_ - decodeBuffer_->GetStart();
-            if (currentPos != decodePosition_)
+            unsigned totalBytes;
+            
+            // Handle possible wraparound
+            if (currentPos >= decodePosition_)
+                totalBytes = currentPos - decodePosition_;
+            else
+                totalBytes = decodeBuffer_->GetDataSize() - decodePosition_ + currentPos;
+            
+            while (totalBytes)
             {
             {
-                // If buffer has wrapped, decode first to the end
-                if (currentPos < decodePosition_)
+                // Calculate size of current decode work unit (may need to do in two parts if wrapping)
+                unsigned bytes = decodeBuffer_->GetDataSize() - decodePosition_;
+                if (bytes > totalBytes)
+                    bytes = totalBytes;
+                
+                unsigned outBytes = 0;
+                
+                if (!eof)
                 {
                 {
-                    unsigned bytes = decodeBuffer_->GetDataSize() - decodePosition_;
-                    unsigned outBytes = sound_->Decode(decoder_, decodeBuffer_->GetStart() + decodePosition_, bytes);
-                    // If produced less output, end of sound encountered. Fill rest with zero
+                    outBytes = sound_->Decode(decoder_, decodeBuffer_->GetStart() + decodePosition_, bytes);
+                    // If decoded less than the requested amount, has reached end. Rewind (looped) or fill rest with zero (oneshot)
                     if (outBytes < bytes)
                     if (outBytes < bytes)
                     {
                     {
-                        memset(decodeBuffer_->GetStart() + decodePosition_ + outBytes, 0, bytes - outBytes);
-                        eof = true;
-                    }
-                    decodePosition_ = 0;
-                }
-                if (currentPos > decodePosition_)
-                {
-                    unsigned bytes = currentPos - decodePosition_;
-                    unsigned outBytes = sound_->Decode(decoder_, decodeBuffer_->GetStart() + decodePosition_, bytes);
-                    // If produced less output, end of sound encountered. Fill rest with zero
-                    if (outBytes < bytes)
-                    {
-                        memset(decodeBuffer_->GetStart() + decodePosition_ + outBytes, 0, bytes - outBytes);
                         if (sound_->IsLooped())
                         if (sound_->IsLooped())
+                        {
+                            sound_->RewindDecoder(decoder_);
+                            timePosition_ = 0.0f;
+                        }
+                        else
+                        {
+                            decodeBuffer_->SetLooped(false); // Stop after the current decode buffer has been played
                             eof = true;
                             eof = true;
+                        }
                     }
                     }
-
-                    // If wrote to buffer start, correct interpolation wraparound
-                    if (!decodePosition_)
-                        decodeBuffer_->FixInterpolation();
                 }
                 }
-            }
-
-            // If end of stream encountered, check whether we should rewind or stop
-            if (eof)
-            {
-                if (sound_->IsLooped())
+                else
                 {
                 {
-                    sound_->RewindDecoder(decoder_);
-                    timePosition_ = 0.0f;
+                    memset(decodeBuffer_->GetStart() + decodePosition_, 0, bytes);
+                    outBytes = bytes;
                 }
                 }
-                else
-                    decodeBuffer_->SetLooped(false); // Stop after the current decode buffer has been played
+                
+                decodePosition_ += outBytes;
+                decodePosition_ %= decodeBuffer_->GetDataSize();
+                totalBytes -= outBytes;
             }
             }
-
-            decodePosition_ = currentPos;
         }
         }
         else
         else
         {
         {
-            // Setup the decoder and decode buffer
+            // Setup the decoder and decode initial buffer
             decoder_ = sound_->AllocateDecoder();
             decoder_ = sound_->AllocateDecoder();
             unsigned sampleSize = sound_->GetSampleSize();
             unsigned sampleSize = sound_->GetSampleSize();
             unsigned DecodeBufferSize = sampleSize * sound_->GetIntFrequency() * DECODE_BUFFER_LENGTH / 1000;
             unsigned DecodeBufferSize = sampleSize * sound_->GetIntFrequency() * DECODE_BUFFER_LENGTH / 1000;