mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 17:26:38 +00:00 
			
		
		
		
	Merge branch 'fix_configure_light_buffer_layout' into 'master'
Avoid resetting buffer object when configuring light buffer layout (#6064) Closes #6064 See merge request OpenMW/openmw!913
This commit is contained in:
		
						commit
						a5bf056860
					
				
					 1 changed files with 58 additions and 42 deletions
				
			
		|  | @ -103,47 +103,12 @@ namespace SceneUtil | ||||||
|             : mData(new osg::FloatArray(3*4*count)) |             : mData(new osg::FloatArray(3*4*count)) | ||||||
|             , mEndian(osg::getCpuByteOrder()) |             , mEndian(osg::getCpuByteOrder()) | ||||||
|             , mCount(count) |             , mCount(count) | ||||||
|             , mStride(12) |  | ||||||
|             , mCachedSunPos(osg::Vec4()) |             , mCachedSunPos(osg::Vec4()) | ||||||
|         { |         { | ||||||
|             mOffsets[Diffuse] = 0; |  | ||||||
|             mOffsets[Ambient] = 1; |  | ||||||
|             mOffsets[Specular] = 2; |  | ||||||
|             mOffsets[DiffuseSign] = 3; |  | ||||||
|             mOffsets[Position] = 4; |  | ||||||
|             mOffsets[AttenuationRadius] = 8; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         LightBuffer(const LightBuffer&) = delete; |         LightBuffer(const LightBuffer&) = delete; | ||||||
| 
 | 
 | ||||||
|         LightBuffer(const LightBuffer& other, int offsetColors, int offsetPosition, int offsetAttenuationRadius, int size, int stride) |  | ||||||
|             : mData(new osg::FloatArray(size / sizeof(GL_FLOAT))) |  | ||||||
|             , mEndian(other.mEndian) |  | ||||||
|             , mCount(other.mCount) |  | ||||||
|             , mStride((offsetAttenuationRadius + sizeof(GL_FLOAT) * osg::Vec4::num_components + stride) / 4) |  | ||||||
|             , 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) | ||||||
|         { |         { | ||||||
|             // Deal with negative lights (negative diffuse) by passing a sign bit in the unused alpha component
 |             // Deal with negative lights (negative diffuse) by passing a sign bit in the unused alpha component
 | ||||||
|  | @ -214,15 +179,69 @@ namespace SceneUtil | ||||||
| 
 | 
 | ||||||
|         int getOffset(int index, LayoutOffset slot) const |         int getOffset(int index, LayoutOffset slot) const | ||||||
|         { |         { | ||||||
|             return mStride * index + mOffsets[slot]; |             return mOffsets.get(index, slot); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         void configureLayout(int offsetColors, int offsetPosition, int offsetAttenuationRadius, int size, int stride) | ||||||
|  |         { | ||||||
|  |             const Offsets offsets(offsetColors, offsetPosition, offsetAttenuationRadius, stride); | ||||||
|  | 
 | ||||||
|  |             // Copy cloned data using current layout into current data using new layout.
 | ||||||
|  |             // This allows to preserve osg::FloatArray buffer object in mData.
 | ||||||
|  |             const auto data = mData->asVector(); | ||||||
|  |             mData->resizeArray(static_cast<unsigned>(size)); | ||||||
|  |             for (int i = 0; i < mCount; ++i) | ||||||
|  |             { | ||||||
|  |                 std::memcpy(&(*mData)[offsets.get(i, Diffuse)], data.data() + getOffset(i, Diffuse), sizeof(osg::Vec4f)); | ||||||
|  |                 std::memcpy(&(*mData)[offsets.get(i, Position)], data.data() + getOffset(i, Position), sizeof(osg::Vec4f)); | ||||||
|  |                 std::memcpy(&(*mData)[offsets.get(i, AttenuationRadius)], data.data() + getOffset(i, AttenuationRadius), sizeof(osg::Vec4f)); | ||||||
|  |             } | ||||||
|  |             mOffsets = offsets; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|     private: |     private: | ||||||
|  |         class Offsets | ||||||
|  |         { | ||||||
|  |             public: | ||||||
|  |                 Offsets() | ||||||
|  |                     : mStride(12) | ||||||
|  |                 { | ||||||
|  |                     mValues[Diffuse] = 0; | ||||||
|  |                     mValues[Ambient] = 1; | ||||||
|  |                     mValues[Specular] = 2; | ||||||
|  |                     mValues[DiffuseSign] = 3; | ||||||
|  |                     mValues[Position] = 4; | ||||||
|  |                     mValues[AttenuationRadius] = 8; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 Offsets(int offsetColors, int offsetPosition, int offsetAttenuationRadius, int stride) | ||||||
|  |                     : mStride((offsetAttenuationRadius + sizeof(GL_FLOAT) * osg::Vec4::num_components + stride) / 4) | ||||||
|  |                 { | ||||||
|  |                     constexpr auto sizeofFloat = sizeof(GL_FLOAT); | ||||||
|  |                     const auto diffuseOffset = offsetColors / sizeofFloat; | ||||||
|  | 
 | ||||||
|  |                     mValues[Diffuse] = diffuseOffset; | ||||||
|  |                     mValues[Ambient] = diffuseOffset + 1; | ||||||
|  |                     mValues[Specular] = diffuseOffset + 2; | ||||||
|  |                     mValues[DiffuseSign] = diffuseOffset + 3; | ||||||
|  |                     mValues[Position] = offsetPosition / sizeofFloat; | ||||||
|  |                     mValues[AttenuationRadius] = offsetAttenuationRadius / sizeofFloat; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 int get(int index, LayoutOffset slot) const | ||||||
|  |                 { | ||||||
|  |                     return mStride * index + mValues[slot]; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             private: | ||||||
|  |                 int mStride; | ||||||
|  |                 std::array<int, 6> mValues; | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|         osg::ref_ptr<osg::FloatArray> mData; |         osg::ref_ptr<osg::FloatArray> mData; | ||||||
|         osg::Endian mEndian; |         osg::Endian mEndian; | ||||||
|         int mCount; |         int mCount; | ||||||
|         int mStride; |         Offsets mOffsets; | ||||||
|         std::array<std::size_t, 6> mOffsets; |  | ||||||
|         osg::Vec4 mCachedSunPos; |         osg::Vec4 mCachedSunPos; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | @ -751,10 +770,7 @@ namespace SceneUtil | ||||||
|             ext->glGetActiveUniformsiv(handle, indices.size(), indices.data(), GL_UNIFORM_OFFSET, offsets.data()); |             ext->glGetActiveUniformsiv(handle, indices.size(), indices.data(), GL_UNIFORM_OFFSET, offsets.data()); | ||||||
| 
 | 
 | ||||||
|             for (int i = 0; i < 2; ++i) |             for (int i = 0; i < 2; ++i) | ||||||
|             { |                 mLightManager->getLightBuffer(i)->configureLayout(offsets[0], offsets[1], offsets[2], totalBlockSize, stride); | ||||||
|                 auto& buf = mLightManager->getLightBuffer(i); |  | ||||||
|                 buf = new LightBuffer(*buf, offsets[0], offsets[1], offsets[2], totalBlockSize, stride); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         void apply(osg::State& state) const override |         void apply(osg::State& state) const override | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue