From 5127d05dfdc877b0fc06e6ec228cfef09b98539a Mon Sep 17 00:00:00 2001 From: Andreas Grois Date: Sat, 10 Mar 2018 18:48:52 +0100 Subject: Add command line parsing --- BuddhaTest/src/Helpers.cpp | 154 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 2 deletions(-) (limited to 'BuddhaTest/src/Helpers.cpp') diff --git a/BuddhaTest/src/Helpers.cpp b/BuddhaTest/src/Helpers.cpp index eacaf5d..889db7e 100644 --- a/BuddhaTest/src/Helpers.cpp +++ b/BuddhaTest/src/Helpers.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include namespace Helpers { @@ -155,7 +157,7 @@ namespace Helpers return ProgramID; } - void WriteOutputPNG(const std::vector& data, unsigned int width, unsigned int bufferHeight, double gamma, double colorScale) + void WriteOutputPNG(const std::string &path, const std::vector& data, unsigned int width, unsigned int bufferHeight, double gamma, double colorScale) { std::vector pngData(3*width*2*bufferHeight); std::vector rows{2*bufferHeight}; @@ -188,7 +190,7 @@ namespace Helpers } } - ScopedCFileDescriptor fd("image.png", "wb"); + ScopedCFileDescriptor fd(path.c_str(), "wb"); if(!fd.IsValid()) { std::cout << "Failed to open image.png for writing." << std::endl; @@ -243,4 +245,152 @@ namespace Helpers return Descriptor != nullptr; } + bool RenderSettings::CheckValidity() + { + if(imageHeight%2 != 0) + { + std::cout << "Image height has to be an even number." << std::endl; + return false; + } + const unsigned int bufferHeight = imageHeight/2; + const unsigned int pixelCount{(imageWidth * imageHeight/2)*3}; //*3 -> RGB + int maxSSBOSize; + glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE,&maxSSBOSize); + if(pixelCount * 4 > maxSSBOSize) + { + std::cout << "Requested buffer size larger than maximum allowed by graphics driver. Max pixel number: " << maxSSBOSize/12 << std::endl; + return false; + } + int WorkGroupSizeLimitX, WorkGroupSizeLimitY, WorkGroupSizeLimitZ; + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT,0,&WorkGroupSizeLimitX); + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT,1,&WorkGroupSizeLimitY); + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT,2,&WorkGroupSizeLimitZ); + if(globalWorkGroupSizeX > WorkGroupSizeLimitX || + globalWorkGroupSizeY > WorkGroupSizeLimitY || + globalWorkGroupSizeZ > WorkGroupSizeLimitZ) + { + std::cout << "Requested global work group size exceeds maximum dimension. Limits: " << WorkGroupSizeLimitX << ", " << WorkGroupSizeLimitY << ", " << WorkGroupSizeLimitZ << std::endl; + return false; + } + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE,0,&WorkGroupSizeLimitX); + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE,1,&WorkGroupSizeLimitY); + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE,2,&WorkGroupSizeLimitZ); + if(localWorkgroupSizeX > WorkGroupSizeLimitX || + localWorkgroupSizeY > WorkGroupSizeLimitY || + localWorkgroupSizeZ > WorkGroupSizeLimitZ) + { + std::cout << "Requested local work group size exceeds maximum dimension. Limits: " << WorkGroupSizeLimitX << ", " << WorkGroupSizeLimitY << ", " << WorkGroupSizeLimitZ << std::endl; + return false; + } + int maxInvocations; + glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS,&maxInvocations); + if(localWorkgroupSizeX*localWorkgroupSizeY*localWorkgroupSizeZ > maxInvocations) + { + std::cout << "Requested local work group size exceeds maximum total count (Product of x*y*z dimensions). Limit: " << maxInvocations << std::endl; + return false; + } + return true; + } + + bool RenderSettings::ParseCommandLine(int argc, char *argv[]) + { + struct SettingsPointer + { + public: + SettingsPointer(unsigned int * ptr) : intPtr(ptr), dblPtr(nullptr), stringPtr(nullptr) {} + SettingsPointer(double * ptr) : intPtr(nullptr), dblPtr(ptr), stringPtr(nullptr) {} + SettingsPointer(std::string * ptr) : intPtr(nullptr), dblPtr(nullptr), stringPtr(ptr) {} + unsigned int * GetIntPtr() const { return intPtr; } + double * GetDblPtr() const { return dblPtr;} + std::string * GetStringPtr() const { return stringPtr;} + private: + unsigned int * intPtr = nullptr; + double * dblPtr = nullptr; + std::string * stringPtr = nullptr; + }; + std::unordered_map commandMap{ + {"--imageWidth",&imageWidth}, + {"--imageHeight",&imageHeight}, + {"--windowWidth",&windowWidth}, + {"--windowHeight",&windowHeight}, + {"--orbitLengthRed",&orbitLengthRed}, + {"--orbitLengthGreen",&orbitLengthGreen}, + {"--orbitLengthBlue",&orbitLengthBlue}, + {"--localWorkgroupSizeX", &localWorkgroupSizeX}, + {"--localWorkgroupSizeY", &localWorkgroupSizeY}, + {"--localWorkgroupSizeZ", &localWorkgroupSizeZ}, + {"--globalWorkgroupSizeX", &globalWorkGroupSizeX}, + {"--globalWorkgroupSizeY", &globalWorkGroupSizeY}, + {"--globalWorkgroupSizeZ", &globalWorkGroupSizeZ}, + {"--imageGamma",&pngGamma}, + {"--imageColorScale",&pngColorScale}, + {"--output", &pngFilename} + }; + + for(int i=1; i < argc;++i) + { + std::string argAsString(argv[i]); + if(argAsString == "--help") //help is a special case. + { + std::cout << "Draws a buddhabrot and iterates until the user closes the window. If a --output filename is given, a png file will afterwards be written there." <second; + if(auto intProp = ptr.GetIntPtr()) + { + *intProp = std::stoi(valueAsString); + } + else if(auto dblProp = ptr.GetDblPtr()) + { + *dblProp = std::stod(valueAsString); + } + else if(auto strPtr = ptr.GetStringPtr()) + { + *strPtr = valueAsString; + } + else + { + std::cerr << "Something went horribly wrong with command line parsing. This is a bug." << std::endl; + return false; + } + } + + return true; + } + } -- cgit v1.2.3