home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / Lighting / lighting_preview.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-23  |  11.7 KB  |  473 lines

  1. /*************************************************/
  2. /* Compute a preview image and preview wireframe */
  3. /*************************************************/
  4.  
  5. #include <gtk/gtk.h>
  6.  
  7. #include <libgimp/gimp.h>
  8.  
  9. #include <gck/gck.h>
  10.  
  11. #include "lighting_main.h"
  12. #include "lighting_ui.h"
  13. #include "lighting_image.h"
  14. #include "lighting_apply.h"
  15. #include "lighting_shade.h"
  16.  
  17. #include "lighting_preview.h"
  18.  
  19. gint       lightx, lighty;
  20. BackBuffer backbuf= { 0, 0, 0, 0, NULL };
  21.  
  22. /* g_free()'ed on exit */ 
  23. gdouble *xpostab = NULL;
  24. gdouble *ypostab = NULL;
  25.  
  26. static gint xpostab_size = -1;   /* if preview size change, do realloc */
  27. static gint ypostab_size = -1;
  28.  
  29. /* Protos */
  30. /* ====== */
  31.  
  32. static void
  33. compute_preview (gint startx,
  34.          gint starty,
  35.          gint w,
  36.          gint h)
  37. {
  38.   gint xcnt,ycnt,f1,f2;
  39.   gdouble imagex,imagey;
  40.   gint32 index=0;
  41.   GckRGB color,darkcheck,lightcheck,temp;
  42.   GimpVector3 pos;
  43.   get_ray_func ray_func;
  44.  
  45.   if (xpostab_size != w)
  46.     {
  47.       if (xpostab)
  48.     {
  49.       g_free(xpostab);
  50.       xpostab = NULL;
  51.     }
  52.     }
  53.   if (!xpostab)
  54.     {
  55.       xpostab = (gdouble *)g_malloc(sizeof(gdouble)*w);
  56.       xpostab_size = w;
  57.     }
  58.  
  59.   if (ypostab_size != h)
  60.     {
  61.       if (ypostab)
  62.     {
  63.       g_free(ypostab);
  64.       ypostab = NULL;
  65.     }
  66.     }
  67.   if (!ypostab)
  68.     {
  69.       ypostab = (gdouble *)g_malloc(sizeof(gdouble)*h);
  70.       ypostab_size = h;
  71.     }
  72.  
  73.   for (xcnt=0;xcnt<w;xcnt++)
  74.     xpostab[xcnt]=(gdouble)width*((gdouble)xcnt/(gdouble)w);
  75.   for (ycnt=0;ycnt<h;ycnt++)
  76.     ypostab[ycnt]=(gdouble)height*((gdouble)ycnt/(gdouble)h);
  77.  
  78.   init_compute();
  79.   precompute_init(width,height);
  80.   
  81.   gck_rgb_set(&lightcheck,0.75,0.75,0.75);
  82.   gck_rgb_set(&darkcheck, 0.50,0.50,0.50);
  83.   gck_rgb_set(&color,0.3,0.7,1.0);
  84.   
  85.   if (mapvals.bump_mapped==TRUE && mapvals.bumpmap_id!=-1)
  86.     {
  87.       gimp_pixel_rgn_init (&bump_region, gimp_drawable_get(mapvals.bumpmap_id), 
  88.                0, 0, width, height, FALSE, FALSE);
  89.     }
  90.  
  91.   imagey=0;
  92.  
  93.   if (mapvals.previewquality)
  94.     ray_func = get_ray_color;
  95.   else
  96.     ray_func = get_ray_color_no_bilinear;
  97.   
  98.   if (mapvals.env_mapped==TRUE && mapvals.envmap_id!=-1) 
  99.     {
  100.       env_width = gimp_drawable_width(mapvals.envmap_id);
  101.       env_height = gimp_drawable_height(mapvals.envmap_id);
  102.       gimp_pixel_rgn_init (&env_region, gimp_drawable_get(mapvals.envmap_id), 
  103.                0, 0, env_width, env_height, FALSE, FALSE);
  104.  
  105.       if (mapvals.previewquality)
  106.         ray_func = get_ray_color_ref;
  107.       else
  108.         ray_func = get_ray_color_no_bilinear_ref;      
  109.     }
  110.  
  111.   for (ycnt=0;ycnt<PREVIEW_HEIGHT;ycnt++)
  112.     {
  113.       for (xcnt=0;xcnt<PREVIEW_WIDTH;xcnt++)
  114.         {
  115.           if ((ycnt>=starty && ycnt<(starty+h)) &&
  116.               (xcnt>=startx && xcnt<(startx+w)))
  117.             {
  118.           imagex=xpostab[xcnt-startx];
  119.           imagey=ypostab[ycnt-starty];
  120.           pos=int_to_posf(imagex,imagey);
  121.           if (mapvals.bump_mapped==TRUE && mapvals.bumpmap_id!=-1 && xcnt==startx)
  122.         {
  123.           pos_to_float(pos.x,pos.y,&imagex,&imagey);
  124.           precompute_normals(0,width,(gint)(imagey+0.5));
  125.         }
  126.  
  127.           color=(*ray_func)(&pos);
  128.                
  129.           if (color.a<1.0)
  130.         {
  131.           f1=((xcnt % 32)<16);
  132.           f2=((ycnt % 32)<16);
  133.           f1=f1^f2;
  134.     
  135.           if (f1)
  136.             {
  137.               if (color.a==0.0)
  138.             color=lightcheck;
  139.               else
  140.             {
  141.               gck_rgb_mul(&color,color.a);
  142.               temp=lightcheck;
  143.               gck_rgb_mul(&temp,1.0-color.a);
  144.               gck_rgb_add(&color,&temp);
  145.             }
  146.             }
  147.           else
  148.             {
  149.               if (color.a==0.0)
  150.             color=darkcheck;
  151.               else
  152.             {
  153.               gck_rgb_mul(&color,color.a);
  154.               temp=darkcheck;
  155.               gck_rgb_mul(&temp,1.0-color.a);
  156.               gck_rgb_add(&color,&temp);
  157.             }
  158.             }
  159.         }
  160.  
  161.           preview_rgb_data[index++]=(guchar)(255.0*color.r);
  162.           preview_rgb_data[index++]=(guchar)(255.0*color.g);
  163.           preview_rgb_data[index++]=(guchar)(255.0*color.b);
  164.           imagex++;
  165.             }
  166.           else
  167.             {
  168.               preview_rgb_data[index++]=200;
  169.               preview_rgb_data[index++]=200;
  170.               preview_rgb_data[index++]=200;
  171.             }
  172.         }
  173.     }
  174.  
  175.   gck_rgb_to_gdkimage(visinfo, preview_rgb_data, image, PREVIEW_WIDTH, PREVIEW_HEIGHT);
  176. }
  177.  
  178. /*
  179. static void
  180. blah (void)
  181. {
  182. */
  183.   /* First, compute the linear mapping (x,y,x+w,y+h) to (0,0,pw,ph) */
  184.   /* ============================================================== */
  185.  
  186. /*  realw=(p2.x-p1.x);
  187.   realh=(p2.y-p1.y);
  188.  
  189.   for (xcnt=0;xcnt<pw;xcnt++)
  190.     xpostab[xcnt]=p1.x+realw*((double)xcnt/(double)pw);
  191.  
  192.   for (ycnt=0;ycnt<ph;ycnt++)
  193.     ypostab[ycnt]=p1.y+realh*((double)ycnt/(double)ph); */
  194.   
  195.   /* Compute preview using the offset tables */
  196.   /* ======================================= */
  197.  
  198. /*  if (mapvals.transparent_background==TRUE)
  199.     gck_rgba_set(&background,0.0,0.0,0.0,0.0);
  200.   else
  201.     {
  202.       gimp_palette_get_background(&r,&g,&b);
  203.       background.r=(gdouble)r/255.0;
  204.       background.g=(gdouble)g/255.0;
  205.       background.b=(gdouble)b/255.0;
  206.       background.a=1.0;
  207.     }
  208.  
  209.   gck_rgb_set(&lightcheck,0.75,0.75,0.75);
  210.   gck_rgb_set(&darkcheck, 0.50,0.50,0.50);
  211.   gck_vector3_set(&p2,-1.0,-1.0,0.0);
  212.  
  213.   for (ycnt=0;ycnt<ph;ycnt++)
  214.     {
  215.       for (xcnt=0;xcnt<pw;xcnt++)
  216.         {
  217.           p1.x=xpostab[xcnt];
  218.           p1.y=ypostab[ycnt]; */
  219.           
  220.           /* If oldpos = newpos => same color, so skip shading */
  221.           /* ================================================= */
  222.           
  223. /*          p2=p1;
  224.           color=get_ray_color(&p1);
  225.  
  226.           if (color.a<1.0)
  227.             {
  228.               f1=((xcnt % 32)<16);
  229.               f2=((ycnt % 32)<16);
  230.               f1=f1^f2;
  231.  
  232.               if (f1)
  233.                 {
  234.                   if (color.a==0.0)
  235.                     color=lightcheck;
  236.                   else
  237.                     {
  238.                       gck_rgb_mul(&color,color.a);
  239.                       temp=lightcheck;
  240.                       gck_rgb_mul(&temp,1.0-color.a);
  241.                       gck_rgb_add(&color,&temp);
  242.                     }
  243.                 }
  244.               else
  245.                 {
  246.                   if (color.a==0.0)
  247.                     color=darkcheck;
  248.                   else
  249.                     {
  250.                       gck_rgb_mul(&color,color.a);
  251.                       temp=darkcheck;
  252.                       gck_rgb_mul(&temp,1.0-color.a);
  253.                       gck_rgb_add(&color,&temp);
  254.                     }
  255.                 }
  256.             }
  257.  
  258.           preview_rgb_data[index++]=(guchar)(color.r*255.0);
  259.           preview_rgb_data[index++]=(guchar)(color.g*255.0);
  260.           preview_rgb_data[index++]=(guchar)(color.b*255.0);
  261.         }
  262.     } */
  263.  
  264.   /* Convert to visual type */
  265.   /* ====================== */
  266.  
  267. /*  gck_rgb_to_gdkimage(visinfo,preview_rgb_data,image,pw,ph); */
  268. /*
  269. }
  270. */
  271.  
  272. /*************************************************/
  273. /* Check if the given position is within the     */
  274. /* light marker. Return TRUE if so, FALSE if not */
  275. /*************************************************/
  276.  
  277. gint
  278. check_light_hit (gint xpos,
  279.          gint ypos)
  280. {
  281. /*  gdouble dx,dy,r;
  282.   
  283.   if (mapvals.lightsource.type==POINT_LIGHT)
  284.     {
  285.       dx=(gdouble)lightx-xpos;
  286.       dy=(gdouble)lighty-ypos;
  287.       r=sqrt(dx*dx+dy*dy)+0.5;
  288.  
  289.       if ((gint)r>7)
  290.         return(FALSE);
  291.       else
  292.         return(TRUE);
  293.     }
  294.    */
  295.   return FALSE;
  296. }
  297.  
  298. /****************************************/
  299. /* Draw a marker to show light position */
  300. /****************************************/
  301.  
  302. /*
  303. static void
  304. draw_light_marker (gint xpos,
  305.            gint ypos)
  306. {
  307. */
  308. /*  gck_gc_set_foreground(visinfo,gc,0,50,255);
  309.   gck_gc_set_background(visinfo,gc,0,0,0);
  310.  
  311.   gdk_gc_set_function(gc,GDK_COPY);
  312.  
  313.   if (mapvals.lightsource.type==POINT_LIGHT)
  314.     {
  315.       lightx=xpos;
  316.       lighty=ypos; */
  317.     
  318.       /* Save background */
  319.       /* =============== */
  320.  
  321. /*      backbuf.x=lightx-7;
  322.       backbuf.y=lighty-7;
  323.       backbuf.w=14;
  324.       backbuf.h=14; */
  325.     
  326.       /* X doesn't like images that's outside a window, make sure */
  327.       /* we get the backbuffer image from within the boundaries   */
  328.       /* ======================================================== */
  329.  
  330. /*      if (backbuf.x<0)
  331.         backbuf.x=0;
  332.       else if ((backbuf.x+backbuf.w)>PREVIEW_WIDTH)
  333.         backbuf.w=(PREVIEW_WIDTH-backbuf.x);
  334.  
  335.       if (backbuf.y<0)
  336.         backbuf.y=0;
  337.       else if ((backbuf.y+backbuf.h)>PREVIEW_HEIGHT)
  338.         backbuf.h=(PREVIEW_WIDTH-backbuf.y);
  339.  
  340.       backbuf.image=gdk_image_get(previewarea->window,backbuf.x,backbuf.y,backbuf.w,backbuf.h);
  341.       gdk_draw_arc(previewarea->window,gc,TRUE,lightx-7,lighty-7,14,14,0,360*64);
  342.     } */
  343. /*}*/
  344.  
  345. static void
  346. clear_light_marker (void)
  347. {
  348.   /* Restore background if it has been saved */
  349.   /* ======================================= */
  350.   
  351. /*  if (backbuf.image!=NULL)
  352.     {
  353.       gck_gc_set_foreground(visinfo,gc,255,255,255);
  354.       gck_gc_set_background(visinfo,gc,0,0,0);
  355.  
  356.       gdk_gc_set_function(gc,GDK_COPY);
  357.       gdk_draw_image(previewarea->window,gc,backbuf.image,0,0,backbuf.x,backbuf.y,
  358.         backbuf.w,backbuf.h);
  359.       gdk_image_destroy(backbuf.image);
  360.       backbuf.image=NULL;
  361.     } */
  362. }
  363.  
  364. /*
  365. static void
  366. draw_lights (void)
  367. {
  368.   gdouble dxpos,dypos;
  369.   gint xpos,ypos;
  370.  
  371.   clear_light_marker();
  372.  
  373.   gck_3d_to_2d(startx,starty,pw,ph,&dxpos,&dypos,&mapvals.viewpoint,
  374.     &mapvals.lightsource.position);
  375.  
  376.   xpos=(gint)(dxpos+0.5);
  377.   ypos=(gint)(dypos+0.5);
  378.  
  379.   if (xpos>=0 && xpos<=PREVIEW_WIDTH && ypos>=0 && ypos<=PREVIEW_HEIGHT)
  380.     draw_light_marker(xpos,ypos);
  381. }*/
  382.  
  383. /*************************************************/
  384. /* Update light position given new screen coords */
  385. /*************************************************/
  386.  
  387. void
  388. update_light (gint xpos,
  389.           gint ypos)
  390. {
  391. /*  gint startx,starty,pw,ph;
  392.  
  393.   pw=PREVIEW_WIDTH >> mapvals.preview_zoom_factor;
  394.   ph=PREVIEW_HEIGHT >> mapvals.preview_zoom_factor;
  395.   startx=(PREVIEW_WIDTH-pw)>>1;
  396.   starty=(PREVIEW_HEIGHT-ph)>>1;
  397.   
  398.   gck_2d_to_3d(startx,starty,pw,ph,xpos,ypos,&mapvals.viewpoint,
  399.     &mapvals.lightsource.position);
  400.  
  401.   draw_lights(startx,starty,pw,ph); */
  402. }
  403.  
  404. static void
  405. compute_preview_rectangle (gint *xp,
  406.                gint *yp,
  407.                gint *wid,
  408.                gint *heig)
  409. {
  410.   gdouble x, y, w, h;
  411.  
  412.   if (width>=height)
  413.     {
  414.       w=(PREVIEW_WIDTH-50.0);
  415.       h=(gdouble)height*(w/(gdouble)width);
  416.       
  417.       x=(PREVIEW_WIDTH-w)/2.0;
  418.       y=(PREVIEW_HEIGHT-h)/2.0;
  419.     }
  420.   else
  421.     {
  422.       h=(PREVIEW_HEIGHT-50.0);
  423.       w=(gdouble)width*(h/(gdouble)height);
  424.       
  425.       x=(PREVIEW_WIDTH-w)/2.0;
  426.       y=(PREVIEW_HEIGHT-h)/2.0;
  427.     }
  428.  
  429.   *xp=(gint)(x+0.5);
  430.   *yp=(gint)(y+0.5);
  431.   *wid=(gint)(w+0.5);
  432.   *heig=(gint)(h+0.5);
  433. }
  434.  
  435. /******************************************************************/
  436. /* Draw preview image. if DoCompute is TRUE then recompute image. */
  437. /******************************************************************/
  438.  
  439. void
  440. draw_preview_image (gint recompute)
  441. {
  442.   gint startx, starty, pw, ph;
  443.   
  444.   gck_gc_set_foreground (visinfo, gc, 255, 255, 255);
  445.   gck_gc_set_background (visinfo, gc,   0,   0,   0);
  446.  
  447.   gdk_gc_set_function (gc, GDK_COPY);
  448.  
  449.   compute_preview_rectangle (&startx, &starty, &pw, &ph);
  450.  
  451.   if (recompute == TRUE)
  452.     {
  453.       GdkCursor *newcursor;
  454.  
  455.       newcursor = gdk_cursor_new (GDK_WATCH);
  456.       gdk_window_set_cursor (previewarea->window, newcursor);
  457.       gdk_cursor_destroy (newcursor);
  458.       gdk_flush();
  459.  
  460.       compute_preview (startx, starty, pw, ph);
  461.  
  462.       newcursor = gdk_cursor_new (GDK_HAND2);
  463.       gdk_window_set_cursor (previewarea->window, newcursor);
  464.       gdk_cursor_destroy (newcursor);
  465.       gdk_flush();
  466.  
  467.       clear_light_marker ();
  468.     }
  469.  
  470.   gdk_draw_image (previewarea->window, gc, image,
  471.           0, 0, 0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT);
  472. }
  473.