diff --git a/src/planet/Planet.cpp b/src/planet/Planet.cpp index ba3ee1c..11dae2b 100644 --- a/src/planet/Planet.cpp +++ b/src/planet/Planet.cpp @@ -2,7 +2,8 @@ #include "planet/PlanetFace.h" Planet::Planet(glm::vec3 position, float radius, PlanetNoiseParams &noiseParams) : - m_position(position), m_radius(radius), m_noise(noiseParams.frequency, noiseParams.amplitude, noiseParams.lacunarity, noiseParams.persistence) + m_position(position), m_radius(radius), m_noise(noiseParams.frequency, noiseParams.amplitude, noiseParams.lacunarity, noiseParams.persistence), + m_ibuffers(new PlanetIndexBuffer(15)) { for (int i = 0; i < 6; i++) { @@ -16,6 +17,7 @@ Planet::~Planet() { delete m_faces[i]; } + delete m_ibuffers; } void Planet::draw(Camera* camera, Shader* shader) diff --git a/src/planet/Planet.h b/src/planet/Planet.h index f6e2349..468c2c3 100644 --- a/src/planet/Planet.h +++ b/src/planet/Planet.h @@ -6,6 +6,8 @@ #include "Shader.h" #include "Camera.h" +#include "planet/PlanetIndexBuffer.h" + struct PlanetNoiseParams { float frequency; float amplitude; @@ -14,6 +16,7 @@ struct PlanetNoiseParams { }; class PlanetFace; +class PlanetFaceNode; class Planet { public: @@ -29,10 +32,13 @@ class Planet void tick(Camera* camera, GLfloat dtime); void draw(Camera* camera, Shader* shader); - SimplexNoise& getNoise() { return m_noise; } + inline SimplexNoise& getNoise() { return m_noise; } + inline PlanetIndexBuffer* getBuffers() { return m_ibuffers; } + inline PlanetFace* getFace(const unsigned int face) { return m_faces[face]; } glm::mat4 getTransformation(); private: + PlanetIndexBuffer* m_ibuffers; SimplexNoise m_noise; glm::vec3 m_position; float m_radius; diff --git a/src/planet/PlanetFace.cpp b/src/planet/PlanetFace.cpp index 06304f8..1324d5f 100644 --- a/src/planet/PlanetFace.cpp +++ b/src/planet/PlanetFace.cpp @@ -1,4 +1,5 @@ #include "planet/PlanetFace.h" +#include // Correlates directly to Face enum const glm::vec3 FACE_NORMALS[6] = { @@ -10,8 +11,8 @@ const glm::vec3 FACE_NORMALS[6] = { glm::vec3(0.0f, 0.0f, 1.0f) }; -PlanetFaceNode::PlanetFaceNode(Planet* planet, PlanetFace* face, glm::vec3 position, const unsigned int level) : - m_planet(planet), m_planetFace(face), m_pos(position), m_level(level), m_generated(false), m_dirty(true), m_leaf(true) +PlanetFaceNode::PlanetFaceNode(Planet* planet, PlanetFace* face, glm::vec3 position, const unsigned int index, const unsigned int level) : + m_planet(planet), m_planetFace(face), m_pos(position), m_index(index), m_level(level), m_generated(false), m_dirty(true), m_leaf(true) { glm::vec3 normal = face->getNormal(); m_left = glm::vec3(normal.y, normal.z, normal.x); @@ -23,6 +24,8 @@ PlanetFaceNode::PlanetFaceNode(Planet* planet, PlanetFace* face, glm::vec3 posit m_pos = m_pos - (m_left * radius); m_pos = m_pos - (m_forward * radius); } + + generate(); } PlanetFaceNode::~PlanetFaceNode() @@ -35,36 +38,19 @@ PlanetFaceNode::~PlanetFaceNode() } return; } - - glDeleteBuffers(1, &m_vao); - glDeleteBuffers(1, &m_vbo); - glDeleteBuffers(1, &m_ebo); } -void PlanetFaceNode::tick(Camera* camera, GLfloat dtime, bool& tickUpdatedLOD, bool& tickGeneratedFace) +void PlanetFaceNode::tick(Camera* camera, GLfloat dtime) { - if (tickUpdatedLOD == true || tickGeneratedFace == true) - return; - // TODO: based on planet transform float camToOrigin = glm::distance(camera->getPosition(), (m_planet->getPosition() + m_center)); float divisionLevel = (float)pow(2, m_level); float splitDistance = m_planet->getRadius() / divisionLevel; - - if (camToOrigin < splitDistance * 1.5 && m_leaf) - tickUpdatedLOD = this->subdivide(); - else if (camToOrigin > splitDistance * 2 && !m_leaf) - tickUpdatedLOD = this->merge(); - - // TODO: fix weird vanishing meshes - - if (tickUpdatedLOD) + if (camToOrigin < splitDistance * 1.5 && m_leaf) { + this->subdivide(); return; - - if (m_leaf && m_generated == false) - { - tickGeneratedFace = true; - generate(); + } else if (camToOrigin > splitDistance * 2.0 && !m_leaf) { + this->merge(); return; } @@ -72,13 +58,17 @@ void PlanetFaceNode::tick(Camera* camera, GLfloat dtime, bool& tickUpdatedLOD, b { for (int i = 0; i < 4; i++) { - m_children[i]->tick(camera, dtime, tickUpdatedLOD, tickGeneratedFace); - if (tickGeneratedFace || tickUpdatedLOD) - break; + m_children[i]->tick(camera, dtime); } } } +void PlanetFaceNode::setIndexBuffer(PlanetBufferIndex buf) { + PIB* indx = m_planet->getBuffers()->getBuffer(buf); + m_ebo = indx->ebo; + m_indices = indx->indices.size(); +} + void PlanetFaceNode::draw(Camera* camera, Shader* shader) { // TODO: occlusion culling @@ -109,7 +99,6 @@ void PlanetFaceNode::generate() return; std::vector vertices; - std::vector indices; float divisionLevel = (float)pow(2.0, m_level); float radius = m_planet->getRadius(); @@ -140,135 +129,16 @@ void PlanetFaceNode::generate() } } - bool fanTop = true; - bool fanLeft = true; - bool fanRight = true; - bool fanBottom = true; - - // Create indices for mesh - for (int gz = 0; gz < RESOLUTION - 1; gz++) - { - bool slantLeft = gz % 2 == 0; - for (int gx = 0; gx < RESOLUTION - 1; gx++) - { - int topLeft = (gz * RESOLUTION) + gx; - int topRight = topLeft + 1; - int bottomLeft = ((gz + 1) * RESOLUTION) + gx; - int bottomRight = bottomLeft + 1; - - bool uTri1 = true; - bool uTri2 = true; - int tri1[3]; - int tri2[3]; - - if (slantLeft) - { - tri1[0] = topLeft; - tri1[1] = bottomLeft; - tri1[2] = bottomRight; - tri2[0] = topLeft; - tri2[1] = bottomRight; - tri2[2] = topRight; - } - else - { - tri1[0] = topLeft; - tri1[1] = bottomLeft; - tri1[2] = topRight; - tri2[0] = bottomLeft; - tri2[1] = bottomRight; - tri2[2] = topRight; - } - - if (fanTop && gz == 0) - { - if (gx % 2 == 0) - { - tri2[0] = topLeft; - tri2[1] = bottomRight; - tri2[2] = topRight + 1; - } - else - { - uTri1 = false; - } - } - - if (fanRight && gx == RESOLUTION - 2) - { - if (gz % 2 == 0) - { - tri2[0] = topRight; - tri2[1] = bottomLeft; - tri2[2] = bottomRight + RESOLUTION; - } - else - { - uTri2 = false; - } - } - - if (fanBottom && gz == RESOLUTION - 2) - { - if (gx % 2 == 0) - { - tri2[0] = bottomLeft; - tri2[1] = bottomRight + 1; - tri2[2] = topRight; - } - else - { - uTri1 = false; - } - } - - if (fanLeft && gx == 0) - { - if (gz % 2 == 0) - { - tri1[0] = topLeft; - tri1[1] = bottomLeft + RESOLUTION; - tri1[2] = bottomRight; - } - else - { - uTri1 = false; - } - } - - if (uTri1) - { - indices.push_back(tri1[0]); - indices.push_back(tri1[1]); - indices.push_back(tri1[2]); - } - - if (uTri2) - { - indices.push_back(tri2[0]); - indices.push_back(tri2[1]); - indices.push_back(tri2[2]); - } - - slantLeft = !slantLeft; - } - } - - m_indices = indices.size(); - glGenVertexArrays(1, &m_vao); glBindVertexArray(m_vao); glGenBuffers(1, &m_vbo); - glGenBuffers(1, &m_ebo); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * m_indices, &(indices[0]), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertices.size(), &(vertices[0]), GL_STATIC_DRAW); m_generated = true; + setIndexBuffer(PlanetBufferIndex::Base); } bool PlanetFaceNode::subdivide() @@ -282,12 +152,15 @@ bool PlanetFaceNode::subdivide() glm::vec3 stepLeft = m_left * (radius / (float)pow(2, lv)); glm::vec3 stepForward = m_forward * (radius / (float)pow(2, lv)); + m_children[TOP_LEFT] = new PlanetFaceNode(m_planet, m_planetFace, m_pos, TOP_LEFT, lv); + m_children[TOP_RIGHT] = new PlanetFaceNode(m_planet, m_planetFace, m_pos + stepForward, TOP_RIGHT, lv); + m_children[BOTTOM_RIGHT] = new PlanetFaceNode(m_planet, m_planetFace, (m_pos + stepLeft) + stepForward, BOTTOM_RIGHT, lv); + m_children[BOTTOM_LEFT] = new PlanetFaceNode(m_planet, m_planetFace, (m_pos + stepLeft), BOTTOM_LEFT, lv); + m_leaf = false; - m_children[0] = new PlanetFaceNode(m_planet, m_planetFace, m_pos + stepForward, lv); - m_children[1] = new PlanetFaceNode(m_planet, m_planetFace, (m_pos + stepLeft) + stepForward, lv); - m_children[2] = new PlanetFaceNode(m_planet, m_planetFace, m_pos, lv); - m_children[3] = new PlanetFaceNode(m_planet, m_planetFace, (m_pos + stepLeft), lv); + for (int i = 0; i < 4; i++) + m_children[i]->m_parent = this; this->dispose(); @@ -303,22 +176,19 @@ bool PlanetFaceNode::merge() // Merge and dispose the children for (int i = 0; i < 4; i++) { - m_children[i]->merge(); m_children[i]->dispose(); delete m_children[i]; } // We're a leaf now m_leaf = true; + generate(); return true; } void PlanetFaceNode::dispose() { m_generated = false; - glDeleteBuffers(1, &m_vao); - glDeleteBuffers(1, &m_vbo); - glDeleteBuffers(1, &m_ebo); } bool PlanetFaceNode::isLeaf() @@ -326,27 +196,141 @@ bool PlanetFaceNode::isLeaf() return m_leaf; } +void PlanetFaceNode::getNeighbors() { + if (m_level == 0) + { + // The m_neighbors of root nodes never change + if (m_neighborTop != nullptr) return; + std::cout << m_planet->getFace(FACE_TOP)->getLODRoot() << std::endl; + switch (m_index) + { + // Front face + case FACE_FRONT: + m_neighborTop = m_planet->getFace(FACE_TOP)->getLODRoot(); + m_neighborLeft = m_planet->getFace(FACE_LEFT)->getLODRoot(); + m_neighborRight = m_planet->getFace(FACE_RIGHT)->getLODRoot(); + m_neighborBottom = m_planet->getFace(FACE_BOTTOM)->getLODRoot(); + break; + // Back face + case FACE_BACK: + m_neighborTop = m_planet->getFace(FACE_TOP)->getLODRoot(); + m_neighborLeft = m_planet->getFace(FACE_RIGHT)->getLODRoot(); + m_neighborRight = m_planet->getFace(FACE_LEFT)->getLODRoot(); + m_neighborBottom = m_planet->getFace(FACE_BOTTOM)->getLODRoot(); + break; + // Left face + case FACE_LEFT: + m_neighborTop = m_planet->getFace(FACE_TOP)->getLODRoot(); + m_neighborLeft = m_planet->getFace(FACE_BACK)->getLODRoot(); + m_neighborRight = m_planet->getFace(FACE_FRONT)->getLODRoot(); + m_neighborBottom = m_planet->getFace(FACE_BOTTOM)->getLODRoot(); + break; + // Right face + case FACE_RIGHT: + m_neighborTop = m_planet->getFace(FACE_TOP)->getLODRoot(); + m_neighborLeft = m_planet->getFace(FACE_FRONT)->getLODRoot(); + m_neighborRight = m_planet->getFace(FACE_BACK)->getLODRoot(); + m_neighborBottom = m_planet->getFace(FACE_BOTTOM)->getLODRoot(); + break; + // Top face + case FACE_TOP: + m_neighborTop = m_planet->getFace(FACE_BACK)->getLODRoot(); + m_neighborLeft = m_planet->getFace(FACE_LEFT)->getLODRoot(); + m_neighborRight = m_planet->getFace(FACE_RIGHT)->getLODRoot(); + m_neighborBottom = m_planet->getFace(FACE_FRONT)->getLODRoot(); + break; + // Bottom face + case FACE_BOTTOM: + m_neighborTop = m_planet->getFace(FACE_FRONT)->getLODRoot(); + m_neighborLeft = m_planet->getFace(FACE_LEFT)->getLODRoot(); + m_neighborRight = m_planet->getFace(FACE_RIGHT)->getLODRoot(); + m_neighborBottom = m_planet->getFace(FACE_BACK)->getLODRoot(); + break; + } + return; + } + + if (m_parent == nullptr) return; + + switch (m_index) + { + // Top left corner + case TOP_LEFT: + if (m_parent->m_neighborTop != nullptr) + m_neighborTop = m_parent->m_neighborTop->m_children[BOTTOM_LEFT]; + + if (m_parent->m_children[TOP_RIGHT] != nullptr) + m_neighborRight = m_parent->m_children[TOP_RIGHT]; + + if (m_parent->m_children[BOTTOM_LEFT] != nullptr) + m_neighborBottom = m_parent->m_children[BOTTOM_LEFT]; + + if (m_parent->m_neighborLeft != nullptr) + m_neighborLeft = m_parent->m_neighborLeft->m_children[TOP_RIGHT]; + break; + // Top right corner + case TOP_RIGHT: + if (m_parent->m_neighborTop != nullptr) + m_neighborTop = m_parent->m_neighborTop->m_children[BOTTOM_RIGHT]; + + if (m_parent->m_neighborRight != nullptr) + m_neighborRight = m_parent->m_neighborRight->m_children[TOP_LEFT]; + + if (m_parent->m_children[BOTTOM_RIGHT] != nullptr) + m_neighborBottom = m_parent->m_children[BOTTOM_RIGHT]; + + if (m_parent->m_children[TOP_LEFT] != nullptr) + m_neighborLeft = m_parent->m_children[TOP_LEFT]; + break; + // Bottom right corner + case BOTTOM_RIGHT: + if (m_parent->m_children[TOP_RIGHT] != nullptr) + m_neighborTop = m_parent->m_children[TOP_RIGHT]; + + if (m_parent->m_neighborRight != nullptr) + m_neighborRight = m_parent->m_neighborRight->m_children[BOTTOM_LEFT]; + + if (m_parent->m_neighborBottom != nullptr) + m_neighborBottom = m_parent->m_neighborBottom->m_children[TOP_RIGHT]; + + if (m_parent->m_children[BOTTOM_LEFT] != nullptr) + m_neighborLeft = m_parent->m_children[BOTTOM_LEFT]; + break; + // Bottom left corner + case BOTTOM_LEFT: + if (m_parent->m_children[TOP_RIGHT] != nullptr) + m_neighborTop = m_parent->m_children[TOP_RIGHT]; + + if (m_parent->m_children[BOTTOM_RIGHT] != nullptr) + m_neighborRight = m_parent->m_children[BOTTOM_RIGHT]; + + if (m_parent->m_neighborBottom != nullptr) + m_neighborBottom = m_parent->m_neighborBottom->m_children[TOP_RIGHT]; + + if (m_parent->m_neighborLeft != nullptr) + m_neighborLeft = m_parent->m_neighborLeft->m_children[BOTTOM_RIGHT]; + break; + } +} + PlanetFace::PlanetFace(Planet* planet, const unsigned int face) : m_planet(planet), m_face(face) { m_normal = FACE_NORMALS[m_face]; - m_planetFace = new PlanetFaceNode(planet, this, m_normal * (m_planet->getRadius() / 2.0f), 0); + m_lod = new PlanetFaceNode(planet, this, m_normal * (m_planet->getRadius() / 2.0f), face, 0); } PlanetFace::~PlanetFace() { - delete m_planetFace; + delete m_lod; } void PlanetFace::draw(Camera* camera, Shader* shader) { - m_planetFace->draw(camera, shader); + m_lod->draw(camera, shader); } void PlanetFace::tick(Camera* camera, GLfloat dtime) { - // Do only one operation per tick, TODO: maybe allow more? - bool tickUpdatedLOD = false; - bool tickGeneratedFace = false; - m_planetFace->tick(camera, dtime, tickUpdatedLOD, tickGeneratedFace); + m_lod->tick(camera, dtime); } diff --git a/src/planet/PlanetFace.h b/src/planet/PlanetFace.h index 61858cf..0f18b1c 100644 --- a/src/planet/PlanetFace.h +++ b/src/planet/PlanetFace.h @@ -6,7 +6,7 @@ #include "Shader.h" #include "Camera.h" -#define RESOLUTION 61 +#define RESOLUTION 15 enum Face { @@ -15,6 +15,12 @@ enum Face FACE_FRONT, FACE_BACK }; +enum LODFace +{ + TOP_LEFT, TOP_RIGHT, + BOTTOM_RIGHT, BOTTOM_LEFT +}; + struct Vertex { glm::vec3 position; @@ -28,10 +34,10 @@ class PlanetFace; class PlanetFaceNode { public: - PlanetFaceNode(Planet* planet, PlanetFace* face, glm::vec3 position, const unsigned int level); + PlanetFaceNode(Planet* planet, PlanetFace* face, glm::vec3 position, const unsigned int index, const unsigned int level); ~PlanetFaceNode(); - void tick(Camera* camera, GLfloat dtime, bool& tickUpdatedLOD, bool& tickGeneratedFace); + void tick(Camera* camera, GLfloat dtime); void draw(Camera* camera, Shader* shader); bool isLeaf(); @@ -46,13 +52,23 @@ class PlanetFaceNode bool merge(); void dispose(); + void setIndexBuffer(PlanetBufferIndex buf); + void getNeighbors(); + Planet* m_planet; PlanetFace* m_planetFace; PlanetFaceNode* m_parent; PlanetFaceNode* m_children[4]; + PlanetFaceNode* m_neighborTop; + PlanetFaceNode* m_neighborRight; + PlanetFaceNode* m_neighborLeft; + PlanetFaceNode* m_neighborBottom; + + unsigned int m_index; unsigned int m_level; + bool m_dirty; bool m_generated; bool m_leaf; @@ -78,12 +94,13 @@ class PlanetFace inline Planet* getPlanet() const { return m_planet; } inline const glm::vec3 getNormal() const { return m_normal; } + inline PlanetFaceNode* getLODRoot() { return m_lod; } private: Planet* m_planet; unsigned int m_face; glm::vec3 m_normal; - PlanetFaceNode* m_planetFace; + PlanetFaceNode* m_lod; }; #endif // __PLANETFACE_H__ diff --git a/src/planet/PlanetIndexBuffer.cpp b/src/planet/PlanetIndexBuffer.cpp new file mode 100644 index 0000000..48a031e --- /dev/null +++ b/src/planet/PlanetIndexBuffer.cpp @@ -0,0 +1,145 @@ +#include "PlanetIndexBuffer.h" + +PlanetIndexBuffer::PlanetIndexBuffer(unsigned int resolution) : m_resolution(resolution) { + createBuffer(PlanetBufferIndex::Base); + createBuffer(PlanetBufferIndex::FixR, false, true, false, false); + createBuffer(PlanetBufferIndex::FixL, false, false, true, false); + createBuffer(PlanetBufferIndex::FixB, false, false, false, true); + createBuffer(PlanetBufferIndex::FixT, true, false, false, false); + createBuffer(PlanetBufferIndex::FixTR, true, true, false, false); + createBuffer(PlanetBufferIndex::FixTL, true, false, true, false); + createBuffer(PlanetBufferIndex::FixBR, false, true, false, true); + createBuffer(PlanetBufferIndex::FixBL, false, false, true, true); +} + +PlanetIndexBuffer::~PlanetIndexBuffer() { + for (int i = 0; i < 9; i++) { + if (m_buffers[i] == nullptr) continue; + glDeleteBuffers(1, &m_buffers[i]->ebo); + m_buffers[i]->indices.clear(); + delete m_buffers[i]; + } +} + +PIB* PlanetIndexBuffer::getBuffer(PlanetBufferIndex idx) { + return m_buffers[idx]; +} + +void PlanetIndexBuffer::createBuffer(PlanetBufferIndex idx, bool fanTop, bool fanRight, bool fanLeft, bool fanBottom) { + PIB* buffer = new PIB(); + // Create indices for mesh + for (unsigned int gz = 0; gz < m_resolution - 1; gz++) + { + bool slantLeft = gz % 2 == 0; + for (unsigned int gx = 0; gx < m_resolution - 1; gx++) + { + unsigned int topLeft = (gz * m_resolution) + gx; + unsigned int topRight = topLeft + 1; + unsigned int bottomLeft = ((gz + 1) * m_resolution) + gx; + unsigned int bottomRight = bottomLeft + 1; + + bool uTri1 = true; + bool uTri2 = true; + unsigned int tri1[3]; + unsigned int tri2[3]; + + if (slantLeft) + { + tri1[0] = topLeft; + tri1[1] = bottomLeft; + tri1[2] = bottomRight; + tri2[0] = topLeft; + tri2[1] = bottomRight; + tri2[2] = topRight; + } + else + { + tri1[0] = topLeft; + tri1[1] = bottomLeft; + tri1[2] = topRight; + tri2[0] = bottomLeft; + tri2[1] = bottomRight; + tri2[2] = topRight; + } + + if (fanTop && gz == 0) + { + if (gx % 2 == 0) + { + tri2[0] = topLeft; + tri2[1] = bottomRight; + tri2[2] = topRight + 1; + } + else + { + uTri1 = false; + } + } + + if (fanRight && gx == m_resolution - 2) + { + if (gz % 2 == 0) + { + tri2[0] = topRight; + tri2[1] = bottomLeft; + tri2[2] = bottomRight + m_resolution; + } + else + { + uTri2 = false; + } + } + + if (fanBottom && gz == m_resolution - 2) + { + if (gx % 2 == 0) + { + tri2[0] = bottomLeft; + tri2[1] = bottomRight + 1; + tri2[2] = topRight; + } + else + { + uTri1 = false; + } + } + + if (fanLeft && gx == 0) + { + if (gz % 2 == 0) + { + tri1[0] = topLeft; + tri1[1] = bottomLeft + m_resolution; + tri1[2] = bottomRight; + } + else + { + uTri1 = false; + } + } + + if (uTri1) + { + buffer->indices.push_back(tri1[0]); + buffer->indices.push_back(tri1[1]); + buffer->indices.push_back(tri1[2]); + } + + if (uTri2) + { + buffer->indices.push_back(tri2[0]); + buffer->indices.push_back(tri2[1]); + buffer->indices.push_back(tri2[2]); + } + + slantLeft = !slantLeft; + } + } + + glGenBuffers(1, &(buffer->ebo)); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * buffer->indices.size(), &(buffer->indices[0]), GL_STATIC_DRAW); + + m_buffers[idx] = buffer; +} diff --git a/src/planet/PlanetIndexBuffer.h b/src/planet/PlanetIndexBuffer.h new file mode 100644 index 0000000..c84170c --- /dev/null +++ b/src/planet/PlanetIndexBuffer.h @@ -0,0 +1,27 @@ +#ifndef __PLANETINDEXBUFFER_H__ +#define __PLANETINDEXBUFFER_H__ + +#include "util/Common.h" + +struct PIB { + GLuint ebo; + std::vector indices; +}; + +enum PlanetBufferIndex { + Base, FixR, FixL, FixB, FixT, FixTR, FixTL, FixBR, FixBL +}; + +class PlanetIndexBuffer { + public: + PlanetIndexBuffer(unsigned int resolution); + ~PlanetIndexBuffer(); + + PIB* getBuffer(PlanetBufferIndex idx); + private: + void createBuffer(PlanetBufferIndex idx, bool fanTop = false, bool fanRight = false, bool fanLeft = false, bool fanBottom = false); + PIB* m_buffers[9]; + unsigned int m_resolution; +}; + +#endif // __PLANETINDEXBUFFER_H__