Hi,
Ryan Joseph wrote 12 lines
I actually got the problem wrong and still haven’t figured it out so
here’s another go.
I have a number which I need to encode as an RGB value each component
being 4 bytes (12 bytes total) so I need to extract each digit as a byte
(and then each byte back to a digit). It’s basic low level computer
science stuff I never learned well. The old version of GLSL I’m using
(1.2) doesn’t support bit shifting (which I think I could use) so I need
to do this using arithmetic.
On Google I found a good method to have the compiler convert a word to
an array of bytes using variant records such as:
I'm not particularly fond of this method, because this is not endian safe. It won't work on bigendian CPUs (which are marginal, and a thing of the past, sort of, but their heritage is still with us thanks to the network byte order, which is bigendian, and some languages like Java, which use bigendian internally).
Show quoted text 18 lines
type
TBytes = record
case byte of
0: (i : word);
1: (u : array[0..3] of byte);
2: (r, g, b, a: byte);
end;
so for the number 1234:
var
c: TBytes;
FillChar(c, sizeof(c), 0);
c.i := 300;
writeln(c.r, ' ', c.g, ' ', c.b, ' ', c.a);
I get: 44 1 0 0
A Word in Pascal is always two bytes. So I don't understand what you want here.
How do I convert this back to 300 using arithmetic? I see you can add
255 to first value plus the next value (1) to get 300 but what’s the
correct method to use I could make into a function?
You're seeing the bytes of a two byte "word" value in little endian, which is the endianness of x86 and ARM CPUs by default. If you need to process the data byte by byte, you need to swap the order of bytes around.
In your example:
writeln((c.g shl 8) + c.r);
should print "300";
If you change "i" to dword, For a 32bit value this would be:
writeln((c.a shl 24) + (c.b shl 16) + (c.g shl 8) + c.a;
But you cannot apply this method to floats, such byte-magic only works on integers (well, you need to also swap around bytes of a float if you process them as bytes, but that's beside the point here). You also cannot extract the 10-base digits of an integer value like this (unless we're talking about BCD numbers, which is again, an entirely different topic).
I still not entirely understand what you want to achieve, but to extract the digits of a fractional number, you could simply do the following:
var
a: single;
begin
a:=1234.5678;
// integer part
writeln(trunc(a) mod 10000 div 1000);
writeln(trunc(a) mod 1000 div 100);
writeln(trunc(a) mod 100 div 10);
writeln(trunc(a) mod 10 div 1);
// fractional part
writeln(trunc(a*10) mod 10);
writeln(trunc(a*100) mod 10);
writeln(trunc(a*1000) mod 10);
writeln(trunc(a*10000) mod 10);
end.
But anyway, I guess this is not so useful for you any more. So if you can tell what *actually* you want to do, like convert a vec4 of GLSL float to Pascal, or convert a 32bit RGBA value to a GLSL vec4, maybe that would be more easy to help you with.
Also, are you trying to generate GLSL source with this, or you're processing binary data returned by your shader code in a buffer?
Charlie