diff options
author | Andreas Grois <andi@grois.info> | 2018-03-10 15:43:36 +0100 |
---|---|---|
committer | Andreas Grois <andi@grois.info> | 2018-03-10 15:43:36 +0100 |
commit | 704ecb6bbabe4a73c45bb6ae2433754bb8260bde (patch) | |
tree | eb0f4a46c4cca4ff3a77ad387a8b1e28e4f4a4ff | |
parent | a0afe4bf8c011222b85c481ae209b09f75189858 (diff) |
Gamma correction for output
-rw-r--r-- | BuddhaTest/include/Helpers.h | 2 | ||||
-rw-r--r-- | BuddhaTest/src/BuddhaTest.cpp | 54 | ||||
-rw-r--r-- | BuddhaTest/src/Helpers.cpp | 12 |
3 files changed, 59 insertions, 9 deletions
diff --git a/BuddhaTest/include/Helpers.h b/BuddhaTest/include/Helpers.h index a4bf15d..e4b7ffd 100644 --- a/BuddhaTest/include/Helpers.h +++ b/BuddhaTest/include/Helpers.h @@ -9,7 +9,7 @@ namespace Helpers GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path);
GLuint LoadComputeShader(const char * compute_file_path, unsigned int localSizeX, unsigned int localSizeY, unsigned int localSizeZ);
- void WriteOutputPNG(const std::vector<uint32_t>& data, unsigned int width, unsigned int bufferHeight);
+ void WriteOutputPNG(const std::vector<uint32_t>& data, unsigned int width, unsigned int bufferHeight, double gamma);
/** Wraps around a C file descriptor. Libpng could be taught to use C++ streams, but I'm too lazy and rather wrap this ugly thing up, so it gets cleaned... */
class ScopedCFileDescriptor
diff --git a/BuddhaTest/src/BuddhaTest.cpp b/BuddhaTest/src/BuddhaTest.cpp index f23fc5d..9ac6ae3 100644 --- a/BuddhaTest/src/BuddhaTest.cpp +++ b/BuddhaTest/src/BuddhaTest.cpp @@ -11,8 +11,8 @@ void error_callback(int error, const char* description) int main()
{
- unsigned int bufferWidth = 1600;
- unsigned int bufferHeight = 450;
+ unsigned int bufferWidth = 1920;
+ unsigned int bufferHeight = 540;
unsigned int windowWidth = 1600;
unsigned int windowHeight = 900;
@@ -29,6 +29,8 @@ int main() unsigned int globalWorkGroupSizeY = 1;
unsigned int globalWorkGroupSizeZ = 1;
+ double pngGamma = 1.0;
+
GLFWwindow* window;
/* Initialize the library */
@@ -54,6 +56,49 @@ int main() glfwMakeContextCurrent(window);
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
+ //we have a context. Let's check if input is sane.
+ //calcualte buffer size, and make sure it's allowed by the driver.
+ const unsigned int pixelCount{(bufferWidth * bufferHeight)*3}; //*3 -> RGB
+ const unsigned int integerCount = pixelCount + 2; //first two elements in buffer: width/height.
+ {
+ int maxSSBOSize;
+ glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE,&maxSSBOSize);
+ if(integerCount * 4 > maxSSBOSize)
+ {
+ std::cout << "Requested buffer size larger than maximum allowed by graphics driver. Max pixel number: " << maxSSBOSize/12 - 2 << std::endl;
+ glfwTerminate();
+ return 0;
+ }
+ 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;
+ glfwTerminate();
+ return 0;
+ }
+ 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;
+ glfwTerminate();
+ return 0;
+ }
+ 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;
+ glfwTerminate();
+ return 0;
+ }
+ }
+
+
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
@@ -75,8 +120,6 @@ int main() glGenBuffers(1, &drawBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, drawBuffer);
{
- const unsigned int pixelCount{(bufferWidth * bufferHeight)*3}; //*3 -> RGB
- const unsigned int integerCount = pixelCount + 2; //first two elements in buffer: width/height.
std::vector<uint32_t> initializeBuffer(integerCount,0);
initializeBuffer[0] = bufferWidth;
initializeBuffer[1] = bufferHeight;
@@ -138,10 +181,9 @@ int main() glMemoryBarrier(GL_ALL_BARRIER_BITS);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, drawBuffer);
{
- const unsigned int pixelCount{(bufferWidth * bufferHeight)*3}; //*3 -> RGB
std::vector<uint32_t> readBackBuffer(pixelCount);
glGetBufferSubData(GL_SHADER_STORAGE_BUFFER,4*2,4 * pixelCount,readBackBuffer.data()); //offset of 2*4, that's the dimension integers.
- Helpers::WriteOutputPNG(readBackBuffer,bufferWidth,bufferHeight);
+ Helpers::WriteOutputPNG(readBackBuffer,bufferWidth,bufferHeight, pngGamma);
}
//a bit of cleanup
diff --git a/BuddhaTest/src/Helpers.cpp b/BuddhaTest/src/Helpers.cpp index 881d01f..bde6b8a 100644 --- a/BuddhaTest/src/Helpers.cpp +++ b/BuddhaTest/src/Helpers.cpp @@ -5,6 +5,7 @@ #include <iostream>
#include <vector>
#include <png.h>
+#include <cmath>
namespace Helpers
{
@@ -154,7 +155,7 @@ namespace Helpers return ProgramID;
}
- void WriteOutputPNG(const std::vector<uint32_t>& data, unsigned int width, unsigned int bufferHeight)
+ void WriteOutputPNG(const std::vector<uint32_t>& data, unsigned int width, unsigned int bufferHeight, double gamma)
{
std::vector<png_byte> pngData(3*width*2*bufferHeight);
std::vector<png_byte *> rows{2*bufferHeight};
@@ -170,7 +171,14 @@ namespace Helpers }
for(unsigned int i = 0; i < data.size();++i)
{
- pngData[data.size() + i] = (255*data[i] + (maxValue/2))/maxValue;
+ if(fabs(gamma - 1.0) > 0.0001)
+ {
+ pngData[data.size() + i] = 255.0 * pow(static_cast<double>(data[i])/static_cast<double>(maxValue),gamma);
+ }
+ else
+ {
+ pngData[data.size() + i] = (255*data[i] + (maxValue/2))/maxValue;
+ }
}
for(int i = 0; i < bufferHeight;++i)
{
|