Merged
Conversation
Adds UboBlocks.h with NamedColorsBlock definition and UboManager with lazy UBO rebuild pattern. Uses glBufferSubData on a buffer to update the block.
Reviewer's GuideIntroduce a GPU-driven weather system (atmosphere, precipitation, time-of-day) with new UBO blocks, shaders, meshes, and configuration controls, refactoring UBO management and render pipeline to support time-based transitions and per-frame updates. Sequence diagram for frame update and weather rendering pipelinesequenceDiagram
participant User
participant FrameManager
participant MapCanvas
participant OpenGL
participant Functions as Legacy_Functions
participant UboManager as Legacy_UboManager
participant GLWeather
participant GPU as Shaders_And_Pipeline
User->>FrameManager: requestFrame()
activate FrameManager
FrameManager->>FrameManager: beginFrame()
Note over FrameManager: Compute deltaTime and m_elapsedTime
FrameManager->>UboManager: get<TimeBlock>()
FrameManager->>UboManager: invalidate(TimeBlock)
deactivate FrameManager
User->>MapCanvas: paintGL()
activate MapCanvas
MapCanvas->>OpenGL: getOpenGL()
MapCanvas->>GLWeather: update()
activate GLWeather
GLWeather->>FrameManager: getElapsedTime()
GLWeather->>UboManager: get<WeatherBlock>()
Note over GLWeather: applyTransition for intensities and timeOfDay
deactivate GLWeather
MapCanvas->>GLWeather: prepare()
activate GLWeather
GLWeather->>OpenGL: getSharedFunctions(Badge_GLWeather)
GLWeather->>Functions: getUboManager()
GLWeather->>UboManager: bind(Functions, CameraBlock)
GLWeather->>UboManager: bind(Functions, WeatherBlock)
deactivate GLWeather
MapCanvas->>UboManager: bind(Functions, TimeBlock)
MapCanvas->>GLWeather: render(renderState)
activate GLWeather
alt precipitation active
GLWeather->>Shaders_And_Pipeline: ParticleSimulationShader + ParticleRenderShader
end
alt atmosphere or fog active
GLWeather->>Shaders_And_Pipeline: AtmosphereShader
end
alt time-of-day overlay active
GLWeather->>Shaders_And_Pipeline: TimeOfDayShader
end
deactivate GLWeather
Shaders_And_Pipeline-->>User: updated weather visuals on screen
deactivate MapCanvas
Class diagram for updated UBO management and weather UBO blocksclassDiagram
direction LR
namespace Legacy {
class UboManager {
-EnumIndexedArray~RebuildFunction,SharedVboEnum~ m_rebuildFunctions
-EnumIndexedArray~optional~GLuint~~ m_boundBuffers
-SharedVboBlocks m_shadowBlocks
+template~SharedVboEnum Block~ BlockType~Block~::type &get()
+template~SharedVboEnum Block~ const BlockType~Block~::type &get() const
+void invalidate(SharedVboEnum block)
+void registerRebuildFunction(SharedVboEnum block, RebuildFunction func, bool allowOverwrite=false)
+void unregisterRebuildFunction(SharedVboEnum block)
+bool isInvalid(SharedVboEnum block) const
+GLuint update(Functions &gl, SharedVboEnum block, const void *data, size_t size)
+template~SharedVboEnum Block~ GLuint update(Functions &gl, const BlockType~Block~::type &data)
+template~SharedVboEnum Block~ GLuint sync(Functions &gl)
+template~SharedVboEnum Block, typename T, typename... Us~ void syncFields(Functions &gl, Us T::*...members)
+template~SharedVboEnum Block, typename T, typename U~ void syncField(Functions &gl, U T::*member)
+GLuint bind(Functions &gl, SharedVboEnum block)
}
class SharedVboEnum {
<<enum>>
NamedColorsBlock
CameraBlock
TimeBlock
WeatherBlock
NUM_BLOCKS
}
class CameraBlock {
+mat4 viewProj
+vec4 playerPos
}
class TimeBlock {
+vec4 time
}
class WeatherBlock {
+vec4 intensities
+vec4 targets
+vec4 timeOfDay
+vec4 config
}
class NamedColorsBlock {
+array~vec4,MAX_NAMED_COLORS~ colors
}
class BlockType~Block~ {
<<template specialization>>
}
class SharedVboBlocks {
<<typedef>>
%% tuple<NamedColorsBlock,CameraBlock,TimeBlock,WeatherBlock>
}
class Functions {
+void glBindBuffer(GLenum target, GLuint buffer)
+void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
+void glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
+void glUniformBlockBinding(GLuint program, SharedVboEnum block)
+const char *getShaderVersion() const
+static const char *getUniformBlockName(SharedVboEnum block)
+void applyDefaultUniformBlockBindings(GLuint program)
+UboManager &getUboManager()
}
}
class FrameManager {
-QOpenGLWindow &m_window
-Legacy::UboManager &m_uboManager
-float m_elapsedTime
+FrameManager(QOpenGLWindow &window, Legacy::UboManager &uboManager, QObject *parent)
+~FrameManager()
+optional~Frame~ beginFrame()
+float getElapsedTime() const
}
class MapCanvas {
-OpenGL m_opengl
-FrameManager m_frameManager
+void initializeGL()
+void actuallyPaintGL()
+void onViewProjDirty() const
}
class GLWeather {
-OpenGL &m_gl
-FrameManager &m_animationManager
-float m_currentRainIntensity
-float m_currentSnowIntensity
-float m_currentCloudsIntensity
-float m_currentFogIntensity
-float m_currentTimeOfDayIntensity
-float m_gameRainIntensity
-float m_gameSnowIntensity
-float m_gameCloudsIntensity
-float m_gameFogIntensity
-float m_gameTimeOfDayIntensity
+GLWeather(OpenGL &gl, MapData &mapData, const MapCanvasTextures &textures, GameObserver &observer, FrameManager &frameManager)
+~GLWeather()
+void update()
+void prepare()
+void render(const GLRenderState &rs)
+bool isAnimating() const
+bool isTransitioning() const
}
%% Relationships
UboManager --> SharedVboEnum
UboManager --> SharedVboBlocks
SharedVboBlocks --> NamedColorsBlock
SharedVboBlocks --> CameraBlock
SharedVboBlocks --> TimeBlock
SharedVboBlocks --> WeatherBlock
BlockType~Block~ <.. SharedVboEnum
Functions --> UboManager
FrameManager --> UboManager : holds reference
FrameManager --> TimeBlock : updates via get<TimeBlock>()
MapCanvas --> OpenGL : m_opengl
MapCanvas --> FrameManager : m_frameManager
MapCanvas --> CameraBlock : rebuild function updates
GLWeather --> OpenGL
GLWeather --> FrameManager
GLWeather --> WeatherBlock : uses via UboManager.get<WeatherBlock>()
GLWeather --> NamedColorsBlock : uses in shaders via UBO
Class diagram for new weather rendering subsystem (GLWeather, meshes, shaders)classDiagram
direction LR
class GLWeather {
-OpenGL &m_gl
-MapData &m_data
-const MapCanvasTextures &m_textures
-FrameManager &m_animationManager
-GameObserver &m_observer
-ChangeMonitor::Lifetime m_lifetime
-float m_currentRainIntensity
-float m_currentSnowIntensity
-float m_currentCloudsIntensity
-float m_currentFogIntensity
-float m_currentTimeOfDayIntensity
-float m_gameRainIntensity
-float m_gameSnowIntensity
-float m_gameCloudsIntensity
-float m_gameFogIntensity
-float m_gameTimeOfDayIntensity
-MumeTimeEnum m_currentTimeOfDay
-MumeMoonVisibilityEnum m_moonVisibility
-unique_ptr~Legacy::ParticleSimulationMesh~ m_simulation
-unique_ptr~Legacy::ParticleRenderMesh~ m_particles
-UniqueMesh m_atmosphere
-UniqueMesh m_timeOfDay
+GLWeather(OpenGL &gl, MapData &mapData, const MapCanvasTextures &textures, GameObserver &observer, FrameManager &frameManager)
+~GLWeather()
+void update()
+void prepare()
+void render(const GLRenderState &rs)
+bool isAnimating() const
+bool isTransitioning() const
-void updateTargets()
-void updateFromGame()
-void initMeshes()
-void syncWeatherAtmosphere()
-void syncWeatherTimeOfDay()
-float applyTransition(float startTime, float startVal, float targetVal) const
-template~T~ T applyTransition(float startTime, T startVal, T targetVal) const
-template~T~ struct TransitionPair
-template~Pairs...~ void startTransitions(float &startTime, Pairs... pairs)
-NamedColorEnum getCurrentColorIdx() const
}
class MapCanvas {
-GLWeather m_weather
+MapCanvas(MapData &mapData, GameObserver &observer, PrespammedPath &prespammedPath, Mmapper2Group &groupManager, QWindow *parent)
+void initializeGL()
+void actuallyPaintGL()
+void onMovement()
+void onViewProjDirty() const
}
class FrameManager {
-Legacy::UboManager &m_uboManager
-float m_elapsedTime
+FrameManager(QOpenGLWindow &window, Legacy::UboManager &uboManager, QObject *parent)
+~FrameManager()
+optional~Frame~ beginFrame()
+float getElapsedTime() const
}
class GameObserver {
+MumeTimeEnum getTimeOfDay() const
+MumeMoonVisibilityEnum getMoonVisibility() const
+PromptWeatherEnum getWeather() const
+PromptFogEnum getFog() const
+Signal2~PromptWeatherEnum~ sig2_weatherChanged
+Signal2~PromptFogEnum~ sig2_fogChanged
+Signal2~MumeTimeEnum~ sig2_timeOfDayChanged
+Signal2~MumeMoonVisibilityEnum~ sig2_moonVisibilityChanged
}
class MapCanvasTextures {
+SharedMMTexture noise
}
namespace Legacy {
class AtmosphereMesh {
+AtmosphereMesh(SharedFunctions sharedFunctions, shared_ptr~AtmosphereShader~ program)
+~AtmosphereMesh()
+void virt_render(const GLRenderState &renderState)
}
class TimeOfDayMesh {
+TimeOfDayMesh(SharedFunctions sharedFunctions, shared_ptr~TimeOfDayShader~ program)
+~TimeOfDayMesh()
+void virt_render(const GLRenderState &renderState)
}
class ParticleSimulationMesh {
-SharedFunctions m_shared_functions
-Functions &m_functions
-shared_ptr~ParticleSimulationShader~ m_program
-TFO m_tfo
-VBO m_vbos[2]
-VAO m_vaos[2]
-uint32_t m_currentBuffer
-uint32_t m_numParticles
-bool m_initialized
+ParticleSimulationMesh(SharedFunctions shared_functions, shared_ptr~ParticleSimulationShader~ program)
+~ParticleSimulationMesh()
+bool virt_isEmpty() const
+uint32_t getCurrentBuffer() const
+uint32_t getNumParticles() const
+const VBO &getParticleVbo(uint32_t index) const
-void init()
-void virt_reset()
-void virt_render(const GLRenderState &renderState)
}
class ParticleRenderMesh {
-SharedFunctions m_shared_functions
-Functions &m_functions
-shared_ptr~ParticleRenderShader~ m_program
-const ParticleSimulationMesh &m_simulation
-VAO m_vaos[2]
-float m_intensity
-bool m_initialized
+ParticleRenderMesh(SharedFunctions shared_functions, shared_ptr~ParticleRenderShader~ program, const ParticleSimulationMesh &simulation)
+~ParticleRenderMesh()
+void setIntensity(float intensity)
-void init()
-void virt_reset()
-bool virt_isEmpty() const
-void virt_render(const GLRenderState &renderState)
}
class TFO {
-WeakFunctions m_weakFunctions
-GLuint m_tfo
+TFO()
+~TFO()
+void emplace(const SharedFunctions &sharedFunctions)
+void reset()
+GLuint get() const
}
class AtmosphereShader {
+~AtmosphereShader()
-void virt_setUniforms(const mat4 &mvp, const GLRenderState::Uniforms &uniforms)
}
class TimeOfDayShader {
+~TimeOfDayShader()
-void virt_setUniforms(const mat4 &mvp, const GLRenderState::Uniforms &uniforms)
}
class ParticleSimulationShader {
+~ParticleSimulationShader()
-void virt_setUniforms(const mat4 &mvp, const GLRenderState::Uniforms &uniforms)
}
class ParticleRenderShader {
+~ParticleRenderShader()
-void virt_setUniforms(const mat4 &mvp, const GLRenderState::Uniforms &uniforms)
}
class ShaderPrograms {
-shared_ptr~AtmosphereShader~ m_atmosphere
-shared_ptr~TimeOfDayShader~ m_timeOfDay
-shared_ptr~ParticleSimulationShader~ m_particleSimulation
-shared_ptr~ParticleRenderShader~ m_particleRender
+const shared_ptr~AtmosphereShader~ &getAtmosphereShader()
+const shared_ptr~TimeOfDayShader~ &getTimeOfDayShader()
+const shared_ptr~ParticleSimulationShader~ &getParticleSimulationShader()
+const shared_ptr~ParticleRenderShader~ &getParticleRenderShader()
}
}
%% Relationships
MapCanvas --> GLWeather : "m_weather"
MapCanvas --> FrameManager : "m_frameManager"
GLWeather --> MapData
GLWeather --> MapCanvasTextures
GLWeather --> GameObserver
GLWeather --> FrameManager
GLWeather --> Legacy.ParticleSimulationMesh
GLWeather --> Legacy.ParticleRenderMesh
GLWeather --> Legacy.AtmosphereMesh
GLWeather --> Legacy.TimeOfDayMesh
GLWeather --> Legacy.ShaderPrograms
Legacy.ParticleSimulationMesh --> Legacy.TFO
Legacy.ParticleSimulationMesh --> Legacy.VBO
Legacy.ParticleSimulationMesh --> Legacy.VAO
Legacy.ParticleSimulationMesh --> Legacy.ParticleSimulationShader
Legacy.ParticleRenderMesh --> Legacy.ParticleRenderShader
Legacy.ParticleRenderMesh --> Legacy.ParticleSimulationMesh
Legacy.ParticleRenderMesh --> Legacy.VAO
Legacy.ShaderPrograms --> Legacy.AtmosphereShader
Legacy.ShaderPrograms --> Legacy.TimeOfDayShader
Legacy.ShaderPrograms --> Legacy.ParticleSimulationShader
Legacy.ShaderPrograms --> Legacy.ParticleRenderShader
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- In
UboManager::syncFieldsthe template parameter packUs T::*...membersis misused: thesizeof(Us)expression inside the parameter pack expansion will use only the lastUstype rather than the type of each member, which makes the upload size incorrect for all but (at best) one field; consider computing the size per member usingsizeof(std::decay_t<decltype(blockData.*members)>)or similar inside the fold expression.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `UboManager::syncFields` the template parameter pack `Us T::*...members` is misused: the `sizeof(Us)` expression inside the parameter pack expansion will use only the last `Us` type rather than the type of each member, which makes the upload size incorrect for all but (at best) one field; consider computing the size per member using `sizeof(std::decay_t<decltype(blockData.*members)>)` or similar inside the fold expression.
## Individual Comments
### Comment 1
<location path="src/opengl/Weather.cpp" line_range="213-218" />
<code_context>
+ m_gl.getUboManager().unregisterRebuildFunction(Legacy::SharedVboEnum::WeatherBlock);
+}
+
+void GLWeather::updateFromGame()
+{
+ auto w = m_observer.getWeather();
+ auto f = m_observer.getFog();
+
+ switch (w) {
+ case PromptWeatherEnum::NICE:
+ m_gameRainIntensity = 0.0f;
</code_context>
<issue_to_address>
**issue (bug_risk):** Weather switch does not reset all intensity channels, causing stale rain/snow when switching to CLOUDS
In `updateFromGame()`, only the `NICE` case resets all precipitation intensities to 0. When switching from RAIN or SNOW to `CLOUDS`, we only set `m_gameCloudsIntensity = 0.5f` and leave `m_gameRainIntensity` / `m_gameSnowIntensity` as-is, so prior values can still affect the targets under cloudy weather. To avoid this stale state, either clear all precipitation-related intensities at the start of the function or ensure each weather case sets all four channels (rain, snow, clouds, fog) explicitly.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Adds GLWeather with CameraBlock, TimeBlock, and WeatherBlock UBO support. Includes particle simulation via transform feedback, atmospheric overlay, and time-of-day color transitions driven by MUME weather state. Exposes weather intensity controls in the graphics preferences UI.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #478 +/- ##
===========================================
- Coverage 66.48% 25.17% -41.31%
===========================================
Files 85 511 +426
Lines 4186 42182 +37996
Branches 255 4560 +4305
===========================================
+ Hits 2783 10619 +7836
- Misses 1403 31563 +30160 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary by Sourcery
Add a GPU-accelerated, UBO-driven weather and time-of-day system with configurable intensities and integrate it into the rendering pipeline.
New Features:
Bug Fixes:
Enhancements:
Build: