如何使用 GL_TRIANGLE_STRIP 绘制一个矩形框?

Posted

技术标签:

【中文标题】如何使用 GL_TRIANGLE_STRIP 绘制一个矩形框?【英文标题】:How do I draw a rectangular box using GL_TRIANGLE_STRIP? 【发布时间】:2021-01-29 17:00:00 【问题描述】:

我是 OpenGL 编程的新手,需要一些帮助来解决这个问题。我发现这个answer 详细说明了如何使用 GL_TRIANGLE_STRIP 创建立方体网格。但是,我想创建一个矩形框,其中一个轴不仅被拉长,而且被重复,因此几何图形最终如下所示:

我无法弄清楚我应该如何构建这样一个形状,其中几何体可以正确生成,具有正确的法线和封闭端,以及要记住的缠绕顺序等等。

我应该如何思考和定义顶点?

【问题讨论】:

离题但是...我能问一下为什么三角形需要沿一个轴重复而不是简单地拉长吗? 我希望它用作投影贴花的网格,并能够在每个部分弯曲它。正计划将其用作轮胎痕迹的技术。 【参考方案1】:

三角形条形立方体的公式完成了大部分工作,您所要做的就是扩展长面以在其间添加更多内容,这可以通过 for 循环来完成。 条带有两次改变方向,都在底面上,所以我们只需要在那里做一些手工工作。我编写了这个简单的函数来根据长度创建顶点,它会构建一个长度乘以 1 乘以 1 的矩形。

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));
    

从这里我们得到了我们的矩形,对于纹理,我只是使用了立方体贴图,因为我一直在做天空盒。 OpenGL 足够聪明,知道缠绕顺序每隔一个三角形就会反转,所以不需要做任何花哨的数学运算。您只需要确保第一个是正确的,在这种情况下,第一个是逆时针的。

对于法线生成,这有点困难,因为顶点也必须共享法线,即使它被用于不同的面。我不认为有解决方法,但我没有对三角形条做太多,所以可能有,也许与几何着色器有关。

【讨论】:

感谢您的回复!我会研究它并在我回家时尝试一下。法线需要手动计算吗?正如您所说,当顶点是共享的时,如何做到这一点? (忘记我之前的评论,我的解释不正确)。当条带缠绕到新面孔时,问题就出现了。因为这两个三角形共享它们的两个顶点,所以它们也必须共享法线。但是,这是不正确的,因为它们在不同的面上并且需要不同的法线。 抱歉,我花了这么长时间才尝试,您的解决方案效果很好。非常感谢!

以上是关于如何使用 GL_TRIANGLE_STRIP 绘制一个矩形框?的主要内容,如果未能解决你的问题,请参考以下文章

IBO 比 GL_TRIANGLE_STRIP 更糟?

使用 glDrawElements 绘制 std::vector

OpenGL VBO 绘制顺序

背面剔除 + GL_TRIANGLE_STRIP?

计算机图形学5--绘制基本图元

使用 glDrawElements 很难理解索引