0

I'm new to OpenGL programming and need some help wrapping my head around this issue. I found this answer detailing how to create a cube mesh using a GL_TRIANGLE_STRIP. However, I want to create a rectangular box where the one axis isn't just elongated but rather repeated, so that the geometry ends up something like this:

enter image description here

I can't figure out how I'm supposed to construct such a shape where the geometry gets generated correctly, with correct normals and closed ends, with the winding order to keep in mind and what-not.

How should I be thinking and defining the vertices?

Niklas
  • 465
  • 2
  • 9
  • 19
  • Off topic but... can I ask why the triangles need to be repeated along one axis rather than simply elongated? – G.M. Jan 29 '21 at 17:12
  • I'm wanting to it use as a mesh for projecting decals and be able to curve it at each section. Was planning to use it as a technique for tyre tracks. – Niklas Jan 29 '21 at 20:11

1 Answers1

1

The formula for the triangle strip cube does most of the work, all you have to do is extend the long faces to add more in between, which can be done with for loops. Cube with long faces There are two times the strip changes direction, both on the bottom face, so we just need a little manual work there. I wrote up this simple function to create vertices based on a length, and it will build a length by 1 by 1 rectangle.

void generateRect(int length, std::vector<glm::vec3>& vertices) {
    std::vector<glm::vec3> vertexArray;
    
    //Generate nescessary points
    float x = length / 2.0f;
    for (int i = 0; i <= length; i++) {
        vertexArray.push_back(glm::vec3(x, -0.5f, 0.5f));
        vertexArray.push_back(glm::vec3(x, -0.5f, -0.5f));
        vertexArray.push_back(glm::vec3(x, 0.5f, 0.5f));
        vertexArray.push_back(glm::vec3(x, 0.5f, -0.5f));
        x -= 1.0f;
    }
    
    //+Y face
    for (int i = 0; i <= length; i++) {
        int index = i * 4 + 3;
        vertices.push_back(vertexArray.at(index));
        vertices.push_back(vertexArray.at(index - 1));
    }
    
    //Change direction (Half of -X face)
    vertices.push_back(vertexArray.at(length * 4));
    
    //+Z face
    for (int i = length - 1; i >= 0; i--) {
        int index = i * 4;
        vertices.push_back(vertexArray.at(index + 2));
        vertices.push_back(vertexArray.at(index));
    }
    
    //-Z face (+X face created as well)
    for (int i = 0; i <= length; i++) {
        int index = i * 4 + 3;
        vertices.push_back(vertexArray.at(index));
        vertices.push_back(vertexArray.at(index - 2));
    }
    
    //Change direction (Other half of -X face)
    vertices.push_back(vertexArray.at(length * 4));
    
    //-Y face
    for (int i = length - 1; i >= 0; i--) {
        int index = i * 4;
        vertices.push_back(vertexArray.at(index + 1));
        vertices.push_back(vertexArray.at(index));
    }
}

From this we get our rectangle, and for texturing I just used a cubemap as I've been doing skyboxes. OpenGL is smart enough to know the winding order will be reversed every other triangle, so no need to do any fancy math. You just have to make sure it's right for the first one, in this case the first one is counter-clockwise.

Result

For normal generation, it's a little harder as the vertices must share a normal as well, even if it's being used for a different face. I don't think there is a workaround, but I haven't done much with triangle strip so there may be, perhaps something to do with a geometry shader.

Ty Staszak
  • 115
  • 2
  • 11
  • Thank you for your reply! I'll look into it and try it out when I get home. Do normals need to be calculated manually? How does one do that when, as you said, vertices are shared? – Niklas Jan 29 '21 at 20:25
  • (Forget my previous comment, my explanation is incorrect). The problem comes when the strip wraps around to a new face. Because the two triangles share two of their vertices, they must also share normals. However, this would be incorrect, as they are on different faces and need different normals. – Ty Staszak Jan 29 '21 at 21:00
  • Sorry it took me so long to try it out, your solution worked perfectly. Thank you so much! – Niklas Feb 01 '21 at 20:46