Skip to content
  • 首页
  • 留言
  • 关于

Share the joys of programming and technology

OpenGL绘制桥梁模型

OpenGL绘制桥梁模型

2021年6月30日 liyanliang Comments 1 comment
阅读次数: 387

本文主要讲述如何使用现代OpenGL绘制一个完整的桥梁模型,包括箱梁、盖梁和桥墩,关于OpenGL方面,主要添加的shader,使用phong光照模型实现。

一、绘制箱梁

1.1 箱梁的的截面和坐标系

截面:

坐标系:

1.2 箱梁的顶点及其法向量

    float vertices[] = {
        //////////////////////////////////////////////////////////////////////////
        //前视图
        // 左翼缘
        // positions          // normals 
        -1.0f, 0.3f, 30.1f,    0.0f, 0.0f, 1.0f,
        -1.0f, 0.2f, 30.1f,    0.0f, 0.0f, 1.0f,
        -0.5f, 0.3f, 30.1f,    0.0f, 0.0f, 1.0f,
    
        -1.0f, 0.2f, 30.1f,    0.0f, 0.0f, 1.0f,
        -0.5f, 0.1f, 30.1f,   0.0f, 0.0f, 1.0f,
        -0.5f, 0.3f, 30.1f,   0.0f, 0.0f, 1.0f,
    
        // 左矩形
        -0.5f, 0.3f,   30.1f,  0.0f, 0.0f, 1.0f,
        -0.5f, -0.3f,  30.1f,  0.0f, 0.0f, 1.0f,
        -0.35f, -0.3f, 30.1f,  0.0f, 0.0f, 1.0f,
    
        -0.5f, 0.3f,   30.1f,  0.0f, 0.0f, 1.0f,
        -0.35f, -0.3f, 30.1f,  0.0f, 0.0f, 1.0f,
        -0.35f, 0.3f,  30.1f,  0.0f, 0.0f, 1.0f,
    
        // 上矩形
        -0.35f, 0.3f, 30.1f,   0.0f, 0.0f, 1.0f,
        -0.35f, 0.2f, 30.1f,   0.0f, 0.0f, 1.0f,
        -0.0f, 0.3f,  30.1f,   0.0f, 0.0f, 1.0f,
    
        -0.35f, 0.2f, 30.1f,   0.0f, 0.0f, 1.0f,
        -0.0f, 0.3f,  30.1f,   0.0f, 0.0f, 1.0f,
        -0.0f, 0.2f,  30.1f,      0.0f, 0.0f, 1.0f,
    
        // 下矩形
        -0.35f, -0.3f, 30.1f,  0.0f, 0.0f, 1.0f,
        -0.35f, -0.2f, 30.1f,  0.0f, 0.0f, 1.0f,
        -0.0f, -0.3f,  30.1f,  0.0f, 0.0f, 1.0f,
    
        -0.35f, -0.2f, 30.1f,  0.0f, 0.0f, 1.0f,
        -0.0f, -0.3f,  30.1f,  0.0f, 0.0f, 1.0f,
        -0.0f, -0.2f,  30.1f,  0.0f, 0.0f, 1.0f,
    
        // 左上倒角
        -0.35f, 0.2f,  30.1f,  0.0f, 0.0f, 1.0f,
        -0.35f, 0.15f, 30.1f,  0.0f, 0.0f, 1.0f,
        -0.25f, 0.2f,  30.1f,  0.0f, 0.0f, 1.0f,
    
        // 左下倒角
        -0.35f, -0.2f,  30.1f, 0.0f, 0.0f, 1.0f,
        -0.35f, -0.15f, 30.1f, 0.0f, 0.0f, 1.0f,
        -0.25f, -0.2f,  30.1f, 0.0f, 0.0f, 1.0f,
    
            //对称 右边
            //右翼缘
        1.0f, 0.3f, 30.1f,   0.0f, 0.0f, 1.0f,
        1.0f, 0.2f, 30.1f,  0.0f, 0.0f, 1.0f,
        0.5f, 0.3f, 30.1f,  0.0f, 0.0f, 1.0f,
    
        1.0f, 0.2f, 30.1f,   0.0f, 0.0f, 1.0f,
        0.5f, 0.1f, 30.1f,  0.0f, 0.0f, 1.0f,
        0.5f, 0.3f, 30.1f,  0.0f, 0.0f, 1.0f,
    
        // 右矩形
        0.5f, 0.3f,   30.1f, 0.0f, 0.0f, 1.0f,
        0.5f, -0.3f,  30.1f, 0.0f, 0.0f, 1.0f,
        0.35f, -0.3f, 30.1f, 0.0f, 0.0f, 1.0f,
    
        0.5f, 0.3f,   30.1f, 0.0f, 0.0f, 1.0f,
        0.35f, -0.3f, 30.1f,    0.0f, 0.0f, 1.0f,
        0.35f, 0.3f,  30.1f,    0.0f, 0.0f, 1.0f,
    
        // 上矩形
        0.35f, 0.3f, 30.1f, 0.0f, 0.0f, 1.0f,
        0.35f, 0.2f, 30.1f, 0.0f, 0.0f, 1.0f,
        0.0f, 0.3f,  30.1f, 0.0f, 0.0f, 1.0f,
    
        0.35f, 0.2f, 30.1f, 0.0f, 0.0f, 1.0f,
        0.0f, 0.3f,  30.1f, 0.0f, 0.0f, 1.0f,
        0.0f, 0.2f,  30.1f, 0.0f, 0.0f, 1.0f,
    
        // 下矩形
        0.35f, -0.3f, 30.1f, 0.0f, 0.0f, 1.0f,
        0.35f, -0.2f, 30.1f, 0.0f, 0.0f, 1.0f,
        0.0f, -0.3f,  30.1f, 0.0f, 0.0f, 1.0f,
    
        0.35f, -0.2f, 30.1f, 0.0f, 0.0f, 1.0f,
        0.0f, -0.3f,  30.1f, 0.0f, 0.0f, 1.0f,
        0.0f, -0.2f,  30.1f,    0.0f, 0.0f, 1.0f,
    
        // 右上倒角
        0.35f, 0.2f,  30.1f, 0.0f, 0.0f, 1.0f,
        0.35f, 0.15f, 30.1f, 0.0f, 0.0f, 1.0f,
        0.25f, 0.2f,  30.1f, 0.0f, 0.0f, 1.0f,
    
        // 右下倒角
        0.35f, -0.2f,  30.1f, 0.0f, 0.0f, 1.0f,
        0.35f, -0.15f, 30.1f, 0.0f, 0.0f, 1.0f,
        0.25f, -0.2f,  30.1f, 0.0f, 0.0f, 1.0f,
    
        //////////////////////////////////////////////////////////////////////////
        //后视图
        // 左翼缘
        -1.0f, 0.3f, -30.1f, 0.0f, 0.0f, -1.0f,
        -1.0f, 0.2f, -30.1f, 0.0f, 0.0f, -1.0f,
        -0.5f, 0.3f, -30.1f, 0.0f, 0.0f, -1.0f,
    
        -1.0f, 0.2f, -30.1f, 0.0f, 0.0f, -1.0f,
        -0.5f, 0.1f, -30.1f,    0.0f, 0.0f, -1.0f,
        -0.5f, 0.3f, -30.1f,    0.0f, 0.0f, -1.0f,
    
        // 左矩形
        -0.5f, 0.3f,   -30.1f, 0.0f, 0.0f, -1.0f,
        -0.5f, -0.3f,  -30.1f, 0.0f, 0.0f, -1.0f,
        -0.35f, -0.3f, -30.1f, 0.0f, 0.0f, -1.0f,
    
        -0.5f, 0.3f,   -30.1f,  0.0f, 0.0f, -1.0f,
        -0.35f, -0.3f, -30.1f,  0.0f, 0.0f, -1.0f,
        -0.35f, 0.3f,  -30.1f,  0.0f, 0.0f, -1.0f,
    
        // 上矩形
        -0.35f, 0.3f, -30.1f,   0.0f, 0.0f, -1.0f,
        -0.35f, 0.2f, -30.1f,   0.0f, 0.0f, -1.0f,
        -0.0f, 0.3f,  -30.1f,   0.0f, 0.0f, -1.0f,
    
        -0.35f, 0.2f, -30.1f,   0.0f, 0.0f, -1.0f,
        -0.0f, 0.3f,  -30.1f,   0.0f, 0.0f, -1.0f,
        -0.0f, 0.2f,  -30.1f,   0.0f, 0.0f, -1.0f,
    
        // 下矩形
        -0.35f, -0.3f, -30.1f,  0.0f, 0.0f, -1.0f,
        -0.35f, -0.2f, -30.1f,  0.0f, 0.0f, -1.0f,
        -0.0f, -0.3f,  -30.1f,  0.0f, 0.0f, -1.0f,
    
        -0.35f, -0.2f, -30.1f,  0.0f, 0.0f, -1.0f,
        -0.0f, -0.3f,  -30.1f,  0.0f, 0.0f, -1.0f,
        -0.0f, -0.2f,  -30.1f,  0.0f, 0.0f, -1.0f,
    
        // 左上倒角
        -0.35f, 0.2f,  -30.1f,  0.0f, 0.0f, -1.0f,
        -0.35f, 0.15f, -30.1f,  0.0f, 0.0f, -1.0f,
        -0.25f, 0.2f,  -30.1f,  0.0f, 0.0f, -1.0f,
    
        // 左下倒角
        -0.35f, -0.2f,  -30.1f, 0.0f, 0.0f, -1.0f,
        -0.35f, -0.15f, -30.1f, 0.0f, 0.0f, -1.0f,
        -0.25f, -0.2f,  -30.1f, 0.0f, 0.0f, -1.0f,
    
        //对称 右边
        //右翼缘
        1.0f, 0.3f, -30.1f,    0.0f, 0.0f, -1.0f,
        1.0f, 0.2f, -30.1f,       0.0f, 0.0f, -1.0f,
        0.5f, 0.3f, -30.1f,       0.0f, 0.0f, -1.0f,
    
        1.0f, 0.2f, -30.1f,    0.0f, 0.0f, -1.0f,
        0.5f, 0.1f, -30.1f,   0.0f, 0.0f, -1.0f,
        0.5f, 0.3f, -30.1f,   0.0f, 0.0f, -1.0f,
    
        // 右矩形
        0.5f, 0.3f,   -30.1f,  0.0f, 0.0f, -1.0f,
        0.5f, -0.3f,  -30.1f,  0.0f, 0.0f, -1.0f,
        0.35f, -0.3f, -30.1f,  0.0f, 0.0f, -1.0f,
    
        0.5f, 0.3f,   -30.1f,  0.0f, 0.0f, -1.0f,
        0.35f, -0.3f, -30.1f,  0.0f, 0.0f, -1.0f,
        0.35f, 0.3f,  -30.1f,  0.0f, 0.0f, -1.0f,
    
        // 上矩形
        0.35f, 0.3f, -30.1f,   0.0f, 0.0f, -1.0f,
        0.35f, 0.2f, -30.1f,   0.0f, 0.0f, -1.0f,
        0.0f, 0.3f,  -30.1f,   0.0f, 0.0f, -1.0f,
    
        0.35f, 0.2f, -30.1f,   0.0f, 0.0f, -1.0f,
        0.0f, 0.3f,  -30.1f,   0.0f, 0.0f, -1.0f,
        0.0f, 0.2f,  -30.1f,      0.0f, 0.0f, -1.0f,
    
        // 下矩形
        0.35f, -0.3f, -30.1f,  0.0f, 0.0f, -1.0f,
        0.35f, -0.2f, -30.1f,  0.0f, 0.0f, -1.0f,
        0.0f, -0.3f,  -30.1f,  0.0f, 0.0f, -1.0f,
    
        0.35f, -0.2f, -30.1f,  0.0f, 0.0f, -1.0f,
        0.0f, -0.3f,  -30.1f,  0.0f, 0.0f, -1.0f,
        0.0f, -0.2f,  -30.1f,  0.0f, 0.0f, -1.0f,
    
        // 右上倒角
        0.35f, 0.2f,  -30.1f, 0.0f, 0.0f, -1.0f,
        0.35f, 0.15f, -30.1f, 0.0f, 0.0f, -1.0f,
        0.25f, 0.2f,  -30.1f, 0.0f, 0.0f, -1.0f,
    
        // 右下倒角
        0.35f, -0.2f,  -30.1f,  0.0f, 0.0f, -1.0f,
        0.35f, -0.15f, -30.1f,  0.0f, 0.0f, -1.0f,
        0.25f, -0.2f,  -30.1f,  0.0f, 0.0f, -1.0f,
​
        //////////////////////////////////////////////////////////////////////////
        //左视图
        // 上矩形
        -1.0f, 0.3f, -30.1f,  -1.0f, 0.0f, 0.0f,
        -1.0f, 0.2f, -30.1f,  -1.0f, 0.0f, 0.0f,
        -1.0f, 0.3f,  30.1f,  -1.0f, 0.0f, 0.0f,
​
        -1.0f, 0.2f, -30.1f,  -1.0f, 0.0f, 0.0f,
        -1.0f, 0.3f,  30.1f,  -1.0f, 0.0f, 0.0f,
        -1.0f, 0.2f,  30.1f,     -1.0f, 0.0f, 0.0f,
​
        // 左翼缘斜面 
        -1.0f, 0.2f, -30.1f,  -0.196116135f, -0.980580688f, -0.0f,
        -0.5f, 0.1f, -30.1f,  -0.196116135f, -0.980580688f, -0.0f,
        -1.0f, 0.2f,  30.1f,  -0.196116135f, -0.980580688f, -0.0f,
        
        -0.5f, 0.1f, -30.1f,  -0.196116135f, -0.980580688f, -0.0f,
        -1.0f, 0.2f,  30.1f,  -0.196116135f, -0.980580688f, -0.0f,
        -0.5f, 0.1f,  30.1f,  -0.196116135f, -0.980580688f, -0.0f,
​
        // 下矩形
        -0.5f, 0.1f, -30.1f,  -1.0f, 0.0f, 0.0f,
        -0.5f, -0.3f, -30.1f, -1.0f, 0.0f, 0.0f,
        -0.5f, 0.1f,  30.1f,  -1.0f, 0.0f, 0.0f,
        
        -0.5f, -0.3f, -30.1f, -1.0f, 0.0f, 0.0f,
        -0.5f, 0.1f,  30.1f,  -1.0f, 0.0f, 0.0f,
        -0.5f, -0.3f, 30.1f,  -1.0f, 0.0f, 0.0f,
​
        //////////////////////////////////////////////////////////////////////////
        //右视图
        // 上矩形
        1.0f, 0.3f, -30.1f,  1.0f, 0.0f, 0.0f,
        1.0f, 0.2f, -30.1f,     1.0f, 0.0f, 0.0f,
        1.0f, 0.3f,  30.1f,     1.0f, 0.0f, 0.0f,
​
        1.0f, 0.2f, -30.1f,  1.0f, 0.0f, 0.0f,
        1.0f, 0.3f,  30.1f,  1.0f, 0.0f, 0.0f,
        1.0f, 0.2f,  30.1f,  1.0f, 0.0f, 0.0f,
​
        // 右翼缘斜面
        1.0f, 0.2f, -30.1f, 0.196116135f, -0.980580688f, 0.0f,
        0.5f, 0.1f, -30.1f, 0.196116135f, -0.980580688f, 0.0f,
        1.0f, 0.2f,  30.1f, 0.196116135f, -0.980580688f, 0.0f,
​
        0.5f, 0.1f, -30.1f, 0.196116135f, -0.980580688f, 0.0f,
        1.0f, 0.2f,  30.1f, 0.196116135f, -0.980580688f, 0.0f,
        0.5f, 0.1f,  30.1f, 0.196116135f, -0.980580688f, 0.0f,
​
        // 下矩形
        0.5f, 0.1f, -30.1f,  1.0f, 0.0f, 0.0f,
        0.5f, -0.3f, -30.1f, 1.0f, 0.0f, 0.0f,
        0.5f, 0.1f,  30.1f,     1.0f, 0.0f, 0.0f,
​
        0.5f, -0.3f, -30.1f, 1.0f, 0.0f, 0.0f,
        0.5f, 0.1f,  30.1f,     1.0f, 0.0f, 0.0f,
        0.5f, -0.3f, 30.1f,     1.0f, 0.0f, 0.0f,
​
        //////////////////////////////////////////////////////////////////////////
        //附视图
        -1.0f, 0.3f, -30.1f, 0.0f, 1.0f, 0.0f,
        -1.0f, 0.3f,  30.1f,    0.0f, 1.0f, 0.0f,
        1.0f, 0.3f, -30.1f,     0.0f, 1.0f, 0.0f,
​
        -1.0f, 0.3f,  30.1f, 0.0f, 1.0f, 0.0f,
        1.0f, 0.3f, -30.1f,     0.0f, 1.0f, 0.0f,
        1.0f, 0.3f, 30.1f,  0.0f, 1.0f, 0.0f,
​
        //////////////////////////////////////////////////////////////////////////
        //底视图
        -0.5f, -0.3f, -30.1f, 0.0f, -1.0f, 0.0f,
        -0.5f, -0.3f,  30.1f, 0.0f, -1.0f, 0.0f,
        0.5f, -0.3f, -30.1f,  0.0f, -1.0f, 0.0f,
​
        -0.5f, -0.3f,  30.1f, 0.0f, -1.0f, 0.0f,
        0.5f, -0.3f, -30.1f,  0.0f, -1.0f, 0.0f,
        0.5f, -0.3f, 30.1f,      0.0f, -1.0f, 0.0f,
​
        //////////////////////////////////////////////////////////////////////////
        // 内侧平面
​
        //////////////////////////////////////////////////////////////////////////
        // 内-左半部分
​
        // 左矩形
        -0.35f, 0.15f, 30.1f,    1.0f, 0.0f, 0.0f,
        -0.35f, -0.15f, 30.1f,   1.0f, 0.0f, 0.0f,
        -0.35f, -0.15f, -30.1f,  1.0f, 0.0f, 0.0f,
​
        -0.35f, 0.15f, 30.1f,    1.0f, 0.0f, 0.0f,
        -0.35f, -0.15f, -30.1f,  1.0f, 0.0f, 0.0f,
        -0.35f, 0.15f, -30.1f,   1.0f, 0.0f, 0.0f,
​
        // 上矩形
        -0.25f, 0.2f, 30.1f,    0.0f, -1.0f, 0.0f,
         0.0f, 0.2f,  30.1f,    0.0f, -1.0f, 0.0f,
         0.0f, 0.2f, -30.1f,    0.0f, -1.0f, 0.0f,
​
         -0.25f, 0.2f, 30.1f,    0.0f, -1.0f, 0.0f,
          0.0f, 0.2f, -30.1f,    0.0f, -1.0f, 0.0f,
         -0.25f, 0.2f, -30.1f,   0.0f, -1.0f, 0.0f,
​
         // 下矩形
         -0.25f, -0.2f, 30.1f,    0.0f, 1.0f, 0.0f,
         0.0f,  -0.2f,  30.1f,    0.0f, 1.0f, 0.0f,
         0.0f,  -0.2f, -30.1f,    0.0f, 1.0f, 0.0f,
​
         -0.25f, -0.2f, 30.1f,    0.0f, 1.0f, 0.0f,
          0.0f,  -0.2f, -30.1f,   0.0f, 1.0f, 0.0f,
         -0.25f, -0.2f, -30.1f,   0.0f, 1.0f, 0.0f,
​
         // 左上斜面 
         -0.35f, 0.15f, 30.1f,    0.447213620f, -0.894427240f, 0.0f,
         -0.25f, 0.2f,  30.1f,    0.447213620f, -0.894427240f, 0.0f,
         -0.25f, 0.2f, -30.1f,    0.447213620f, -0.894427240f, 0.0f,
​
         -0.35f, 0.15f, 30.1f,    0.447213620f, -0.894427240f, 0.0f,
         -0.25f, 0.2f, -30.1f,    0.447213620f, -0.894427240f, 0.0f,
         -0.35f, 0.15f, -30.1f,   0.447213620f, -0.894427240f, 0.0f,
​
         // 左下斜面  
         -0.35f, -0.15f, 30.1f,     0.447213620f, 0.894427240f, 0.0f,
         -0.25f, -0.2f,  30.1f,     0.447213620f, 0.894427240f, 0.0f,
         -0.25f, -0.2f, -30.1f,     0.447213620f, 0.894427240f, 0.0f,
​
         -0.35f, -0.15f, 30.1f,    0.447213620f, 0.894427240f, 0.0f,
         -0.25f, -0.2f, -30.1f,    0.447213620f, 0.894427240f, 0.0f,
         -0.35f, -0.15f, -30.1f,   0.447213620f, 0.894427240f, 0.0f,
​
         //////////////////////////////////////////////////////////////////////////
         // 内-右半部分
​
         // 右矩形
         0.35f, 0.15f, 30.1f,    -1.0f, 0.0f, 0.0f,
         0.35f, -0.15f, 30.1f,   -1.0f, 0.0f, 0.0f,
         0.35f, -0.15f, -30.1f,  -1.0f, 0.0f, 0.0f,
​
         0.35f, 0.15f, 30.1f,    -1.0f, 0.0f, 0.0f,
         0.35f, -0.15f, -30.1f,  -1.0f, 0.0f, 0.0f,
         0.35f, 0.15f, -30.1f,   -1.0f, 0.0f, 0.0f,
​
         // 上矩形
         0.25f, 0.2f, 30.1f,    0.0f, -1.0f, 0.0f,
         0.0f, 0.2f,  30.1f,    0.0f, -1.0f, 0.0f,
         0.0f, 0.2f, -30.1f,    0.0f, -1.0f, 0.0f,
​
         0.25f, 0.2f, 30.1f,    0.0f, -1.0f, 0.0f,
         0.0f, 0.2f, -30.1f,    0.0f, -1.0f, 0.0f,
         0.25f, 0.2f, -30.1f,   0.0f, -1.0f, 0.0f,
​
         // 下矩形
         0.25f, -0.2f, 30.1f,    0.0f, 1.0f, 0.0f,
         0.0f,  -0.2f,  30.1f,    0.0f, 1.0f, 0.0f,
         0.0f,  -0.2f, -30.1f,    0.0f, 1.0f, 0.0f,
​
         0.25f, -0.2f, 30.1f,    0.0f, 1.0f, 0.0f,
         0.0f,  -0.2f, -30.1f,   0.0f, 1.0f, 0.0f,
         0.25f, -0.2f, -30.1f,   0.0f, 1.0f, 0.0f,
​
         // 右上斜面 
         0.35f, 0.15f, 30.1f,    -0.447213620f, -0.894427240f, 0.0f,
         0.25f, 0.2f,  30.1f,    -0.447213620f, -0.894427240f, 0.0f,
         0.25f, 0.2f, -30.1f,    -0.447213620f, -0.894427240f, 0.0f,
​
         0.35f, 0.15f, 30.1f,    -0.447213620f, -0.894427240f, 0.0f,
         0.25f, 0.2f, -30.1f,    -0.447213620f, -0.894427240f, 0.0f,
         0.35f, 0.15f, -30.1f,   -0.447213620f, -0.894427240f, 0.0f,
​
         // 右下斜面  
         0.35f, -0.15f, 30.1f,    -0.447213620f, 0.894427240f, 0.0f,
         0.25f, -0.2f,  30.1f,    -0.447213620f, 0.894427240f, 0.0f,
         0.25f, -0.2f, -30.1f,    -0.447213620f, 0.894427240f, 0.0f,
​
         0.35f, -0.15f, 30.1f,   -0.447213620f, 0.894427240f, 0.0f,
         0.25f, -0.2f, -30.1f,   -0.447213620f, 0.894427240f, 0.0f,
         0.35f, -0.15f, -30.1f,  -0.447213620f, 0.894427240f, 0.0f,
        
​
    }; 

