properly indent code

felipesanches-svg
don bright 2013-02-01 02:47:12 +01:00
parent f8ebf1c963
commit 466490a55a
2 changed files with 223 additions and 223 deletions

View File

@ -6,49 +6,49 @@
void bind_offscreen_context(OffscreenContext *ctx)
{
if (ctx) fbo_bind(ctx->fbo);
if (ctx) fbo_bind(ctx->fbo);
}
/*
Capture framebuffer from OpenGL and write it to the given filename as PNG.
*/
Capture framebuffer from OpenGL and write it to the given filename as PNG.
*/
bool save_framebuffer(OffscreenContext *ctx, const char *filename)
{
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;
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;
}
/*!
Capture framebuffer from OpenGL and write it to the given ostream.
Called by save_framebuffer() from platform-specific code.
*/
Called by save_framebuffer() from platform-specific code.
*/
bool save_framebuffer_common(OffscreenContext *ctx, std::ostream &output)
{
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]);
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]);
// Flip it vertically - images read from OpenGL buffers are upside-down
int rowBytes = samplesPerPixel * ctx->width;
// Flip it vertically - images read from OpenGL buffers are upside-down
int rowBytes = samplesPerPixel * ctx->width;
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);
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);
bool writeok = write_png(output, flippedBuffer, ctx->width, ctx->height);
bool writeok = write_png(output, flippedBuffer, ctx->width, ctx->height);
free(flippedBuffer);
free(flippedBuffer);
return writeok;
}
@ -58,17 +58,17 @@ OffscreenContext *create_offscreen_context_common(OffscreenContext *ctx)
{
if (!ctx) return NULL;
GLenum err = glewInit(); // must come after Context creation and before FBO c$
if (GLEW_OK != err) {
std::cerr << "Unable to init GLEW: " << glewGetErrorString(err) << "\n";
return NULL;
}
//cerr << glew_dump(0);
if (GLEW_OK != err) {
std::cerr << "Unable to init GLEW: " << glewGetErrorString(err) << "\n";
return NULL;
}
//cerr << glew_dump(0);
ctx->fbo = fbo_new();
if (!fbo_init(ctx->fbo, ctx->width, ctx->height)) {
return NULL;
}
ctx->fbo = fbo_new();
if (!fbo_init(ctx->fbo, ctx->width, ctx->height)) {
return NULL;
}
return ctx;
return ctx;
}

View File

