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();
// 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

View File

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

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
};