1.3箱梁的VAO、VBO

    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
​
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
​
    glBindVertexArray(VAO);
​
    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // normal attribute
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
​
​
    // 单片箱梁的位置
    glm::vec3 beamPosition[] = {
        glm::vec3( 0.0f,  0.0f,  0.0f),
        glm::vec3( 2.0f,  0.0f,  0.0f),
        glm::vec3( 4.0f,  0.0f,  0.0f),
        glm::vec3( 6.0f,  0.0f,  0.0f),
    };
​
    // 单片箱梁的颜色
    glm::vec3 modelColor[] = {
        glm::vec3( 1.0f,  0.75f, 0.51f),
        glm::vec3( 1.0f,  0.75f, 0.51f),
        glm::vec3( 1.0f,  0.75f, 0.51f),
        glm::vec3( 1.0f,  0.75f, 0.51f),
    };

1.4绘制箱梁

        glm::mat4 viewOrigin = camera.GetViewMatrix();
        lightingShader.setMat4("view", viewOrigin);
​
        // 绘制箱梁
        int nPntCount = sizeof(vertices)/sizeof(float) / 2 / 3;
        int nBeamCount = sizeof(beamPosition) / sizeof(glm::vec3);
        // 复制箱梁
        for (int i = 0; i < nBeamCount; ++i)
        {
            glm::mat4 model = glm::mat4(1.0);
​
            //移动
            model = glm::translate(model, beamPosition[i]);
            lightingShader.setMat4("model", model);
​
            //颜色
            lightingShader.setVec3("objectColor", modelColor[i]);
            glBindVertexArray(VAO);
            glDrawArrays(GL_TRIANGLES, 0, nPntCount);
        }   

