#ifndef GROUND_H #define GROUND_H #include #include "../gl/GLHelper.h" #include "../gl/GLTriangles.h" #include "../Renderable.h" #include "../../lib/gpc/Polygon.h" class Ground : public Renderable { private: Floorplan::Floor* floor; GLTriangles flooring; GLTriangles ceiling; public: /** ctor */ Ground(Floorplan::Floor* floor) : floor(floor) { ; } void initGL() override { build(); flooring.setDiffuse(":/res/gl/tex/floor4.jpg"); flooring.setNormalMap(":/res/gl/tex/floor4_normal.jpg"); ceiling.setDiffuse(":/res/gl/tex/floor4.jpg"); ceiling.setNormalMap(":/res/gl/tex/floor4_normal.jpg"); flooring.build(); ceiling.build(); loadShader(":/res/gl/vertex1.glsl", ":/res/gl/fragmentTex.glsl"); program.setUniformValue("texDiffuse", 0); program.setUniformValue("texNormalMap", 1); } /** render the floor */ void _render() override { flooring.render(&program); ceiling.render(&program); } private: void build() { std::vector add; std::vector rem; const std::vector& polys = floor->outline; Polygon pol; for (Floorplan::FloorOutlinePolygon* poly : polys) { switch (poly->method) { case Floorplan::OutlineMethod::ADD: pol.add(poly->poly); break; case Floorplan::OutlineMethod::REMOVE: pol.remove(poly->poly); break; default: throw 1; } } std::vector> trias = pol.get(floor->atHeight); // is stored as TRIANGLE_STRIP // => triangle might have more than 3 points for (const std::vector& tria : trias) { const QVector3D normFloor(0, +1, 0); const QVector3D normCeil(0, +1, 0); // why +1??? const QVector3D t(1,0,0); const float s = 0.6; // add vertices for (int i = 2; i < (int) tria.size(); i+=1) { const Point3 p1 = tria[i-2]; const Point3 p2 = tria[i-1]; const Point3 p3 = tria[i-0]; const QVector3D vert1(p1.x, p1.z, p1.y); const QVector3D vert2(p2.x, p2.z, p2.y); const QVector3D vert3(p3.x, p3.z, p3.y); { const VertNormTexTan vnt1(vert1, normFloor, tex(vert1*s), t); const VertNormTexTan vnt2(vert2, normFloor, tex(vert2*s), t); const VertNormTexTan vnt3(vert3, normFloor, tex(vert3*s), t); flooring.addFaceCCW(vnt1, vnt2, vnt3); } { const VertNormTexTan vnt1(vert1, normCeil, tex(vert1*s), t); const VertNormTexTan vnt2(vert2, normCeil, tex(vert2*s), t); const VertNormTexTan vnt3(vert3, normCeil, tex(vert3*s), t); ceiling.addFaceCW(vnt1, vnt2, vnt3); } } } } private: QVector2D tex(const QVector3D vert) { return QVector2D(vert.x(), vert.z()); } }; #endif // GROUND_H