doc/web: Place examples section more visibly.
[Ale.git] / d2 / render.h
blobe5825e64b998b0562fa08510abf6d08e7a80b918
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.
25 #ifndef __render_h__
26 #define __render_h__
28 #include "transformation.h"
29 #include "image.h"
30 #include "point.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.
41 class render {
42 private:
43 static unsigned int rx_count;
44 static exclusion *rx_parameters;
45 static int rx_show;
46 static render *directory[ACTIVE_RENDERER_COUNT];
47 static int directory_length;
48 static int extend;
49 static ale_pos scale_factor;
50 static ale_real wt;
52 image **queue;
53 unsigned int queue_size;
54 int step_num;
55 int entry_number;
57 static int strpfix(const char *a, const char *b) {
58 return strncmp(a, b, strlen(a));
61 protected:
63 * Constructor
65 render() {
66 if (directory_length >= ACTIVE_RENDERER_COUNT) {
67 fprintf(stderr, "\n\n*** Too many renderers in d2::render::render() ***\n\n");
68 exit(1);
71 directory[directory_length] = this;
72 entry_number = directory_length;
74 directory_length++;
76 step_num = -1;
77 queue = NULL;
78 queue_size = 0;
82 * Get extension state
84 int is_extend() {
85 return extend;
89 * Get the scale factor
91 ale_pos get_scale_factor() {
92 return scale_factor;
96 * Get the current step number
99 int get_step() {
100 return step_num;
104 * Perform the current rendering step.
107 virtual void step() = 0;
109 public:
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])
125 return 1;
127 return 0;
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])
139 return 1;
141 return 0;
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])
160 return 1;
162 return 0;
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])
174 return 1;
176 return 0;
179 static int render_count() {
180 return directory_length;
182 static render *render_num(int n) {
183 assert (n < directory_length);
184 return directory[n];
187 static void render_init(unsigned int _rx_count, exclusion *_rx_parameters,
188 int _rx_show, int _extend, ale_pos _scale_factor) {
189 rx_count = _rx_count;
190 rx_show = _rx_show;
191 extend = _extend;
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(ale_real _wt) {
211 wt = _wt;
214 static ale_real get_wt() {
215 return wt;
218 static int is_rx_show() {
219 return rx_show;
222 static unsigned int get_rx_count() {
223 return 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) {
241 sync(n);
243 if (n == (unsigned int) step_num)
244 return get_image();
246 n = step_num - n - 1;
248 assert (n < queue_size);
250 return queue[n];
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 *));
265 assert(queue);
266 if (queue == NULL) {
267 fprintf(stderr, "\n\n*** VISE: Unable to allocate memory ***\n\n\n");
268 exit(1);
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;
283 * Sync.
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");
302 step_num++;
303 step();
308 * Perform any final rendering steps. Return a non-zero value if
309 * anything changed.
312 virtual int sync() {
313 return 0;
317 * Set point rendering bounds, if possible.
320 virtual void init_point_renderer(unsigned int h, unsigned int w, unsigned int d) {
321 assert(0);
322 fprintf(stderr, "Error: init_point_renderer() not supported by this renderer\n");
323 exit(1);
327 * Point render.
330 virtual void point_render(unsigned int i, unsigned int j, unsigned int f, transformation t) {
331 assert(0);
332 fprintf(stderr, "Error: point_render() not supported by this renderer\n");
333 exit(1);
337 * Finish point rendering.
340 virtual void finish_point_rendering() {
341 assert(0);
342 fprintf(stderr, "Error: finish_point_rendering() not supported by this renderer\n");
343 exit(1);
346 virtual ~render() {
347 directory[entry_number] = NULL;
350 int entry() {
351 return entry_number;
354 virtual void free_memory() = 0;
356 static void free_entry(int n) {
357 if (directory[n] != NULL) {
358 directory[n]->free_memory();
359 delete directory[n];
360 directory[n] = NULL;
364 static void free_all_memory() {
365 for (int i = 0; i < ACTIVE_RENDERER_COUNT; i++)
366 free_entry(i);
368 directory_length = 0;
371 static void reset() {
372 free_all_memory();
376 #endif