二、绘制盖梁

2.1盖梁的顶点及其法向量

    float capBeamVertices[] = {
        //////////////////////////////////////////////////////////////////////////
        // 前视图
        // 左梯形
        // positions          // normals 
        -0.5f, -0.3f, 0.31f,  0.0f, 0.0f, 1.0f,
        -0.5f, -0.5f, 0.31f,  0.0f, 0.0f, 1.0f,
        -0.2f, -0.3f, 0.31f,  0.0f, 0.0f, 1.0f,
​
        -0.5f, -0.5f, 0.31f,  0.0f, 0.0f, 1.0f,
        -0.2f, -0.7f, 0.31f,  0.0f, 0.0f, 1.0f,
        -0.2f, -0.3f, 0.31f,  0.0f, 0.0f, 1.0f,
​
        // 矩形
        -0.2f, -0.3f, 0.31f,  0.0f, 0.0f, 1.0f,
        -0.2f, -0.7f, 0.31f,  0.0f, 0.0f, 1.0f,
         6.2f, -0.3f, 0.31f,  0.0f, 0.0f, 1.0f,
​
        -0.2f, -0.7f, 0.31f,  0.0f, 0.0f, 1.0f,
         6.2f, -0.3f, 0.31f,  0.0f, 0.0f, 1.0f,
         6.2f, -0.7f, 0.31f,  0.0f, 0.0f, 1.0f,
​
        //右半部分
        // 右梯形
        // positions          // normals 
        6.5f, -0.3f, 0.31f,  0.0f, 0.0f, 1.0f,
        6.5f, -0.5f, 0.31f,  0.0f, 0.0f, 1.0f,
        6.2f, -0.3f, 0.31f,  0.0f, 0.0f, 1.0f,
​
        6.5f, -0.5f, 0.31f,  0.0f, 0.0f, 1.0f,
        6.2f, -0.3f, 0.31f,  0.0f, 0.0f, 1.0f,
        6.2f, -0.7f, 0.31f,  0.0f, 0.0f, 1.0f,
​
        ////////////////////////////////////////////////////////////////////////////
        // 后视图
        // 左梯形
        // positions          // normals 
        -0.5f, -0.3f, -0.31f,  0.0f, 0.0f, 1.0f,
        -0.5f, -0.5f, -0.31f,  0.0f, 0.0f, 1.0f,
        -0.2f, -0.3f, -0.31f,  0.0f, 0.0f, 1.0f,
​
        -0.5f, -0.5f, -0.31f,  0.0f, 0.0f, 1.0f,
        -0.2f, -0.7f, -0.31f,  0.0f, 0.0f, 1.0f,
        -0.2f, -0.3f, -0.31f,  0.0f, 0.0f, 1.0f,
​
        // 矩形
        -0.2f, -0.3f, -0.31f,  0.0f, 0.0f, 1.0f,
        -0.2f, -0.7f, -0.31f,  0.0f, 0.0f, 1.0f,
         6.2f, -0.3f, -0.31f,  0.0f, 0.0f, 1.0f,
​
        -0.2f, -0.7f, -0.31f,  0.0f, 0.0f, 1.0f,
         6.2f, -0.3f, -0.31f,  0.0f, 0.0f, 1.0f,
         6.2f, -0.7f, -0.31f,  0.0f, 0.0f, 1.0f,
​
        //右半部分
        // 右梯形
        // positions          // normals 
        6.5f, -0.3f, -0.31f,  0.0f, 0.0f, 1.0f,
        6.5f, -0.5f, -0.31f,  0.0f, 0.0f, 1.0f,
        6.2f, -0.3f, -0.31f,  0.0f, 0.0f, 1.0f,
​
        6.5f, -0.5f, -0.31f,  0.0f, 0.0f, 1.0f,
        6.2f, -0.3f, -0.31f,  0.0f, 0.0f, 1.0f,
        6.2f, -0.7f, -0.31f,  0.0f, 0.0f, 1.0f,
​
        //////////////////////////////////////////////////////////////////////////
        //顶视图
        // positions          // normals 
        -0.5f, -0.3f, -0.31f,  0.0f, 1.0f, 0.0f,
        -0.5f, -0.3f,  0.31f,  0.0f, 1.0f, 0.0f,
         6.5f, -0.3f, -0.31f,  0.0f, 1.0f, 0.0f,
​
        -0.5f, -0.3f,  0.31f,  0.0f, 1.0f, 0.0f,
         6.5f, -0.3f, -0.31f,  0.0f, 1.0f, 0.0f,
         6.5f, -0.3f,  0.31f,  0.0f, 1.0f, 0.0f,
​
        //////////////////////////////////////////////////////////////////////////
        // 底视图
        // 矩形
        -0.2f, -0.7f,  -0.31f,  0.0f, -1.0f, 0.0f,
        -0.2f, -0.7f,   0.31f,  0.0f, -1.0f, 0.0f,
         6.2f, -0.7f,  -0.31f,  0.0f, -1.0f, 0.0f,
​
        -0.2f, -0.7f,   0.31f,  0.0f, -1.0f, 0.0f,
         6.2f, -0.7f,  -0.31f,  0.0f, -1.0f, 0.0f,
         6.2f, -0.7f,   0.31f,  0.0f, -1.0f, 0.0f,
​
        //////////////////////////////////////////////////////////////////////////
        // 左视图
        // 上矩形
        -0.5f,  -0.3f,  -0.31f,  -1.0f, 0.0f, 0.0f,
        -0.5f,  -0.5f,  -0.31f,  -1.0f, 0.0f, 0.0f,
        -0.5f,  -0.3f,   0.31f,  -1.0f, 0.0f, 0.0f,
​
        -0.5f,  -0.5f,  -0.31f,  -1.0f, 0.0f, 0.0f,
        -0.5f,  -0.3f,   0.31f,  -1.0f, 0.0f, 0.0f,
        -0.5f,  -0.5f,   0.31f,  -1.0f, 0.0f, 0.0f,
​
        // 下斜面 
        -0.5f,  -0.5f,  -0.31f,  -1.0f, 0.0f, 0.0f,
        -0.2f,  -0.7f,  -0.31f,  -1.0f, 0.0f, 0.0f,
        -0.5f,  -0.5f,   0.31f,  -1.0f, 0.0f, 0.0f,
​
        -0.2f,  -0.7f,  -0.31f,  -1.0f, 0.0f, 0.0f,
        -0.5f,  -0.5f,   0.31f,  -1.0f, 0.0f, 0.0f,
        -0.2f,  -0.7f,   0.31f,  -1.0f, 0.0f, 0.0f,
​
        //////////////////////////////////////////////////////////////////////////
        // 右视图
        // 上矩形
        6.5f,  -0.3f,  -0.31f,  1.0f, 0.0f, 0.0f,
        6.5f,  -0.5f,  -0.31f,  1.0f, 0.0f, 0.0f,
        6.5f,  -0.5f,   0.31f,  1.0f, 0.0f, 0.0f,
​
        6.5f,  -0.3f,  -0.31f,  1.0f, 0.0f, 0.0f,
        6.5f,  -0.5f,   0.31f,  1.0f, 0.0f, 0.0f,
        6.5f,  -0.3f,   0.31f,  1.0f, 0.0f, 0.0f,
​
        // 下斜面
        6.5f,  -0.5f,  -0.31f,  1.0f, 0.0f, 0.0f,
        6.2f,  -0.7f,  -0.31f,  1.0f, 0.0f, 0.0f,
        6.5f,  -0.5f,   0.31f,  1.0f, 0.0f, 0.0f,
​
        6.2f,  -0.7f,  -0.31f,  1.0f, 0.0f, 0.0f,
        6.5f,  -0.5f,   0.31f,  1.0f, 0.0f, 0.0f,
        6.2f,  -0.7f,   0.31f,  1.0f, 0.0f, 0.0f,
​
    };

