00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00028 #ifndef MULTIDISPLAY_H
00029 #define MULTIDISPLAY_H
00030
00031 #include <vector>
00032 #include <algorithm>
00033
00034 namespace Display
00035 {
00061 template <typename Renderer>
00062 class Multi
00063 {
00064 public:
00065 Multi();
00066 ~Multi();
00067
00074 void add(Renderer* ren, float scalingX, float scalingY, float scalingZ);
00075
00077 void remove(Renderer* ren);
00078
00080 void display() const;
00081
00082 private:
00085 class Display : public Renderer
00086 {
00088 void tearUp() const;
00089
00091 void tearDown() const;
00092
00094 void bind3Dtexture() const;
00095
00096 friend class Multi;
00097 };
00098
00100 struct PixelScaling
00101 {
00102 PixelScaling(float x,float y,float z) : x(x),y(y),z(z) {}
00103 float x,y,z;
00104 };
00105
00106 private:
00107 std::vector<Display*> m_renderers;
00108 std::vector<PixelScaling> m_scalings;
00109 };
00110 };
00111
00112 namespace Display
00113 {
00114 template <typename Renderer>
00115 Multi<Renderer>::Multi()
00116 {
00117 }
00118
00119 template <typename Renderer>
00120 Multi<Renderer>::~Multi()
00121 {
00122 }
00123
00124 template <typename Renderer>
00125 void Multi<Renderer>::add(Renderer* ren, float scalingX, float scalingY, float scalingZ)
00126 {
00127 Display* ptr = static_cast<Display*>(ren);
00128
00129
00130 if(std::find(m_renderers.begin(), m_renderers.end(), ptr) == m_renderers.end())
00131 {
00132 m_renderers.push_back(ptr);
00133 m_scalings.push_back(PixelScaling(scalingX, scalingY, scalingZ));
00134 }
00135 }
00136
00137 template <typename Renderer>
00138 void Multi<Renderer>::remove(Renderer* ren)
00139 {
00140 Display* ptr = static_cast<Display*>(ren);
00141
00142
00143 typename std::vector<PixelScaling>::iterator pit = m_scalings.begin();
00144 for(typename std::vector<Display*>::iterator it = m_renderers.begin(); it != m_renderers.end(); ++it, ++pit)
00145 {
00146 if(*it == ptr)
00147 {
00148 it = m_renderers.erase(it);
00149 pit = m_scalings.erase(pit);
00150 }
00151 }
00152 }
00153
00154 template <typename Renderer>
00155 void Multi<Renderer>::display() const
00156 {
00157
00158
00159 glMatrixMode(GL_MODELVIEW);
00160 float plane_matrix[16];
00161 glGetFloatv(GL_MODELVIEW_MATRIX, plane_matrix);
00162 Renderer::transp(plane_matrix);
00163 plane_matrix[12] = plane_matrix[13] = plane_matrix[14] = 0;
00164 Renderer::normalize(plane_matrix);
00165
00166
00167 float nbPlanes = 0;
00168 for(typename std::vector<Display*>::const_iterator it = m_renderers.begin(); it != m_renderers.end(); ++it)
00169 {
00170 float nb = (*it)->getNbRenderingPlanes() * (*it)->m_quality;
00171 if(nb > nbPlanes)
00172 nbPlanes = nb;
00173 }
00174 float step = 1.73f / nbPlanes;
00175
00176
00177
00178
00179
00180 float epsilon = step * 0.1;
00181 for(float d=-0.87f; d<0.87f; d+=step)
00182 {
00183 float offset = 0;
00184 for(unsigned int r=0; r<m_renderers.size(); ++r)
00185 {
00186
00187 float scaling[3] = {
00188 m_scalings[r].x,
00189 m_scalings[r].y,
00190 m_scalings[r].z,
00191 };
00192
00193 glMatrixMode(GL_TEXTURE);
00194 glPushMatrix();
00195 glTranslatef(+0.5f,+0.5f,+0.5f);
00196 glScalef(1.0f/scaling[0],
00197 1.0f/scaling[1],
00198 1.0f/scaling[2]);
00199 glTranslatef(-0.5f,-0.5f,-0.5f);
00200 glMatrixMode(GL_MODELVIEW);
00201
00202
00203
00204 plane_matrix[12] = (d+offset)*plane_matrix[8];
00205 plane_matrix[13] = (d+offset)*plane_matrix[9];
00206 plane_matrix[14] = (d+offset)*plane_matrix[10];
00207
00208
00209 m_renderers[r]->tearUp();
00210
00211
00212 m_renderers[r]->renderSlice(plane_matrix);
00213
00214
00215 m_renderers[r]->tearDown();
00216
00217
00218 offset += epsilon;
00219
00220 glMatrixMode(GL_TEXTURE);
00221 glPopMatrix();
00222 glMatrixMode(GL_MODELVIEW);
00223 }
00224 }
00225 }
00226
00227 template <typename Renderer>
00228 void Multi<Renderer>::Display::tearUp() const
00229 {
00230
00231 if(!this->m_gpu_program) return;
00232
00233
00234 glUseProgram(this->m_gpu_program);
00235
00236
00237 glActiveTexture(GL_TEXTURE1);
00238 glEnable(GL_TEXTURE_2D);
00239 glBindTexture(GL_TEXTURE_2D, this->m_lut_texture); glCheckError();
00240 glDisable(GL_TEXTURE_2D);
00241
00242
00243 glActiveTexture(GL_TEXTURE0);
00244 glEnable(GL_TEXTURE_3D);
00245 bind3Dtexture();
00246
00247
00248 glMatrixMode(GL_TEXTURE);
00249 glPushMatrix();
00250 glScalef(this->m_texture_scale[0], this->m_texture_scale[1], this->m_texture_scale[2]);
00251 glTranslatef(0.5,0.5,0.5);
00252
00253
00254 switch(this->m_rendering_mode)
00255 {
00256 case Display::VRT:
00257
00258 glEnable(GL_BLEND);
00259 glBlendEquation(GL_FUNC_ADD);
00260 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00261 break;
00262
00263 case Display::MIP:
00264
00265 glEnable(GL_BLEND);
00266 glBlendEquation(GL_MAX);
00267 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00268 break;
00269 default: break;
00270 };
00271 }
00272
00273 template <typename Renderer>
00274 void Multi<Renderer>::Display::tearDown() const
00275 {
00276
00277 if(!this->m_gpu_program) return;
00278
00279 glMatrixMode(GL_TEXTURE);
00280 glPopMatrix();
00281
00282 glDisable(GL_TEXTURE_3D);
00283
00284
00285 glUseProgram(0);
00286
00287 glMatrixMode(GL_MODELVIEW);
00288 }
00289
00290 template <typename Renderer>
00291 void Multi<Renderer>::Display::bind3Dtexture() const
00292 {
00293 glBindTexture(GL_TEXTURE_3D, this->m_data_texture); glCheckError();
00294 }
00295 }
00296
00297 #include <display/display4d.h>
00298
00299 namespace Display
00300 {
00301
00302 template <>
00303 void Multi<Volume4D>::Display::bind3Dtexture() const
00304 {
00305 glBindTexture(GL_TEXTURE_3D, this->m_data_texture[m_frame]); glCheckError();
00306 }
00307 };
00308
00309 #endif