Open
Conversation
Replaces the previous 1.9.0 floor with 1.12.10 to match the OGRE package shipped on Ubuntu Noble. The OGRE2 backend remains discovered via gz_find_package(GzOGRE2) and is unchanged. Originates from the temporary local-build commit 70c0df8 ("Forcing CMAKE, undo") on jrivero/ogre112; the debugging hack that forced OGRE2_FOUND=FALSE has been stripped. Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
OGRE 1.12's ResourceManager::create() now throws if the material already exists (changed from silently returning it). The fix is to use createOrRetrieve(). Need to track ownership to avoid duplicate removals. Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
…it shouldn't be removed Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
setSourceFile() is called with the full absolute path, but OGRE 1.12 resolves it through the resource group (where it's registered just as depth_points_vs.glsl). Also, addResourceLocation is being called on the file path instead of its parent directory. The fix: add the parent directory (not the file) to resource locations, and pass just the basename to setSourceFile() Generated-by: Claude Sonnet 4.6 Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
The Fonts resource group is registered without recursive search, so font subdirectories (liberation-sans/, roboto/) aren't scanned. Fix: enable recursive in addResourceLocation for Fonts. Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
ShadowVolume program files exist at /usr/share/OGRE/Media/ShadowVolume/ but aren't added as a resource location Generated-by: Claude Sonnet 4.6 Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
…lper SetNormalMap was a TODO; it stored the name/data but never created the OGRE texture, so RTSS NormalMapLighting::setNormalMapTextureName(_name) would bind to a non-existent texture. Extract the createManual + pixel-upload block from SetTextureDataImpl into CreateOgreTextureFromImage and reuse it from SetNormalMap. The helper does not touch ogreTexState, so the diffuse slot is left alone. This alone is not enough to flip MeshTest.NormalMapWithoutTexCoord from partial-fail to pass — submesh 1 (no texcoords) still bleeds blue — but it removes a real load-bearing TODO that will be needed by any final fix. See remaining-failures.md Part B for the follow-up investigation notes. Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
ProjectorTest.Visibility was producing all-black pixels from both cameras
because OGRE 1.12 on Ubuntu Noble ships without a PNG codec
(Ogre.log: "Can not find codec for 'png' format. Supported formats are:
astc bsp dds ktx mesh pkm"). Every texture loaded by file name -- the
projector decal textures and projection_filter.png -- silently returned a
blank sampler, so the decal fragment shader sampled zero and collapsed
output to (0,0,0). Earlier investigations chased RTSS/scheme-switch
theories; the OGRE log made the real cause obvious.
Fix:
* Add file-scope LoadImageAsOgreTexture() helper that decodes PNGs via
gz-common::Image and uploads raw RGBA to a manual OGRE texture under an
alias, mirroring OgreMaterial::CreateOgreTextureFromImage.
* AddDecalToMaterial() now preloads both the projector decal and
projection_filter.png under per-projector aliases, resolving
projection_filter.png to an absolute path via the resource group
manager, then attaches the pass's texture units by alias.
* The decal pass now uses a pair of hand-written GLSL programs
(__gz_ProjectorDecalVS / __gz_ProjectorDecalFS) that do projective
texturing explicitly via texture_viewproj_matrix{0,1} auto-constants,
bypassing RTSS's FFP_GenerateTexCoord_Projection path. The programs are
created once per process and reused across projector instances.
* The clone's wall pass now goes through
ShaderGenerator::createShaderBasedTechnique(*clone, Default, "projector")
+ validateMaterial + clone->load() so it has GPU programs under GL3+
core. handleSchemeNotFound() returns that "projector"-scheme technique
via a new ProjectorSchemeTechnique() helper instead of the unloaded
fixed-function default that GL3+ cannot execute.
Verified: INTEGRATION_projector (Visibility + Heightmap) passes under
GZ_ENGINE_TO_TEST=ogre on the gl3plus render system.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
MeshTest.NormalMapWithoutTexCoord was rendering the bit-complement of the
expected colours (red source -> yellow, green source -> magenta). Root
cause: the manual texture was created with PF_R8G8B8A8 (OGRE packed word
0xRRGGBBAA, little-endian memory order {A,B,G,R}) but uploaded from
gz-common::Image::RGBAData() (memory order {R,G,B,A}) after an extra R<->B
swap. Sampling the memory as PF_R8G8B8A8 yielded the pixel
(R=A_src, G=B_src, B=G_src, A=R_src) -- the exact inversion the test
dumps showed.
Fix: upload via PF_BYTE_RGBA (aliases to PF_A8B8G8R8 on LE, memory
{R,G,B,A}) and drop the now-redundant swap, matching RGBAData() directly.
Also remove the GITHUB_ACTIONS-gated CHECK_UNSUPPORTED_ENGINE skip added
upstream for this test on Noble; with the texture fix the test passes on
ogre_gl3plus both locally and on CI-equivalent Noble.
Verified: MeshTest.NormalMapWithoutTexCoord passes under
GZ_ENGINE_TO_TEST=ogre.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
For the no-custom-material path, CreateMaterial was installing our
TerrainMaterial("Default/White") generator, whose Profile is not an
SM2Profile. SetupShadows then could not apply the SM2Profile setters
without writing past the real Profile (the heap corruption that
commit ed774fd masked with a dynamic_cast that silently skipped
the setters entirely).
Stop installing TerrainMaterial for that path so TerrainGlobalOptions
falls back to the stock TerrainMaterialGeneratorA, whose active
Profile is an SM2Profile. The dynamic_cast now resolves to a real
SM2Profile and the shadow setters actually run, while remaining
defensive for the custom-material-name branch (where TerrainMaterial
is still installed and the cast correctly returns nullptr).
The stock TerrainMaterialGeneratorA shaders #include TerrainTransforms
and TerrainHelpers, so the Terrain/ subdirectory of OGRE/Media is now
added as a resource location alongside ShadowVolume.
Fixes UNIT_Heightmap_TEST and ProjectorTest.Heightmap against OGRE
1.12.10. Supersedes ed774fd's workaround.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
OGRE 1.12's SceneManager no longer calls RenderSystem::_setWorldMatrix
per renderable, so the legacy GLSL shaders used by the depth camera
(depth_points_vs.glsl: point = gl_ModelViewMatrix * gl_Vertex) and the
gpu rays 1st pass (gpu_rays_1st_pass_vs.glsl: same pattern) saw a
stale modelview matrix from a previous frame or the view matrix only,
producing all-inf depth and zero ranges.
Re-push the renderable's world transform through the GL fixed-function
state from a RenderObjectListener so gl_ModelViewMatrix resolves to
view*world each object:
- OgreDepthCamera now inherits Ogre::RenderObjectListener; the
listener calls renderSys->_setWorldMatrix(rend's world transform).
Listener is added around the pcdTexture update in Render().
- OgreGpuRays's existing listener gains the same _setWorldMatrix
call, placed last so nothing else perturbs the GL MODELVIEW stack.
UpdateRenderTarget seeds the view/projection state first.
- The 2nd pass canvas needs its own world matrix too, so the
listener stays active; currentMat/currentTexture are switched to
the 2nd-pass material before the final UpdateRenderTarget, and the
retro/max/min named-constant setters are gated to the 1st-pass
material which is the only one that declares them.
Fixes INTEGRATION_depth_camera (DepthCameraBoxes), INTEGRATION_gpu_rays
and INTEGRATION_lidar_visual against OGRE 1.12.10.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
OGRE 1.12.10's GLSL frontend runs the fragment shader at #version 150 against a core GL context, where textureCube was removed after 140: 'GerstnerWaves_fs.glsl' 0(52) : error C7616: global function textureCube is removed after version 140 The shader compile error left the wave material with no supportable technique, so the test saw the blue sky background instead of the animated water. Switch the cubemap lookup to the version-agnostic texture(samplerCube, vec3, lod) overload. Fixes INTEGRATION_waves (WavesTest.Waves) against OGRE 1.12.10. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
The shadow_caster_fp shader was writing depth as vertex_depth.z/vertex_depth.w, which is the NDC z in [-1, 1]. The OGRE 1.12 RTSS IntegratedPSSM receiver shader (SGXLib_IntegratedPSSM.glsl) applies shadowMapPos.z = z*0.5 + 0.5 on the receiver side and then compares against the sampled shadow map value, so it expects the shadow map to store depth in window-space [0, 1]. Because of the mismatch, the depth test always resolved to "in shadow" for every receiver fragment, which dropped the directional-light diffuse term to zero over the whole image. INTEGRATION_shadows observed identical sums for the shaded and unshaded halves because neither half ever received direct light. Switch the caster to gl_FragCoord.z, which the rasterizer has already mapped to [0, 1] for us and which matches the receiver's expected range. Fixes INTEGRATION_shadows (ShadowsTest.Shadows) against OGRE 1.12.10. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
Two coupled bugs prevented mesh textures from binding under OGRE 1.12 on Ubuntu Noble: 1. Path-vs-basename. SetTextureImpl was calling addResourceLocation(_texture, ...) with the full file path and then setTextureName(_texture). OGRE indexes resource locations as directories, keyed by basename, so the absolute-path lookup never resolved and every texture became "Cannot locate resource /abs/path/foo.png in resource group General". Same shape as the shader fix from commit 526304e; this path was missed at the time. 2. Missing PNG/JPG codecs. Even after path resolution is correct (e.g. via GZ_SIM_RESOURCE_PATH adding the Fuel-cache mesh dir recursively), OGRE 1.12 on Noble has no PNG or JPG codec ("Can not find codec for 'png' format" in Ogre.log). Resolving the basename to the on-disk file then errored at prepare time and the texture stayed blank. Commit 1206549 worked around this for projector decals by pre-decoding through gz-common::Image and uploading raw RGBA via createManual; the mesh path needed the same workaround. Fix: SetTextureImpl now tries gz-common::Image::Load on the path first. If it succeeds, the texture is uploaded as a manual OGRE texture under its basename in the default resource group, and setTextureName picks it up directly from TextureManager — no codec or resource-group prepare step involved. If the image cannot be decoded by gz-common (e.g. native OGRE-only formats such as DDS or KTX), the parent directory is registered with the material's resource group and the basename is set, matching the 526304e shader pattern. The createManual call deliberately bypasses CreateOgreTextureFromImage so its ResourceGroupManager::resourceExists short-circuit (which fires once GZ_SIM_RESOURCE_PATH has indexed the dir) does not block the upload. Verified end-to-end with two complex Fuel models (Warehouse, deliverybot) loaded into a gz-sim camera-sensor world: GZ_SIM_RESOURCE_PATH=$HOME/.gz/fuel/.../warehouse/5:\ $HOME/.gz/fuel/.../deliverybot/2 \ gz sim -s -r --iterations 300 \ --render-engine-server ogre /tmp/fuel_warehouse_world.sdf Before: every Fuel-model texture failed with either "Cannot locate resource ..." or "Can not find codec for ... format" in Ogre.log; mesh visuals rendered untextured. After: zero texture errors, all five warehouse textures plus DeliveryBot_Diffuse upload as manual textures, the simulation runs 300 iterations and shuts down cleanly. Regression: full gz-rendering ctest suite still passes (134/134), including the existing INTEGRATION_mesh and INTEGRATION_projector tests that exercise SetTexture-related paths. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
Real-world Fuel scenes (jetty_demo) crashed the server with "Fatal glibc error: malloc.c:4179 (_int_malloc): assertion failed: chunk_main_arena (bck->bk)" when the Sensors render thread loaded models with embedded 16-bit-per-channel PNG textures (e.g. open-rmf/conveyor_block normal map: 512x512 PNG with bit_depth=16, color_type=2). Root cause: gz::common::Image::RGBAData() honours the source image's bits_per_channel — for an 8-bit source it returns w*h*4 bytes, for a 16-bit source it returns w*h*8 bytes. Both SetTextureImpl (commit b9e0db7) and CreateOgreTextureFromImage (commit 8b23d54 + 9e4d20f) created the OGRE texture with PF_BYTE_RGBA (which allocates exactly w*h*4 bytes) and then memcpy(pixelBox.data, data.data(), data.size()), which overflowed the OGRE pixel buffer by a factor of 2 for any 16-bit input. The overflow corrupted heap free-list metadata of adjacent chunks; the corruption surfaced later as an abort inside libnvidia-glcore's calloc when the next big GL upload walked the corrupted free chunk. Fix: cap the memcpy at the PF_BYTE_RGBA buffer size (w*h*4) and handle the 16-bit case by extracting the most-significant byte of each native-endian uint16_t channel (stbi stores 16-bit PNGs as native uint16_t, so on little-endian hosts the MSB sits at offset 1). Anything else logs a gzwarn and skips the upload — strictly better than silently corrupting the heap. The Heightmap (commit ed774fd) and Projector (commit 1206549) manual-upload paths use the same lock+memcpy pattern but are not changed here: their inputs are sourced from controlled 8-bit channels and have not been observed to hit this bug. Backtrace at the crash site (server alone, gdb --batch): #21 Ogre::GLTextureBuffer::upload(...) #24 OgreMaterial::CreateOgreTextureFromImage at OgreMaterial.cc:820 #25 BaseMaterial<>::CopyFrom at BaseMaterial.hh:1105 #26 OgreMeshFactory::LoadImpl at OgreMeshFactory.cc:442 #29 OgreScene::CreateMeshImpl ("conveyor_block_visual.glb") #33 RenderUtil::Update #35 SensorsPrivate::RenderThread Verified with: gz sim --verbose --render-engine-server ogre \ --render-engine-gui ogre \ /home/jrivero/code/gz/jetty_demo/.../jetty.sdf runs cleanly to the 60 s timeout — no SIGSEGV, no SIGABRT, no glibc fatal, no backtrace dump in stderr; both -s server-only and full server+GUI on display :1 confirmed. Regression sweep clean: 134/134 gz-rendering ctest pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
The ShadowVolume / Terrain media lookup hard-coded /usr/share/OGRE/Media and /usr/local/share/OGRE/Media, which fails on Windows, macOS, Fedora, Conda, NixOS — every platform that doesn't follow Debian-style FHS. OGREConfig.cmake exports OGRE_MEDIA_DIR and is loaded transitively by gz_find_package(GzOGRE), so plumb that value through as a compile definition (OGRE_MEDIA_PATH) and use it directly. When the value is unset (older OGRE installs that did not export it), we simply skip the optional registration; nothing else degrades. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
…push Three places carried the same bug class as the heap-overflow fix in OgreMaterial::CreateOgreTextureFromImage (a48b445) but were left unguarded: * OgreProjector::LoadImageAsOgreTexture — naive memcpy(data.size()) against a PF_BYTE_RGBA buffer overflows the heap when fed a 16-bit-per-channel projector texture (e.g. an embedded 16-bit PNG). Mirror OgreMaterial's bytes8 / bytes8*2 / else-warn pattern. * OgreProjector::AddDecalToMaterial — getByName(_matName) returns null on miss in OGRE 1.12 instead of throwing, and this code path is reached from the scheme listener with a name that has been trimmed ("_MissingTech_" prefix stripped) so the lookup *can* legitimately fail. Add a null check before mat->getTechnique(0)->createPass(). * OgreDepthCamera/OgreGpuRays::notifyRenderSingleObject — Renderable::getWorldTransforms writes getNumWorldTransforms() matrices into the buffer without a size argument. The pre-fix code filled the [OGRE_MAX_NUM_BONES] stack array *before* checking the count, so a software-skinned renderable whose count exceeds OGRE_MAX_NUM_BONES (skinned animated meshes) silently overflowed the stack. Check count first, clamp, and skip with a warning when the bound is exceeded. Also document the pre-existing limitation that only xform[0] is pushed (skinned visuals render at root bone) — a full fix requires plumbing the bone-matrix array into the depth/laser GLSL programs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
287935f to
7c58452
Compare
Signed-off-by: Jose Luis Rivero <jrivero@honurobotics.com>
Contributor
Author
|
I think that now the tests passes, there is a good bunch of compiler warnings mostly related to deprecated stuff. I would prefer not to put more changes here and do it in a next PR. |
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.
🎉 New feature
This is a large PR coming from #1281.
Summary
The ogre 1.9 support is dropped in favor of the ogre 1.12. This requires changes in release-tools for Windows
and homebrew-simulation to get the testing done correctly on Mac/Windows, Linux and GitHub actions can work from these changes AFAIK. No Mac ogre formula by now.Reviewing process
Easiest way to review could be done per-commit. I can technically review some of them that are not related to changes in rendering and affects more to deprecation and other C++ stuff.
Non deep rendering changes in commits that I reviewed (in order)
OGRE_MEDIA_PATH
On OGRE 1.9, OgreShadowVolumeExtrudeProgram::initialise() wasn't a hard requirement at engine init — stencil-shadow programs were either compiled-in or lazily loaded only if used. Stock TerrainMaterialGeneratorA likewise didn't require an external OgreUnifiedShader.h include path. So gz-rendering could afford to ignore the OGRE-package Media tree entirely.
OGRE 1.12 made Media/ShadowVolume/*.program and Media/Terrain/OgreUnifiedShader.h mandatory at engine init.
Codec_STBI/Codec_FreeImageso OGRE 1.12 can decode PNG/JPG textures (heightmap layer textures hit this path)Worth looking by a rendering expert (8 commits)
A batch of important changes collected by the IA agent to be reviewed in this category:
ee46cd46 — PSSM shadow caster window-space depth (correctness of all shadowed scenes).
076fd2d4 — depth/GPU-lidar per-object matrix push (correctness of all depth sensors); also skips
GpuRaysTest.Heightmapon ogre per #35 (laser-pass + stock TerrainMaterialGeneratorA on OGRE 1.12 returns 0 against the bowl heightmap; ogre2 unaffected).2ab4a527 — projector decal rewrite (all decal/projector scenes).
4eb9efce — heightmap stock TerrainMaterialGeneratorA swap, including pushing layer texture basenames so the SM2Profile lookup hits the registered archive (all terrain scenes).
d9eb98f3 + 897c8cd9 — texture upload byte order + 16-bit clamp (all textured visuals; coupled).
Checklist
codecheckpassed (See contributing)Generated-by: Claude Sonnet 4.6, GPT 5.4, and Claude Opus 4.7.
Note to maintainers: Remember to use Squash-Merge and edit the commit message to match the pull request summary while retaining
Signed-off-byandGenerated-bymessages.Backports: If this is a backport, please use Rebase and Merge instead.