2.2盖梁的VAO、VBO

    unsigned int capVBO, capVAO;
    glGenVertexArrays(1, &capVAO);
    glGenBuffers(1, &capVBO);
​
    glBindBuffer(GL_ARRAY_BUFFER, capVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(capBeamVertices), capBeamVertices, GL_STATIC_DRAW);
​
    glBindVertexArray(capVAO);
​
    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // normal attribute
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
​
​
    // 单片箱梁的位置
    glm::vec3 capPosition[] = {
        glm::vec3( 0.0f,  0.0f,   capSpace/2.0f),  // 前一
        glm::vec3( 0.0f,  0.0f,  -capSpace/2.0f),  // 后一
​
        glm::vec3( 0.0f,  0.0f,   capSpace/2.0f + capSpace),   // 前二
        glm::vec3( 0.0f,  0.0f,  -(capSpace/2.0f + capSpace)), // 后二
    };
​
    // 单片箱梁的颜色
    glm::vec3 capColor[] = {
        glm::vec3(  1.0f, 0.5f, 0.31f),
        glm::vec3(  1.0f, 0.5f, 0.31f),
        glm::vec3(  1.0f, 0.5f, 0.31f),
        glm::vec3(  1.0f, 0.5f, 0.31f),
    };

2.3绘制盖梁

        int capCount = sizeof(capPosition) / sizeof(glm::vec3);
        int nCapPtCount = sizeof(capBeamVertices)/sizeof(float) / 2 / 3;
        for (int iCap = 0; iCap < capCount; ++iCap)
        {
            glm::mat4 modelCap = glm::mat4(1.0);
            modelCap = glm::translate(modelCap, capPosition[iCap]);
            lightingShader.setMat4("model", modelCap);
​
            lightingShader.setVec3("objectColor", capColor[iCap]);
            glBindVertexArray(capVAO);
            glDrawArrays(GL_TRIANGLES, 0, nCapPtCount);
        }   

