new topology code
This commit is contained in:
parent
44c54b03bf
commit
c1e3e2fd3d
|
@ -205,7 +205,7 @@ void Application::run()
|
||||||
// TEST CODE
|
// TEST CODE
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_FRONT);
|
||||||
|
|
||||||
if (!m_pauseLod)
|
if (!m_pauseLod)
|
||||||
pl->tick(m_camera, deltaTime);
|
pl->tick(m_camera, deltaTime);
|
||||||
|
|
|
@ -204,22 +204,23 @@ void Camera::processMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean co
|
||||||
|
|
||||||
void Camera::processMouseScroll(GLfloat yoffset)
|
void Camera::processMouseScroll(GLfloat yoffset)
|
||||||
{
|
{
|
||||||
if (m_zoom >= 44.0f && m_zoom <= 45.0f)
|
// if (m_zoom >= 44.0f && m_zoom <= 45.0f)
|
||||||
{
|
// {
|
||||||
m_zoom -= yoffset;
|
// m_zoom -= yoffset;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (m_zoom <= 44.0f)
|
// if (m_zoom <= 44.0f)
|
||||||
{
|
// {
|
||||||
m_zoom = 44.0f;
|
// m_zoom = 44.0f;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (m_zoom >= 45.0f)
|
// if (m_zoom >= 45.0f)
|
||||||
{
|
// {
|
||||||
m_zoom = 45.0f;
|
// m_zoom = 45.0f;
|
||||||
}
|
// }
|
||||||
|
|
||||||
updateProjection();
|
// updateProjection();
|
||||||
|
m_movementSpeed += yoffset * 50.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::updateProjection(void)
|
void Camera::updateProjection(void)
|
||||||
|
|
|
@ -2,9 +2,22 @@
|
||||||
#include "planet/PlanetFace.h"
|
#include "planet/PlanetFace.h"
|
||||||
|
|
||||||
Planet::Planet(glm::vec3 position, float radius, PlanetNoiseParams &noiseParams) :
|
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 (unsigned int a = 0; a <= 4; a++)
|
||||||
|
{
|
||||||
|
for (unsigned int b = 0; b <= 4; b++)
|
||||||
|
{
|
||||||
|
for (unsigned int c = 0; c <= 4; c++)
|
||||||
|
{
|
||||||
|
for (unsigned int d = 0; d <= 4; d++)
|
||||||
|
{
|
||||||
|
m_ibuffers[a][b][c][d] = new PlanetIndexBuffer(16, a, b, c, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
m_faces[i] = new PlanetFace(this, i);
|
m_faces[i] = new PlanetFace(this, i);
|
||||||
|
@ -18,7 +31,21 @@ Planet::~Planet()
|
||||||
{
|
{
|
||||||
delete m_faces[i];
|
delete m_faces[i];
|
||||||
}
|
}
|
||||||
delete m_ibuffers;
|
|
||||||
|
for (unsigned int a = 0; a <= 4; a++)
|
||||||
|
{
|
||||||
|
for (unsigned int b = 0; b <= 4; b++)
|
||||||
|
{
|
||||||
|
for (unsigned int c = 0; c <= 4; c++)
|
||||||
|
{
|
||||||
|
for (unsigned int d = 0; d <= 4; d++)
|
||||||
|
{
|
||||||
|
delete m_ibuffers[a][b][c][d];
|
||||||
|
m_ibuffers[a][b][c][d] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Planet::draw(Camera* camera, Shader* shader)
|
void Planet::draw(Camera* camera, Shader* shader)
|
||||||
|
@ -60,3 +87,7 @@ glm::mat4 Planet::getTransformation()
|
||||||
newMat = glm::translate(newMat, m_position);
|
newMat = glm::translate(newMat, m_position);
|
||||||
return newMat;
|
return newMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlanetIndexBuffer* Planet::getIndexBuffer(const unsigned int detailTop, const unsigned int detailRight, const unsigned int detailBottom, const unsigned int detailLeft) {
|
||||||
|
return m_ibuffers[detailTop][detailRight][detailBottom][detailLeft];
|
||||||
|
}
|
||||||
|
|
|
@ -33,14 +33,14 @@ class Planet
|
||||||
void draw(Camera* camera, Shader* shader);
|
void draw(Camera* camera, Shader* shader);
|
||||||
|
|
||||||
inline 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]; }
|
inline PlanetFace* getFace(const unsigned int face) { return m_faces[face]; }
|
||||||
|
PlanetIndexBuffer* getIndexBuffer(const unsigned int detailTop, const unsigned int detailRight, const unsigned int detailBottom, const unsigned int detailLeft);
|
||||||
|
|
||||||
glm::mat4 getTransformation();
|
glm::mat4 getTransformation();
|
||||||
private:
|
private:
|
||||||
void connectFaces();
|
void connectFaces();
|
||||||
|
|
||||||
PlanetIndexBuffer* m_ibuffers;
|
PlanetIndexBuffer* m_ibuffers[5][5][5][5];
|
||||||
SimplexNoise m_noise;
|
SimplexNoise m_noise;
|
||||||
glm::vec3 m_position;
|
glm::vec3 m_position;
|
||||||
float m_radius;
|
float m_radius;
|
||||||
|
|
|
@ -236,6 +236,12 @@ void PlanetFaceNode::updateNeighborDetailDifferences(const unsigned int side)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the neighbor detail (depth) difference [0,MAX_DETAIL_DIFFERENCE]
|
||||||
|
unsigned int PlanetFaceNode::getNeighborDetailDifference(const unsigned int side) const
|
||||||
|
{
|
||||||
|
return neighborDetailDifferences[side];
|
||||||
|
}
|
||||||
|
|
||||||
void PlanetFaceNode::tick(Camera* camera, GLfloat dtime)
|
void PlanetFaceNode::tick(Camera* camera, GLfloat dtime)
|
||||||
{
|
{
|
||||||
// TODO: based on planet transform
|
// TODO: based on planet transform
|
||||||
|
@ -259,12 +265,6 @@ void PlanetFaceNode::tick(Camera* camera, GLfloat dtime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlanetFaceNode::setIndexBuffer(PlanetBufferIndex buf) {
|
|
||||||
PIB* indx = m_planetFace->getPlanet()->getBuffers()->getBuffer(buf);
|
|
||||||
m_ebo = indx->ebo;
|
|
||||||
m_indices = indx->indices.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlanetFaceNode::draw(Camera* camera, Shader* shader)
|
void PlanetFaceNode::draw(Camera* camera, Shader* shader)
|
||||||
{
|
{
|
||||||
// TODO: occlusion culling
|
// TODO: occlusion culling
|
||||||
|
@ -280,49 +280,20 @@ void PlanetFaceNode::draw(Camera* camera, Shader* shader)
|
||||||
if (!m_generated)
|
if (!m_generated)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (neighborDetailDifferences[TOP] == 1) {
|
PlanetIndexBuffer* buffers = m_planetFace->getPlanet()->getIndexBuffer(
|
||||||
if (neighborDetailDifferences[RIGHT] == 1) {
|
getNeighborDetailDifference(TOP),
|
||||||
setIndexBuffer(FixTR);
|
getNeighborDetailDifference(RIGHT),
|
||||||
} else if (neighborDetailDifferences[LEFT] == 1) {
|
getNeighborDetailDifference(BOTTOM),
|
||||||
setIndexBuffer(FixTL);
|
getNeighborDetailDifference(LEFT)
|
||||||
} else {
|
);
|
||||||
setIndexBuffer(FixT);
|
|
||||||
}
|
|
||||||
} else if (neighborDetailDifferences[BOTTOM] == 1) {
|
|
||||||
if (neighborDetailDifferences[RIGHT] == 1) {
|
|
||||||
setIndexBuffer(FixBR);
|
|
||||||
} else if (neighborDetailDifferences[LEFT] == 1) {
|
|
||||||
setIndexBuffer(FixBL);
|
|
||||||
} else {
|
|
||||||
setIndexBuffer(FixB);
|
|
||||||
}
|
|
||||||
} else if (neighborDetailDifferences[RIGHT] == 1) {
|
|
||||||
if (neighborDetailDifferences[BOTTOM] == 1) {
|
|
||||||
setIndexBuffer(FixBR);
|
|
||||||
} else if (neighborDetailDifferences[TOP] == 1) {
|
|
||||||
setIndexBuffer(FixTR);
|
|
||||||
} else {
|
|
||||||
setIndexBuffer(FixR);
|
|
||||||
}
|
|
||||||
} else if (neighborDetailDifferences[LEFT] == 1) {
|
|
||||||
if (neighborDetailDifferences[BOTTOM] == 1) {
|
|
||||||
setIndexBuffer(FixBL);
|
|
||||||
} else if (neighborDetailDifferences[TOP] == 1) {
|
|
||||||
setIndexBuffer(FixTL);
|
|
||||||
} else {
|
|
||||||
setIndexBuffer(FixL);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setIndexBuffer(Base);
|
|
||||||
}
|
|
||||||
|
|
||||||
shader->setBuffers(m_vao, m_vbo, m_ebo);
|
shader->setBuffers(m_vao, m_vbo, buffers->getIbo());
|
||||||
shader->use();
|
shader->use();
|
||||||
|
|
||||||
camera->shaderViewProjection(*shader);
|
camera->shaderViewProjection(*shader);
|
||||||
shader->setUniform("modelMatrix", m_planetFace->getPlanet()->getTransformation());
|
shader->setUniform("modelMatrix", m_planetFace->getPlanet()->getTransformation());
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES, m_indices, GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, buffers->getVertexCount(), GL_UNSIGNED_SHORT, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlanetFaceNode::generate()
|
void PlanetFaceNode::generate()
|
||||||
|
@ -405,8 +376,6 @@ void PlanetFaceNode::generate()
|
||||||
m_center = boundingSphereCenterF;
|
m_center = boundingSphereCenterF;
|
||||||
m_radius = boundingSphereRadiusF;
|
m_radius = boundingSphereRadiusF;
|
||||||
|
|
||||||
std::cout << m_radius << std::endl;
|
|
||||||
|
|
||||||
m_generated = true;
|
m_generated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +453,7 @@ PlanetFace::PlanetFace(Planet* planet, const unsigned int face) :
|
||||||
m_planet(planet), m_face(face)
|
m_planet(planet), m_face(face)
|
||||||
{
|
{
|
||||||
m_normal = FACE_NORMALS[m_face];
|
m_normal = FACE_NORMALS[m_face];
|
||||||
m_lod = new PlanetFaceNode(this, 0, m_normal, face);
|
m_lod = new PlanetFaceNode(this, 0, m_normal, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlanetFace::~PlanetFace()
|
PlanetFace::~PlanetFace()
|
||||||
|
@ -505,8 +474,9 @@ void PlanetFace::tick(Camera* camera, GLfloat dtime)
|
||||||
|
|
||||||
void PlanetFace::connect(const unsigned int side, PlanetFace* face)
|
void PlanetFace::connect(const unsigned int side, PlanetFace* face)
|
||||||
{
|
{
|
||||||
if (m_lod && face->getLODRoot())
|
if (m_lod && face->getLODRoot()) {
|
||||||
m_lod->setNeighbor(side, face->getLODRoot());
|
m_lod->setNeighbor(side, face->getLODRoot());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlanetFace::hasSplitsLeft()
|
bool PlanetFace::hasSplitsLeft()
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
|
||||||
#define RESOLUTION 15
|
#define RESOLUTION 17
|
||||||
|
|
||||||
enum Face
|
enum Face
|
||||||
{
|
{
|
||||||
|
@ -24,12 +24,6 @@ enum Quadrant
|
||||||
BOTTOM_RIGHT, BOTTOM_LEFT
|
BOTTOM_RIGHT, BOTTOM_LEFT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Direction
|
|
||||||
{
|
|
||||||
TOP, RIGHT,
|
|
||||||
BOTTOM, LEFT,
|
|
||||||
};
|
|
||||||
|
|
||||||
const unsigned int MAX_SPLITS_PER_UPDATE = 2;
|
const unsigned int MAX_SPLITS_PER_UPDATE = 2;
|
||||||
|
|
||||||
#define MIRROR(s) (((s) + 2) % 4)
|
#define MIRROR(s) (((s) + 2) % 4)
|
||||||
|
@ -74,8 +68,6 @@ class PlanetFaceNode
|
||||||
bool merge();
|
bool merge();
|
||||||
void dispose();
|
void dispose();
|
||||||
|
|
||||||
void setIndexBuffer(PlanetBufferIndex buf);
|
|
||||||
|
|
||||||
void findNeighbor(const unsigned int side);
|
void findNeighbor(const unsigned int side);
|
||||||
void getNeighbor(const unsigned int side);
|
void getNeighbor(const unsigned int side);
|
||||||
void updateNeighborDetailDifferences(const unsigned int side);
|
void updateNeighborDetailDifferences(const unsigned int side);
|
||||||
|
|
|
@ -1,145 +1,179 @@
|
||||||
#include "PlanetIndexBuffer.h"
|
#include "PlanetIndexBuffer.h"
|
||||||
|
|
||||||
PlanetIndexBuffer::PlanetIndexBuffer(unsigned int resolution) : m_resolution(resolution) {
|
PlanetIndexBuffer::PlanetIndexBuffer(
|
||||||
createBuffer(PlanetBufferIndex::Base);
|
unsigned int resolution,
|
||||||
createBuffer(PlanetBufferIndex::FixT, false, false, true, false);
|
const unsigned int detailTop,
|
||||||
createBuffer(PlanetBufferIndex::FixR, true, false, false, false);
|
const unsigned int detailRight,
|
||||||
createBuffer(PlanetBufferIndex::FixB, false, true, false, false);
|
const unsigned int detailBottom,
|
||||||
createBuffer(PlanetBufferIndex::FixL, false, false, false, true);
|
const unsigned int detailLeft
|
||||||
createBuffer(PlanetBufferIndex::FixTL, false, false, true, true);
|
) : m_resolution(resolution) {
|
||||||
createBuffer(PlanetBufferIndex::FixTR, true, false, true, false);
|
TriangleFanList triangleFans;
|
||||||
createBuffer(PlanetBufferIndex::FixBR, true, true, false, false);
|
|
||||||
createBuffer(PlanetBufferIndex::FixBL, false, true, false, true);
|
// Build the patch body (without edges)
|
||||||
|
for (unsigned int x = 2; x < m_resolution - 1; x += 2)
|
||||||
|
{
|
||||||
|
for (unsigned int y = 2; y < m_resolution - 1; y += 2)
|
||||||
|
{
|
||||||
|
addTriangleFan(triangleFans);
|
||||||
|
addTriangleFanVertex(triangleFans, x, y);
|
||||||
|
addTriangleFanVertex(triangleFans, x + 1, y + 1);
|
||||||
|
addTriangleFanVertex(triangleFans, x, y + 1);
|
||||||
|
addTriangleFanVertex(triangleFans, x - 1, y + 1);
|
||||||
|
addTriangleFanVertex(triangleFans, x - 1, y);
|
||||||
|
addTriangleFanVertex(triangleFans, x - 1, y - 1);
|
||||||
|
addTriangleFanVertex(triangleFans, x, y - 1);
|
||||||
|
addTriangleFanVertex(triangleFans, x + 1, y - 1);
|
||||||
|
addTriangleFanVertex(triangleFans, x + 1, y);
|
||||||
|
addTriangleFanVertex(triangleFans, x + 1, y + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build all four edges
|
||||||
|
buildEdge(triangleFans, TOP, detailLeft);
|
||||||
|
buildEdge(triangleFans, RIGHT, detailBottom);
|
||||||
|
buildEdge(triangleFans, BOTTOM, detailRight);
|
||||||
|
buildEdge(triangleFans, LEFT, detailTop);
|
||||||
|
|
||||||
|
// Count the number of triangles and reserve three vertices per triangle
|
||||||
|
int triangleCount = 0;
|
||||||
|
for (unsigned int i = 0; i < triangleFans.size(); i++)
|
||||||
|
if (triangleFans[i].size() > 2)
|
||||||
|
triangleCount += triangleFans[i].size() - 2;
|
||||||
|
m_vertexCount = 3 * triangleCount;
|
||||||
|
|
||||||
|
// Create an index array
|
||||||
|
GLushort *indexData = new GLushort[m_vertexCount];
|
||||||
|
int n = 0;
|
||||||
|
for (unsigned int i = 0; i < triangleFans.size(); i++)
|
||||||
|
{
|
||||||
|
for (unsigned int j = 2; j < triangleFans[i].size(); j++)
|
||||||
|
{
|
||||||
|
indexData[n++] = triangleFans[i][0];
|
||||||
|
indexData[n++] = triangleFans[i][j-1];
|
||||||
|
indexData[n++] = triangleFans[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the index buffer object (IBO)
|
||||||
|
glGenBuffers(1, &m_ibo);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * m_vertexCount, indexData, GL_STATIC_DRAW);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
// Delete unnecessary data
|
||||||
|
triangleFans.clear();
|
||||||
|
delete[] indexData;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlanetIndexBuffer::~PlanetIndexBuffer() {
|
PlanetIndexBuffer::~PlanetIndexBuffer() {
|
||||||
for (int i = 0; i < 9; i++) {
|
glDeleteBuffers(1, &m_ibo);
|
||||||
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) {
|
void PlanetIndexBuffer::rotateIndices(unsigned int &x, unsigned int &y, const unsigned int rotation)
|
||||||
return m_buffers[idx];
|
{
|
||||||
|
// Change the indices to match the given rotation
|
||||||
|
switch (rotation)
|
||||||
|
{
|
||||||
|
case TOP:
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
case RIGHT:
|
||||||
|
std::swap(x, y);
|
||||||
|
y = m_resolution - y;
|
||||||
|
return;
|
||||||
|
case BOTTOM:
|
||||||
|
x = m_resolution - x;
|
||||||
|
y = m_resolution - y;
|
||||||
|
return;
|
||||||
|
case LEFT:
|
||||||
|
std::swap(x, y);
|
||||||
|
x = m_resolution - x;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlanetIndexBuffer::createBuffer(PlanetBufferIndex idx, bool fanTop, bool fanRight, bool fanLeft, bool fanBottom) {
|
// Creates and adds a triangle fan
|
||||||
PIB* buffer = new PIB();
|
void PlanetIndexBuffer::addTriangleFan(TriangleFanList &triangleFans)
|
||||||
// Create indices for mesh
|
{
|
||||||
for (unsigned int gz = 0; gz < m_resolution - 1; gz++)
|
triangleFans.push_back(TriangleFan());
|
||||||
{
|
}
|
||||||
bool slantLeft = gz % 2 == 0;
|
|
||||||
for (unsigned int gx = 0; gx < m_resolution - 1; gx++)
|
// adds a vertex index to the most recently added triangle fan
|
||||||
{
|
void PlanetIndexBuffer::addTriangleFanVertex(TriangleFanList &triangleFans, unsigned int x, unsigned int y, const unsigned int rotation)
|
||||||
unsigned int topLeft = (gz * m_resolution) + gx;
|
{
|
||||||
unsigned int topRight = topLeft + 1;
|
// Rotate and use the x and y indices
|
||||||
unsigned int bottomLeft = ((gz + 1) * m_resolution) + gx;
|
PlanetIndexBuffer::rotateIndices(x, y, rotation);
|
||||||
unsigned int bottomRight = bottomLeft + 1;
|
triangleFans.back().push_back(index1D(x,y));
|
||||||
|
}
|
||||||
bool uTri1 = true;
|
|
||||||
bool uTri2 = true;
|
void PlanetIndexBuffer::buildEdge(TriangleFanList &triangleFans, const unsigned int side, const unsigned int detail)
|
||||||
unsigned int tri1[3];
|
{
|
||||||
unsigned int tri2[3];
|
// If detail difference is 0 (default case) or too high
|
||||||
|
if (detail == 0 || detail > 4)
|
||||||
if (slantLeft)
|
{
|
||||||
{
|
for (unsigned int x = 0; x < m_resolution - 1; x += 2)
|
||||||
tri1[0] = topLeft;
|
{
|
||||||
tri1[1] = bottomLeft;
|
addTriangleFan(triangleFans);
|
||||||
tri1[2] = bottomRight;
|
addTriangleFanVertex(triangleFans, x + 1, m_resolution - 1, side);
|
||||||
tri2[0] = topLeft;
|
for (int d = -1; d <= 1; d++)
|
||||||
tri2[1] = bottomRight;
|
addTriangleFanVertex(triangleFans, x + 1 - d, m_resolution, side);
|
||||||
tri2[2] = topRight;
|
|
||||||
}
|
if (x > 0)
|
||||||
else
|
{
|
||||||
{
|
addTriangleFan(triangleFans);
|
||||||
tri1[0] = topLeft;
|
addTriangleFanVertex(triangleFans, x, m_resolution, side);
|
||||||
tri1[1] = bottomLeft;
|
for (int d = -1; d <= 1; d++)
|
||||||
tri1[2] = topRight;
|
addTriangleFanVertex(triangleFans, x + d, m_resolution - 1, side);
|
||||||
tri2[0] = bottomLeft;
|
}
|
||||||
tri2[1] = bottomRight;
|
}
|
||||||
tri2[2] = topRight;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fanTop && gz == 0)
|
// Calculate step sizes; step = 2^detail
|
||||||
{
|
const int step = 1 << detail;
|
||||||
if (gx % 2 == 0)
|
const int halfStep = step / 2;
|
||||||
{
|
|
||||||
tri2[0] = topLeft;
|
unsigned int x = 0;
|
||||||
tri2[1] = bottomRight;
|
for (x = 0; x < m_resolution; x += step)
|
||||||
tri2[2] = topRight + 1;
|
{
|
||||||
}
|
addTriangleFan(triangleFans);
|
||||||
else
|
addTriangleFanVertex(triangleFans, x, m_resolution, side);
|
||||||
{
|
addTriangleFanVertex(triangleFans, x + halfStep, m_resolution - 1, side);
|
||||||
uTri1 = false;
|
addTriangleFanVertex(triangleFans, x + step, m_resolution, side);
|
||||||
}
|
|
||||||
}
|
if (x > 0)
|
||||||
|
{
|
||||||
if (fanRight && gx == m_resolution - 2)
|
addTriangleFan(triangleFans);
|
||||||
{
|
addTriangleFanVertex(triangleFans, x, m_resolution, side);
|
||||||
if (gz % 2 == 0)
|
for (int d = -halfStep; d <= halfStep; d++)
|
||||||
{
|
addTriangleFanVertex(triangleFans, x + d, m_resolution - 1, side);
|
||||||
tri2[0] = topRight;
|
}
|
||||||
tri2[1] = bottomLeft;
|
}
|
||||||
tri2[2] = bottomRight + m_resolution;
|
|
||||||
}
|
if (step > 2)
|
||||||
else
|
{
|
||||||
{
|
addTriangleFan(triangleFans);
|
||||||
uTri2 = false;
|
addTriangleFanVertex(triangleFans, 0, m_resolution, side);
|
||||||
}
|
for (int d = 1; d <= halfStep; d++)
|
||||||
}
|
addTriangleFanVertex(triangleFans, d, m_resolution - 1, side);
|
||||||
|
|
||||||
if (fanBottom && gz == m_resolution - 2)
|
addTriangleFan(triangleFans);
|
||||||
{
|
addTriangleFanVertex(triangleFans, m_resolution, m_resolution, side);
|
||||||
if (gx % 2 == 0)
|
for (int d = -halfStep; d <= -1; d++)
|
||||||
{
|
addTriangleFanVertex(triangleFans, m_resolution + d, m_resolution - 1, side);
|
||||||
tri2[0] = bottomLeft;
|
}
|
||||||
tri2[1] = bottomRight + 1;
|
}
|
||||||
tri2[2] = topRight;
|
|
||||||
}
|
GLsizei PlanetIndexBuffer::getVertexCount() const
|
||||||
else
|
{
|
||||||
{
|
return m_vertexCount;
|
||||||
uTri1 = false;
|
}
|
||||||
}
|
|
||||||
}
|
GLuint PlanetIndexBuffer::getIbo() const
|
||||||
|
{
|
||||||
if (fanLeft && gx == 0)
|
return m_ibo;
|
||||||
{
|
}
|
||||||
if (gz % 2 == 0)
|
|
||||||
{
|
unsigned int PlanetIndexBuffer::index1D(const unsigned int x, const unsigned int y) {
|
||||||
tri1[0] = topLeft;
|
return ((x) + (y) * (m_resolution + 1));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,24 +3,37 @@
|
||||||
|
|
||||||
#include "util/Common.h"
|
#include "util/Common.h"
|
||||||
|
|
||||||
struct PIB {
|
enum Direction
|
||||||
GLuint ebo;
|
{
|
||||||
std::vector<uint> indices;
|
TOP, RIGHT,
|
||||||
|
BOTTOM, LEFT,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PlanetBufferIndex {
|
|
||||||
Base, FixT, FixR, FixB, FixL, FixTL, FixTR, FixBR, FixBL
|
typedef std::vector<GLushort> TriangleFan;
|
||||||
};
|
typedef std::vector<TriangleFan> TriangleFanList;
|
||||||
|
|
||||||
class PlanetIndexBuffer {
|
class PlanetIndexBuffer {
|
||||||
public:
|
public:
|
||||||
PlanetIndexBuffer(unsigned int resolution);
|
PlanetIndexBuffer(unsigned int resolution, const unsigned int detailTop, const unsigned int detailRight, const unsigned int detailBottom, const unsigned int detailLeft);
|
||||||
~PlanetIndexBuffer();
|
~PlanetIndexBuffer();
|
||||||
|
|
||||||
PIB* getBuffer(PlanetBufferIndex idx);
|
// Instance methods
|
||||||
|
GLsizei getVertexCount() const;
|
||||||
|
GLuint getIbo() const;
|
||||||
private:
|
private:
|
||||||
void createBuffer(PlanetBufferIndex idx, bool fanTop = false, bool fanRight = false, bool fanLeft = false, bool fanBottom = false);
|
void rotateIndices(unsigned int &x, unsigned int &y, const unsigned int rotation);
|
||||||
PIB* m_buffers[9];
|
void addTriangleFan(TriangleFanList &triangleFans);
|
||||||
|
void addTriangleFanVertex(TriangleFanList &triangleFans, unsigned int x, unsigned int y, const unsigned int rotation = 0);
|
||||||
|
void buildEdge(TriangleFanList &triangleFans, const unsigned int side, const unsigned int detail = 0);
|
||||||
|
|
||||||
|
// Instance variables
|
||||||
|
GLsizei m_vertexCount;
|
||||||
|
GLuint m_ibo;
|
||||||
|
|
||||||
|
// TODO: move to utility
|
||||||
|
unsigned int index1D(const unsigned int x, const unsigned int y);
|
||||||
|
|
||||||
unsigned int m_resolution;
|
unsigned int m_resolution;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue