OpenGL绘制桥梁模型

本文主要讲述如何使用现代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





One thought on “OpenGL绘制桥梁模型”
内容好多,感谢