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绘制桥梁模型”
内容好多,感谢