f562c49d7a575c4cc5f40eb8022f6c6c5932e96d
[universe.git] / retina.h
1
2 ////////////////////////////////////////////////////////////////////////////////
3 // This program is free software; you can redistribute it and/or              //
4 // modify it under the terms of the GNU General Public License                //
5 // version 2 as published by the Free Software Foundation.                    //
6 //                                                                            //
7 // This program is distributed in the hope that it will be useful, but        //
8 // WITHOUT ANY WARRANTY; without even the implied warranty of                 //
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU          //
10 // General Public License for more details.                                   //
11 //                                                                            //
12 // Written and (C) by François Fleuret                                        //
13 // Contact <francois.fleuret@epfl.ch> for comments & bug reports              //
14 ////////////////////////////////////////////////////////////////////////////////
15
16 #ifndef RETINA_H
17 #define RETINA_H
18
19 #include <iostream>
20 #include <fstream>
21
22 using namespace std;
23
24 #include "misc.h"
25 #include "map.h"
26 #include "universe.h"
27
28 #include "simple_window.h"
29
30 class Retina : public Map {
31   static const int _width = 512, _height = 512;
32
33   class Tag {
34   public:
35     int index;
36     scalar_t red, green, blue;
37     Tag *next;
38   };
39
40   Universe *_universe;
41   Tag **_tag_map;
42
43   // We have our own stack of tags to avoid numerous news and deletes
44   Tag *_tag_stack, *_tag_stack_top;
45   scalar_t *_red_imap, *_green_imap, *_blue_imap;
46   int _current_polygon;
47   scalar_t _eye_x, _eye_y;
48
49   inline void protected_push_tag(int x, int y, scalar_t r, scalar_t g, scalar_t b) {
50     if(y >= 0 && y < _height) {
51       if(x < 0) x = 0;
52       else if(x >= _width) x = _width - 1;
53       int t = y * _width + x;
54       _tag_stack_top->next = _tag_map[t];
55       _tag_stack_top->index = _current_polygon;
56       _tag_stack_top->red = r;
57       _tag_stack_top->green = g;
58       _tag_stack_top->blue = b;
59       _tag_map[t] = _tag_stack_top;
60       _tag_stack_top++;
61     }
62   }
63
64   inline void push_tag(int x, int y, scalar_t r, scalar_t g, scalar_t b) {
65     int t = y * _width + x;
66     _tag_stack_top->next = _tag_map[t];
67     _tag_stack_top->index = _current_polygon;
68     _tag_stack_top->red = r;
69     _tag_stack_top->green = g;
70     _tag_stack_top->blue = b;
71     _tag_map[t] = _tag_stack_top;
72     _tag_stack_top++;
73   }
74
75   inline scalar_t red_sum(int xmin, int ymin, int xmax, int ymax) {
76     return _red_imap[xmax + (_width + 1) * ymax]
77       + _red_imap[xmin + (_width + 1) * ymin]
78       - _red_imap[xmax + (_width + 1) * ymin]
79       - _red_imap[xmin + (_width + 1) * ymax];
80   }
81
82   inline scalar_t green_sum(int xmin, int ymin, int xmax, int ymax) {
83     return _green_imap[xmax + (_width + 1) * ymax]
84       + _green_imap[xmin + (_width + 1) * ymin]
85       - _green_imap[xmax + (_width + 1) * ymin]
86       - _green_imap[xmin + (_width + 1) * ymax];
87   }
88
89   inline scalar_t blue_sum(int xmin, int ymin, int xmax, int ymax) {
90     return _blue_imap[xmax + (_width + 1) * ymax]
91       + _blue_imap[xmin + (_width + 1) * ymin]
92       - _blue_imap[xmax + (_width + 1) * ymin]
93       - _blue_imap[xmin + (_width + 1) * ymax];
94   }
95
96 public:
97
98   inline int width() { return _width; }
99   inline int height() { return _height; }
100   inline void set_location(scalar_t x, scalar_t y) { _eye_x = x; _eye_y = y; }
101
102   Retina(Universe *universe);
103   ~Retina();
104   void reset();
105
106   void draw_polygon(Polygon *p, scalar_t delta_x, scalar_t delta_y);
107   void fill();
108
109   void raw_rectangle(unsigned char *image, int xmin, int ymin, int w, int h,
110                      scalar_t red, scalar_t green, scalar_t blue);
111
112   void update_map();
113   void draw_on_universe(SimpleWindow *window);
114   void draw_parameters(int x0, int y0, SimpleWindow *window);
115
116   void save_as_ppm(char *filename);
117 };
118
119 #endif