openscad/src/OffscreenContextAll.hpp

74 lines
2.0 KiB
C++
Raw Normal View History

// Functions shared by OffscreenContext[platform].cc
// #include this directly after definition of struct OffscreenContext.
2013-01-26 10:10:36 +04:00
2013-01-28 23:56:17 +04:00
#include <vector>
#include <ostream>
2013-01-26 10:10:36 +04:00
void bind_offscreen_context(OffscreenContext *ctx)
{
2013-02-01 05:47:12 +04:00
if (ctx) fbo_bind(ctx->fbo);
2013-01-26 10:10:36 +04:00
}
/*
2013-02-01 05:47:12 +04:00
Capture framebuffer from OpenGL and write it to the given filename as PNG.
*/
2013-01-26 10:10:36 +04:00
bool save_framebuffer(OffscreenContext *ctx, const char *filename)
{
2013-02-01 05:47:12 +04:00
std::ofstream fstream(filename,std::ios::out|std::ios::binary);
if (!fstream.is_open()) {
std::cerr << "Can't open file " << filename << " for writing";
return false;
} else {
save_framebuffer(ctx, fstream);
fstream.close();
}
return true;
2013-01-26 10:10:36 +04:00
}
/*!
Capture framebuffer from OpenGL and write it to the given ostream.
2013-02-01 05:47:12 +04:00
Called by save_framebuffer() from platform-specific code.
*/
2013-01-26 10:10:36 +04:00
bool save_framebuffer_common(OffscreenContext *ctx, std::ostream &output)
{
2013-02-01 05:47:12 +04:00
if (!ctx) return false;
int samplesPerPixel = 4; // R, G, B and A
std::vector<GLubyte> pixels(ctx->width * ctx->height * samplesPerPixel);
glReadPixels(0, 0, ctx->width, ctx->height, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
2013-01-26 10:10:36 +04:00
2013-02-01 05:47:12 +04:00
// Flip it vertically - images read from OpenGL buffers are upside-down
int rowBytes = samplesPerPixel * ctx->width;
2013-01-26 10:10:36 +04:00
2013-02-01 05:47:12 +04:00
unsigned char *flippedBuffer = (unsigned char *)malloc(rowBytes * ctx->height);
if (!flippedBuffer) {
std::cerr << "Unable to allocate flipped buffer for corrected image.";
return 1;
}
flip_image(&pixels[0], flippedBuffer, samplesPerPixel, ctx->width, ctx->height);
2013-01-26 10:10:36 +04:00
2013-02-01 05:47:12 +04:00
bool writeok = write_png(output, flippedBuffer, ctx->width, ctx->height);
2013-01-26 10:10:36 +04:00
2013-02-01 05:47:12 +04:00
free(flippedBuffer);
2013-01-26 10:10:36 +04:00
return writeok;
}
// Called by create_offscreen_context() from platform-specific code.
OffscreenContext *create_offscreen_context_common(OffscreenContext *ctx)
{
if (!ctx) return NULL;
GLenum err = glewInit(); // must come after Context creation and before FBO c$
2013-02-01 05:47:12 +04:00
if (GLEW_OK != err) {
std::cerr << "Unable to init GLEW: " << glewGetErrorString(err) << "\n";
return NULL;
}
2013-01-26 10:10:36 +04:00
2013-02-01 05:47:12 +04:00
ctx->fbo = fbo_new();
if (!fbo_init(ctx->fbo, ctx->width, ctx->height)) {
return NULL;
}
2013-01-26 10:10:36 +04:00
2013-02-01 05:47:12 +04:00
return ctx;
2013-01-26 10:10:36 +04:00
}