三、绘制桥墩

3.1计算圆周上的点和法向量

struct TVertex {
    // position
    glm::vec3 Position;
    // normal
    glm::vec3 Normal;
};
​
std::vector<TVertex> getUnitCircleVertices()
{
    const float PI = 3.1415926f;
    float sectorStep = 2 * PI / sectorCount;
    float sectorAngle = 0.0f;
​
    glm::vec3 position;
    glm::vec3 normal;
    TVertex tVertex;
​
    std::vector<TVertex> unitCircleVertices;
    for (int i = 0; i <= sectorCount; ++i)
    {
        sectorAngle = i * sectorStep;
        position.x = pierRadius * cos(sectorAngle);
        position.y = 0.0f;
        position.z = pierRadius * sin(sectorAngle);
​
        normal.x = cos(sectorAngle);
        normal.y = 0.0f;
        normal.z = sin(sectorAngle);
​
        tVertex.Position = position;
        tVertex.Normal = normal;
​
        unitCircleVertices.push_back(tVertex);
    }
​
    return unitCircleVertices;
}

3.2计算圆柱side和上圆形和下圆形

// generate vertices for a cylinder
void buildCylinderVertices(std::vector<TVertex>& vertices)
{
    std::vector<TVertex> unitVertices = getUnitCircleVertices();
​
    // 获取上、下圆周点数组
    std::vector<TVertex> vctTop;
    std::vector<TVertex> vctBot;
​
    TVertex tVertex;
    for(int i = 0; i < unitVertices.size(); ++i)
    {
        tVertex.Position = unitVertices[i].Position;
        tVertex.Position.y = pierHeight;
        tVertex.Normal = unitVertices[i].Normal;
        vctTop.push_back(tVertex);  
​
        tVertex.Position.y = 0.0f;
        vctBot.push_back(tVertex);     
    }
​
    assert(vctTop.size() >= 2);
    assert(vctBot.size() >= 2);
​
    // put side vertices to arrays
    for(int i = 0; i < vctTop.size() - 1; ++i)
    {
        // 左三角形
        vertices.push_back(vctTop[i]);
        vertices.push_back(vctBot[i]);
        vertices.push_back(vctBot[i+1]);
        
        // 右三角形
        vertices.push_back(vctTop[i]);
        vertices.push_back(vctTop[i+1]);
        vertices.push_back(vctBot[i+1]);
    }
    
    // 顶部圆形
    glm::vec3 position;
    for (int i = 0; i < vctTop.size() - 1; ++i)
    {
        glm::vec3 position(0.0f, pierHeight, 0.0f);
        glm::vec3 normal(0.0f, 1.0f, 0.0f);
        tVertex.Position = position;
        tVertex.Normal = normal;
        vertices.push_back(tVertex);
​
        tVertex.Position = vctTop[i].Position;
        vertices.push_back(tVertex);
​
        tVertex.Position = vctTop[i+1].Position;
        vertices.push_back(tVertex);
    }
​
    // 底部圆形
    for (int i = 0; i < vctBot.size() - 1; ++i)
    {
        glm::vec3 position(0.0f, 0.0f, 0.0f);
        glm::vec3 normal(0.0f, -1.0f, 0.0f);
        tVertex.Position = position;
        tVertex.Normal = normal;
        vertices.push_back(tVertex);
​
        tVertex.Position = vctBot[i].Position;
        vertices.push_back(tVertex);
​
        tVertex.Position = vctBot[i+1].Position;
        vertices.push_back(tVertex);
    }
}

