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

  std::vector<TVertex> pierVertices;
  buildCylinderVertices(pierVertices);
  
  unsigned int pierVBO, pierVAO;
  glGenVertexArrays(1, &pierVAO);
  glGenBuffers(1, &pierVBO);

  glBindVertexArray(pierVAO);
  glBindBuffer(GL_ARRAY_BUFFER, pierVBO);

  glBufferData(GL_ARRAY_BUFFER, pierVertices.size() * sizeof(TVertex), &pierVertices[0], GL_STATIC_DRAW);
  
  // position attribute
  glEnableVertexAttribArray(0);
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TVertex), (void*)0);
  // normal attribute
  glEnableVertexAttribArray(1);
  glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(TVertex), (void*)offsetof(TVertex, Normal));

  glBindVertexArray(0);

  // 单个桥墩的位置
  float pierPosY = -(pierHeight + 0.7f);
  float pierPosLx = -0.2f + pierRadius + 1.0f;
  float pierPosRx = 6.2f - pierRadius - 1.0f;
  glm::vec3 pierPosition[] = {
	  // 前一
	  glm::vec3( pierPosLx,  pierPosY,   capSpace / 2.0f),
	  glm::vec3( pierPosRx,  pierPosY,   capSpace / 2.0f),

	  // 后一
	  glm::vec3( pierPosLx,  pierPosY,  -capSpace / 2.0f),
	  glm::vec3( pierPosRx,  pierPosY,  -capSpace / 2.0f),

	  // 前二
	  glm::vec3( pierPosLx,  pierPosY,   capSpace / 2.0f + capSpace),
	  glm::vec3( pierPosRx,  pierPosY,   capSpace / 2.0f + capSpace),

	  // 后二
	  glm::vec3( pierPosLx,  pierPosY,  -(capSpace / 2.0f + capSpace)),
	  glm::vec3( pierPosRx,  pierPosY,  -(capSpace / 2.0f + capSpace)),
  };

  // 单个桥墩的颜色
  glm::vec3 pierColor[] = {
	  glm::vec3(  0.5f, 0.7f, 0.7f),
	  glm::vec3(  0.5f, 0.7f, 0.7f),

	  glm::vec3(  0.5f, 0.7f, 0.7f),
	  glm::vec3(  0.5f, 0.7f, 0.7f),

	  glm::vec3(  0.5f, 0.7f, 0.7f),
	  glm::vec3(  0.5f, 0.7f, 0.7f),

	  glm::vec3(  0.5f, 0.7f, 0.7f),
	  glm::vec3(  0.5f, 0.7f, 0.7f),
  };

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

原文地址:
http://liyanliang.net/index.php/2021/06/30/opengldarwcivilmodel/

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值