From c116a0849c7531ec4d0e59b6d61aaf6137dcd568 Mon Sep 17 00:00:00 2001 From: don bright Date: Sat, 26 Jan 2013 01:36:55 +0100 Subject: undo experiment with object orientation diff --git a/openscad.pro b/openscad.pro index 51f4439..4fdd11e 100644 --- a/openscad.pro +++ b/openscad.pro @@ -232,7 +232,6 @@ HEADERS += src/version_check.h \ src/svg.h \ \ src/lodepng.h \ - src/OffscreenContext.h \ src/OffscreenView.h \ src/fbo.h \ src/imageutils.h \ @@ -306,16 +305,16 @@ SOURCES += src/version_check.cc \ src/mainwin.cc unix:!macx { - SOURCES += src/OffscreenContextGLX.cc SOURCES += src/imageutils-lodepng.cc + SOURCES += src/OffscreenContextGLX.cc } macx { - SOURCES += src/OffscreenContext.mm SOURCES += src/imageutils-macosx.cc + SOURCES += src/OffscreenContextCGL.mm } win32* { - SOURCES += src/OffscreenContextWGL.cc SOURCES += src/imageutils-lodepng.cc + SOURCES += src/OffscreenContextWGL.cc } opencsg { diff --git a/src/OffscreenContext.h b/src/OffscreenContext.h index 6eebcba..8645da7 100644 --- a/src/OffscreenContext.h +++ b/src/OffscreenContext.h @@ -1,7 +1,7 @@ #ifndef OFFSCREENCONTEXT_H_ #define OFFSCREENCONTEXT_H_ -#include // for error output +#include #include struct OffscreenContext *create_offscreen_context(int w, int h); diff --git a/src/OffscreenContext.mm b/src/OffscreenContext.mm deleted file mode 100644 index a0995fa..0000000 --- a/src/OffscreenContext.mm +++ /dev/null @@ -1,146 +0,0 @@ -#include "OffscreenContext.h" -#include "imageutils.h" -#include "fbo.h" -#include -#include - -#import // for NSOpenGL... -#include -#include - -#define REPORTGLERROR(task) { GLenum tGLErr = glGetError(); if (tGLErr != GL_NO_ERROR) { std::cout << "OpenGL error " << tGLErr << " while " << task << "\n"; } } - -struct OffscreenContext -{ - NSOpenGLContext *openGLContext; - NSAutoreleasePool *pool; - int width; - int height; - fbo_t *fbo; -}; - -std::string offscreen_context_getinfo(OffscreenContext *ctx) -{ - std::stringstream out; - - struct utsname name; - uname(&name); - - SInt32 majorVersion,minorVersion,bugFixVersion; - - Gestalt(gestaltSystemVersionMajor, &majorVersion); - Gestalt(gestaltSystemVersionMinor, &minorVersion); - Gestalt(gestaltSystemVersionBugFix, &bugFixVersion); - - const char *arch = "unknown"; - if (sizeof(int*) == 4) arch = "32-bit"; - else if (sizeof(int*) == 8) arch = "64-bit"; - - out << "GL context creator: Cocoa / CGL\n" - << "PNG generator: Core Foundation\n" - << "OS info: Mac OS X " << majorVersion << "." << minorVersion << "." << bugFixVersion << " (" << name.machine << " kernel)\n" - << "Machine: " << arch << "\n"; - return out.str(); -} - -OffscreenContext *create_offscreen_context(int w, int h) -{ - OffscreenContext *ctx = new OffscreenContext; - ctx->width = w; - ctx->height = h; - - ctx->pool = [NSAutoreleasePool new]; - - // Create an OpenGL context just so that OpenGL calls will work. - // Will not be used for actual rendering. - - NSOpenGLPixelFormatAttribute attributes[] = { - NSOpenGLPFAPixelBuffer, - NSOpenGLPFANoRecovery, - NSOpenGLPFADepthSize, 24, - NSOpenGLPFAStencilSize, 8, -// Took out the acceleration requirement to be able to run the tests -// in a non-accelerated VM. -// NSOpenGLPFAAccelerated, - (NSOpenGLPixelFormatAttribute) 0 - }; - NSOpenGLPixelFormat *pixFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease]; - - // Create and make current the OpenGL context to render with (with color and depth buffers) - ctx->openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixFormat shareContext:nil]; - if (!ctx->openGLContext) { - std::cerr << "Unable to create NSOpenGLContext\n"; - return NULL; - } - - [ctx->openGLContext makeCurrentContext]; - - // glewInit must come after Context creation and before FBO calls. - GLenum err = glewInit(); - if (GLEW_OK != err) { - std::cerr << "Unable to init GLEW: " << glewGetErrorString(err) << std::endl; - return NULL; - } - glew_dump(); - - ctx->fbo = fbo_new(); - if (!fbo_init(ctx->fbo, w, h)) { - return NULL; - } - - return ctx; -} - -bool teardown_offscreen_context(OffscreenContext *ctx) -{ - fbo_unbind(ctx->fbo); - fbo_delete(ctx->fbo); - - /* - * Cleanup - */ - [ctx->openGLContext clearDrawable]; - [ctx->openGLContext release]; - - [ctx->pool release]; - return true; -} - -/*! - Capture framebuffer from OpenGL and write it to the given filename as PNG. -*/ -bool save_framebuffer(OffscreenContext *ctx, const char *filename) -{ - if (!ctx || !filename) return false; - // Read pixels from OpenGL - int samplesPerPixel = 4; // R, G, B and A - int rowBytes = samplesPerPixel * ctx->width; - unsigned char *bufferData = (unsigned char *)malloc(rowBytes * ctx->height); - if (!bufferData) { - std::cerr << "Unable to allocate buffer for image extraction."; - return 1; - } - glReadPixels(0, 0, ctx->width, ctx->height, GL_RGBA, GL_UNSIGNED_BYTE, - bufferData); - REPORTGLERROR("reading pixels from framebuffer"); - - // Flip it vertically - images read from OpenGL buffers are upside-down - unsigned char *flippedBuffer = (unsigned char *)malloc(rowBytes * ctx->height); - if (!flippedBuffer) { - std::cout << "Unable to allocate flipped buffer for corrected image."; - return 1; - } - flip_image(bufferData, flippedBuffer, samplesPerPixel, ctx->width, ctx->height); - - bool writeok = write_png(filename, flippedBuffer, ctx->width, ctx->height); - - free(flippedBuffer); - free(bufferData); - - return writeok; -} - -void bind_offscreen_context(OffscreenContext *ctx) -{ - fbo_bind(ctx->fbo); -} diff --git a/src/OffscreenContextCGL.mm b/src/OffscreenContextCGL.mm new file mode 100644 index 0000000..a0995fa --- /dev/null +++ b/src/OffscreenContextCGL.mm @@ -0,0 +1,146 @@ +#include "OffscreenContext.h" +#include "imageutils.h" +#include "fbo.h" +#include +#include + +#import // for NSOpenGL... +#include +#include + +#define REPORTGLERROR(task) { GLenum tGLErr = glGetError(); if (tGLErr != GL_NO_ERROR) { std::cout << "OpenGL error " << tGLErr << " while " << task << "\n"; } } + +struct OffscreenContext +{ + NSOpenGLContext *openGLContext; + NSAutoreleasePool *pool; + int width; + int height; + fbo_t *fbo; +}; + +std::string offscreen_context_getinfo(OffscreenContext *ctx) +{ + std::stringstream out; + + struct utsname name; + uname(&name); + + SInt32 majorVersion,minorVersion,bugFixVersion; + + Gestalt(gestaltSystemVersionMajor, &majorVersion); + Gestalt(gestaltSystemVersionMinor, &minorVersion); + Gestalt(gestaltSystemVersionBugFix, &bugFixVersion); + + const char *arch = "unknown"; + if (sizeof(int*) == 4) arch = "32-bit"; + else if (sizeof(int*) == 8) arch = "64-bit"; + + out << "GL context creator: Cocoa / CGL\n" + << "PNG generator: Core Foundation\n" + << "OS info: Mac OS X " << majorVersion << "." << minorVersion << "." << bugFixVersion << " (" << name.machine << " kernel)\n" + << "Machine: " << arch << "\n"; + return out.str(); +} + +OffscreenContext *create_offscreen_context(int w, int h) +{ + OffscreenContext *ctx = new OffscreenContext; + ctx->width = w; + ctx->height = h; + + ctx->pool = [NSAutoreleasePool new]; + + // Create an OpenGL context just so that OpenGL calls will work. + // Will not be used for actual rendering. + + NSOpenGLPixelFormatAttribute attributes[] = { + NSOpenGLPFAPixelBuffer, + NSOpenGLPFANoRecovery, + NSOpenGLPFADepthSize, 24, + NSOpenGLPFAStencilSize, 8, +// Took out the acceleration requirement to be able to run the tests +// in a non-accelerated VM. +// NSOpenGLPFAAccelerated, + (NSOpenGLPixelFormatAttribute) 0 + }; + NSOpenGLPixelFormat *pixFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease]; + + // Create and make current the OpenGL context to render with (with color and depth buffers) + ctx->openGLContext = [[NSOpenGLContext alloc] initWithFormat:pixFormat shareContext:nil]; + if (!ctx->openGLContext) { + std::cerr << "Unable to create NSOpenGLContext\n"; + return NULL; + } + + [ctx->openGLContext makeCurrentContext]; + + // glewInit must come after Context creation and before FBO calls. + GLenum err = glewInit(); + if (GLEW_OK != err) { + std::cerr << "Unable to init GLEW: " << glewGetErrorString(err) << std::endl; + return NULL; + } + glew_dump(); + + ctx->fbo = fbo_new(); + if (!fbo_init(ctx->fbo, w, h)) { + return NULL; + } + + return ctx; +} + +bool teardown_offscreen_context(OffscreenContext *ctx) +{ + fbo_unbind(ctx->fbo); + fbo_delete(ctx->fbo); + + /* + * Cleanup + */ + [ctx->openGLContext clearDrawable]; + [ctx->openGLContext release]; + + [ctx->pool release]; + return true; +} + +/*! + Capture framebuffer from OpenGL and write it to the given filename as PNG. +*/ +bool save_framebuffer(OffscreenContext *ctx, const char *filename) +{ + if (!ctx || !filename) return false; + // Read pixels from OpenGL + int samplesPerPixel = 4; // R, G, B and A + int rowBytes = samplesPerPixel * ctx->width; + unsigned char *bufferData = (unsigned char *)malloc(rowBytes * ctx->height); + if (!bufferData) { + std::cerr << "Unable to allocate buffer for image extraction."; + return 1; + } + glReadPixels(0, 0, ctx->width, ctx->height, GL_RGBA, GL_UNSIGNED_BYTE, + bufferData); + REPORTGLERROR("reading pixels from framebuffer"); + + // Flip it vertically - images read from OpenGL buffers are upside-down + unsigned char *flippedBuffer = (unsigned char *)malloc(rowBytes * ctx->height); + if (!flippedBuffer) { + std::cout << "Unable to allocate flipped buffer for corrected image."; + return 1; + } + flip_image(bufferData, flippedBuffer, samplesPerPixel, ctx->width, ctx->height); + + bool writeok = write_png(filename, flippedBuffer, ctx->width, ctx->height); + + free(flippedBuffer); + free(bufferData); + + return writeok; +} + +void bind_offscreen_context(OffscreenContext *ctx) +{ + fbo_bind(ctx->fbo); +} diff --git a/src/OffscreenView.h b/src/OffscreenView.h index a44e0c1..f401bef 100644 --- a/src/OffscreenView.h +++ b/src/OffscreenView.h @@ -9,6 +9,7 @@ #include #endif #include "system-gl.h" +#include class OffscreenView { @@ -24,6 +25,7 @@ public: void setupOrtho(bool offset=false); void paintGL(); bool save(const char *filename); + bool save(std::ostream &output); std::string getInfo(); GLint shaderinfo[11]; diff --git a/src/export_png.cc b/src/export_png.cc index 16e2a69..d983bc1 100644 --- a/src/export_png.cc +++ b/src/export_png.cc @@ -17,6 +17,7 @@ void export_png_with_cgal(CGAL_Nef_polyhedron *root_N, std::ostream &output) csgInfo.glview = new OffscreenView(512,512); } catch (int error) { fprintf(stderr,"Can't create OpenGL OffscreenView. Code: %i.\n", error); + return; } CGALRenderer cgalRenderer(*root_N); diff --git a/src/imageutils-lodepng.cc b/src/imageutils-lodepng.cc index a74f107..96d9d90 100644 --- a/src/imageutils-lodepng.cc +++ b/src/imageutils-lodepng.cc @@ -1,35 +1,16 @@ +#include "imageutils.h" #include "lodepng.h" #include #include bool write_png(std::ostream &output, unsigned char *pixels, int width, int height) { - size_t dataout_size = -1; - unsigned char *dataout = (unsigned char *)malloc(width*height*4); - LodePNG_encode(&dataout, &dataout_size, pixels, width, height, LCT_RGBA, 8); - output.write( dataout, dataout_size );; - free( dataout ); - return true; -} - -bool write_png(const char *filename, unsigned char *pixels, int width, int height) -{ //encoder.settings.zlibsettings.windowSize = 2048; //LodePNG_Text_add(&encoder.infoPng.text, "Comment", "Created with LodePNG"); - size_t dataout_size = -1; unsigned char *dataout = (unsigned char *)malloc(width*height*4); LodePNG_encode(&dataout, &dataout_size, pixels, width, height, LCT_RGBA, 8); - //LodePNG_saveFile(dataout, dataout_size, "blah2.png"); - - FILE *f = fopen(filename, "wb"); - if (!f) { - free(dataout); - return false; - } - - fwrite(dataout, 1, dataout_size, f); - fclose(f); - free(dataout); + output.write( reinterpret_cast(dataout), dataout_size );; + free( dataout ); return true; } diff --git a/src/imageutils-macosx.cc b/src/imageutils-macosx.cc index 8074f3f..fc4803b 100644 --- a/src/imageutils-macosx.cc +++ b/src/imageutils-macosx.cc @@ -1,40 +1,34 @@ #include #include -#include +#include "imageutils.h" -CGDataConsumerCallbacks callbacks; +CGDataConsumerCallbacks dc_callbacks; size_t write_bytes_to_ostream (void *info,const void *buffer,size_t count) { - assert( info ); + assert( info && buffer ); std::ostream *output = (std::ostream *)info; - output->write( (const char *) buffer, count ); - return count; + size_t startpos = output->tellp(); + size_t endpos = startpos; + try { + output->write( reinterpret_castbuffer, count ); + endpos = output->tellp(); + } catch (const std::ios_base::failure& e) + std::cerr << "Error writing to ostream:" << e.what() << "\n"; + } + return endpos-startpos; } CGDataConsumerRef dataconsumer CGDataConsumerCreateWithOstream(std::ostream &output) { - callbacks.putBytes = write_bytes_to_ostream; - callbacks.releaseConsumer = NULL; - CGDataConsumerRef dc = CGDataConsumerCreate ( (void *)output, &callbacks ); + dc_callbacks.putBytes = write_bytes_to_ostream; + dc_callbacks.releaseConsumer = NULL; // ostream closed by caller of write_png + CGDataConsumerRef dc = CGDataConsumerCreate ( (void *)(&output), &dc_callbacks ); return dc; } -bool write_png(const char *filename, unsigned char *pixels, int width, int height) -{ - assert( filename ); - std::stringstream dummy; - write_png_base( filename, dummy, pixels, width, height ); -} - bool write_png(std::ostream &output, unsigned char *pixels, int width, int height) { - write_png_base( NULL, output, pixels, width, height ); -} - -bool write_png_base(const char *filename, std::ostream &output, unsigned char *pixels, int width, int height) -{ - size_t rowBytes = width * 4; // CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); @@ -54,19 +48,18 @@ bool write_png_base(const char *filename, std::ostream &output, unsigned char *p return false; } - if ( filename == NULL ) { - CGDataConsumerRef dataconsumer = CGDataConsumerCreateWithOstream(output); - } else { - CFStringRef fname = CFStringCreateWithCString(kCFAllocatorDefault, filename, kCFStringEncodingUTF8); - CFURLRef fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, - fname, kCFURLPOSIXPathStyle, false); - if (!fileURL) { - std::cerr << "Unable to create file URL ref."; - return false; - } + CGDataConsumerRef dataconsumer = CGDataConsumerCreateWithOstream(output); + /* + CFStringRef fname = CFStringCreateWithCString(kCFAllocatorDefault, filename, kCFStringEncodingUTF8); + CFURLRef fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, + fname, kCFURLPOSIXPathStyle, false); + if (!fileURL) { + std::cerr << "Unable to create file URL ref."; + return false; + } - CGDataConsumerRef dataconsumer = CGDataConsumerCreateWithURL(fileURL); - } + CGDataConsumerRef dataconsumer = CGDataConsumerCreateWithURL(fileURL); + */ CFIndex fileImageIndex = 1; CFMutableDictionaryRef fileDict = NULL; diff --git a/src/imageutils.cc b/src/imageutils.cc index 7ee14e9..eaab3b7 100644 --- a/src/imageutils.cc +++ b/src/imageutils.cc @@ -1,5 +1,6 @@ #include "imageutils.h" #include +#include void flip_image(const unsigned char *src, unsigned char *dst, size_t pixelsize, size_t width, size_t height) { @@ -8,3 +9,16 @@ void flip_image(const unsigned char *src, unsigned char *dst, size_t pixelsize, memmove(dst + (height - i - 1) * rowBytes, src + i * rowBytes, rowBytes); } } + +bool write_png(const char *filename, unsigned char *pixels, int width, int height) { + std::ofstream fstream( filename ); + if (fstream.is_open()) { + write_png( fstream, pixels, width, height ); + fstream.close(); + return true; + } else { + std::cerr << "Can't open file " << filename << " for export."; + return false; + } +} + diff --git a/src/imageutils.h b/src/imageutils.h index b8d1663..c9bb8de 100644 --- a/src/imageutils.h +++ b/src/imageutils.h @@ -2,6 +2,7 @@ #define IMAGEUTILS_H_ #include +#include bool write_png(const char *filename, unsigned char *pixels, int width, int height); bool write_png(std::ostream &output, unsigned char *pixels, int width, int height); -- cgit v0.10.1