简体   繁体   中英

How do I draw a rectangular box using GL_TRIANGLE_STRIP?

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:

在此处输入图像描述

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?

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. 长脸立方体 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.

结果

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM