0
votes

So I'm writing some WebGL, no THREE.JS. I'm trying to render a cube, with a single texture mapped to every face of the cube. In my code where I set up my attributes I have something like:

  var vertices = new Float32Array([
    // x,    y,    z                              u, v
     1.0,  1.0,  1.0, /* v0 right top front */    1.0, 1.0,
    -1.0,  1.0,  1.0, /* v1 left top front */     0.0, 1.0,
    -1.0, -1.0,  1.0, /* v2 left bottom front */  0.0, 0.0,
     1.0, -1.0,  1.0, /* v3 right bottom front */ 1.0, 0.0,
     // u's switch for back faces
     1.0, -1.0, -1.0, /* v4 right bottom back */  0.0, 0.0,
     1.0,  1.0, -1.0, /* v5 right top back */     0.0, 1.0,
    -1.0,  1.0, -1.0, /* v6 left top back */      1.0, 1.0,
    -1.0, -1.0, -1.0, /* v7 left bottom back */   1.0, 0.0
  ]);

  // the pairs of vertex triples
  // 3 vertices = 1 triangle
  // 2 triangles = 1 quad = 1 face
  var indices = new Uint8Array([
    0, 1, 2,  0, 2, 3, // front
    0, 3, 4,  0, 4, 5, // right
    //0, 5, 6,  0, 6, 1, // top
    1, 6, 7,  1, 7, 2, // left
    //7, 4, 3,  7, 3, 2, // bottom
    4, 7, 6,  4, 6, 5  // back
  ]);

I wind up with a cube with the texture reflected for the right and left faces, which is fine. For the top and the bottom, I have no faces because of the two commented out lines. When I comment them in, the faces don't have the texture sampled as I expected. Sure enough, if you look at the indices for the top face for instance, and the UV coordinates that they would have:

index | u   | v
  0   | 1.0 | 1.0
  1   | 0.0 | 1.0
  5   | 0.0 | 1.0
  6   | 1.0 | 1.0

So we can see that index 1 and 5 (also, 0 and 6) have the same UV coordinates, so of course it wont look right on a quad.

I've been trying to draw out on paper, but I can't change the UV's without messing up another face's coordinates. What I'm wondering is: is it possible to use ELEMENT_ARRAY_BUFFERs to map UV coordinates on a cube, or do I need to use more data and draw using an ARRAY_BUFFER?

== EDIT ==

Looks like a dupe: OpenGL ES - texture map all faces of an 8 vertex cube?

1

1 Answers

0
votes

Hate to answer my own question, but based on the hint here, I was able to get it to work by using 24 vertices instead of 8. I can use 24 instead of 36 because I'm repeating indices in my ELEMENT_ARRAY_BUFFER (something I wouldn't be able to do with just an ARRAY_BUFFER).

  var vertices = new Float32Array([
    // x,    y,    z,   u,   v
    // front face (z: +1)
     1.0,  1.0,  1.0, 1.0, 1.0, // top right
    -1.0,  1.0,  1.0, 0.0, 1.0, // top left
    -1.0, -1.0,  1.0, 0.0, 0.0, // bottom left
     1.0, -1.0,  1.0, 1.0, 0.0, // bottom right
    // right face (x: +1)
     1.0,  1.0, -1.0, 1.0, 1.0, // top right
     1.0,  1.0,  1.0, 0.0, 1.0, // top left
     1.0, -1.0,  1.0, 0.0, 0.0, // bottom left
     1.0, -1.0, -1.0, 1.0, 0.0, // bottom right
    // top face (y: +1)
     1.0,  1.0, -1.0, 1.0, 1.0, // top right
    -1.0,  1.0, -1.0, 0.0, 1.0, // top left
    -1.0,  1.0,  1.0, 0.0, 0.0, // bottom left
     1.0,  1.0,  1.0, 1.0, 0.0, // bottom right
    // left face (x: -1)
    -1.0,  1.0,  1.0, 1.0, 1.0, // top right
    -1.0,  1.0, -1.0, 0.0, 1.0, // top left
    -1.0, -1.0, -1.0, 0.0, 0.0, // bottom left
    -1.0, -1.0,  1.0, 1.0, 0.0, // bottom right
    // bottom face (y: -1)
     1.0, -1.0,  1.0, 1.0, 1.0, // top right
    -1.0, -1.0,  1.0, 0.0, 1.0, // top left
    -1.0, -1.0, -1.0, 0.0, 0.0, // bottom left
     1.0, -1.0, -1.0, 1.0, 0.0, // bottom right
    // back face (x: -1)
    -1.0,  1.0, -1.0, 1.0, 1.0, // top right
     1.0,  1.0, -1.0, 0.0, 1.0, // top left
     1.0, -1.0, -1.0, 0.0, 0.0, // bottom left
    -1.0, -1.0, -1.0, 1.0, 0.0  // bottom right
  ]);

  // the pairs of vertex triples
  // 3 vertices = 1 triangle
  // 2 triangles = 1 quad = 1 face
  var indices = new Uint8Array([
     0,  1,  2,   0,  2,  3,
     4,  5,  6,   4,  6,  7,
     8,  9, 10,   8, 10, 11,
    12, 13, 14,  12, 14, 15,
    16, 17, 18,  16, 18, 19,
    20, 21, 22,  20, 22, 23
  ]);

Scroll above code example ^

The number of vertices can be further reduced, because some indices share the same XYZ and UV coordinates, though if I add normals to my interleaved buffer later (or any other attribute) I may need the repeated values.