"Fossies" - the Fresh Open Source Software Archive

Member "gfsview-snapshot-121130/batch/render.c" (30 Nov 2012, 7665 Bytes) of package /linux/privat/gfsview-snapshot-121130.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "render.c" see the Fossies "Dox" file reference documentation.

    1 /* Gerris - The GNU Flow Solver
    2  * Copyright (C) 2010 National Institute of Water and
    3  * Atmospheric Research
    4  *
    5  * This program is free software; you can redistribute it and/or
    6  * modify it under the terms of the GNU General Public License as
    7  * published by the Free Software Foundation; either version 2 of the
    8  * License, or (at your option) any later version.
    9  *
   10  * This program is distributed in the hope that it will be useful,
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   13  * General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU General Public License
   16  * along with this program; if not, write to the Free Software
   17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   18  * 02111-1307, USA.  
   19  */
   20 
   21 #include <string.h>
   22 #include <GL/osmesa.h>
   23 #if defined(__APPLE__)
   24 #  include <OpenGL/glu.h>
   25 #else
   26 #  include <GL/glu.h>
   27 #endif
   28 
   29 #include "config.h"
   30 #ifdef HAVE_MPI
   31 #  include <mpi.h>
   32 #endif /* HAVE_MPI */
   33 
   34 #include "render.h"
   35 #include "gl/trackball.h"
   36 
   37 static GList * get_symmetries (GList * i)
   38 {
   39   GList * symmetry = NULL;
   40 
   41   while (i) {
   42     if (GFS_IS_GL_SYMMETRY (i->data))
   43       symmetry = g_list_append (symmetry, i->data);
   44     i = i->next;
   45   }
   46   return symmetry;
   47 }
   48 
   49 static void view_draw (GfsGlViewParams * view,
   50                GfsGl2PSParams * p,
   51                GfsDomain * domain,
   52                GList * list,
   53                guint width, guint height)
   54 {
   55   GLfloat m[4][4];
   56   gdouble max;
   57   GList * i;
   58 
   59   glMatrixMode (GL_PROJECTION);
   60   glLoadIdentity ();
   61   GList * symmetries = get_symmetries (list);
   62   max = gfs_gl_domain_extent (domain, symmetries);
   63   gluPerspective (view->fov, width/(float)height, 1., 1. + 2.*max);
   64   glMatrixMode (GL_MODELVIEW);
   65         
   66   glLoadIdentity ();
   67   glTranslatef (view->tx, view->ty, - (1. + max));
   68   gfs_gl_build_rotmatrix (m, view->quat);
   69   glMultMatrixf (&m[0][0]);
   70   glScalef (view->sx, view->sy, view->sz);
   71         
   72   glClearColor (view->bg.r, view->bg.g, view->bg.b, 0.);
   73   glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
   74 
   75   GfsFrustum frustum;
   76   gfs_gl_get_frustum (view, symmetries, &frustum);
   77   GLuint display_list = glGenLists (1);
   78 
   79   glNewList (display_list, GL_COMPILE);
   80   i = list;
   81   while (i) {
   82     GfsGl * gl = i->data;
   83 
   84     if (GFS_IS_GL_CLIP_PLANE (gl)) {
   85       gl->format = p->format;
   86       gfs_gl_clip_plane_disable (GFS_GL_CLIP_PLANE (gl));
   87     }
   88     i = i->next;
   89   }
   90   i = list;
   91   while (i) {
   92     if (GFS_IS_GL_CUT_PLANE (i->data))
   93       GFS_GL_CUT_PLANE (i->data)->list = list;
   94     i = i->next;
   95   }
   96 
   97   GSList * clip = NULL;
   98   gboolean firstclip = TRUE;
   99   i = list;
  100   while (i) {
  101     GfsGl * gl = i->data;
  102     gl->format = p->format;
  103     if (GFS_IS_GL_CLIP_PLANE (gl)) {
  104       if (firstclip) {
  105     g_slist_foreach (clip, (GFunc) gfs_gl_clip_plane_disable, NULL);
  106     g_slist_free (clip); clip = NULL;
  107     firstclip = FALSE;    
  108       }
  109       gfs_gl_draw (gl, &frustum);
  110       clip = g_slist_prepend (clip, gl);
  111     }
  112     else {
  113       gfs_gl_draw (gl, &frustum);
  114       firstclip = TRUE;
  115     }
  116     i = i->next;
  117   }  
  118   g_slist_free (clip);
  119   glEndList();
  120 
  121   gfs_gl_symmetry_apply (symmetries, display_list);
  122   gfs_gl_frustum_free (&frustum);
  123   g_list_free (symmetries);
  124   glDeleteLists (display_list, 1);
  125   glFinish ();
  126 }
  127 
  128 #ifdef HAVE_MPI
  129 #if FTT_2D
  130 static void compose_image (GLubyte * bg, GLubyte * fg,
  131                guint width, guint height)
  132 {
  133   int i;
  134   for (i = 0; i < 4*width*height; i += 4)
  135     if (bg[i+3] == 0) {
  136       bg[i] = fg[i]; bg[i+1] = fg[i+1]; bg[i+2] = fg[i+2]; bg[i+3] = fg[i+3];
  137     }
  138 }
  139 #else /* 3D */
  140 static void compose_image (GLubyte * bg, guint32 * bgdepth,
  141                GLubyte * fg, guint32 * fgdepth,
  142                guint width, guint height)
  143 {
  144   int i;
  145   for (i = 0; i < 4*width*height; i += 4)
  146     if (bgdepth[i/4] > fgdepth[i/4]) {
  147       bg[i] = fg[i]; bg[i+1] = fg[i+1]; bg[i+2] = fg[i+2]; bg[i+3] = fg[i+3];
  148       bgdepth[i/4] = fgdepth[i/4];
  149     }
  150 }
  151 #endif /* 3D */
  152 #endif /* HAVE_MPI */
  153 
  154 void gfs_gl_osmesa_render (GfsGl2PSParams * p, GfsSimulation * sim,
  155                GfsGlViewParams * view, GList * list,
  156                FILE * fptr,
  157                gboolean parallel)
  158 {
  159   OSMesaContext ctx;
  160   guint width = p->width > 0 ? p->width : 640;
  161   guint height = p->height > 0 ? p->height : 480;
  162   void * image = g_malloc (width*height*4*sizeof (GLubyte));
  163 
  164   /* OSMesa somehow generates floating-point exceptions... turn them
  165      off so that people don't blame gfsview! */
  166   gfs_disable_floating_point_exceptions ();
  167         
  168   /* Create an RGBA-mode context for OSMesa */
  169 #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
  170   /* specify Z, stencil, accum sizes */
  171   ctx = OSMesaCreateContextExt (OSMESA_RGBA, 32, 0, 0, NULL);
  172 #else
  173   ctx = OSMesaCreateContext (OSMESA_RGBA, NULL);
  174 #endif
  175   if (!ctx) {
  176     fprintf (stderr, "gfsview-batch: OSMesaCreateContext failed!\n");
  177     exit (1);
  178   }
  179 
  180   if (!OSMesaMakeCurrent (ctx, image, GL_UNSIGNED_BYTE, width, height)) {
  181     fprintf (stderr, "gfsview-batch: OSMesaMakeCurrent failed!\n");
  182     exit (1);
  183   }
  184     
  185   gfs_gl_init_gl ();
  186 
  187   if (sim) {
  188     switch (p->format) {
  189 
  190     case GFSGL_PPM_OFFSCREEN: case GFSGL_PPM_SCREEN: {
  191       view_draw (view, p, GFS_DOMAIN (sim), list, width, height);
  192 #ifdef HAVE_MPI
  193       if (parallel && GFS_DOMAIN (sim)->pid >= 0) {
  194     int size = width*height*4;
  195 #if FTT_2D
  196     if (GFS_DOMAIN (sim)->pid == 0) {
  197       void * image1 = g_malloc (size);
  198       int pe, npe;
  199       MPI_Comm_size (MPI_COMM_WORLD, &npe);
  200       for (pe = 1; pe < npe; pe++) {
  201         MPI_Status status;
  202         MPI_Recv (image1, size, MPI_BYTE, pe, 0, MPI_COMM_WORLD, &status);
  203         compose_image (image, image1, width, height);
  204       }
  205       g_free (image1);
  206     } else
  207       MPI_Send (image, size, MPI_BYTE, 0, 0, MPI_COMM_WORLD);
  208 #else /* 3D */
  209     void * depth1;
  210     GLint width1, height1, bytesPerValue;
  211     OSMesaGetDepthBuffer (ctx, &width1, &height1, &bytesPerValue, &depth1);
  212     g_assert (width == width1 && height == height1 && bytesPerValue == 4);
  213     if (GFS_DOMAIN (sim)->pid == 0) {
  214       void * depth = g_malloc (size);
  215       memcpy (depth, depth1, size);
  216       depth1 = g_malloc (size);
  217       void * image1 = g_malloc (size);
  218       int pe, npe;
  219       MPI_Comm_size (MPI_COMM_WORLD, &npe);
  220       for (pe = 1; pe < npe; pe++) {
  221         MPI_Status status;
  222         MPI_Recv (image1, size, MPI_BYTE, pe, 0, MPI_COMM_WORLD, &status);
  223         MPI_Recv (depth1, size, MPI_BYTE, pe, 0, MPI_COMM_WORLD, &status);
  224         compose_image (image, depth, image1, depth1, width, height);
  225       }
  226       g_free (image1);
  227       g_free (depth1);
  228       g_free (depth);
  229     } else {
  230       MPI_Send (image,  size, MPI_BYTE, 0, 0, MPI_COMM_WORLD);
  231       MPI_Send (depth1, size, MPI_BYTE, 0, 0, MPI_COMM_WORLD);
  232     }
  233 #endif /* 3D */
  234       }
  235 #endif /* HAVE_MPI */
  236       gfs_gl_write_image (fptr, image, width, height);
  237       break;
  238     }
  239 
  240     case GFSGL_GNUPLOT: case GFSGL_OBJ: case GFSGL_KML: {
  241       guint buffsize = 0;
  242       gboolean done = FALSE;
  243       gfloat res = view->res;
  244       view->res = 0.;
  245       while (!done) {
  246     GfsGlFeedback * f;
  247     buffsize += 2048*2048;
  248     f = gfs_gl_feedback_begin (buffsize);
  249     view_draw (view, p, GFS_DOMAIN (sim), list, width, height);
  250     done = gfs_gl_feedback_end (f, sim, fptr, p->format);
  251       }
  252       view->res = res;
  253       break;
  254     }
  255 
  256     default: {
  257       GLint buffsize = 0, state = GL2PS_OVERFLOW;
  258       while (state == GL2PS_OVERFLOW) {
  259     buffsize += 2048*2048;
  260     gl2psBeginPage ("", "GfsView",
  261             NULL,
  262             p->format, p->sort, p->options, 
  263             GL_RGBA, 0, NULL, 
  264             0, 0, 0,
  265             buffsize, fptr, "");
  266     view->lw = p->lw;
  267     view_draw (view, p, GFS_DOMAIN (sim), list, width, height);
  268     state = gl2psEndPage();
  269       }
  270     }
  271     }
  272   }
  273         
  274   g_free (image);
  275   fflush (fptr);
  276 
  277   OSMesaDestroyContext (ctx);
  278 
  279   gfs_enable_floating_point_exceptions ();
  280 }