3.3桥墩的VAO、VBO

  // generate vertices for a cylinder
void buildCylinderVertices(std::vector<TVertex>& vertices)
{
    std::vector<TVertex> unitVertices = getUnitCircleVertices();
​
    // 获取上、下圆周点数组
    std::vector<TVertex> vctTop;
    std::vector<TVertex> vctBot;
​
    TVertex tVertex;
    for(int i = 0; i < unitVertices.size(); ++i)
    {
        tVertex.Position = unitVertices[i].Position;
        tVertex.Position.y = pierHeight;
        tVertex.Normal = unitVertices[i].Normal;
        vctTop.push_back(tVertex);  
​
        tVertex.Position.y = 0.0f;
        vctBot.push_back(tVertex);     
    }
​
    assert(vctTop.size() >= 2);
    assert(vctBot.size() >= 2);
​
    // put side vertices to arrays
    for(int i = 0; i < vctTop.size() - 1; ++i)
    {
        // 左三角形
        vertices.push_back(vctTop[i]);
        vertices.push_back(vctBot[i]);
        vertices.push_back(vctBot[i+1]);
        
        // 右三角形
        vertices.push_back(vctTop[i]);
        vertices.push_back(vctTop[i+1]);
        vertices.push_back(vctBot[i+1]);
    }
    
    // 顶部圆形
    glm::vec3 position;
    for (int i = 0; i < vctTop.size() - 1; ++i)
    {
        glm::vec3 position(0.0f, pierHeight, 0.0f);
        glm::vec3 normal(0.0f, 1.0f, 0.0f);
        tVertex.Position = position;
        tVertex.Normal = normal;
        vertices.push_back(tVertex);
​
        tVertex.Position = vctTop[i].Position;
        vertices.push_back(tVertex);
​
        tVertex.Position = vctTop[i+1].Position;
        vertices.push_back(tVertex);
    }
​
    // 底部圆形
    for (int i = 0; i < vctBot.size() - 1; ++i)
    {
        glm::vec3 position(0.0f, 0.0f, 0.0f);
        glm::vec3 normal(0.0f, -1.0f, 0.0f);
        tVertex.Position = position;
        tVertex.Normal = normal;
        vertices.push_back(tVertex);
​
        tVertex.Position = vctBot[i].Position;
        vertices.push_back(tVertex);
​
        tVertex.Position = vctBot[i+1].Position;
        vertices.push_back(tVertex);
    }
}

