diff --git a/src/Application.cpp b/src/Application.cpp index 099ee13..e05cc6e 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -74,7 +74,7 @@ void Application::initialize() glewInit(); // Create camera - m_camera = new Camera(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), 90.0f, 0.0f); + m_camera = new Camera(glm::vec3(0.0f, 0.0f, -800.0f), glm::vec3(0.0f, 1.0f, 0.0f), 90.0f, 0.0f); // Run the engine run(); @@ -143,6 +143,10 @@ void Application::handleEvents() if(Input::getInstance().isKeyPressed(SDL_BUTTON_LEFT)) std::cout << "mX: " << mousepos.x << " mY: " << mousepos.y << std::endl; + // Toggle wireframe + if(Input::getInstance().isKeyPressed(SDLK_x)) + m_wireframe = !m_wireframe; + // Exit game on Esc if(Input::getInstance().isKeyPressed(SDLK_ESCAPE)) exit(); @@ -152,15 +156,15 @@ void Application::handleEvents() void Application::run() { m_run = true; + m_wireframe = false; m_now = SDL_GetPerformanceCounter(); m_last = 0; // TEST CODE SDL_ShowCursor(SDL_DISABLE); Input::getInstance().setMouseCoords(m_width/2, m_height/2); - glEnable(GL_DEPTH_TEST); - Planet* pl = new Planet(glm::vec3(0.0f,0.0f,0.0f), 128.0f); + Planet* pl = new Planet(glm::vec3(0.0f,0.0f,0.0f), 500.0f); // Create the shader and link them together Shader& chunkShader = Shader::createShader("data/shaders/chunk.vert", "data/shaders/chunk.frag"); chunkShader.linkShaders(); @@ -186,14 +190,19 @@ void Application::run() deltaTime = ((m_now - m_last) / (double)SDL_GetPerformanceFrequency()); // TEST CODE + glEnable(GL_DEPTH_TEST); + //glEnable(GL_CULL_FACE); + //glCullFace(GL_BACK); pl->tick(m_camera, deltaTime); - //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + if (m_wireframe) + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); pl->draw(m_camera, &chunkShader); - //glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + if (m_wireframe) + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); // END TEST CODE diff --git a/src/Application.h b/src/Application.h index 833507e..6e5d6dc 100644 --- a/src/Application.h +++ b/src/Application.h @@ -45,6 +45,7 @@ class Application : public Singleton double deltaTime; bool m_run; + bool m_wireframe; void handleEvents(); void run(); diff --git a/src/planet/Planet.cpp b/src/planet/Planet.cpp index cc06ecd..feb8de4 100644 --- a/src/planet/Planet.cpp +++ b/src/planet/Planet.cpp @@ -32,3 +32,10 @@ void Planet::tick(Camera* camera, GLfloat dtime) m_faces[i]->tick(camera, dtime); } } + +glm::mat4 Planet::getTransformation() +{ + glm::mat4 newMat = glm::mat4(1.0f); + newMat = glm::translate(newMat, m_position); + return newMat; +} diff --git a/src/planet/Planet.h b/src/planet/Planet.h index 29d6ebf..179790a 100644 --- a/src/planet/Planet.h +++ b/src/planet/Planet.h @@ -20,6 +20,8 @@ class Planet void tick(Camera* camera, GLfloat dtime); void draw(Camera* camera, Shader* shader); + + glm::mat4 getTransformation(); private: glm::vec3 m_position; float m_radius; diff --git a/src/planet/PlanetFace.cpp b/src/planet/PlanetFace.cpp index eb9bda8..fff5395 100644 --- a/src/planet/PlanetFace.cpp +++ b/src/planet/PlanetFace.cpp @@ -1,5 +1,6 @@ #include "planet/PlanetFace.h" +// Correlates directly to Face enum const glm::vec3 FACE_NORMALS[6] = { glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), @@ -10,7 +11,7 @@ const glm::vec3 FACE_NORMALS[6] = { }; 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_planet(planet), m_planetFace(face), m_pos(position), 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); @@ -26,9 +27,13 @@ PlanetFaceNode::PlanetFaceNode(Planet* planet, PlanetFace* face, glm::vec3 posit PlanetFaceNode::~PlanetFaceNode() { - for (int i = 0; i < 4; i++) + if (!m_leaf) { - delete m_children[i]; + for (int i = 0; i < 4; i++) + { + delete m_children[i]; + } + return; } glDeleteBuffers(1, &m_vao); @@ -36,13 +41,56 @@ PlanetFaceNode::~PlanetFaceNode() glDeleteBuffers(1, &m_ebo); } -void PlanetFaceNode::tick(Camera* camera, GLfloat dtime) +void PlanetFaceNode::tick(Camera* camera, GLfloat dtime, bool& tickUpdatedLOD, bool& tickGeneratedFace) { + 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 and m_leaf) + tickUpdatedLOD = this->subdivide(); + else if (camToOrigin > splitDistance * 2 and !m_leaf) + tickUpdatedLOD = this->merge(); + + if (tickUpdatedLOD) + return; + + // TODO: fix weird missing meshes + + if (m_leaf && m_generated == false) + { + generate(); + tickGeneratedFace = true; + return; + } + + if (!m_leaf) + { + for (int i = 0; i < 4; i++) + { + m_children[i]->tick(camera, dtime, tickUpdatedLOD, tickGeneratedFace); + if (tickGeneratedFace || tickUpdatedLOD) + break; + } + } } void PlanetFaceNode::draw(Camera* camera, Shader* shader) { + // TODO: occlusion culling + if (!m_leaf) + { + for (int i = 0; i < 4; i++) + { + m_children[i]->draw(camera, shader); + } + return; + } + if (!m_generated) return; @@ -50,7 +98,7 @@ void PlanetFaceNode::draw(Camera* camera, Shader* shader) shader->use(); camera->shaderViewProjection(*shader); - shader->setUniform("modelMatrix", glm::translate(glm::mat4(1.0f), m_planet->getPosition())); + shader->setUniform("modelMatrix", m_planet->getTransformation()); glDrawElements(GL_TRIANGLES, m_indices, GL_UNSIGNED_INT, nullptr); } @@ -85,6 +133,9 @@ void PlanetFaceNode::generate() // Add vertices.push_back({ pos, vertNormal, glm::vec2(j * (1.0 / RESOLUTION), i * (1.0 / RESOLUTION)) }); + + if ((i == RESOLUTION / 2 and j == RESOLUTION / 2)) + m_center = pos; } } @@ -97,12 +148,12 @@ void PlanetFaceNode::generate() int bottomLeft = ((gz + 1) * RESOLUTION) + gx; int bottomRight = bottomLeft + 1; - indices.push_back(topLeft); - indices.push_back(topRight); indices.push_back(bottomLeft); - indices.push_back(bottomLeft); - indices.push_back(topRight); indices.push_back(bottomRight); + indices.push_back(topRight); + indices.push_back(topRight); + indices.push_back(topLeft); + indices.push_back(bottomLeft); } } @@ -121,13 +172,12 @@ void PlanetFaceNode::generate() glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertices.size(), &(vertices[0]), GL_STATIC_DRAW); m_generated = true; - m_leaf = true; } -void PlanetFaceNode::subdivide() +bool PlanetFaceNode::subdivide() { - if (m_level == 4) - return; + if (m_level == 8) + return false; int lv = m_level + 1; float radius = m_planet->getRadius(); @@ -142,13 +192,17 @@ void PlanetFaceNode::subdivide() m_leaf = false; this->dispose(); + + return true; } -void PlanetFaceNode::merge() +bool PlanetFaceNode::merge() { - if (m_level == 0 && m_leaf) - return; + // Leaves don't ever need to be merged + if (m_leaf) + return false; + // Merge and dispose the children for (int i = 0; i < 4; i++) { m_children[i]->merge(); @@ -156,7 +210,9 @@ void PlanetFaceNode::merge() delete m_children[i]; } + // We're a leaf now m_leaf = true; + return true; } void PlanetFaceNode::dispose() @@ -177,7 +233,6 @@ PlanetFace::PlanetFace(Planet* planet, const unsigned int face) : { m_normal = FACE_NORMALS[m_face]; m_planetFace = new PlanetFaceNode(planet, this, m_normal * (m_planet->getRadius() / 2.0f), 0); - m_planetFace->generate(); } PlanetFace::~PlanetFace() @@ -192,5 +247,7 @@ void PlanetFace::draw(Camera* camera, Shader* shader) void PlanetFace::tick(Camera* camera, GLfloat dtime) { - m_planetFace->tick(camera, dtime); + bool tickUpdatedLOD = false; + bool tickGeneratedFace = false; + m_planetFace->tick(camera, dtime, tickUpdatedLOD, tickGeneratedFace); } diff --git a/src/planet/PlanetFace.h b/src/planet/PlanetFace.h index 5d0d936..aa475ce 100644 --- a/src/planet/PlanetFace.h +++ b/src/planet/PlanetFace.h @@ -6,7 +6,7 @@ #include "Shader.h" #include "Camera.h" -#define RESOLUTION 128 +#define RESOLUTION 64 enum Face { @@ -31,13 +31,9 @@ class PlanetFaceNode PlanetFaceNode(Planet* planet, PlanetFace* face, glm::vec3 position, const unsigned int level); ~PlanetFaceNode(); - void tick(Camera* camera, GLfloat dtime); + void tick(Camera* camera, GLfloat dtime, bool& tickUpdatedLOD, bool& tickGeneratedFace); void draw(Camera* camera, Shader* shader); - void generate(); - void subdivide(); - void merge(); - void dispose(); bool isLeaf(); inline Planet* getPlanet() const { return m_planet; } @@ -45,6 +41,11 @@ class PlanetFaceNode inline glm::vec3 getAbsolutePosition() const { return m_planet->getPosition() + m_pos; } private: + void generate(); + bool subdivide(); + bool merge(); + void dispose(); + Planet* m_planet; PlanetFace* m_planetFace; @@ -60,6 +61,7 @@ class PlanetFaceNode int m_indices; glm::vec3 m_pos; + glm::vec3 m_center; glm::vec3 m_left; glm::vec3 m_forward; };