How to compute 64 bit integer in vtkShaderProgram?

I’m really don’t know what I am doing when it comes to OpenGL and OpenGL Shader and all of that but I have a custom piece of code that was written for us:

    std::string FSSource = shaders[vtkShader::Fragment]->GetSource();
    vtkShaderProgram::Substitute(FSSource, "//VTK::Picking::Impl",
                                 "//DREAM3D-NX::Picking::Impl\n"
                                 "  ivec2 size = textureSize(actortexture,0);\n"
                                 "  vec2 fsize = vec2(size);\n"
                                 "  vec2 fcoord = tcoordVCVSOutput * fsize;\n"
                                 "  ivec2 coord = ivec2(fcoord);\n"
                                 "  int idx = coord.y * size.x + coord.x;\n"
                                 "  fragOutput0 = vec4(double(idx % 256) / 255.0, double((idx / 256) % 256) / 255.0, double((idx / 65536) % 256) / 255.0, 1.0);\n");
    shaders[vtkShader::Fragment]->SetSource(FSSource);

and the issue is that somewhere in that code we are overflowing at 24 bits for the ‘idx’ calculation. I have tried to use dvec2 but that just throws errors about reserved words.

What version of OpenGL Shader Language does Vtk 9.2.6 use? Would it be any better with a newer version of VTK?

How could I adjust the code to allow for the proper calculation of the “idx” variable without over flowing the 24 bit of precision.

Thanks.

Hello,

The dvecn type is supposed to be used in that case. I think you should work on the errors you’re getting. How about sharing them here?

best,

PC

I think you’ll do fine if you just use unsigned integer math instead of signed integer math.

For unsigned integers, overflow for multiplication and addition is well defined: the overflowed bits are lost, but the lower 32 bits that actually fit in the output are fine. (Overflow for signed integers, by comparison, is a mess.)

The “fragOutput0” line only actually needs the lower 24 bits of the integer to compute the result, so the 32 bits provided by uint is plenty. No need for 64 bit ints.

My suggested code:

uint idx = uint(coord.y) * uint(size.x) + uint(coord.x);
fragOutput0 = vec4((idx % 256) / 255.0,
                   ((idx / 256) % 256) / 255.0,
                   ((idx / 65536) % 256) / 255.0,
                   1.0);

Edit: This is just a shot in the dark, but depending on what this code is actually for, you might need to change the “fragOutput0” so that it consumes 30 bits instead of only 24 bits:

uint idx = uint(coord.y) * uint(size.x) + uint(coord.x);
fragOutput0 = vec4((idx % 1024) / 1023.0,
                   ((idx / 1024) % 1024) / 1023.0,
                   ((idx / 1048576) % 1024) / 1023.0,
                   1.0);