planet face subdivision(not perfect)m wireframe toggle

This commit is contained in:
Evert Prants 2020-03-26 19:42:05 +02:00
parent b9de341ed9
commit c49f2d7ea2
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
6 changed files with 107 additions and 29 deletions

View File

@ -74,7 +74,7 @@ void Application::initialize()
glewInit(); glewInit();
// Create camera // 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 the engine
run(); run();
@ -143,6 +143,10 @@ void Application::handleEvents()
if(Input::getInstance().isKeyPressed(SDL_BUTTON_LEFT)) if(Input::getInstance().isKeyPressed(SDL_BUTTON_LEFT))
std::cout << "mX: " << mousepos.x << " mY: " << mousepos.y << std::endl; 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 // Exit game on Esc
if(Input::getInstance().isKeyPressed(SDLK_ESCAPE)) if(Input::getInstance().isKeyPressed(SDLK_ESCAPE))
exit(); exit();
@ -152,15 +156,15 @@ void Application::handleEvents()
void Application::run() void Application::run()
{ {
m_run = true; m_run = true;
m_wireframe = false;
m_now = SDL_GetPerformanceCounter(); m_now = SDL_GetPerformanceCounter();
m_last = 0; m_last = 0;
// TEST CODE // TEST CODE
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
Input::getInstance().setMouseCoords(m_width/2, m_height/2); 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 // Create the shader and link them together
Shader& chunkShader = Shader::createShader("data/shaders/chunk.vert", "data/shaders/chunk.frag"); Shader& chunkShader = Shader::createShader("data/shaders/chunk.vert", "data/shaders/chunk.frag");
chunkShader.linkShaders(); chunkShader.linkShaders();
@ -186,14 +190,19 @@ void Application::run()
deltaTime = ((m_now - m_last) / (double)SDL_GetPerformanceFrequency()); deltaTime = ((m_now - m_last) / (double)SDL_GetPerformanceFrequency());
// TEST CODE // TEST CODE
glEnable(GL_DEPTH_TEST);
//glEnable(GL_CULL_FACE);
//glCullFace(GL_BACK);
pl->tick(m_camera, deltaTime); 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); 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 // END TEST CODE

View File

@ -45,6 +45,7 @@ class Application : public Singleton<Application>
double deltaTime; double deltaTime;
bool m_run; bool m_run;
bool m_wireframe;
void handleEvents(); void handleEvents();
void run(); void run();

View File

@ -32,3 +32,10 @@ void Planet::tick(Camera* camera, GLfloat dtime)
m_faces[i]->tick(camera, 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;
}

View File

@ -20,6 +20,8 @@ class Planet
void tick(Camera* camera, GLfloat dtime); void tick(Camera* camera, GLfloat dtime);
void draw(Camera* camera, Shader* shader); void draw(Camera* camera, Shader* shader);
glm::mat4 getTransformation();
private: private:
glm::vec3 m_position; glm::vec3 m_position;
float m_radius; float m_radius;

View File

@ -1,5 +1,6 @@
#include "planet/PlanetFace.h" #include "planet/PlanetFace.h"
// Correlates directly to Face enum
const glm::vec3 FACE_NORMALS[6] = { const glm::vec3 FACE_NORMALS[6] = {
glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f),
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) : 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(); glm::vec3 normal = face->getNormal();
m_left = glm::vec3(normal.y, normal.z, normal.x); 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() 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); glDeleteBuffers(1, &m_vao);
@ -36,13 +41,56 @@ PlanetFaceNode::~PlanetFaceNode()
glDeleteBuffers(1, &m_ebo); 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) 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) if (!m_generated)
return; return;
@ -50,7 +98,7 @@ void PlanetFaceNode::draw(Camera* camera, Shader* shader)
shader->use(); shader->use();
camera->shaderViewProjection(*shader); 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); glDrawElements(GL_TRIANGLES, m_indices, GL_UNSIGNED_INT, nullptr);
} }
@ -85,6 +133,9 @@ void PlanetFaceNode::generate()
// Add // Add
vertices.push_back({ pos, vertNormal, glm::vec2(j * (1.0 / RESOLUTION), i * (1.0 / RESOLUTION)) }); 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 bottomLeft = ((gz + 1) * RESOLUTION) + gx;
int bottomRight = bottomLeft + 1; int bottomRight = bottomLeft + 1;
indices.push_back(topLeft);
indices.push_back(topRight);
indices.push_back(bottomLeft); indices.push_back(bottomLeft);
indices.push_back(bottomLeft);
indices.push_back(topRight);
indices.push_back(bottomRight); 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); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertices.size(), &(vertices[0]), GL_STATIC_DRAW);
m_generated = true; m_generated = true;
m_leaf = true;
} }
void PlanetFaceNode::subdivide() bool PlanetFaceNode::subdivide()
{ {
if (m_level == 4) if (m_level == 8)
return; return false;
int lv = m_level + 1; int lv = m_level + 1;
float radius = m_planet->getRadius(); float radius = m_planet->getRadius();
@ -142,13 +192,17 @@ void PlanetFaceNode::subdivide()
m_leaf = false; m_leaf = false;
this->dispose(); this->dispose();
return true;
} }
void PlanetFaceNode::merge() bool PlanetFaceNode::merge()
{ {
if (m_level == 0 && m_leaf) // Leaves don't ever need to be merged
return; if (m_leaf)
return false;
// Merge and dispose the children
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
m_children[i]->merge(); m_children[i]->merge();
@ -156,7 +210,9 @@ void PlanetFaceNode::merge()
delete m_children[i]; delete m_children[i];
} }
// We're a leaf now
m_leaf = true; m_leaf = true;
return true;
} }
void PlanetFaceNode::dispose() void PlanetFaceNode::dispose()
@ -177,7 +233,6 @@ PlanetFace::PlanetFace(Planet* planet, const unsigned int face) :
{ {
m_normal = FACE_NORMALS[m_face]; m_normal = FACE_NORMALS[m_face];
m_planetFace = new PlanetFaceNode(planet, this, m_normal * (m_planet->getRadius() / 2.0f), 0); m_planetFace = new PlanetFaceNode(planet, this, m_normal * (m_planet->getRadius() / 2.0f), 0);
m_planetFace->generate();
} }
PlanetFace::~PlanetFace() PlanetFace::~PlanetFace()
@ -192,5 +247,7 @@ void PlanetFace::draw(Camera* camera, Shader* shader)
void PlanetFace::tick(Camera* camera, GLfloat dtime) 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);
} }

