1 /* === S I N F G =========================================================== */
5 ** $Id: render.cpp,v 1.1.1.1 2005/01/04 01:23:14 darco Exp $
8 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
10 ** This software and associated documentation
11 ** are CONFIDENTIAL and PROPRIETARY property of
12 ** the above-mentioned copyright holder.
14 ** You may not copy, print, publish, or in any
15 ** other way distribute this software without
16 ** a prior written agreement with
17 ** the copyright holder.
20 /* ========================================================================= */
22 /* === H E A D E R S ======================================================= */
24 #define SINFG_NO_ANGLE
35 #include <sys/types.h>
50 using namespace sinfg;
53 /* === M A C R O S ========================================================= */
55 /* === P R O C E D U R E S ================================================= */
58 sinfg::parametric_render(
62 ProgressCallback *callback
66 u,v, // Current location in image
67 su,sv, // Starting locations
68 du, dv, // Distance between pixels
69 dsu,dsv; // Distance between subpixels
72 no_clamp=!desc.get_clamp();
77 a(desc.get_antialias());
84 // gamma(desc.get_gamma());
87 x,y, // Current location on output bitmap
88 x2,y2; // Subpixel counters
91 pool; // Alpha pool (for correct alpha antialiasing)
93 // Calculate the number of channels
94 //chan=channels(desc.get_pixel_format());
96 // Calculate the distance between pixels
97 du=(br[0]-tl[0])/(Point::value_type)w;
98 dv=(br[1]-tl[1])/(Point::value_type)h;
100 // Calculate the distance between sub pixels
101 dsu=du/(Point::value_type)a;
102 dsv=dv/(Point::value_type)a;
104 // Calculate the starting points
105 //su=tl[0]+(du-dsu)/(Point::value_type)2.0;
106 //sv=tl[1]-(dv-dsv)/(Point::value_type)2.0;
110 surface.set_wh(desc.get_w(),desc.get_h());
114 // Loop through all horizontal lines
115 for(y=0,v=sv;y<h;y++,v+=dv)
117 // Set the current pixel pointer
118 // to the start of the line
119 Color *colordata=surface[y];
123 // If we have a callback that we need
124 // to report to, do so now.
126 if( callback->amount_complete(y,h) == false )
128 // If the callback returns false,
129 // then the render has been aborted.
134 // Loop through every pixel in row
135 for(x=0,u=su;x<w;x++,u+=du)
137 Color &c(*(colordata++));
140 // Loop through all subpixels
141 for(y2=0,pool=0;y2<a;y2++)
144 Color color=context.get_color(
146 u+(Point::value_type)(x2)*dsu,
147 v+(Point::value_type)(y2)*dsv
152 color=color.clamped();
153 c+=color*color.get_a();
158 c+=color*color.get_a();
167 // Give the callback one more last call,
168 // this time with the full height as the
171 callback->amount_complete(h,h);
173 // Report our success
180 Target_Scanline::Handle target,
181 const RendDesc &desc,
182 ProgressCallback *callback)
185 u,v, // Current location in image
186 su,sv, // Starting locations
187 du, dv, // Distance between pixels
188 dsu,dsv; // Distance between subpixels
191 no_clamp=!desc.get_clamp();
196 a(desc.get_antialias());
203 // gamma(desc.get_gamma());
206 x,y, // Current location on output bitmap
207 x2,y2; // Subpixel counters
210 pool; // Alpha pool (for correct alpha antialiasing)
214 // If we do not have a a target then bail
218 // Calculate the number of channels
219 //chan=channels(desc.get_pixel_format());
221 // Calculate the distance between pixels
222 du=(br[0]-tl[0])/(Point::value_type)w;
223 dv=(br[1]-tl[1])/(Point::value_type)h;
225 // Calculate the distance between sub pixels
226 dsu=du/(Point::value_type)a;
227 dsv=dv/(Point::value_type)a;
229 // Calculate the starting points
230 su=tl[0]+(du-dsu)/(Point::value_type)2.0;
231 sv=tl[1]-(dv-dsv)/(Point::value_type)2.0;
233 // Mark the start of a new frame.
234 if(!target->start_frame(callback))
237 // Loop through all horizontal lines
238 for(y=0,v=sv;y<h;y++,v+=dv)
240 // Set the current pixel pointer
241 // to the start of the line
242 Color *colordata=target->start_scanline(y);
246 if(callback)callback->error(_("Target panic"));
247 else throw(string(_("Target panic")));
251 // If we have a callback that we need
252 // to report to, do so now.
254 if( callback->amount_complete(y,h) == false )
256 // If the callback returns false,
257 // then the render has been aborted.
260 target->end_scanline();
265 // Loop through every pixel in row
266 for(x=0,u=su;x<w;x++,u+=du)
268 Color &c(*(colordata++));
271 // Loop through all subpixels
272 for(y2=0,pool=0;y2<a;y2++)
275 Color color=context.get_color(
277 u+(Point::value_type)(x2)*dsu,
278 v+(Point::value_type)(y2)*dsv
283 color=color.clamped();
284 c+=color*color.get_a();
289 c+=color*color.get_a();
297 // Send the buffer to the render target.
298 // If anything goes wrong, cleanup and bail.
299 if(!target->end_scanline())
301 if(callback)callback->error(_("Target panic"));
302 else throw(string(_("Target panic")));
307 // Finish up the target's frame
310 // Give the callback one more last call,
311 // this time with the full height as the
314 callback->amount_complete(h,h);
316 // Report our success
321 sinfg::render_threaded(
323 Target_Scanline::Handle target,
324 const RendDesc &desc,
325 ProgressCallback *callback,
329 struct _render_thread
354 u,v, // Current location in image
355 su,sv, // Starting locations
356 du, dv, // Distance between pixels
357 dsu,dsv; // Distance between subpixels
360 no_clamp=!desc.get_clamp();
365 a(desc.get_antialias());
372 x,y, // Current location on output bitmap
373 x2,y2; // Subpixel counters
376 pool; // Alpha pool (for correct alpha antialiasing)
380 // If we do not have a a target then bail
384 // Calculate the distance between pixels
385 du=(br[0]-tl[0])/(Point::value_type)w;
386 dv=(br[1]-tl[1])/(Point::value_type)h;
388 // Calculate the distance between sub pixels
389 dsu=du/(Point::value_type)a;
390 dsv=dv/(Point::value_type)a;
392 // Calculate the starting points
393 su=tl[0]+(du-dsu)/(Point::value_type)2.0;
394 sv=tl[1]-(dv-dsv)/(Point::value_type)2.0;
396 render_thread=new _render_thread[threads];
399 for(i=0;i<threads;i++)
407 render_thread[i].pid=pid;
410 // Mark the start of a new frame.
411 if(!target->start_frame(callback))
416 // Set the current pixel pointer
417 // to the start of the line
418 Color *colordata(target->start_scanline(y));
422 if(callback)callback->error(_("Target panic"));
423 else throw(string(_("Target panic")));
427 // If we have a callback that we need
428 // to report to, do so now.
430 if( callback->amount_complete(y,h) == false )
432 // If the callback returns false,
433 // then the render has been aborted.
436 target->end_scanline();
438 delete [] render_thread;
442 read(render_thread[y%threads].pipe_read,colordata,w*sizeof(Color));
444 // Send the buffer to the render target.
445 // If anything goes wrong, cleanup and bail.
446 if(!target->end_scanline())
448 delete [] render_thread;
449 if(callback)callback->error(_("Target panic"));
450 else throw(string(_("Target panic")));
455 // Finish up the target's frame
458 // Give the callback one more last call,
459 // this time with the full height as the
462 callback->amount_complete(h,h);
464 delete [] render_thread;
469 // Change the random seed, so that each thread has a different one
470 srand(mythread*20+threads+time(0));
472 Color *buffer(new Color[w]);
474 // Loop through all horizontal lines
475 for(y=mythread,v=sv+dv*(Real)mythread;y<h;y+=threads,v+=dv*(Real)threads)
477 // Set the current pixel pointer
478 // to the start of the line
479 Color* colordata(buffer);
481 // Loop through every pixel in row
482 for(x=0,u=su;x<w;x++,u+=du)
484 Color &c(*(colordata++));
487 // Loop through all subpixels
488 for(y2=0,pool=0;y2<a;y2++)
491 Color color=context.get_color(
493 u+(Point::value_type)(x2)*dsu,
494 v+(Point::value_type)(y2)*dsv
499 color=color.clamped();
500 c+=color*color.get_a();
505 c+=color*color.get_a();
513 // Send the buffer to the primary thread.
514 write(render_thread[mythread].pipe_write,buffer,w*sizeof(Color));
522 return render(context, target, desc, callback);