Vertex Array problem

I was following this tutorial: http://www.java-gaming.org/index.php?topic=24272.0

And he said to do this:


glColorPointer(3, 3 << 2, cBuffer);
glVertexPointer(3, 3 << 2, vBuffer);
glDrawArrays(GL_TRIANGLES, 0, 3);

What do those bitwise operators mean and what does it do?

[icode]x << 2[/icode] == [icode]x * 4[/icode]

<< 1 = * 2
<< 2 = * 4
<< 3 = * 8
<< 4 = * 16

etc.

1 = / 2
2 = / 4
3 = / 8
4 = / 16

etc.

To add on to what @basil_ said, you need to pass the size in bytes. A float is 4 bytes, so you need to multiply the buffer size by 4.

If you do not recognize bit-shifting and/or its meaning in VBOs, don’t touch LWJGL. Learn the basics first, or you’ll find yourself perpetually stuck, knee deep in excrement.

I know some people don’t want me suggesting learning outdated stuff, but the easiest way to learn LWJGL (in my opinion) and work up to Vertex Arrays and bitshifting is to go:

  • Immediate Mode
  • Display Lists
  • Vertex Array Objects or Framebuffers

Just my thoughts,
CopyableCougar4

You can probably skip Display Lists.

As soon as you get the basics of Immediate mode move on to VBOs.

@Copyable how does learning immediate mode teach you anything about bitshifts.

I never understood why people do that bitshift instead of just doing *4. Maybe someone could enlighten me?

When I do anything with bitwise operations it is because I want to make it clear that I am using this int as 32 bits rather than a decimal integer number. When you do something like x << 2 instead of x * 4 just because you can, it seems to me like you are obfuscating your code with no good reason. Its like turning all your constant numbers into Hex just because you can.

I pretty sure when u do bitshifts instead of * or /, the system can do those calculations faster. There really isn’t any reason someone shouldn’t learn bitshifts. :wink:

I’d say the difference in speed is equivalent to typing ‘u’ instead of ‘you’ in a long sentence. i.e, negligible.

Please learn to spell.

Any sane compiler would optimise multiplication by powers of two anyway.
The only difference is to the programmer. Hence The Lion King’s question as to why people use it when they’re not manipulating bits.

[quote]I’d say the difference in speed is equivalent to typing ‘u’ instead of ‘you’ in a long sentence. i.e, negligible.

Please learn to spell.
[/quote]
I will write ‘you’ instead of ‘u’ next time. :stuck_out_tongue:

[quote]Any sane compiler would optimise multiplication by powers of two anyway.
The only difference is to the programmer. Hence The Lion King’s question as to why people use it when they’re not manipulating bits.
[/quote]
Well in that case, I’m as clueless as the op.

I choose to use << 2, because it immediately makes it obvious (to me) that the operation has no meaning in the business logic, we’re just converting from an offset measured in floats (or, say… shorts, <<1) to an offset in bytes. A multiplication by 4 (or 2, for that matter) actually hides what is happening, as we conceptually simply want to shift bits here. Primitives are POT for a reason… hence converting among them involves plain POT operations like bitshifting. A multiplication by 4 is easily confused with a meaningful value, like vertices in a quad or other values in your model. People get strides and offsets wrong all the time (involving trial and error until it doesn’t crash anymore). Using bit shifting is my way to separate business logic and POT unit conversion in a way that imho actually makes more sense than the simple multiplication.

Ramble ramble.

Whether this increases performance is irrelevant.

Hi

The display lists are broken in numerous drivers, even on “outdated” hardware. I would rather suggest to start with immediate mode (only for learning purposes), then to switch to vertex arrays, VBO and finally VAO. The use of vertex arrays allows to get accustomed with the retained mode. In my humble opinion, switching from immediate mode to VAO is a bit too much.

3 * sizeOfFloats would make much sense (to me).

I’d have prefered to use Float.SIZE, but it holds 32 (as opposed to 4), making it useless as [icode]* (Float.SIZE / Byte.SIZE)[/icode] is too verbose. :frowning: Static imports also don’t work out when every single class wrapping a primitive has the static field named SIZE. A utility function is overkill and verbose… so icode << 2[/icode] it is!

Why not adding a constant SIZEOF_FLOAT into org.lwjgl.BufferUtils to store the size of a float in bytes? It would be easier to understand.

might aswell add [icode]int FLOAT_POT = 2[/icode] and use [icode]4 << FLOAT_POT[/icode] … absurd.

<< is a operator just like any other (+ - * /), i use it cos’ i am used to.

3 * SIZEOF_FLOAT is easier to understand (to me) than <<, >>, < and > even though I know their effects.