Reputation: 41
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];
}
Upvotes: 4
Views: 193
Reputation:
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.
Upvotes: 2
Reputation: 6693
&
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.
Upvotes: 1