3.4绘制桥墩

        int pierCount = sizeof(pierPosition) / sizeof(glm::vec3);
        for (int iPier = 0; iPier < pierCount; ++iPier)
        {
            lightingShader.setMat4("view", viewOrigin);
            glm::mat4 modelPier = glm::mat4(1.0f);
            modelPier = glm::translate(modelPier, pierPosition[iPier]);
            lightingShader.setMat4("model", modelPier);
            lightingShader.setVec3("objectColor", pierColor[iPier]);
​
            glBindVertexArray(pierVAO);
            glDrawArrays(GL_TRIANGLES, 0, pierVertices.size());
        }

四、着色器

4.1顶点着色器

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
​
out vec3 FragPos;
out vec3 Normal;
​
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
​
void main()
{
    FragPos = vec3(model * vec4(aPos, 1.0));
    Normal = mat3(transpose(inverse(model))) * aNormal;  
    
    gl_Position = projection * view * vec4(FragPos, 1.0);
}

4.2片段着色器

#version 330 core
out vec4 FragColor;
​
in vec3 Normal;  
in vec3 FragPos;  
  
uniform vec3 lightPos; 
uniform vec3 lightDirection; 
uniform vec3 viewPos; 
uniform vec3 lightColor;
uniform vec3 objectColor;
​
void main()
{
    // ambient
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;
    
    // diffuse 
    vec3 norm = normalize(Normal);
    //vec3 lightDir = normalize(lightPos - FragPos);
    vec3 lightDir = normalize(-lightDirection);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;
    
    // specular
    float specularStrength = 0.5;
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);  
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
    vec3 specular = specularStrength * spec * lightColor;  
        
    vec3 result = (ambient + diffuse + specular) * objectColor;
    FragColor = vec4(result, 1.0);
} 

