diff --git a/source/MRViewer/MRGLStaticHolder.cpp b/source/MRViewer/MRGLStaticHolder.cpp index 26f3aac04f66..df82745c95c5 100644 --- a/source/MRViewer/MRGLStaticHolder.cpp +++ b/source/MRViewer/MRGLStaticHolder.cpp @@ -182,7 +182,14 @@ void GLStaticHolder::createShader_( ShaderType type ) out vec3 world_pos; out float primitiveIdf0; out float primitiveIdf1; - +)" +#ifndef __EMSCRIPTEN__ + // desktop GL has integer varyings, so the id needs no float round-trip + R"( + flat out uint primitiveIdFlat; +)" +#endif + R"( void main() { world_pos = vec3(model*vec4 (position, 1.0)); @@ -190,6 +197,13 @@ void GLStaticHolder::createShader_( ShaderType type ) uint primId = uint(gl_VertexID) / primBucketSize; primitiveIdf1 = float( uint( primId >> 20u ) ) + 0.5; primitiveIdf0 = float( primId % uint( 1u << 20u ) ) + 0.5; +)" +#ifndef __EMSCRIPTEN__ + R"( + primitiveIdFlat = primId; +)" +#endif + R"( gl_PointSize = pointSize; } )"; diff --git a/source/MRViewer/MRShaderBlocks.cpp b/source/MRViewer/MRShaderBlocks.cpp index f15cd093d208..2e182fa07fd0 100644 --- a/source/MRViewer/MRShaderBlocks.cpp +++ b/source/MRViewer/MRShaderBlocks.cpp @@ -22,11 +22,18 @@ std::string getPickerFragmentShader( bool points, bool cornerMode ) out highp uvec4 color; )"; + // outside corner mode the id arrives in a flat integer varying: gl_PrimitiveID came back + // as garbage under llvmpipe 21.1.8 / Mesa 26.0.8. Declared only where read, so the pickers + // that stay in corner mode keep linking against vertex shaders without it. const std::string primId = cornerMode ? R"( uint primitiveId = ( uint(primitiveIdf1) << 20u ) + uint(primitiveIdf0); )" : R"( - uint primitiveId = uint(gl_PrimitiveID); + uint primitiveId = primitiveIdFlat; +)"; + + const std::string idDecl = cornerMode ? "" : R"( + flat in uint primitiveIdFlat; )"; const std::string tail = R"( @@ -39,6 +46,7 @@ std::string getPickerFragmentShader( bool points, bool cornerMode ) return head + + idDecl + getShaderMainBeginBlock( false ) + ( points ? getFragmentShaderPointSizeBlock() : R"()" ) + getFragmentShaderClippingBlock() +