diff options
-rw-r--r-- | BuddhaTest/CMakeLists.txt | 8 | ||||
-rw-r--r-- | BuddhaTest/include/Helpers.h | 5 | ||||
-rw-r--r-- | BuddhaTest/src/BuddhaTest.cpp | 13 | ||||
-rw-r--r-- | BuddhaTest/src/Helpers.cpp | 64 |
4 files changed, 84 insertions, 6 deletions
diff --git a/BuddhaTest/CMakeLists.txt b/BuddhaTest/CMakeLists.txt index d58d00a..be7d4d6 100644 --- a/BuddhaTest/CMakeLists.txt +++ b/BuddhaTest/CMakeLists.txt @@ -10,6 +10,8 @@ configure_file("Shaders/BuddhaCompute.glsl" ${CMAKE_CURRENT_BINARY_DIR}/Shaders/ configure_file("Shaders/BuddhaVertex.glsl" ${CMAKE_CURRENT_BINARY_DIR}/Shaders/BuddhaVertex.glsl)
find_package(OpenGL REQUIRED)
-target_include_directories(BuddhaTest PRIVATE "include" ${OPENGL_INCLUDE_DIR})
-target_link_libraries(BuddhaTest glfw ${OPENGL_gl_LIBRARY})
-# on Linux we need to link against libdl. Maybe add id here?
\ No newline at end of file +find_package(PNG REQUIRED)
+target_include_directories(BuddhaTest PRIVATE "include" ${OPENGL_INCLUDE_DIR} ${PNG_INCLUDE_DIRS})
+target_link_libraries(BuddhaTest glfw ${OPENGL_gl_LIBRARY} ${PNG_LIBRARIES})
+add_definitions(${PNG_DEFINITIONS})
+# on Linux we need to link against libdl. Maybe add id here?
diff --git a/BuddhaTest/include/Helpers.h b/BuddhaTest/include/Helpers.h index 05ad151..c24e2c7 100644 --- a/BuddhaTest/include/Helpers.h +++ b/BuddhaTest/include/Helpers.h @@ -1,9 +1,12 @@ #pragma once
#include <glad/glad.h>
#include <GLFW/glfw3.h>
+#include <vector>
namespace Helpers
{
GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path);
GLuint LoadComputeShader(const char * compute_file_path);
-}
\ No newline at end of file +
+ void WriteOutputPNG(const std::vector<uint32_t>& data, unsigned int width, unsigned int height);
+}
diff --git a/BuddhaTest/src/BuddhaTest.cpp b/BuddhaTest/src/BuddhaTest.cpp index 57edc14..d1b6a66 100644 --- a/BuddhaTest/src/BuddhaTest.cpp +++ b/BuddhaTest/src/BuddhaTest.cpp @@ -14,8 +14,8 @@ int main() unsigned int bufferWidth = 1600;
unsigned int bufferHeight = 900;
- unsigned int orbitLengthRed = 100;
- unsigned int orbitLengthGreen = 10;
+ unsigned int orbitLengthRed = 10;
+ unsigned int orbitLengthGreen = 100;
unsigned int orbitLengthBlue = 1000;
GLFWwindow* window;
@@ -124,6 +124,15 @@ int main() glfwPollEvents();
}
+ 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);
+ }
+
glfwTerminate();
return 0;
}
diff --git a/BuddhaTest/src/Helpers.cpp b/BuddhaTest/src/Helpers.cpp index e9caba9..69dafa3 100644 --- a/BuddhaTest/src/Helpers.cpp +++ b/BuddhaTest/src/Helpers.cpp @@ -3,6 +3,7 @@ #include <fstream>
#include <sstream>
#include <vector>
+#include <png.h>
namespace Helpers
{
@@ -146,4 +147,67 @@ namespace Helpers glDeleteShader(ComputeShaderID);
return ProgramID;
}
+ void WriteOutputPNG(const std::vector<uint32_t>& data, unsigned int width, unsigned int height)
+ {
+ png_byte ** row_pointers = static_cast<png_byte **>(calloc(height,sizeof(void *)));
+ for(int i = 0; i < height ; ++i)
+ {
+ row_pointers[i] = static_cast<png_byte *>(calloc(3*width,sizeof(png_byte)));
+ }
+
+ uint32_t maxValue{UINT32_C(0)};
+ for(unsigned int i = 0; i < data.size();++i)
+ {
+ maxValue = std::max(maxValue,data[i]);
+ }
+ for(unsigned int i = 0; i < data.size();++i)
+ {
+ unsigned int row = (i)/(3*width);
+ unsigned int col = i - 3*row*width;
+ row_pointers[row][col] = (255*data[i] + (maxValue/2))/maxValue;
+ }
+
+ //beware, this is going to be ugly C syntax, but well, libpng...
+ FILE * fp = fopen("image.png", "wb");
+ if(!fp)
+ {
+ return;
+ }
+ png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
+ if(!png_ptr)
+ {
+ fclose(fp);
+ return;
+ }
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if(!info_ptr)
+ {
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ fclose(fp);
+ return;
+ }
+ if(setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ fclose(fp);
+ return;
+ }
+ png_init_io(png_ptr, fp);
+ png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+ png_write_info(png_ptr, info_ptr);
+ //header written.
+
+ png_write_image(png_ptr, row_pointers);
+
+ png_write_end(png_ptr, info_ptr);
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ for(int i = 0; i < height ; ++i)
+ {
+ free(row_pointers[i]);
+ }
+
+ free(row_pointers);
+ }
}
|