Refactoring example code.
This commit is contained in:
parent
3f849e19a4
commit
565aa21799
@ -72,27 +72,26 @@ public:
|
|||||||
BasicExample(QWidget *parent)
|
BasicExample(QWidget *parent)
|
||||||
:OpenGLWidget(parent)
|
:OpenGLWidget(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initialize() override
|
void initialize() override
|
||||||
{
|
{
|
||||||
//Create an empty volume and then place a sphere in it
|
//Create an empty volume and then place a sphere in it
|
||||||
PagedVolume<uint8_t> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63)));
|
PagedVolume<uint8_t> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63)));
|
||||||
createSphereInVolume(volData, 30);
|
createSphereInVolume(volData, 30);
|
||||||
|
|
||||||
// Extract the surface for the specified region of the volume. Uncomment the line for the kind of surface extraction you want to see.
|
// Extract the surface for the specified region of the volume. Uncomment the line for the kind of surface extraction you want to see.
|
||||||
auto mesh = extractCubicMesh(&volData, volData.getEnclosingRegion());
|
auto mesh = extractCubicMesh(&volData, volData.getEnclosingRegion());
|
||||||
//auto mesh = extractMarchingCubesMesh(&volData, volData.getEnclosingRegion());
|
//auto mesh = extractMarchingCubesMesh(&volData, volData.getEnclosingRegion());
|
||||||
|
|
||||||
// The surface extractor outputs the mesh in an efficient compressed format which is not directly suitable for rendering. The easiest approach is to
|
// The surface extractor outputs the mesh in an efficient compressed format which is not directly suitable for rendering. The easiest approach is to
|
||||||
// decode this on the CPU as shown below, though more advanced applications can upload the compressed mesh to the GPU and decompress in shader code.
|
// decode this on the CPU as shown below, though more advanced applications can upload the compressed mesh to the GPU and decompress in shader code.
|
||||||
auto decodedMesh = decodeMesh(mesh);
|
auto decodedMesh = decodeMesh(mesh);
|
||||||
|
|
||||||
//Pass the surface to the OpenGL window
|
//Pass the surface to the OpenGL window
|
||||||
addMesh(decodedMesh);
|
addMesh(decodedMesh);
|
||||||
//openGLWidget.addMesh(mesh2);
|
//openGLWidget.addMesh(mesh2);
|
||||||
setViewableRegion(volData.getEnclosingRegion());
|
setViewableRegion(volData.getEnclosingRegion());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -72,7 +72,6 @@ public:
|
|||||||
DecodeOnGPUExample(QWidget *parent)
|
DecodeOnGPUExample(QWidget *parent)
|
||||||
:OpenGLWidget(parent)
|
:OpenGLWidget(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -114,60 +113,60 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OpenGLMeshData buildOpenGLMeshData(const PolyVox::Mesh< PolyVox::MarchingCubesVertex< uint8_t > >& surfaceMesh, const PolyVox::Vector3DInt32& translation = PolyVox::Vector3DInt32(0, 0, 0), float scale = 1.0f)
|
OpenGLMeshData buildOpenGLMeshData(const PolyVox::Mesh< PolyVox::MarchingCubesVertex< uint8_t > >& surfaceMesh, const PolyVox::Vector3DInt32& translation = PolyVox::Vector3DInt32(0, 0, 0), float scale = 1.0f)
|
||||||
{
|
{
|
||||||
// Convienient access to the vertices and indices
|
// Convienient access to the vertices and indices
|
||||||
const auto& vecIndices = surfaceMesh.getIndices();
|
const auto& vecIndices = surfaceMesh.getIndices();
|
||||||
const auto& vecVertices = surfaceMesh.getVertices();
|
const auto& vecVertices = surfaceMesh.getVertices();
|
||||||
|
|
||||||
// This struct holds the OpenGL properties (buffer handles, etc) which will be used
|
// This struct holds the OpenGL properties (buffer handles, etc) which will be used
|
||||||
// to render our mesh. We copy the data from the PolyVox mesh into this structure.
|
// to render our mesh. We copy the data from the PolyVox mesh into this structure.
|
||||||
OpenGLMeshData meshData;
|
OpenGLMeshData meshData;
|
||||||
|
|
||||||
// Create the VAO for the mesh
|
// Create the VAO for the mesh
|
||||||
glGenVertexArrays(1, &(meshData.vertexArrayObject));
|
glGenVertexArrays(1, &(meshData.vertexArrayObject));
|
||||||
glBindVertexArray(meshData.vertexArrayObject);
|
glBindVertexArray(meshData.vertexArrayObject);
|
||||||
|
|
||||||
// The GL_ARRAY_BUFFER will contain the list of vertex positions
|
// The GL_ARRAY_BUFFER will contain the list of vertex positions
|
||||||
glGenBuffers(1, &(meshData.vertexBuffer));
|
glGenBuffers(1, &(meshData.vertexBuffer));
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, meshData.vertexBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, meshData.vertexBuffer);
|
||||||
glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof(MarchingCubesVertex< uint8_t >), vecVertices.data(), GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof(MarchingCubesVertex< uint8_t >), vecVertices.data(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
// and GL_ELEMENT_ARRAY_BUFFER will contain the indices
|
// and GL_ELEMENT_ARRAY_BUFFER will contain the indices
|
||||||
glGenBuffers(1, &(meshData.indexBuffer));
|
glGenBuffers(1, &(meshData.indexBuffer));
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshData.indexBuffer);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshData.indexBuffer);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vecIndices.size() * sizeof(uint32_t), vecIndices.data(), GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vecIndices.size() * sizeof(uint32_t), vecIndices.data(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
// Every surface extractor outputs valid positions for the vertices, so tell OpenGL how these are laid out
|
// Every surface extractor outputs valid positions for the vertices, so tell OpenGL how these are laid out
|
||||||
glEnableVertexAttribArray(0); // Attrib '0' is the vertex positions
|
glEnableVertexAttribArray(0); // Attrib '0' is the vertex positions
|
||||||
glVertexAttribIPointer(0, 3, GL_UNSIGNED_SHORT, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, encodedPosition))); //take the first 3 floats from every sizeof(decltype(vecVertices)::value_type)
|
glVertexAttribIPointer(0, 3, GL_UNSIGNED_SHORT, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, encodedPosition))); //take the first 3 floats from every sizeof(decltype(vecVertices)::value_type)
|
||||||
|
|
||||||
// Some surface extractors also generate normals, so tell OpenGL how these are laid out. If a surface extractor
|
// Some surface extractors also generate normals, so tell OpenGL how these are laid out. If a surface extractor
|
||||||
// does not generate normals then nonsense values are written into the buffer here and sghould be ignored by the
|
// does not generate normals then nonsense values are written into the buffer here and sghould be ignored by the
|
||||||
// shader. This is mostly just to simplify this example code - in a real application you will know whether your
|
// shader. This is mostly just to simplify this example code - in a real application you will know whether your
|
||||||
// chosen surface extractor generates normals and can skip uploading them if not.
|
// chosen surface extractor generates normals and can skip uploading them if not.
|
||||||
glEnableVertexAttribArray(1); // Attrib '1' is the vertex normals.
|
glEnableVertexAttribArray(1); // Attrib '1' is the vertex normals.
|
||||||
glVertexAttribIPointer(1, 1, GL_UNSIGNED_SHORT, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, encodedNormal)));
|
glVertexAttribIPointer(1, 1, GL_UNSIGNED_SHORT, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, encodedNormal)));
|
||||||
|
|
||||||
// Finally a surface extractor will probably output additional data. This is highly application dependant. For this example code
|
// Finally a surface extractor will probably output additional data. This is highly application dependant. For this example code
|
||||||
// we're just uploading it as a set of bytes which we can read individually, but real code will want to do something specialised here.
|
// we're just uploading it as a set of bytes which we can read individually, but real code will want to do something specialised here.
|
||||||
glEnableVertexAttribArray(2); //We're talking about shader attribute '2'
|
glEnableVertexAttribArray(2); //We're talking about shader attribute '2'
|
||||||
GLint size = (std::min)(sizeof(uint8_t), size_t(4)); // Can't upload more that 4 components (vec4 is GLSL's biggest type)
|
GLint size = (std::min)(sizeof(uint8_t), size_t(4)); // Can't upload more that 4 components (vec4 is GLSL's biggest type)
|
||||||
glVertexAttribIPointer(2, size, GL_UNSIGNED_BYTE, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, data)));
|
glVertexAttribIPointer(2, size, GL_UNSIGNED_BYTE, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, data)));
|
||||||
|
|
||||||
// We're done uploading and can now unbind.
|
// We're done uploading and can now unbind.
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
// A few additional properties can be copied across for use during rendering.
|
// A few additional properties can be copied across for use during rendering.
|
||||||
meshData.noOfIndices = vecIndices.size();
|
meshData.noOfIndices = vecIndices.size();
|
||||||
meshData.translation = QVector3D(translation.getX(), translation.getY(), translation.getZ());
|
meshData.translation = QVector3D(translation.getX(), translation.getY(), translation.getZ());
|
||||||
meshData.scale = scale;
|
meshData.scale = scale;
|
||||||
|
|
||||||
// Set 16 or 32-bit index buffer size.
|
// Set 16 or 32-bit index buffer size.
|
||||||
meshData.indexType = sizeof(PolyVox::Mesh< PolyVox::MarchingCubesVertex< uint8_t > >::IndexType) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
|
meshData.indexType = sizeof(PolyVox::Mesh< PolyVox::MarchingCubesVertex< uint8_t > >::IndexType) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
|
||||||
|
|
||||||
return meshData;
|
return meshData;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
@ -47,100 +47,110 @@ using namespace std;
|
|||||||
|
|
||||||
const int32_t g_uVolumeSideLength = 128;
|
const int32_t g_uVolumeSideLength = 128;
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
class OpenGLExample : public OpenGLWidget
|
||||||
{
|
{
|
||||||
FilePager<MaterialDensityPair88>* pager = new FilePager<MaterialDensityPair88>(".");
|
public:
|
||||||
PagedVolume<MaterialDensityPair88> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(g_uVolumeSideLength - 1, g_uVolumeSideLength - 1, g_uVolumeSideLength - 1)), pager);
|
OpenGLExample(QWidget *parent)
|
||||||
|
:OpenGLWidget(parent)
|
||||||
//Make our volume contain a sphere in the center.
|
|
||||||
int32_t minPos = 0;
|
|
||||||
int32_t midPos = g_uVolumeSideLength / 2;
|
|
||||||
int32_t maxPos = g_uVolumeSideLength - 1;
|
|
||||||
|
|
||||||
cout << "Creating sphere 1" << std::endl;
|
|
||||||
createSphereInVolume(volData, 60.0f, 5);
|
|
||||||
cout << "Creating sphere 2" << std::endl;
|
|
||||||
createSphereInVolume(volData, 50.0f, 4);
|
|
||||||
cout << "Creating sphere 3" << std::endl;
|
|
||||||
createSphereInVolume(volData, 40.0f, 3);
|
|
||||||
cout << "Creating sphere 4" << std::endl;
|
|
||||||
createSphereInVolume(volData, 30.0f, 2);
|
|
||||||
cout << "Creating sphere 5" << std::endl;
|
|
||||||
createSphereInVolume(volData, 20.0f, 1);
|
|
||||||
|
|
||||||
cout << "Creating cubes" << std::endl;
|
|
||||||
createCubeInVolume(volData, Vector3DInt32(minPos, minPos, minPos), Vector3DInt32(midPos-1, midPos-1, midPos-1), 0);
|
|
||||||
createCubeInVolume(volData, Vector3DInt32(midPos+1, midPos+1, minPos), Vector3DInt32(maxPos, maxPos, midPos-1), 0);
|
|
||||||
createCubeInVolume(volData, Vector3DInt32(midPos+1, minPos, midPos+1), Vector3DInt32(maxPos, midPos-1, maxPos), 0);
|
|
||||||
createCubeInVolume(volData, Vector3DInt32(minPos, midPos+1, midPos+1), Vector3DInt32(midPos-1, maxPos, maxPos), 0);
|
|
||||||
|
|
||||||
createCubeInVolume(volData, Vector3DInt32(1, midPos-10, midPos-10), Vector3DInt32(maxPos-1, midPos+10, midPos+10), MaterialDensityPair44::getMaxDensity());
|
|
||||||
createCubeInVolume(volData, Vector3DInt32(midPos-10, 1, midPos-10), Vector3DInt32(midPos+10, maxPos-1, midPos+10), MaterialDensityPair44::getMaxDensity());
|
|
||||||
createCubeInVolume(volData, Vector3DInt32(midPos-10, midPos-10 ,1), Vector3DInt32(midPos+10, midPos+10, maxPos-1), MaterialDensityPair44::getMaxDensity());
|
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
|
|
||||||
OpenGLWidget openGLWidget(0);
|
|
||||||
|
|
||||||
|
|
||||||
openGLWidget.show();
|
|
||||||
|
|
||||||
QSharedPointer<QGLShaderProgram> shader(new QGLShaderProgram);
|
|
||||||
|
|
||||||
if (!shader->addShaderFromSourceFile(QGLShader::Vertex, ":/openglexample.vert"))
|
|
||||||
{
|
{
|
||||||
std::cerr << shader->log().toStdString() << std::endl;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shader->addShaderFromSourceFile(QGLShader::Fragment, ":/openglexample.frag"))
|
protected:
|
||||||
|
void initialize() override
|
||||||
{
|
{
|
||||||
std::cerr << shader->log().toStdString() << std::endl;
|
FilePager<MaterialDensityPair88>* pager = new FilePager<MaterialDensityPair88>(".");
|
||||||
exit(EXIT_FAILURE);
|
PagedVolume<MaterialDensityPair88> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(g_uVolumeSideLength - 1, g_uVolumeSideLength - 1, g_uVolumeSideLength - 1)), pager);
|
||||||
}
|
|
||||||
|
|
||||||
openGLWidget.setShader(shader);
|
//Make our volume contain a sphere in the center.
|
||||||
|
int32_t minPos = 0;
|
||||||
|
int32_t midPos = g_uVolumeSideLength / 2;
|
||||||
|
int32_t maxPos = g_uVolumeSideLength - 1;
|
||||||
|
|
||||||
QTime time;
|
cout << "Creating sphere 1" << std::endl;
|
||||||
time.start();
|
createSphereInVolume(volData, 60.0f, 5);
|
||||||
//openGLWidget.setVolume(&volData);
|
cout << "Creating sphere 2" << std::endl;
|
||||||
cout << endl << "Time taken = " << time.elapsed() / 1000.0f << "s" << endl << endl;
|
createSphereInVolume(volData, 50.0f, 4);
|
||||||
|
cout << "Creating sphere 3" << std::endl;
|
||||||
|
createSphereInVolume(volData, 40.0f, 3);
|
||||||
|
cout << "Creating sphere 4" << std::endl;
|
||||||
|
createSphereInVolume(volData, 30.0f, 2);
|
||||||
|
cout << "Creating sphere 5" << std::endl;
|
||||||
|
createSphereInVolume(volData, 20.0f, 1);
|
||||||
|
|
||||||
const int32_t extractedRegionSize = 32;
|
cout << "Creating cubes" << std::endl;
|
||||||
int meshCounter = 0;
|
createCubeInVolume(volData, Vector3DInt32(minPos, minPos, minPos), Vector3DInt32(midPos - 1, midPos - 1, midPos - 1), 0);
|
||||||
|
createCubeInVolume(volData, Vector3DInt32(midPos + 1, midPos + 1, minPos), Vector3DInt32(maxPos, maxPos, midPos - 1), 0);
|
||||||
|
createCubeInVolume(volData, Vector3DInt32(midPos + 1, minPos, midPos + 1), Vector3DInt32(maxPos, midPos - 1, maxPos), 0);
|
||||||
|
createCubeInVolume(volData, Vector3DInt32(minPos, midPos + 1, midPos + 1), Vector3DInt32(midPos - 1, maxPos, maxPos), 0);
|
||||||
|
|
||||||
for (int32_t z = 0; z < volData.getDepth(); z += extractedRegionSize)
|
createCubeInVolume(volData, Vector3DInt32(1, midPos - 10, midPos - 10), Vector3DInt32(maxPos - 1, midPos + 10, midPos + 10), MaterialDensityPair44::getMaxDensity());
|
||||||
{
|
createCubeInVolume(volData, Vector3DInt32(midPos - 10, 1, midPos - 10), Vector3DInt32(midPos + 10, maxPos - 1, midPos + 10), MaterialDensityPair44::getMaxDensity());
|
||||||
for (int32_t y = 0; y < volData.getHeight(); y += extractedRegionSize)
|
createCubeInVolume(volData, Vector3DInt32(midPos - 10, midPos - 10, 1), Vector3DInt32(midPos + 10, midPos + 10, maxPos - 1), MaterialDensityPair44::getMaxDensity());
|
||||||
|
|
||||||
|
QSharedPointer<QGLShaderProgram> shader(new QGLShaderProgram);
|
||||||
|
|
||||||
|
if (!shader->addShaderFromSourceFile(QGLShader::Vertex, ":/openglexample.vert"))
|
||||||
{
|
{
|
||||||
for (int32_t x = 0; x < volData.getWidth(); x += extractedRegionSize)
|
std::cerr << shader->log().toStdString() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shader->addShaderFromSourceFile(QGLShader::Fragment, ":/openglexample.frag"))
|
||||||
|
{
|
||||||
|
std::cerr << shader->log().toStdString() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
setShader(shader);
|
||||||
|
|
||||||
|
QTime time;
|
||||||
|
time.start();
|
||||||
|
//openGLWidget.setVolume(&volData);
|
||||||
|
cout << endl << "Time taken = " << time.elapsed() / 1000.0f << "s" << endl << endl;
|
||||||
|
|
||||||
|
const int32_t extractedRegionSize = 32;
|
||||||
|
int meshCounter = 0;
|
||||||
|
|
||||||
|
for (int32_t z = 0; z < volData.getDepth(); z += extractedRegionSize)
|
||||||
|
{
|
||||||
|
for (int32_t y = 0; y < volData.getHeight(); y += extractedRegionSize)
|
||||||
{
|
{
|
||||||
// Specify the region to extract based on a starting position and the desired region sze.
|
for (int32_t x = 0; x < volData.getWidth(); x += extractedRegionSize)
|
||||||
PolyVox::Region regToExtract(x, y, z, x + extractedRegionSize, y + extractedRegionSize, z + extractedRegionSize);
|
{
|
||||||
|
// Specify the region to extract based on a starting position and the desired region sze.
|
||||||
|
PolyVox::Region regToExtract(x, y, z, x + extractedRegionSize, y + extractedRegionSize, z + extractedRegionSize);
|
||||||
|
|
||||||
// If you uncomment this line you will be able to see that the volume is rendered as multiple seperate meshes.
|
// If you uncomment this line you will be able to see that the volume is rendered as multiple seperate meshes.
|
||||||
//regToExtract.shrink(1);
|
//regToExtract.shrink(1);
|
||||||
|
|
||||||
// Perform the extraction for this region of the volume
|
// Perform the extraction for this region of the volume
|
||||||
auto mesh = extractMarchingCubesMesh(&volData, regToExtract);
|
auto mesh = extractMarchingCubesMesh(&volData, regToExtract);
|
||||||
|
|
||||||
// The returned mesh needs to be decoded to be appropriate for GPU rendering.
|
// The returned mesh needs to be decoded to be appropriate for GPU rendering.
|
||||||
auto decodedMesh = decodeMesh(mesh);
|
auto decodedMesh = decodeMesh(mesh);
|
||||||
|
|
||||||
// Pass the surface to the OpenGL window. Note that we are also passing an offset in this multi-mesh example. This is because
|
// Pass the surface to the OpenGL window. Note that we are also passing an offset in this multi-mesh example. This is because
|
||||||
// the surface extractors return a mesh with 'local space' positions to reduce storage requirements and precision problems.
|
// the surface extractors return a mesh with 'local space' positions to reduce storage requirements and precision problems.
|
||||||
openGLWidget.addMesh(decodedMesh, decodedMesh.getOffset());
|
addMesh(decodedMesh, decodedMesh.getOffset());
|
||||||
|
|
||||||
meshCounter++;
|
meshCounter++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cout << "Rendering volume as " << meshCounter << " seperate meshes" << endl;
|
||||||
|
|
||||||
|
setViewableRegion(volData.getEnclosingRegion());
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
cout << "Rendering volume as " << meshCounter << " seperate meshes" << endl;
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
//Create and show the Qt OpenGL window
|
||||||
openGLWidget.setViewableRegion(volData.getEnclosingRegion());
|
QApplication app(argc, argv);
|
||||||
|
OpenGLExample openGLWidget(0);
|
||||||
|
openGLWidget.show();
|
||||||
|
|
||||||
|
//Run the message pump.
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
@ -139,48 +139,61 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PagingExample : public OpenGLWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PagingExample(QWidget *parent)
|
||||||
|
:OpenGLWidget(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize() override
|
||||||
|
{
|
||||||
|
PerlinNoisePager* pager = new PerlinNoisePager();
|
||||||
|
PagedVolume<MaterialDensityPair44> volData(PolyVox::Region::MaxRegion(), pager, 64);
|
||||||
|
volData.setMemoryUsageLimit(8 * 1024 * 1024); // 8Mb
|
||||||
|
|
||||||
|
//createSphereInVolume(volData, 30);
|
||||||
|
//createPerlinTerrain(volData);
|
||||||
|
//createPerlinVolumeSlow(volData);
|
||||||
|
std::cout << "Memory usage: " << (volData.calculateSizeInBytes() / 1024.0 / 1024.0) << "MB" << std::endl;
|
||||||
|
//std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl;
|
||||||
|
PolyVox::Region reg(Vector3DInt32(-255, 0, 0), Vector3DInt32(255, 255, 255));
|
||||||
|
std::cout << "Prefetching region: " << reg.getLowerCorner() << " -> " << reg.getUpperCorner() << std::endl;
|
||||||
|
volData.prefetch(reg);
|
||||||
|
std::cout << "Memory usage: " << (volData.calculateSizeInBytes() / 1024.0 / 1024.0) << "MB" << std::endl;
|
||||||
|
//std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl;
|
||||||
|
PolyVox::Region reg2(Vector3DInt32(0, 0, 0), Vector3DInt32(255, 255, 255));
|
||||||
|
std::cout << "Flushing region: " << reg2.getLowerCorner() << " -> " << reg2.getUpperCorner() << std::endl;
|
||||||
|
volData.flush(reg2);
|
||||||
|
std::cout << "Memory usage: " << (volData.calculateSizeInBytes() / 1024.0 / 1024.0) << "MB" << std::endl;
|
||||||
|
//std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl;
|
||||||
|
std::cout << "Flushing entire volume" << std::endl;
|
||||||
|
volData.flushAll();
|
||||||
|
std::cout << "Memory usage: " << (volData.calculateSizeInBytes() / 1024.0 / 1024.0) << "MB" << std::endl;
|
||||||
|
//std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl;
|
||||||
|
|
||||||
|
//Extract the surface
|
||||||
|
auto mesh = extractCubicMesh(&volData, reg2);
|
||||||
|
std::cout << "#vertices: " << mesh.getNoOfVertices() << std::endl;
|
||||||
|
|
||||||
|
auto decodedMesh = decodeMesh(mesh);
|
||||||
|
|
||||||
|
//Pass the surface to the OpenGL window
|
||||||
|
addMesh(decodedMesh);
|
||||||
|
|
||||||
|
setViewableRegion(reg2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
//Create and show the Qt OpenGL window
|
//Create and show the Qt OpenGL window
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
OpenGLWidget openGLWidget(0);
|
PagingExample openGLWidget(0);
|
||||||
openGLWidget.show();
|
openGLWidget.show();
|
||||||
|
|
||||||
PerlinNoisePager* pager = new PerlinNoisePager();
|
|
||||||
PagedVolume<MaterialDensityPair44> volData(PolyVox::Region::MaxRegion(), pager, 64);
|
|
||||||
volData.setMemoryUsageLimit(8 * 1024 * 1024); // 8Mb
|
|
||||||
|
|
||||||
//createSphereInVolume(volData, 30);
|
|
||||||
//createPerlinTerrain(volData);
|
|
||||||
//createPerlinVolumeSlow(volData);
|
|
||||||
std::cout << "Memory usage: " << (volData.calculateSizeInBytes()/1024.0/1024.0) << "MB" << std::endl;
|
|
||||||
//std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl;
|
|
||||||
PolyVox::Region reg(Vector3DInt32(-255,0,0), Vector3DInt32(255,255,255));
|
|
||||||
std::cout << "Prefetching region: " << reg.getLowerCorner() << " -> " << reg.getUpperCorner() << std::endl;
|
|
||||||
volData.prefetch(reg);
|
|
||||||
std::cout << "Memory usage: " << (volData.calculateSizeInBytes()/1024.0/1024.0) << "MB" << std::endl;
|
|
||||||
//std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl;
|
|
||||||
PolyVox::Region reg2(Vector3DInt32(0,0,0), Vector3DInt32(255,255,255));
|
|
||||||
std::cout << "Flushing region: " << reg2.getLowerCorner() << " -> " << reg2.getUpperCorner() << std::endl;
|
|
||||||
volData.flush(reg2);
|
|
||||||
std::cout << "Memory usage: " << (volData.calculateSizeInBytes()/1024.0/1024.0) << "MB" << std::endl;
|
|
||||||
//std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl;
|
|
||||||
std::cout << "Flushing entire volume" << std::endl;
|
|
||||||
volData.flushAll();
|
|
||||||
std::cout << "Memory usage: " << (volData.calculateSizeInBytes()/1024.0/1024.0) << "MB" << std::endl;
|
|
||||||
//std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl;
|
|
||||||
|
|
||||||
//Extract the surface
|
|
||||||
auto mesh = extractCubicMesh(&volData, reg2);
|
|
||||||
std::cout << "#vertices: " << mesh.getNoOfVertices() << std::endl;
|
|
||||||
|
|
||||||
auto decodedMesh = decodeMesh(mesh);
|
|
||||||
|
|
||||||
//Pass the surface to the OpenGL window
|
|
||||||
openGLWidget.addMesh(decodedMesh);
|
|
||||||
|
|
||||||
openGLWidget.setViewableRegion(reg2);
|
|
||||||
|
|
||||||
//Run the message pump.
|
//Run the message pump.
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
@ -68,43 +68,56 @@ void createSphereInVolume(PagedVolume<uint8_t>& volData, float fRadius)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SmoothLODExample : public OpenGLWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SmoothLODExample(QWidget *parent)
|
||||||
|
:OpenGLWidget(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initialize() override
|
||||||
|
{
|
||||||
|
//Create an empty volume and then place a sphere in it
|
||||||
|
PagedVolume<uint8_t> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63)));
|
||||||
|
createSphereInVolume(volData, 28);
|
||||||
|
|
||||||
|
//Smooth the data - should reimplement this using LowPassFilter
|
||||||
|
//smoothRegion<PagedVolume, Density8>(volData, volData.getEnclosingRegion());
|
||||||
|
//smoothRegion<PagedVolume, Density8>(volData, volData.getEnclosingRegion());
|
||||||
|
//smoothRegion<PagedVolume, Density8>(volData, volData.getEnclosingRegion());
|
||||||
|
|
||||||
|
RawVolume<uint8_t> volDataLowLOD(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(15, 31, 31)));
|
||||||
|
|
||||||
|
VolumeResampler< PagedVolume<uint8_t>, RawVolume<uint8_t> > volumeResampler(&volData, PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(31, 63, 63)), &volDataLowLOD, volDataLowLOD.getEnclosingRegion());
|
||||||
|
volumeResampler.execute();
|
||||||
|
|
||||||
|
//Extract the surface
|
||||||
|
auto meshLowLOD = extractMarchingCubesMesh(&volDataLowLOD, volDataLowLOD.getEnclosingRegion());
|
||||||
|
// The returned mesh needs to be decoded to be appropriate for GPU rendering.
|
||||||
|
auto decodedMeshLowLOD = decodeMesh(meshLowLOD);
|
||||||
|
|
||||||
|
//Extract the surface
|
||||||
|
auto meshHighLOD = extractMarchingCubesMesh(&volData, PolyVox::Region(Vector3DInt32(30, 0, 0), Vector3DInt32(63, 63, 63)));
|
||||||
|
// The returned mesh needs to be decoded to be appropriate for GPU rendering.
|
||||||
|
auto decodedMeshHighLOD = decodeMesh(meshHighLOD);
|
||||||
|
|
||||||
|
//Pass the surface to the OpenGL window
|
||||||
|
addMesh(decodedMeshHighLOD, Vector3DInt32(30, 0, 0));
|
||||||
|
addMesh(decodedMeshLowLOD, Vector3DInt32(0, 0, 0), 63.0f / 31.0f);
|
||||||
|
|
||||||
|
setViewableRegion(volData.getEnclosingRegion());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
//Create and show the Qt OpenGL window
|
//Create and show the Qt OpenGL window
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
OpenGLWidget openGLWidget(0);
|
SmoothLODExample openGLWidget(0);
|
||||||
openGLWidget.show();
|
openGLWidget.show();
|
||||||
|
|
||||||
//Create an empty volume and then place a sphere in it
|
|
||||||
PagedVolume<uint8_t> volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63)));
|
|
||||||
createSphereInVolume(volData, 28);
|
|
||||||
|
|
||||||
//Smooth the data - should reimplement this using LowPassFilter
|
|
||||||
//smoothRegion<PagedVolume, Density8>(volData, volData.getEnclosingRegion());
|
|
||||||
//smoothRegion<PagedVolume, Density8>(volData, volData.getEnclosingRegion());
|
|
||||||
//smoothRegion<PagedVolume, Density8>(volData, volData.getEnclosingRegion());
|
|
||||||
|
|
||||||
RawVolume<uint8_t> volDataLowLOD(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(15, 31, 31)));
|
|
||||||
|
|
||||||
VolumeResampler< PagedVolume<uint8_t>, RawVolume<uint8_t> > volumeResampler(&volData, PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(31, 63, 63)), &volDataLowLOD, volDataLowLOD.getEnclosingRegion());
|
|
||||||
volumeResampler.execute();
|
|
||||||
|
|
||||||
//Extract the surface
|
|
||||||
auto meshLowLOD = extractMarchingCubesMesh(&volDataLowLOD, volDataLowLOD.getEnclosingRegion());
|
|
||||||
// The returned mesh needs to be decoded to be appropriate for GPU rendering.
|
|
||||||
auto decodedMeshLowLOD = decodeMesh(meshLowLOD);
|
|
||||||
|
|
||||||
//Extract the surface
|
|
||||||
auto meshHighLOD = extractMarchingCubesMesh(&volData, PolyVox::Region(Vector3DInt32(30, 0, 0), Vector3DInt32(63, 63, 63)));
|
|
||||||
// The returned mesh needs to be decoded to be appropriate for GPU rendering.
|
|
||||||
auto decodedMeshHighLOD = decodeMesh(meshHighLOD);
|
|
||||||
|
|
||||||
//Pass the surface to the OpenGL window
|
|
||||||
openGLWidget.addMesh(decodedMeshHighLOD, Vector3DInt32(30, 0, 0));
|
|
||||||
openGLWidget.addMesh(decodedMeshLowLOD, Vector3DInt32(0, 0, 0), 63.0f / 31.0f);
|
|
||||||
|
|
||||||
openGLWidget.setViewableRegion(volData.getEnclosingRegion());
|
|
||||||
|
|
||||||
//Run the message pump.
|
//Run the message pump.
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user