1 // Copyright 2002, 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * render.h: A superclass for all rendering classes.
28 #include "transformation.h"
32 #define ACTIVE_RENDERER_COUNT 30
35 * Class render accepts messages synchronizing rendering steps through the
36 * methods sync(n) and sync(), and returns information about the currently
37 * rendered image via methods get_image() and get_defined(). This class is
38 * abstract, and must be subclassed to be instantiated.
43 static unsigned int rx_count
;
44 static exclusion
*rx_parameters
;
46 static render
*directory
[ACTIVE_RENDERER_COUNT
];
47 static int directory_length
;
49 static double scale_factor
;
53 unsigned int queue_size
;
57 static int strpfix(const char *a
, const char *b
) {
58 return strncmp(a
, b
, strlen(a
));
66 if (directory_length
>= ACTIVE_RENDERER_COUNT
) {
67 fprintf(stderr
, "\n\n*** Too many renderers in d2::render::render() ***\n\n");
71 directory
[directory_length
] = this;
72 entry_number
= directory_length
;
89 * Get the scale factor
91 double get_scale_factor() {
96 * Get the current step number
104 * Perform the current rendering step.
107 virtual void step() = 0;
112 * Check for render-coordinate excluded regions. (Applies an offset to
113 * spatial coordinates internally.)
115 static int is_excluded_r(point offset
, point p
, int f
) {
117 for (unsigned int param
= 0; param
< rx_count
; param
++)
118 if (rx_parameters
[param
].type
== exclusion::RENDER
119 && p
[0] + offset
[0] >= rx_parameters
[param
].x
[0]
120 && p
[0] + offset
[0] <= rx_parameters
[param
].x
[1]
121 && p
[1] + offset
[1] >= rx_parameters
[param
].x
[2]
122 && p
[1] + offset
[1] <= rx_parameters
[param
].x
[3]
123 && f
>= rx_parameters
[param
].x
[4]
124 && f
<= rx_parameters
[param
].x
[5])
129 static int is_excluded_r(point offset
, int i
, int j
, int f
) {
131 for (unsigned int param
= 0; param
< rx_count
; param
++)
132 if (rx_parameters
[param
].type
== exclusion::RENDER
133 && i
+ offset
[0] >= rx_parameters
[param
].x
[0]
134 && i
+ offset
[0] <= rx_parameters
[param
].x
[1]
135 && j
+ offset
[1] >= rx_parameters
[param
].x
[2]
136 && j
+ offset
[1] <= rx_parameters
[param
].x
[3]
137 && f
>= rx_parameters
[param
].x
[4]
138 && f
<= rx_parameters
[param
].x
[5])
143 int is_excluded_r(int i
, int j
, int f
) {
144 return is_excluded_r(get_image()->offset(), i
, j
, f
);
148 * Check for frame-coordinate excluded regions.
150 static int is_excluded_f(point p
, int f
) {
152 for (unsigned int param
= 0; param
< rx_count
; param
++)
153 if (rx_parameters
[param
].type
== exclusion::FRAME
154 && p
[0] >= rx_parameters
[param
].x
[0]
155 && p
[0] <= rx_parameters
[param
].x
[1]
156 && p
[1] >= rx_parameters
[param
].x
[2]
157 && p
[1] <= rx_parameters
[param
].x
[3]
158 && f
>= rx_parameters
[param
].x
[4]
159 && f
<= rx_parameters
[param
].x
[5])
164 static int is_excluded_f(int i
, int j
, int f
) {
166 for (unsigned int param
= 0; param
< rx_count
; param
++)
167 if (rx_parameters
[param
].type
== exclusion::FRAME
168 && i
>= rx_parameters
[param
].x
[0]
169 && i
<= rx_parameters
[param
].x
[1]
170 && j
>= rx_parameters
[param
].x
[2]
171 && j
<= rx_parameters
[param
].x
[3]
172 && f
>= rx_parameters
[param
].x
[4]
173 && f
<= rx_parameters
[param
].x
[5])
179 static int render_count() {
180 return directory_length
;
182 static render
*render_num(int n
) {
183 assert (n
< directory_length
);
187 static void render_init(unsigned int _rx_count
, exclusion
*_rx_parameters
,
188 int _rx_show
, int _extend
, double _scale_factor
) {
189 rx_count
= _rx_count
;
192 scale_factor
= _scale_factor
;
194 rx_parameters
= (exclusion
*) malloc(rx_count
* sizeof(exclusion
));
196 for (unsigned int region
= 0; region
< rx_count
; region
++) {
198 rx_parameters
[region
] = _rx_parameters
[region
];
201 * Scale spatial rendering coordinates
204 if (rx_parameters
[region
].type
== exclusion::RENDER
)
205 for (int p
= 0; p
< 4; p
++)
206 rx_parameters
[region
].x
[p
] *= scale_factor
;
210 static void set_wt(double _wt
) {
214 static double get_wt() {
218 static int is_rx_show() {
222 static unsigned int get_rx_count() {
226 static const exclusion
*get_rx_parameters() {
227 return rx_parameters
;
231 * Current rendering result.
234 virtual const image
*get_image() const = 0;
237 * Result of rendering at the given frame.
240 const image
*get_image(unsigned int n
) {
243 if (n
== (unsigned int) step_num
)
246 n
= step_num
- n
- 1;
248 assert (n
< queue_size
);
254 * Extend the rendering queue.
257 void extend_queue(unsigned int n
) {
259 * Increase the size of the queue, if necessary, to
260 * accommodate the given lag.
262 if (n
> queue_size
) {
263 unsigned int new_size
= n
;
264 queue
= (image
**) realloc(queue
, new_size
* sizeof(image
*));
267 fprintf(stderr
, "\n\n*** VISE: Unable to allocate memory ***\n\n\n");
270 memset(queue
+ queue_size
, 0, (new_size
- queue_size
) * sizeof(image
*));
271 queue_size
= new_size
;
276 * Definition map. Unit-depth image whose pixels are nonzero where
277 * the image is defined.
280 virtual const image
*get_defined() const = 0;
286 virtual void sync(int n
) {
287 assert (step_num
>= -1);
288 for (int i
= step_num
+ 1; i
<= n
; i
++) {
289 if (queue_size
> 0 && step_num
>= 0) {
291 * Shift the current queue so that the new head remains at the
292 * zero index. There are more time-efficient ways to handle
293 * queues, but the benefits are not clear in this case.
295 delete queue
[queue_size
- 1];
296 for (int i
= queue_size
- 1; i
> 0; i
--) {
297 queue
[i
] = queue
[i
- 1];
299 queue
[0] = get_image()->clone("Render queue clone");
308 * Perform any final rendering steps. Return a non-zero value if
317 * Set point rendering bounds, if possible.
320 virtual void init_point_renderer(unsigned int h
, unsigned int w
, unsigned int d
) {
322 fprintf(stderr
, "Error: init_point_renderer() not supported by this renderer\n");
330 virtual void point_render(unsigned int i
, unsigned int j
, unsigned int f
, transformation t
) {
332 fprintf(stderr
, "Error: point_render() not supported by this renderer\n");
337 * Finish point rendering.
340 virtual void finish_point_rendering() {
342 fprintf(stderr
, "Error: finish_point_rendering() not supported by this renderer\n");
347 directory
[entry_number
] = NULL
;
350 virtual void free_memory() = 0;
352 static void free_all_memory() {
354 for (int i
= 0; i
< ACTIVE_RENDERER_COUNT
; i
++)
355 if (directory
[i
] != NULL
) {
356 directory
[i
]->free_memory();
361 directory_length
= 0;
365 static void reset() {