6 #include "../app/Assets.hpp"
7 #include "../graphics/Viewport.hpp"
25 void Body::SetParent(Body &p) {
30 parent->AddChild(*this);
33 void Body::UnsetParent() {
34 if (!HasParent()) return;
35 parent->RemoveChild(*this);
39 void Body::AddChild(Body &c) {
40 children.push_back(&c);
43 void Body::RemoveChild(Body &c) {
44 auto entry = std::find(children.begin(), children.end(), &c);
45 if (entry != children.end()) {
46 children.erase(entry);
51 Planet::Planet(int sidelength)
53 , sidelength(sidelength)
54 , tiles(new Tile[TilesTotal()])
61 void Planet::BuildVAOs() {
64 vao.EnableAttribute(0);
65 vao.EnableAttribute(1);
66 vao.AttributePointer<glm::vec3>(0, false, offsetof(Attributes, position));
67 vao.AttributePointer<glm::vec3>(1, false, offsetof(Attributes, tex_coord));
68 vao.ReserveAttributes(TilesTotal() * 4, GL_STATIC_DRAW);
70 auto attrib = vao.MapAttributes(GL_WRITE_ONLY);
71 float offset = sidelength * 0.5f;
73 for (int index = 0, surface = 0; surface < 6; ++surface) {
74 for (int y = 0; y < sidelength; ++y) {
75 for (int x = 0; x < sidelength; ++x, ++index) {
76 float tex = TileAt(surface, x, y).type;
77 attrib[4 * index + 0].position[(surface + 0) % 3] = x + 0 - offset;
78 attrib[4 * index + 0].position[(surface + 1) % 3] = y + 0 - offset;
79 attrib[4 * index + 0].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
80 attrib[4 * index + 0].tex_coord[0] = 0.0f;
81 attrib[4 * index + 0].tex_coord[1] = 0.0f;
82 attrib[4 * index + 0].tex_coord[2] = tex;
84 attrib[4 * index + 1].position[(surface + 0) % 3] = x + 0 - offset;
85 attrib[4 * index + 1].position[(surface + 1) % 3] = y + 1 - offset;
86 attrib[4 * index + 1].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
87 attrib[4 * index + 1].tex_coord[0] = 0.0f;
88 attrib[4 * index + 1].tex_coord[1] = 1.0f;
89 attrib[4 * index + 1].tex_coord[2] = tex;
91 attrib[4 * index + 2].position[(surface + 0) % 3] = x + 1 - offset;
92 attrib[4 * index + 2].position[(surface + 1) % 3] = y + 0 - offset;
93 attrib[4 * index + 2].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
94 attrib[4 * index + 2].tex_coord[0] = 1.0f;
95 attrib[4 * index + 2].tex_coord[1] = 0.0f;
96 attrib[4 * index + 2].tex_coord[2] = tex;
98 attrib[4 * index + 3].position[(surface + 0) % 3] = x + 1 - offset;
99 attrib[4 * index + 3].position[(surface + 1) % 3] = y + 1 - offset;
100 attrib[4 * index + 3].position[(surface + 2) % 3] = surface < 3 ? offset : -offset;
101 attrib[4 * index + 3].tex_coord[0] = 1.0f;
102 attrib[4 * index + 3].tex_coord[1] = 1.0f;
103 attrib[4 * index + 3].tex_coord[2] = tex;
109 vao.ReserveElements(TilesTotal() * 6, GL_STATIC_DRAW);
111 auto element = vao.MapElements(GL_WRITE_ONLY);
112 for (int index = 0, surface = 0; surface < 6; ++surface) {
113 for (int y = 0; y < sidelength; ++y) {
114 for (int x = 0; x < sidelength; ++x, ++index) {
115 element[6 * index + 0] = 4 * index + 0;
116 element[6 * index + 1] = 4 * index + 1;
117 element[6 * index + 2] = 4 * index + 2;
118 element[6 * index + 3] = 4 * index + 2;
119 element[6 * index + 4] = 4 * index + 1;
120 element[6 * index + 5] = 4 * index + 3;
128 void Planet::Draw(app::Assets &assets, graphics::Viewport &viewport) {
130 // TODO: premultiply normal with model matrix (i.e. just take it from M)
131 assets.shaders.planet_surface.SetNormal(glm::vec3(0.0f, 0.0f, 1.0f));
132 vao.DrawTriangles(TilesTotal() * 4, TilesTotal() * 4 * 0);
133 assets.shaders.planet_surface.SetNormal(glm::vec3(1.0f, 0.0f, 0.0f));
134 vao.DrawTriangles(TilesTotal() * 4, TilesTotal() * 4 * 1);
135 assets.shaders.planet_surface.SetNormal(glm::vec3(0.0f, 1.0f, 0.0f));
136 vao.DrawTriangles(TilesTotal() * 4, TilesTotal() * 4 * 2);
137 assets.shaders.planet_surface.SetNormal(glm::vec3(0.0f, 0.0f, -1.0f));
138 vao.DrawTriangles(TilesTotal() * 4, TilesTotal() * 4 * 3);
139 assets.shaders.planet_surface.SetNormal(glm::vec3(-1.0f, 0.0f, 0.0f));
140 vao.DrawTriangles(TilesTotal() * 4, TilesTotal() * 4 * 4);
141 assets.shaders.planet_surface.SetNormal(glm::vec3(0.0f, -1.0f, 0.0f));
142 vao.DrawTriangles(TilesTotal() * 4, TilesTotal() * 4 * 5);
146 void GenerateTest(Planet &p) {
147 for (int surface = 0; surface <= 5; ++surface) {
148 for (int y = 0; y < p.SideLength(); ++y) {
149 for (int x = 0; x < p.SideLength(); ++x) {
150 p.TileAt(surface, x, y).type = (x == p.SideLength()/2) + (y == p.SideLength()/2);