~ubuntu-branches/debian/squeeze/stellarium/squeeze

« back to all changes in this revision

Viewing changes to src/viewport_distorter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cédric Delfosse
  • Date: 2008-05-19 21:28:23 UTC
  • mfrom: (3.1.5 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080519212823-m5nfiuntxstxzxj7
Tags: 0.9.1-4
Add libxcursor-dev, libxfixes-dev, libxinerama-dev, libqt4-opengl-dev to
build-deps (Closes: #479906)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Stellarium
3
 
 * Copyright (C) Fabien Chereau
4
 
 * Author 2006 Johannes Gajdosik
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the GNU General Public License
8
 
 * as published by the Free Software Foundation; either version 2
9
 
 * of the License, or (at your option) any later version.
10
 
 *
11
 
 * This program 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.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
 
 */
20
 
 
21
 
#include "viewport_distorter.h"
22
 
#include "stel_core.h"
23
 
#include "spheric_mirror_calculator.h"
24
 
#include "init_parser.h"
25
 
 
26
 
#include "SDL_opengl.h"
27
 
 
28
 
class ViewportDistorterDummy : public ViewportDistorter {
29
 
private:
30
 
  friend class ViewportDistorter;
31
 
  string getType(void) const {return "none";}
32
 
  void init(const InitParser &conf) {}
33
 
  void distort(void) const {}
34
 
  bool distortXY(int &x,int &y) {return true;}
35
 
};
36
 
 
37
 
 
38
 
class ViewportDistorterFisheyeToSphericMirror : public ViewportDistorter {
39
 
private:
40
 
  friend class ViewportDistorter;
41
 
  ViewportDistorterFisheyeToSphericMirror(int screenW,int screenH,
42
 
                                          StelCore *core);
43
 
  ~ViewportDistorterFisheyeToSphericMirror(void);
44
 
  string getType(void) const {return "fisheye_to_spheric_mirror";}
45
 
  void init(const InitParser &conf);
46
 
  void distort(void) const;
47
 
  bool distortXY(int &x,int &y);
48
 
  const int screenW;
49
 
  const int screenH;
50
 
  unsigned int mirror_texture;
51
 
  int viewport_wh;
52
 
  float texture_used;
53
 
  struct VertexData {
54
 
    float color[4];
55
 
    float xy[2];
56
 
    double h;
57
 
  };
58
 
  VertexData *trans_array;
59
 
  int trans_width,trans_height;
60
 
  SphericMirrorCalculator calc;
61
 
};
62
 
 
63
 
 
64
 
ViewportDistorterFisheyeToSphericMirror
65
 
   ::ViewportDistorterFisheyeToSphericMirror(int screenW,int screenH,
66
 
                                             StelCore *core)
67
 
    :screenW(screenW),screenH(screenH),trans_array(0) {
68
 
  if (core->getProjectionType() == "fisheye") {
69
 
    core->setMaxFov(175.0);
70
 
  } else {
71
 
    cerr << "ViewportDistorterFisheyeToSphericMirror: "
72
 
         << "what are you doing? the projection type should be fisheye."
73
 
         << endl;
74
 
  }
75
 
  viewport_wh = (screenW < screenH) ? screenW : screenH;
76
 
  int texture_wh = 1;
77
 
  while (texture_wh < viewport_wh) texture_wh <<= 1;
78
 
  texture_used = viewport_wh / (float)texture_wh;
79
 
  
80
 
  glGenTextures(1, &mirror_texture);
81
 
  glBindTexture(GL_TEXTURE_2D, mirror_texture);
82
 
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
83
 
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
84
 
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
85
 
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
86
 
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
87
 
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture_wh, texture_wh, 0,
88
 
               GL_RGB, GL_UNSIGNED_BYTE, 0);
89
 
 
90
 
//  calc.setParams(Vec3d(0,-2,15),Vec3d(0,0,20),1,25,0.125);
91
 
}
92
 
 
93
 
void ViewportDistorterFisheyeToSphericMirror::init(const InitParser &conf) {
94
 
  calc.init(conf);
95
 
  const double gamma = conf.get_double("spheric_mirror","projector_gamma",0.45);
96
 
    // init transformation
97
 
  trans_width = screenW / 16;
98
 
  trans_height = screenH / 16;
99
 
  trans_array = new VertexData[(trans_width+1)*(trans_height+1)];
100
 
  double max_h = 0;
101
 
  for (int j=0;j<=trans_height;j++) {
102
 
    for (int i=0;i<=trans_width;i++) {
103
 
      VertexData &data(trans_array[(j*(trans_width+1)+i)]);
104
 
      Vec3d v,v_x,v_y;
105
 
      bool rc = calc.retransform(
106
 
                        (i-(trans_width>>1))/(double)trans_height,
107
 
                        (j-(trans_height>>1))/(double)trans_height,
108
 
                        v,v_x,v_y);
109
 
      data.h = rc ? (v_x^v_y).length() : 0.0;
110
 
      v[0] = -v[0];
111
 
      const double h = v[1];
112
 
      v[1] = v[2];
113
 
      v[2] = -h;
114
 
      const double oneoverh = 1./sqrt(v[0]*v[0]+v[1]*v[1]);
115
 
      const double a = 0.5 + atan(v[2]*oneoverh)/M_PI; // range: [0..1]
116
 
      double f = a* 180.0/175.0; // MAX_FOV=175.0 for fisheye
117
 
      f *= oneoverh;
118
 
      double x = (0.5 + v[0] * f);
119
 
      double y = (0.5 + v[1] * f);
120
 
      if (x < 0.0) {x=0.0;data.h=0;} else if (x > 1.0) {x=1.0;data.h=0;}
121
 
      if (y < 0.0) {y=0.0;data.h=0;} else if (y > 1.0) {y=1.0;data.h=0;}
122
 
      data.xy[0] = x*texture_used;
123
 
      data.xy[1] = y*texture_used;
124
 
      if (data.h > max_h) max_h = data.h;
125
 
    }
126
 
  }
127
 
  for (int j=0;j<=trans_height;j++) {
128
 
    for (int i=0;i<=trans_width;i++) {
129
 
      VertexData &data(trans_array[(j*(trans_width+1)+i)]);
130
 
      data.color[0] = data.color[1] = data.color[2] =
131
 
        (data.h<=0.0) ? 0.0 : exp(gamma*log(data.h/max_h));
132
 
      data.color[3] = 1.0f;
133
 
    }
134
 
  }
135
 
}
136
 
 
137
 
ViewportDistorterFisheyeToSphericMirror
138
 
    ::~ViewportDistorterFisheyeToSphericMirror(void) {
139
 
  if (trans_array) delete[] trans_array;
140
 
  glDeleteTextures(1,&mirror_texture);
141
 
}
142
 
 
143
 
bool ViewportDistorterFisheyeToSphericMirror::distortXY(int &x,int &y) {
144
 
    // linear interpolation:
145
 
  y = screenH-1-y;
146
 
  const float dx = (x&15)/16.0f;
147
 
  const int i = x >> 4;
148
 
  const float dy = (y&15)/16.0f;
149
 
  const int j = y >> 4;
150
 
  const float f00 = (1.0f-dx)*(1.0f-dy);
151
 
  const float f01 = (     dx)*(1.0f-dy);
152
 
  const float f10 = (1.0f-dx)*(     dy);
153
 
  const float f11 = (     dx)*(     dy);
154
 
  const VertexData *const v = trans_array + (j*(trans_width+1)+i);
155
 
  x = ((screenW-viewport_wh)>>1)
156
 
    + (int)floorf(0.5f +
157
 
                        (v[0].xy[0]*f00
158
 
                       + v[1].xy[0]*f01
159
 
                       + v[trans_width+1].xy[0]*f10
160
 
                       + v[trans_width+2].xy[0]*f11)*viewport_wh/texture_used);
161
 
  y = ((screenH-viewport_wh)>>1)
162
 
    + (int)floorf(0.5f +
163
 
                        ((v[0].xy[1]*f00
164
 
                       + v[1].xy[1]*f01
165
 
                       + v[trans_width+1].xy[1]*f10
166
 
                       + v[trans_width+2].xy[1]*f11)*viewport_wh/texture_used));
167
 
  y = screenH-1-y;
168
 
  return true;
169
 
}
170
 
 
171
 
void ViewportDistorterFisheyeToSphericMirror::distort(void) const {
172
 
  glViewport(0, 0, screenW, screenH);
173
 
  glMatrixMode(GL_PROJECTION);          // projection matrix mode
174
 
  glPushMatrix();                                               // store previous matrix
175
 
  glLoadIdentity();
176
 
  gluOrtho2D(0,screenW,0,screenH);                      // set a 2D orthographic projection
177
 
  glMatrixMode(GL_MODELVIEW);                   // modelview matrix mode
178
 
  glPushMatrix();
179
 
  glLoadIdentity();     
180
 
 
181
 
 
182
 
  glBindTexture(GL_TEXTURE_2D, mirror_texture);
183
 
  glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
184
 
                      (screenW-viewport_wh)>>1,(screenH-viewport_wh)>>1,
185
 
                      viewport_wh,viewport_wh);
186
 
 
187
 
  glEnable(GL_TEXTURE_2D);
188
 
 
189
 
  float color[4] = {1,1,1,1};
190
 
  glColor4fv(color);
191
 
  glDisable(GL_BLEND);
192
 
  glBindTexture(GL_TEXTURE_2D, mirror_texture);
193
 
 
194
 
/*
195
 
  glBegin(GL_QUADS);
196
 
  glTexCoord2f(0.0, 0.0); glVertex3f(screenW,0, 0.0);
197
 
  glTexCoord2f(texture_used, 0.0); glVertex3f(0,0, 0.0);
198
 
  glTexCoord2f(texture_used, texture_used); glVertex3f(0, screenH, 0.0);
199
 
  glTexCoord2f(0.0, texture_used); glVertex3f(screenW, screenH, 0.0);
200
 
  glEnd();
201
 
*/
202
 
 
203
 
 
204
 
  for (int j=0;j<trans_height;j++) {
205
 
    glBegin(GL_QUAD_STRIP);
206
 
    const VertexData *v0 = trans_array + j*(trans_width+1);
207
 
    const VertexData *v1 = v0 + (trans_width+1);
208
 
    for (int i=0;i<=trans_width;i++) {
209
 
      glColor4fv(v0[i].color);
210
 
      glTexCoord2fv(v0[i].xy);
211
 
      glVertex3f(i*16, j*16, 0.0);
212
 
      glColor4fv(v1[i].color);
213
 
      glTexCoord2fv(v1[i].xy);
214
 
      glVertex3f(i*16, (j+1)*16, 0.0);
215
 
    }
216
 
    glEnd();
217
 
  }
218
 
 
219
 
 
220
 
  glMatrixMode(GL_PROJECTION);          // Restore previous matrix
221
 
  glPopMatrix();
222
 
  glMatrixMode(GL_MODELVIEW);
223
 
  glPopMatrix();        
224
 
}
225
 
 
226
 
ViewportDistorter *ViewportDistorter::create(const string &type,
227
 
                                             int width,int height,
228
 
                                             StelCore *core) {
229
 
  if (type == "fisheye_to_spheric_mirror") {
230
 
    return new ViewportDistorterFisheyeToSphericMirror(width,height,core);
231
 
  }
232
 
  return new ViewportDistorterDummy;
233
 
}
234