View File

@ -6,7 +6,7 @@
#include "Shader.h" #include "Shader.h"
#include "Camera.h" #include "Camera.h"
#define RESOLUTION 128 #define RESOLUTION 64
enum Face enum Face
{ {
@ -31,13 +31,9 @@ class PlanetFaceNode
PlanetFaceNode(Planet* planet, PlanetFace* face, glm::vec3 position, const unsigned int level); PlanetFaceNode(Planet* planet, PlanetFace* face, glm::vec3 position, const unsigned int level);
~PlanetFaceNode(); ~PlanetFaceNode();
void tick(Camera* camera, GLfloat dtime); void tick(Camera* camera, GLfloat dtime, bool& tickUpdatedLOD, bool& tickGeneratedFace);
void draw(Camera* camera, Shader* shader); void draw(Camera* camera, Shader* shader);
void generate();
void subdivide();
void merge();
void dispose();
bool isLeaf(); bool isLeaf();
inline Planet* getPlanet() const { return m_planet; } inline Planet* getPlanet() const { return m_planet; }
@ -45,6 +41,11 @@ class PlanetFaceNode
inline glm::vec3 getAbsolutePosition() const { return m_planet->getPosition() + m_pos; } inline glm::vec3 getAbsolutePosition() const { return m_planet->getPosition() + m_pos; }
private: private:
void generate();
bool subdivide();
bool merge();
void dispose();
Planet* m_planet; Planet* m_planet;
PlanetFace* m_planetFace; PlanetFace* m_planetFace;
@ -60,6 +61,7 @@ class PlanetFaceNode
int m_indices; int m_indices;
glm::vec3 m_pos; glm::vec3 m_pos;
glm::vec3 m_center;
glm::vec3 m_left; glm::vec3 m_left;
glm::vec3 m_forward; glm::vec3 m_forward;
}; };