*** empty log message ***
[universe.git] / retina.h
1
2 // Written and (C) by Francois Fleuret
3 // Contact <francois.fleuret@idiap.ch> for comments & bug reports
4
5 #ifndef RETINA_H
6 #define RETINA_H
7
8 #include <iostream>
9 #include <fstream>
10
11 using namespace std;
12
13 #include "misc.h"
14 #include "map.h"
15 #include "universe.h"
16
17 #include "simple_window.h"
18
19 class Retina : public Map {
20   static const int _width = 512, _height = 512;
21
22   class Tag {
23   public:
24     int index;
25     scalar_t red, green, blue;
26     Tag *next;
27   };
28
29   Universe *_universe;
30   Tag **_tag_map;
31
32   // We have our own stack of tags to avoid numerous news and deletes
33   Tag *_tag_stack, *_tag_stack_top;
34   scalar_t *_red_imap, *_green_imap, *_blue_imap;
35   int _current_polygon;
36   scalar_t _eye_x, _eye_y;
37
38   inline void protected_push_tag(int x, int y, scalar_t r, scalar_t g, scalar_t b) {
39     if(y >= 0 && y < _height) {
40       if(x < 0) x = 0;
41       else if(x >= _width) x = _width - 1;
42       int t = y * _width + x;
43       _tag_stack_top->next = _tag_map[t];
44       _tag_stack_top->index = _current_polygon;
45       _tag_stack_top->red = r;
46       _tag_stack_top->green = g;
47       _tag_stack_top->blue = b;
48       _tag_map[t] = _tag_stack_top;
49       _tag_stack_top++;
50     }
51   }
52
53   inline void push_tag(int x, int y, scalar_t r, scalar_t g, scalar_t b) {
54     int t = y * _width + x;
55     _tag_stack_top->next = _tag_map[t];
56     _tag_stack_top->index = _current_polygon;
57     _tag_stack_top->red = r;
58     _tag_stack_top->green = g;
59     _tag_stack_top->blue = b;
60     _tag_map[t] = _tag_stack_top;
61     _tag_stack_top++;
62   }
63
64   inline scalar_t red_sum(int xmin, int ymin, int xmax, int ymax) {
65     return _red_imap[xmax + (_width + 1) * ymax]
66       + _red_imap[xmin + (_width + 1) * ymin]
67       - _red_imap[xmax + (_width + 1) * ymin]
68       - _red_imap[xmin + (_width + 1) * ymax];
69   }
70
71   inline scalar_t green_sum(int xmin, int ymin, int xmax, int ymax) {
72     return _green_imap[xmax + (_width + 1) * ymax]
73       + _green_imap[xmin + (_width + 1) * ymin]
74       - _green_imap[xmax + (_width + 1) * ymin]
75       - _green_imap[xmin + (_width + 1) * ymax];
76   }
77
78   inline scalar_t blue_sum(int xmin, int ymin, int xmax, int ymax) {
79     return _blue_imap[xmax + (_width + 1) * ymax]
80       + _blue_imap[xmin + (_width + 1) * ymin]
81       - _blue_imap[xmax + (_width + 1) * ymin]
82       - _blue_imap[xmin + (_width + 1) * ymax];
83   }
84
85 public:
86
87   inline int width() { return _width; }
88   inline int height() { return _height; }
89   inline void set_location(scalar_t x, scalar_t y) { _eye_x = x; _eye_y = y; }
90
91   Retina(Universe *universe);
92   ~Retina();
93   void reset();
94
95   void draw_polygon(Polygon *p, scalar_t delta_x, scalar_t delta_y);
96   void fill();
97
98   void raw_rectangle(unsigned char *image, int xmin, int ymin, int w, int h,
99                      scalar_t red, scalar_t green, scalar_t blue);
100
101   void update_map();
102   void draw_on_universe(SimpleWindow *window);
103   void draw_parameters(int x0, int y0, SimpleWindow *window);
104
105   void save_as_ppm(const char *filename);
106 };
107
108 #endif