五、项目源代码

链接:https://pan.baidu.com/s/1EA2wd_Rooj-748uKAUugAw 提取码:3d51

相关文章

  • LearnOpenGL脑图汇总LearnOpenGL脑图汇总
  • OpenGL 几何着色器的应用OpenGL 几何着色器的应用
  • Modern OpenGL绘制圆柱体Modern OpenGL绘制圆柱体
  • OpenGL绘制旋转立方体OpenGL绘制旋转立方体
  • OpenGL模型加载-附源码OpenGL模型加载-附源码
  • OpenGL实现多光源-附项目源码OpenGL实现多光源-附项目源码

OpenGL
OpenGL

Post navigation

PREVIOUS
Modern OpenGL绘制圆柱体
NEXT
Midas W-满堂支架快速建模助手开发

One thought on “OpenGL绘制桥梁模型”

  1. 匿名说道:
    2021年11月27日 10:01

    内容好多,感谢

    回复

发表回复 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

近期文章

  • ANR崩溃日志查看方法
  • 通过数学方法来计算short类型的变量w的低八位x和高八位
  • 3dTiles数据解析
  • Games101和Games202脑图汇总
  • LearnOpenGL脑图汇总
  • IBL计算总结
  • C++实现一个简单的语言解释器
  • OpenGL-法线贴图(Normal Mapping)
  • OpenGL-卡通着色(Cartoon)
  • OpenGL几何着色器实现贝塞尔曲线
  • WinDbg检查内存泄漏
  • OpenGL雾化效果实现-每像素雾化
  • OpenGL实现billboard效果(CPU)
  • 算法:寻找异常数字
  • OpenGL 几何着色器的应用
  • Midas XD-构件详图开发
  • Midas XD-选筋助手开发
  • Civil Designer开发-检测规范自动生成控制截面
  • Civil Designer开发-公路桥梁承载能力检算评定
  • Midas W-满堂支架快速建模助手开发

全站热点

  • C++编写的情人节小程序 (2,083)
  • 提取最小封闭区域 (1,696)
  • Modern OpenGL绘制圆柱体 (1,607)
  • OpenGL开发环境搭建-GLFW与GLAD配置 超详细 (1,465)
  • 截面特性计算程序-附源码 (1,290)
  • OpenGL绘制旋转立方体 (1,110)
  • 判断一个点是否在闭合区域内 (1,032)
  • WordPress分页插件 – WP-PageNavi的使用(替换现有脚本) (948)
  • OpenGL实现billboard效果(CPU) (865)
  • Midas W-满堂支架快速建模助手开发 (837)
  • 从DLL中动态加载一个函数:LoadLibrary和GetProcAddress的使用 (748)
  • Midas XD [错误] 右侧挡土墙的最下端深度必须小于地基的最下端深度 (709)
  • 两跨连续梁影响线绘制-附源码 (686)
  • 土木想往土木软件开发方向发展,应该如何准备 (680)
  • OpenGL几何着色器实现贝塞尔曲线 (664)
  • 通过Spy++抓取窗口以查询对话框id (613)
  • 使用ODA数据库出现 “ODA_ASSUME”: 找不到标识符的错误 (547)
  • #pragma message 编译时提示信息 (527)
  • OpenGL雾化效果实现-每像素雾化 (508)
  • midas XD2020的开发 (476)

分类

  • C# (3)
  • C++ (19)
  • GIS (1)
  • MFC (3)
  • ObjectARX (2)
  • OpenGL (11)
  • Revit开发 (1)
  • 学习笔记 (2)
  • 岩土 (2)
  • 算法 (1)
  • 结构设计 (7)
  • 职场生涯 (1)
  • 计算几何 (3)

归档

  • 2024 年 12 月 (1)
  • 2024 年 10 月 (1)
  • 2024 年 9 月 (1)
  • 2023 年 3 月 (2)
  • 2022 年 10 月 (1)
  • 2022 年 3 月 (1)
  • 2022 年 2 月 (1)
  • 2022 年 1 月 (5)
  • 2021 年 11 月 (7)
  • 2021 年 6 月 (3)
  • 2021 年 5 月 (2)
  • 2021 年 3 月 (2)
  • 2021 年 2 月 (8)
  • 2021 年 1 月 (18)

标签

3dtiles anr Bezier Curves BillBoard C++ CDN CivilDesigner DLL EasyX fog glTF MFC Midas W Midas XD NormalMapping ObjectARX ODA OpenGL OpenXML Open XML PBR revit WinDbg 基坑设计 影响线 截面特性 桥梁 桥梁检测 桥梁设计 算法 计算几何 设计模式

书签

  • 李燕良的CSDN
  • 崔济东的博客
  • C++爱好者博客
  • 陈学伟的博客
  • 贾苏的博客
  • 陈睦锋的博客
  • 孙勇的博客

统计

  • 0
  • 190
  • 98
  • 388
  • 145
  • 268,893
  • 77,785

实时访问地域

© 2025   liyanliang.net Copyright. All Rights Reserved.