mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 03:56:39 +00:00 
			
		
		
		
	Merge branch 'fix_light_manager_ub' into 'master'
Fix UB in light initialization See merge request OpenMW/openmw!877
This commit is contained in:
		
						commit
						405e634e09
					
				
					 1 changed files with 31 additions and 36 deletions
				
			
		|  | @ -114,15 +114,35 @@ namespace SceneUtil | ||||||
|             mOffsets[AttenuationRadius] = 8; |             mOffsets[AttenuationRadius] = 8; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         LightBuffer(const LightBuffer& copy) |         LightBuffer(const LightBuffer&) = delete; | ||||||
|             : osg::Referenced() | 
 | ||||||
|             , mData(copy.mData) |         LightBuffer(const LightBuffer& other, int offsetColors, int offsetPosition, int offsetAttenuationRadius, int size, int stride) | ||||||
|             , mEndian(copy.mEndian) |             : mData(new osg::FloatArray(size / sizeof(GL_FLOAT))) | ||||||
|             , mCount(copy.mCount) |             , mEndian(other.mEndian) | ||||||
|             , mStride(copy.mStride) |             , mCount(other.mCount) | ||||||
|             , mOffsets(copy.mOffsets) |             , mStride((offsetAttenuationRadius + sizeof(GL_FLOAT) * osg::Vec4::num_components + stride) / 4) | ||||||
|             , mCachedSunPos(copy.mCachedSunPos) |             , mCachedSunPos(other.mCachedSunPos) | ||||||
|         {} |         { | ||||||
|  |             mData->setBufferObject(other.mData->getBufferObject()); | ||||||
|  | 
 | ||||||
|  |             constexpr auto sizeofFloat = sizeof(GL_FLOAT); | ||||||
|  |             const auto diffuseOffset = offsetColors / sizeofFloat; | ||||||
|  | 
 | ||||||
|  |             mOffsets[Diffuse] = diffuseOffset; | ||||||
|  |             mOffsets[Ambient] = diffuseOffset + 1; | ||||||
|  |             mOffsets[Specular] = diffuseOffset + 2; | ||||||
|  |             mOffsets[DiffuseSign] = diffuseOffset + 3; | ||||||
|  |             mOffsets[Position] = offsetPosition / sizeofFloat; | ||||||
|  |             mOffsets[AttenuationRadius] = offsetAttenuationRadius / sizeofFloat; | ||||||
|  | 
 | ||||||
|  |             // Copy over previous buffers light data. Buffers populate before we know the layout.
 | ||||||
|  |             for (int i = 0; i < other.mCount; ++i) | ||||||
|  |             { | ||||||
|  |                 std::memcpy(&(*mData)[getOffset(i, Diffuse)], &(*other.mData)[other.getOffset(i, Diffuse)], sizeof(osg::Vec4f)); | ||||||
|  |                 std::memcpy(&(*mData)[getOffset(i, Position)], &(*other.mData)[other.getOffset(i, Position)], sizeof(osg::Vec4f)); | ||||||
|  |                 std::memcpy(&(*mData)[getOffset(i, AttenuationRadius)], &(*other.mData)[other.getOffset(i, AttenuationRadius)], sizeof(osg::Vec4f)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         void setDiffuse(int index, const osg::Vec4& value) |         void setDiffuse(int index, const osg::Vec4& value) | ||||||
|         { |         { | ||||||
|  | @ -192,36 +212,11 @@ namespace SceneUtil | ||||||
|             return mEndian == osg::BigEndian ? value.asABGR() : value.asRGBA(); |             return mEndian == osg::BigEndian ? value.asABGR() : value.asRGBA(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         int getOffset(int index, LayoutOffset slot) |         int getOffset(int index, LayoutOffset slot) const | ||||||
|         { |         { | ||||||
|             return mStride * index + mOffsets[slot]; |             return mStride * index + mOffsets[slot]; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void configureLayout(int offsetColors, int offsetPosition, int offsetAttenuationRadius, int size, int stride) |  | ||||||
|         { |  | ||||||
|             constexpr auto sizeofFloat = sizeof(GL_FLOAT); |  | ||||||
|             constexpr auto sizeofVec4 = sizeofFloat * osg::Vec4::num_components; |  | ||||||
| 
 |  | ||||||
|             LightBuffer oldBuffer = LightBuffer(*this); |  | ||||||
| 
 |  | ||||||
|             mOffsets[Diffuse] = offsetColors / sizeofFloat; |  | ||||||
|             mOffsets[Ambient] = mOffsets[Diffuse] + 1; |  | ||||||
|             mOffsets[Specular] = mOffsets[Diffuse] + 2; |  | ||||||
|             mOffsets[DiffuseSign] = mOffsets[Diffuse] + 3; |  | ||||||
|             mOffsets[Position] = offsetPosition / sizeofFloat; |  | ||||||
|             mOffsets[AttenuationRadius] = offsetAttenuationRadius / sizeofFloat; |  | ||||||
|             mStride = (offsetAttenuationRadius + sizeofVec4 + stride) / 4; |  | ||||||
| 
 |  | ||||||
|             // Copy over previous buffers light data. Buffers populate before we know the layout.
 |  | ||||||
|             mData->resize(size / sizeofFloat); |  | ||||||
|             for (int i = 0; i < oldBuffer.mCount; ++i) |  | ||||||
|             { |  | ||||||
|                 std::memcpy(&(*mData)[getOffset(i, Diffuse)], &(*oldBuffer.mData)[oldBuffer.getOffset(i, Diffuse)], sizeof(osg::Vec4f)); |  | ||||||
|                 std::memcpy(&(*mData)[getOffset(i, Position)], &(*oldBuffer.mData)[oldBuffer.getOffset(i, Position)], sizeof(osg::Vec4f)); |  | ||||||
|                 std::memcpy(&(*mData)[getOffset(i, AttenuationRadius)], &(*oldBuffer.mData)[oldBuffer.getOffset(i, AttenuationRadius)], sizeof(osg::Vec4f)); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     private: |     private: | ||||||
|         osg::ref_ptr<osg::FloatArray> mData; |         osg::ref_ptr<osg::FloatArray> mData; | ||||||
|         osg::Endian mEndian; |         osg::Endian mEndian; | ||||||
|  | @ -754,7 +749,7 @@ namespace SceneUtil | ||||||
|             for (int i = 0; i < 2; ++i) |             for (int i = 0; i < 2; ++i) | ||||||
|             { |             { | ||||||
|                 auto& buf = lightManager.getLightBuffer(i); |                 auto& buf = lightManager.getLightBuffer(i); | ||||||
|                 buf->configureLayout(offsets[0], offsets[1], offsets[2], totalBlockSize, stride); |                 buf = new LightBuffer(*buf, offsets[0], offsets[1], offsets[2], totalBlockSize, stride); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue