4

Working on a WebGL project and I am looking over code from a class example. In one of the loops this code was given:

var c = (((i & 0x8) == 0) ^ ((j & 0x8)  == 0));

The variables i and j go up to a certain value in a for loop. What does this statement mean? Does this make sure that the variable c is in hexadecimal form?

var texSize = 64; 
var image1 = new Array(); 
for (var i =0; i<texSize; i++) 
    image1[i] = new Array(); 
for (var i =0; i<texSize; i++) 
    for ( var j = 0; j < texSize; j++) 
        image1[i][j] = new Float32Array(4); 
for (var i =0; i<texSize; i++) 
    for (var j=0; j<texSize; j++) 
    { 
        var c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0)); 
        image1[i][j] = [c, c, c, 1]; 
    }
gman
  • 83,286
  • 25
  • 191
  • 301
  • Not an answer, but you should consider using `===` operator instead of `==` in JavaScript. Especially when you are not sure of what you are doing as operation. – Aracthor Apr 27 '15 at 07:48
  • Important note: "hexadecimal" has absolutely nothing to do with this. It's just a notational convention. Also, variables "are" not "in hex" or not -- they contain *a number* (or another type of value such as `bool` or `string`, but "hex" supposes you are talking about numerical contents). – Jongware Apr 27 '15 at 10:41
  • @Aracthor: `==` is totally fine when values of the same type are compared, as is the case here. – Bergi Apr 27 '15 at 12:10
  • See also [What does this symbol mean in JavaScript?](https://stackoverflow.com/questions/9549780/what-does-this-symbol-mean-in-javascript) – Bergi Apr 27 '15 at 12:13

2 Answers2

2

SMchrohan's answer is correct. The code is basically making a checkerboard texture.

The ?? & 0x8 means it that expression will be true when bit 3 (0,1,2,3) is true. bit 3 in binary is true every other set of 8 values (0-7 it's false, 8-15 it's true, 16-23 it's false, etc).

Then the code takes the opposite of that with == 0.

It does it for both i and j.

The ^ means exclusive-or which is true when both parts are the different (true, false or false, true) and false when they are both the same (false, false, or true, true). Because ^ is a bitwise operator both values are first converted to integers so false becomes 0 and true becomes 1. The 2 int values then have their bits exclusive-ored so

0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 1 = 1
1 ^ 1 = 0

that means each entry in image1 is either [0, 0, 0, 1] or [1, 1, 1, 1]

here's some code to plot it

var texSize = 64; 
var image1 = new Array(); 
for (var i =0; i<texSize; i++) 
    image1[i] = new Array(); 
for (var i =0; i<texSize; i++) 
    for ( var j = 0; j < texSize; j++) 
        image1[i][j] = new Float32Array(4); 
for (var i =0; i<texSize; i++) 
    for (var j=0; j<texSize; j++) 
    { 
        var c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0)); 
        image1[i][j] = [c, c, c, 1]; 
    }

// lets plot it

var ctx = document.createElement("canvas").getContext("2d");
document.body.appendChild(ctx.canvas);
ctx.canvas.width = texSize;
ctx.canvas.height = texSize;

for (var i =0; i<texSize; i++) 
    for (var j=0; j<texSize; j++) 
    { 
        var c = image1[i][j][0]
        ctx.fillStyle = c ? "red" : "yellow";
        ctx.fillRect(i, j, 1, 1);
    }
canvas { border: 1px solid black; }
<body></body>

Note that the code doesn't appear to make much sense. It says texSize so it seems to be making a texture but it's making one Float32Array per pixel (the line that says)

image1[i][j] = new Float32Array(4);

and then it's replacing each of those individual Float32Arrays with a JavaScript native array on this line

image1[i][j] = [c, c, c, 1]; 

Which makes the Float32Array line useless.

On top of that I have no idea what an array or arrays of 1 pixel Float32Arrays is good for. You can't upload it like that to WebGL.

Normally I'd make one Uint8Array for the entire texture like this

var texSize = 64; 
var pixels = new Uint8Array(texSize * texSize * 4);

for (var i =0; i<texSize; i++)  {
    for (var j=0; j<texSize; j++) { 
        var c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0)); 
        var p = c ? 255 : 0;
        var offset = (i * texSize + j) * 4;
        pixels[offset + 0] = p;  // red
        pixels[offset + 1] = p;  // green
        pixels[offset + 2] = p;  // blue
        pixels[offset + 3] = 255;// alpha
    }

}

Or I'd use the 2D canvas API to make the texture

without some context though I don't know what the final purpose of the code is.

gman
  • 83,286
  • 25
  • 191
  • 301
  • I think c actually comes out as an it...surprisingly (to me), `true ^ true` is returning 0, not false. Regardless, yes...this code is pretty opaque. OP shouldn't feel bad about being confused...whoever wrote this seems to have gone out of their way to do things oddly. – S McCrohan Apr 27 '15 at 12:24
  • Oh, interesting. You're right. `^` is a bitwise operator so it will coerce the value to ints. Will fix – gman Apr 27 '15 at 15:52
1

& is bitwise and.

^ is bitwise xor.

0x8 is the hex expression of the integer 8.

c will be 1 if either i or j BUT NOT BOTH have a 1 in their 4th bit - that is, a bitwise and with 0x8 (binary 1000) returns 0.

To walk through this a little more:

i & 0x8 will return either 0 (if the value of i has a 0 in bit 4) or 8 (if it has a 1 in that position).

(i & 0x8) == 0 will be either true or false.

(((i & 0x8) == 0) ^ ((j & 0x8) == 0)) will be 1 if either ((i & 0x8) == 0) or ((j & 0x8) == 0) is true, or 0 if both are false OR both are true.

S McCrohan
  • 6,277
  • 1
  • 26
  • 35
  • So the var c is a boolean value? Here is the rest of the code that might help make a little more sense: var texSize =64; var image1 = new Array() for (var i =0; i – Billy Vivian Apr 27 '15 at 03:27