penrose

program for generating penrose tilings.
Log | Files | Refs | README | LICENSE

commit 1bfd507a21918e7a38218c97c47be528fd9712ed
parent 3e9f96ebcd5b958ce2fb6d4010591764f9733d7c
Author: mpizzzle <m@michaelpercival.xyz>
Date:   Sat, 14 Nov 2020 20:05:25 +0000

successfully writing png image (almost, weird artifact in image)

Diffstat:
Mpenrose.cpp | 30+++++++++++++++---------------
Mpng_writer.cpp | 45++++++++++++++++++++++++++++++++++++---------
Mpng_writer.hpp | 4+++-
3 files changed, 54 insertions(+), 25 deletions(-)

diff --git a/penrose.cpp b/penrose.cpp @@ -14,13 +14,15 @@ #include <vector> #include <random> +#include <png.h> + #include "shader.hpp" #include "png_writer.hpp" static const uint32_t window_w = 1920 * 4; static const uint32_t window_h = 1080 * 4; static const uint32_t depth = 10; //recursion depth - static const bool p2 = true; //tiling type (p2, p3) +static const bool p2 = false; //tiling type (p2, p3) static const float line_w = 2.0f; //line width static const float phi = 1.0 / ((1.0 + sqrt(5.0)) / 2); @@ -180,23 +182,21 @@ int main() { glfwPollEvents(); } - //int width, height; - //glfwGetFramebufferSize(window, &width, &height); - //std::cout << "width: "<< width << " height: " << height << std::endl; - //GLsizei nrChannels = 4; - //GLsizei stride = nrChannels * width; - //stride += (stride % 4) ? (4 - stride % 4) : 0; - //GLsizei bufferSize = stride * height; - //std::vector<char> buffer(bufferSize); - //glPixelStorei(GL_PACK_ALIGNMENT, 4); - //glReadBuffer(GL_FRONT); - //glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data()); + glPixelStorei(GL_PACK_ALIGNMENT, 4); + glReadBuffer(GL_FRONT); + + int frame_w, frame_h; + glfwGetFramebufferSize(window, &frame_w, &frame_h); - //stbi_flip_vertically_on_write(true); - //stbi_write_png(filepath, width, height, nrChannels, buffer.data(), stride); + png_bytep* row_pointers = (png_bytep*) malloc(sizeof(unsigned char) * frame_h); + + for (unsigned int yy = 0; yy < frame_h; ++yy) { + row_pointers[yy] = (png_byte*) malloc((4 * sizeof(png_byte)) * frame_w); + glReadPixels(0, yy, frame_w, 1, GL_RGBA, GL_UNSIGNED_BYTE, row_pointers[yy]); + } - //PngWriter::write_png_file("test.png", window_w, window_h, nullptr); + PngWriter::write_png_file("test.png", frame_w, frame_h, row_pointers); return 0; } diff --git a/png_writer.cpp b/png_writer.cpp @@ -14,38 +14,65 @@ #include "png_writer.hpp" -void PngWriter::write_png_file(std::string file_name, int width, int height, std::byte* row_pointers) { +void abort_(const char * s, ...) +{ + va_list args; + va_start(args, s); + vfprintf(stderr, s, args); + fprintf(stderr, "n"); + va_end(args); + abort(); +} + +void PngWriter::write_png_file(std::string file_name, int width, int height, png_bytep* row_pointers) { png_structp png_ptr; png_infop info_ptr; /* create file */ FILE *fp = fopen(file_name.c_str(), "wb"); + if (!fp) + abort_("[write_png_file] File %s could not be opened for writing", file_name.c_str()); + /* initialize stuff */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr) + abort_("[write_png_file] png_create_write_struct failed"); + info_ptr = png_create_info_struct(png_ptr); - setjmp(png_jmpbuf(png_ptr)); + if (!info_ptr) + abort_("[write_png_file] png_create_info_struct failed"); + + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during init_io"); + png_init_io(png_ptr, fp); - setjmp(png_jmpbuf(png_ptr)); + /* write header */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during writing header"); png_set_IHDR(png_ptr, info_ptr, width, height, - 16, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, + 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); - setjmp(png_jmpbuf(png_ptr)); + /* write bytes */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during writing bytes"); - png_write_image(png_ptr, (png_bytep *)row_pointers); + png_write_image(png_ptr, row_pointers); - setjmp(png_jmpbuf(png_ptr)); + /* end write */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during end of write"); png_write_end(png_ptr, NULL); /* cleanup heap allocation */ - //for (uint32_t y = 0; y < height; y++) + //for (y=0; y<height; y++) // free(row_pointers[y]); - //free(row_pointers); fclose(fp); diff --git a/png_writer.hpp b/png_writer.hpp @@ -5,7 +5,9 @@ #include <string> +#include <png.h> + class PngWriter { public: - static void write_png_file(std::string file_name, int width, int height, std::byte* row_pointers); + static void write_png_file(std::string file_name, int width, int height, png_bytep* row_pointers); };