From 565aa21799a592558612e884acb36917fa46fadb Mon Sep 17 00:00:00 2001 From: David Williams Date: Fri, 20 Feb 2015 11:23:17 +0100 Subject: [PATCH] Refactoring example code. --- examples/Basic/main.cpp | 23 +++-- examples/DecodeOnGPU/main.cpp | 87 +++++++++--------- examples/OpenGL/main.cpp | 160 ++++++++++++++++++---------------- examples/Paging/main.cpp | 85 ++++++++++-------- examples/SmoothLOD/main.cpp | 75 +++++++++------- 5 files changed, 232 insertions(+), 198 deletions(-) diff --git a/examples/Basic/main.cpp b/examples/Basic/main.cpp index f8207e4c..ea93bb68 100644 --- a/examples/Basic/main.cpp +++ b/examples/Basic/main.cpp @@ -72,27 +72,26 @@ public: BasicExample(QWidget *parent) :OpenGLWidget(parent) { - } protected: void initialize() override { - //Create an empty volume and then place a sphere in it - PagedVolume volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63))); - createSphereInVolume(volData, 30); + //Create an empty volume and then place a sphere in it + PagedVolume volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63))); + 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. - auto mesh = extractCubicMesh(&volData, volData.getEnclosingRegion()); - //auto mesh = extractMarchingCubesMesh(&volData, volData.getEnclosingRegion()); + // 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 = 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 - // 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); + // 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. + auto decodedMesh = decodeMesh(mesh); - //Pass the surface to the OpenGL window + //Pass the surface to the OpenGL window addMesh(decodedMesh); - //openGLWidget.addMesh(mesh2); + //openGLWidget.addMesh(mesh2); setViewableRegion(volData.getEnclosingRegion()); } }; diff --git a/examples/DecodeOnGPU/main.cpp b/examples/DecodeOnGPU/main.cpp index 0ce9a2ac..eff3a5a7 100644 --- a/examples/DecodeOnGPU/main.cpp +++ b/examples/DecodeOnGPU/main.cpp @@ -72,7 +72,6 @@ public: DecodeOnGPUExample(QWidget *parent) :OpenGLWidget(parent) { - } protected: @@ -114,60 +113,60 @@ protected: } private: -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 - const auto& vecIndices = surfaceMesh.getIndices(); - const auto& vecVertices = surfaceMesh.getVertices(); + 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 + const auto& vecIndices = surfaceMesh.getIndices(); + const auto& vecVertices = surfaceMesh.getVertices(); - // 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. - OpenGLMeshData meshData; + // 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. + OpenGLMeshData meshData; - // Create the VAO for the mesh - glGenVertexArrays(1, &(meshData.vertexArrayObject)); - glBindVertexArray(meshData.vertexArrayObject); + // Create the VAO for the mesh + glGenVertexArrays(1, &(meshData.vertexArrayObject)); + glBindVertexArray(meshData.vertexArrayObject); - // The GL_ARRAY_BUFFER will contain the list of vertex positions - glGenBuffers(1, &(meshData.vertexBuffer)); - glBindBuffer(GL_ARRAY_BUFFER, meshData.vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof(MarchingCubesVertex< uint8_t >), vecVertices.data(), GL_STATIC_DRAW); + // The GL_ARRAY_BUFFER will contain the list of vertex positions + glGenBuffers(1, &(meshData.vertexBuffer)); + glBindBuffer(GL_ARRAY_BUFFER, meshData.vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, vecVertices.size() * sizeof(MarchingCubesVertex< uint8_t >), vecVertices.data(), GL_STATIC_DRAW); - // and GL_ELEMENT_ARRAY_BUFFER will contain the indices - glGenBuffers(1, &(meshData.indexBuffer)); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshData.indexBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, vecIndices.size() * sizeof(uint32_t), vecIndices.data(), GL_STATIC_DRAW); + // and GL_ELEMENT_ARRAY_BUFFER will contain the indices + glGenBuffers(1, &(meshData.indexBuffer)); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshData.indexBuffer); + 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 - 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) + // 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 + 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 - // 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 - // chosen surface extractor generates normals and can skip uploading them if not. - glEnableVertexAttribArray(1); // Attrib '1' is the vertex normals. - glVertexAttribIPointer(1, 1, GL_UNSIGNED_SHORT, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, encodedNormal))); + // 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 + // 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. + glEnableVertexAttribArray(1); // Attrib '1' is the vertex normals. + 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 - // 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' - 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))); + // 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. + 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) + glVertexAttribIPointer(2, size, GL_UNSIGNED_BYTE, sizeof(MarchingCubesVertex< uint8_t >), (GLvoid*)(offsetof(MarchingCubesVertex< uint8_t >, data))); - // We're done uploading and can now unbind. - glBindVertexArray(0); + // We're done uploading and can now unbind. + glBindVertexArray(0); - // A few additional properties can be copied across for use during rendering. - meshData.noOfIndices = vecIndices.size(); - meshData.translation = QVector3D(translation.getX(), translation.getY(), translation.getZ()); - meshData.scale = scale; + // A few additional properties can be copied across for use during rendering. + meshData.noOfIndices = vecIndices.size(); + meshData.translation = QVector3D(translation.getX(), translation.getY(), translation.getZ()); + meshData.scale = scale; - // 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; + // 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; - return meshData; -} + return meshData; + } }; int main(int argc, char *argv[]) diff --git a/examples/OpenGL/main.cpp b/examples/OpenGL/main.cpp index 6e94c5b8..b9ee73a5 100644 --- a/examples/OpenGL/main.cpp +++ b/examples/OpenGL/main.cpp @@ -47,100 +47,110 @@ using namespace std; const int32_t g_uVolumeSideLength = 128; -int main(int argc, char *argv[]) +class OpenGLExample : public OpenGLWidget { - FilePager* pager = new FilePager("."); - PagedVolume volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(g_uVolumeSideLength - 1, g_uVolumeSideLength - 1, g_uVolumeSideLength - 1)), pager); - - //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 shader(new QGLShaderProgram); - - if (!shader->addShaderFromSourceFile(QGLShader::Vertex, ":/openglexample.vert")) +public: + OpenGLExample(QWidget *parent) + :OpenGLWidget(parent) { - 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; - exit(EXIT_FAILURE); - } + FilePager* pager = new FilePager("."); + PagedVolume 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; - time.start(); - //openGLWidget.setVolume(&volData); - cout << endl << "Time taken = " << time.elapsed() / 1000.0f << "s" << endl << endl; + 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); - const int32_t extractedRegionSize = 32; - int meshCounter = 0; + 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); - for (int32_t z = 0; z < volData.getDepth(); z += extractedRegionSize) - { - for (int32_t y = 0; y < volData.getHeight(); y += 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()); + createCubeInVolume(volData, Vector3DInt32(midPos - 10, midPos - 10, 1), Vector3DInt32(midPos + 10, midPos + 10, maxPos - 1), MaterialDensityPair44::getMaxDensity()); + + QSharedPointer 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. - PolyVox::Region regToExtract(x, y, z, x + extractedRegionSize, y + extractedRegionSize, z + extractedRegionSize); + for (int32_t x = 0; x < volData.getWidth(); x += 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. - //regToExtract.shrink(1); + // If you uncomment this line you will be able to see that the volume is rendered as multiple seperate meshes. + //regToExtract.shrink(1); - // Perform the extraction for this region of the volume - auto mesh = extractMarchingCubesMesh(&volData, regToExtract); + // Perform the extraction for this region of the volume + auto mesh = extractMarchingCubesMesh(&volData, regToExtract); - // The returned mesh needs to be decoded to be appropriate for GPU rendering. - auto decodedMesh = decodeMesh(mesh); + // The returned mesh needs to be decoded to be appropriate for GPU rendering. + 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 - // the surface extractors return a mesh with 'local space' positions to reduce storage requirements and precision problems. - openGLWidget.addMesh(decodedMesh, decodedMesh.getOffset()); + // 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. + 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; - - - openGLWidget.setViewableRegion(volData.getEnclosingRegion()); - +int main(int argc, char *argv[]) +{ + //Create and show the Qt OpenGL window + QApplication app(argc, argv); + OpenGLExample openGLWidget(0); + openGLWidget.show(); + //Run the message pump. return app.exec(); -} +} diff --git a/examples/Paging/main.cpp b/examples/Paging/main.cpp index 09b325d8..6b02e5e0 100644 --- a/examples/Paging/main.cpp +++ b/examples/Paging/main.cpp @@ -139,48 +139,61 @@ public: } }; +class PagingExample : public OpenGLWidget +{ +public: + PagingExample(QWidget *parent) + :OpenGLWidget(parent) + { + } + +protected: + void initialize() override + { + PerlinNoisePager* pager = new PerlinNoisePager(); + PagedVolume 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[]) { //Create and show the Qt OpenGL window QApplication app(argc, argv); - OpenGLWidget openGLWidget(0); + PagingExample openGLWidget(0); openGLWidget.show(); - PerlinNoisePager* pager = new PerlinNoisePager(); - PagedVolume 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. return app.exec(); } diff --git a/examples/SmoothLOD/main.cpp b/examples/SmoothLOD/main.cpp index b8c56f08..cc255d24 100644 --- a/examples/SmoothLOD/main.cpp +++ b/examples/SmoothLOD/main.cpp @@ -68,43 +68,56 @@ void createSphereInVolume(PagedVolume& 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 volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63))); + createSphereInVolume(volData, 28); + + //Smooth the data - should reimplement this using LowPassFilter + //smoothRegion(volData, volData.getEnclosingRegion()); + //smoothRegion(volData, volData.getEnclosingRegion()); + //smoothRegion(volData, volData.getEnclosingRegion()); + + RawVolume volDataLowLOD(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(15, 31, 31))); + + VolumeResampler< PagedVolume, RawVolume > 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[]) { //Create and show the Qt OpenGL window QApplication app(argc, argv); - OpenGLWidget openGLWidget(0); + SmoothLODExample openGLWidget(0); openGLWidget.show(); - //Create an empty volume and then place a sphere in it - PagedVolume volData(PolyVox::Region(Vector3DInt32(0, 0, 0), Vector3DInt32(63, 63, 63))); - createSphereInVolume(volData, 28); - - //Smooth the data - should reimplement this using LowPassFilter - //smoothRegion(volData, volData.getEnclosingRegion()); - //smoothRegion(volData, volData.getEnclosingRegion()); - //smoothRegion(volData, volData.getEnclosingRegion()); - - RawVolume volDataLowLOD(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(15, 31, 31))); - - VolumeResampler< PagedVolume, RawVolume > 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. return app.exec(); }