@ -2,14 +2,14 @@
Create an OpenGL context without creating an OpenGL Window. for Linux.
See Also
See also
glxgears.c by Brian Paul from mesa-demos (mesa3d.org)
http://cgit.freedesktop.org/mesa/demos/tree/src/xdemos?id=mesa-demos-8.0.1
http://www.opengl.org/sdk/docs/man/xhtml/glXIntro.xml
http://www.mesa3d.org/brianp/sig97/offscrn.htm
http://glprogramming.com/blue/ch07.html
OffscreenContext.mm (Mac OSX version)
glxgears.c by Brian Paul from mesa-demos (mesa3d.org)
http://cgit.freedesktop.org/mesa/demos/tree/src/xdemos?id=mesa-demos-8.0.1
http://www.opengl.org/sdk/docs/man/xhtml/glXIntro.xml
http://www.mesa3d.org/brianp/sig97/offscrn.htm
http://glprogramming.com/blue/ch07.html
OffscreenContext.mm (Mac OSX version)
*/
@ -53,241 +53,241 @@ using namespace std;
struct OffscreenContext
{
GLXContext openGLContext;
Display *xdisplay;
Window xwindow;
int width;
int height;
fbo_t *fbo;
GLXContext openGLContext;
Display *xdisplay;
Window xwindow;
int width;
int height;
fbo_t *fbo;
};
#include "OffscreenContextAll.hpp"
void offscreen_context_init(OffscreenContext &ctx, int width, int height)
{
ctx.width = width;
ctx.height = height;
ctx.openGLContext = NULL;
ctx.xdisplay = NULL;
ctx.xwindow = (Window)NULL;
ctx.fbo = NULL;
ctx.width = width;
ctx.height = height;
ctx.openGLContext = NULL;
ctx.xdisplay = NULL;
ctx.xwindow = (Window)NULL;
ctx.fbo = NULL;
}
string get_os_info()
{
struct utsname u;
stringstream out;
struct utsname u;
stringstream out;
if (uname(&u) < 0)
out << "OS info: unknown, uname() error\n";
else {
out << "OS info: "
<< u.sysname << " "
<< u.release << " "
<< u.version << "\n";
out << "Machine: " << u.machine;
}
return out.str();
if (uname(&u) < 0)
out << "OS info: unknown, uname() error\n";
else {
out << "OS info: "
<< u.sysname << " "
<< u.release << " "
<< u.version << "\n";
out << "Machine: " << u.machine;
}
return out.str();
}
string offscreen_context_getinfo(OffscreenContext *ctx)
{
assert(ctx);
assert(ctx);
if (!ctx->xdisplay)
return string("No GL Context initialized. No information to report\n");
if (!ctx->xdisplay)
return string("No GL Context initialized. No information to report\n");
int major, minor;
glXQueryVersion(ctx->xdisplay, &major, &minor);
int major, minor;
glXQueryVersion(ctx->xdisplay, &major, &minor);
stringstream out;
out << "GL context creator: GLX\n"
<< "PNG generator: lodepng\n"
<< "GLX version: " << major << "." << minor << "\n"
<< get_os_info();
stringstream out;
out << "GL context creator: GLX\n"
<< "PNG generator: lodepng\n"
<< "GLX version: " << major << "." << minor << "\n"
<< get_os_info();
return out.str();
return out.str();
}
static XErrorHandler original_xlib_handler = (XErrorHandler) NULL;
static bool XCreateWindow_failed = false;
static int XCreateWindow_error(Display *dpy, XErrorEvent *event)
{
cerr << "XCreateWindow failed: XID: " << event->resourceid
<< " request: " << (int)event->request_code
<< " minor: " << (int)event->minor_code << "\n";
char description[1024];
XGetErrorText( dpy, event->error_code, description, 1023 );
cerr << " error message: " << description << "\n";
XCreateWindow_failed = true;
return 0;
cerr << "XCreateWindow failed: XID: " << event->resourceid
<< " request: " << (int)event->request_code
<< " minor: " << (int)event->minor_code << "\n";
char description[1024];
XGetErrorText( dpy, event->error_code, description, 1023 );
cerr << " error message: " << description << "\n";
XCreateWindow_failed = true;
return 0;
}
bool create_glx_dummy_window(OffscreenContext &ctx)
{
/*
create a dummy X window without showing it. (without 'mapping' it)
and save information to the ctx.
/*
create a dummy X window without showing it. (without 'mapping' it)
and save information to the ctx.
This purposely does not use glxCreateWindow, to avoid crashes,
"failed to create drawable" errors, and Mesa "WARNING: Application calling
GLX 1.3 function when GLX 1.3 is not supported! This is an application bug!"
This purposely does not use glxCreateWindow, to avoid crashes,
"failed to create drawable" errors, and Mesa "WARNING: Application calling
GLX 1.3 function when GLX 1.3 is not supported! This is an application bug!"
This function will alter ctx.openGLContext and ctx.xwindow if successfull
*/
This function will alter ctx.openGLContext and ctx.xwindow if successfull
*/
int attributes[] = {
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT, //support all 3, for OpenCSG
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24, // depth-stencil for OpenCSG
GLX_STENCIL_SIZE, 8,
GLX_DOUBLEBUFFER, True,
None
};
int attributes[] = {
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT, //support all 3, for OpenCSG
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24, // depth-stencil for OpenCSG
GLX_STENCIL_SIZE, 8,
GLX_DOUBLEBUFFER, True,
None
};
Display *dpy = ctx.xdisplay;
Display *dpy = ctx.xdisplay;
int num_returned = 0;
GLXFBConfig *fbconfigs = glXChooseFBConfig( dpy, DefaultScreen(dpy), attributes, &num_returned );
if ( fbconfigs == NULL ) {
cerr << "glXChooseFBConfig failed\n";
return false;
}
int num_returned = 0;
GLXFBConfig *fbconfigs = glXChooseFBConfig( dpy, DefaultScreen(dpy), attributes, &num_returned );
if ( fbconfigs == NULL ) {
cerr << "glXChooseFBConfig failed\n";
return false;
}
XVisualInfo *visinfo = glXGetVisualFromFBConfig( dpy, fbconfigs[0] );
if ( visinfo == NULL ) {
cerr << "glXGetVisualFromFBConfig failed\n";
XFree( fbconfigs );
return false;
}
XVisualInfo *visinfo = glXGetVisualFromFBConfig( dpy, fbconfigs[0] );
if ( visinfo == NULL ) {
cerr << "glXGetVisualFromFBConfig failed\n";
XFree( fbconfigs );
return false;
}
// can't depend on xWin==NULL at failure. use a custom Xlib error handler instead.
original_xlib_handler = XSetErrorHandler( XCreateWindow_error );
// can't depend on xWin==NULL at failure. use a custom Xlib error handler instead.
original_xlib_handler = XSetErrorHandler( XCreateWindow_error );
Window root = DefaultRootWindow( dpy );
XSetWindowAttributes xwin_attr;
int width = ctx.width;
int height = ctx.height;
xwin_attr.background_pixmap = None;
xwin_attr.background_pixel = 0;
xwin_attr.border_pixel = 0;
xwin_attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
xwin_attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
unsigned long int mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
Window root = DefaultRootWindow( dpy );
XSetWindowAttributes xwin_attr;
int width = ctx.width;
int height = ctx.height;
xwin_attr.background_pixmap = None;
xwin_attr.background_pixel = 0;
xwin_attr.border_pixel = 0;
xwin_attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
xwin_attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
unsigned long int mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
Window xWin = XCreateWindow( dpy, root, 0, 0, width, height,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &xwin_attr );
Window xWin = XCreateWindow( dpy, root, 0, 0, width, height,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &xwin_attr );
// Window xWin = XCreateSimpleWindow( dpy, DefaultRootWindow(dpy), 0,0,42,42, 0,0,0 );
// Window xWin = XCreateSimpleWindow( dpy, DefaultRootWindow(dpy), 0,0,42,42, 0,0,0 );
XSync( dpy, false );
if ( XCreateWindow_failed ) {
XFree( visinfo );
XFree( fbconfigs );
return false;
}
XSetErrorHandler( original_xlib_handler );
XSync( dpy, false );
if ( XCreateWindow_failed ) {
XFree( visinfo );
XFree( fbconfigs );
return false;
}
XSetErrorHandler( original_xlib_handler );
// Most programs would call XMapWindow here. But we don't, to keep the window hidden
// XMapWindow( dpy, xWin );
// Most programs would call XMapWindow here. But we don't, to keep the window hidden
// XMapWindow( dpy, xWin );
GLXContext context = glXCreateNewContext( dpy, fbconfigs[0], GLX_RGBA_TYPE, NULL, True );
if ( context == NULL ) {
cerr << "glXCreateNewContext failed\n";
XDestroyWindow( dpy, xWin );
XFree( visinfo );
XFree( fbconfigs );
return false;
}
GLXContext context = glXCreateNewContext( dpy, fbconfigs[0], GLX_RGBA_TYPE, NULL, True );
if ( context == NULL ) {
cerr << "glXCreateNewContext failed\n";
XDestroyWindow( dpy, xWin );
XFree( visinfo );
XFree( fbconfigs );
return false;
}
//GLXWindow glxWin = glXCreateWindow( dpy, fbconfigs[0], xWin, NULL );
//GLXWindow glxWin = glXCreateWindow( dpy, fbconfigs[0], xWin, NULL );
if (!glXMakeContextCurrent( dpy, xWin, xWin, context )) {
//if (!glXMakeContextCurrent( dpy, glxWin, glxWin, context )) {
cerr << "glXMakeContextCurrent failed\n";
glXDestroyContext( dpy, context );
XDestroyWindow( dpy, xWin );
XFree( visinfo );
XFree( fbconfigs );
return false;
}
if (!glXMakeContextCurrent( dpy, xWin, xWin, context )) {
//if (!glXMakeContextCurrent( dpy, glxWin, glxWin, context )) {
cerr << "glXMakeContextCurrent failed\n";
glXDestroyContext( dpy, context );
XDestroyWindow( dpy, xWin );
XFree( visinfo );
XFree( fbconfigs );
return false;
}
ctx.openGLContext = context;
ctx.xwindow = xWin;
ctx.openGLContext = context;
ctx.xwindow = xWin;
XFree( visinfo );
XFree( fbconfigs );
XFree( visinfo );
XFree( fbconfigs );
return true;
}
return true;
}
Bool create_glx_dummy_context(OffscreenContext &ctx);
Bool create_glx_dummy_context(OffscreenContext &ctx);
OffscreenContext *create_offscreen_context(int w, int h)
{
OffscreenContext *ctx = new OffscreenContext;
offscreen_context_init( *ctx, w, h );
OffscreenContext *create_offscreen_context(int w, int h)
{
OffscreenContext *ctx = new OffscreenContext;
offscreen_context_init( *ctx, w, h );
// before an FBO can be setup, a GLX context must be created
// this call alters ctx->xDisplay and ctx->openGLContext
// and ctx->xwindow if successfull
if (!create_glx_dummy_context( *ctx )) {
return NULL;
}
// before an FBO can be setup, a GLX context must be created
// this call alters ctx->xDisplay and ctx->openGLContext
// and ctx->xwindow if successfull
if (!create_glx_dummy_context( *ctx )) {
return NULL;
}
return create_offscreen_context_common( ctx );
}
return create_offscreen_context_common( ctx );
}
bool teardown_offscreen_context(OffscreenContext *ctx)
{
if (ctx) {
fbo_unbind(ctx->fbo);
fbo_delete(ctx->fbo);
XDestroyWindow( ctx->xdisplay, ctx->xwindow );
glXDestroyContext( ctx->xdisplay, ctx->openGLContext );
XCloseDisplay( ctx->xdisplay );
return true;
}
return false;
}
bool teardown_offscreen_context(OffscreenContext *ctx)
{
if (ctx) {
fbo_unbind(ctx->fbo);
fbo_delete(ctx->fbo);
XDestroyWindow( ctx->xdisplay, ctx->xwindow );
glXDestroyContext( ctx->xdisplay, ctx->openGLContext );
XCloseDisplay( ctx->xdisplay );
return true;
}
return false;
}
bool save_framebuffer(OffscreenContext *ctx, std::ostream &output)
{
glXSwapBuffers(ctx->xdisplay, ctx->xwindow);
return save_framebuffer_common(ctx, output);
}
bool save_framebuffer(OffscreenContext *ctx, std::ostream &output)
{
glXSwapBuffers(ctx->xdisplay, ctx->xwindow);
return save_framebuffer_common(ctx, output);
}
#pragma GCC diagnostic ignored "-Waddress"
Bool create_glx_dummy_context(OffscreenContext &ctx)
{
// This will alter ctx.openGLContext and ctx.xdisplay and ctx.xwindow if successfull
int major;
int minor;
Bool result = False;
Bool create_glx_dummy_context(OffscreenContext &ctx)
{
// This will alter ctx.openGLContext and ctx.xdisplay and ctx.xwindow if successfull
int major;
int minor;
Bool result = False;
ctx.xdisplay = XOpenDisplay( NULL );
if ( ctx.xdisplay == NULL ) {
cerr << "Unable to open a connection to the X server\n";
return False;
}
ctx.xdisplay = XOpenDisplay( NULL );
if ( ctx.xdisplay == NULL ) {
cerr << "Unable to open a connection to the X server\n";
return False;
}
// glxQueryVersion is not always reliable. Use it, but then
// also check to see if GLX 1.3 functions exist
// glxQueryVersion is not always reliable. Use it, but then
// also check to see if GLX 1.3 functions exist
glXQueryVersion(ctx.xdisplay, &major, &minor);
if ( major==1 && minor<=2 && glXGetVisualFromFBConfig==NULL ) {
cerr << "Error: GLX version 1.3 functions missing. "
<< "Your GLX version: " << major << "." << minor << endl;
} else {
result = create_glx_dummy_window(ctx);
}
glXQueryVersion(ctx.xdisplay, &major, &minor);
if ( major==1 && minor<=2 && glXGetVisualFromFBConfig==NULL ) {
cerr << "Error: GLX version 1.3 functions missing. "
<< "Your GLX version: " << major << "." << minor << endl;
} else {
result = create_glx_dummy_window(ctx);
}
if (!result) XCloseDisplay( ctx.xdisplay );
return result;
}
if (!result) XCloseDisplay( ctx.xdisplay );
return result;
}