Moka Ihm Qt
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
gl-window.qt.cc
Go to the documentation of this file.
1 /*
2  * Moka : Un modeleur de 3-G-cartes.
3  * Copyright (C) 2004, Moka Team, Université de Poitiers, Laboratoire SIC
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * Copyright (C) 2009, Guillaume Damiand, CNRS, LIRIS,
6  * guillaume.damiand@liris.cnrs.fr, http://liris.cnrs.fr/
7  *
8  * This file is part of Moka
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #include "gl-window.qt.hh"
25 #include "window.qt.hh"
26 #include "HtmlEntities.hh"
27 
28 #include <QtGui/QCloseEvent>
29 #include <QtGui/QMouseEvent>
30 #include <QtGui/QPainter>
31 
32 using namespace GMap3d ;
33 
34 //*****************************************************
35 // Constructeurs
36 //*****************************************************
37 GLWindow :: GLWindow(TView AViewType , QWorkspace * parent ,
38  Window * owner , SelectBar * selection) :
39  QGLWidget(QGLFormat(QGL::SampleBuffers), parent , 0, Qt::SubWindow),
40  FViewType(AViewType),
41  FShared(NULL),
42  isShared(false),
43  FOwner(owner),
44  FSelection(selection),
45  FDragMode(false)
46 {
47  string str = getViewTypeString();
48  setWindowTitle(*HTML::decode(&str));
49  parent->addWindow(this);
50  setAcceptDrops(true);
51 }
52 
53 GLWindow :: GLWindow(TView AViewType , QWorkspace * parent ,
54  Window * owner , GLWindow * share ,
55  SelectBar * selection) :
56  QGLWidget(parent, share , Qt::SubWindow) ,
57  FViewType(AViewType) ,
58  FShared(share) ,
59  isShared(true) ,
60  FOwner(owner),
61  FSelection(selection),
62  FDragMode(false)
63 {
64  string str = getViewTypeString();
65  setWindowTitle(*HTML::decode(&str));
66  parent->addWindow(this);
67  setAcceptDrops(true);
68 }
69 //******************************************************
70 // Destructeur
71 //******************************************************
73 //******************************************************
74 // Accesseurs
75 //******************************************************
77 {
78  return FViewType;
79 }
80 
81 TViewId GLWindow :: getViewId() const
82 {
83  return FViewId;
84 }
85 
87 {
88  switch (FViewType)
89  {
90  case VIEW_XYZ: return string("Vue 3D");
91  case VIEW_XY: return string("Vue XY");
92  case VIEW_XZ: return string("Vue XZ");
93  case VIEW_YZ: return string("Vue YZ");
94  }
95 
96  return string("");
97 }
98 
100 { return FViewId; }
101 
103 { return FViewId; }
104 //********************************************************
105 // Fermeture fenetre
106 //********************************************************
107 void GLWindow::closeEvent(QCloseEvent * e)
108 {
109  // Si c'est la vue mere, on empeche sa fermeture
110  if (FViewId == 0)
111  if (e != NULL)
112  e -> ignore() ;
113  else
114  return ;
115  else
116  {
117  // Sinon on la detruit
118  FOwner->getControler()->viewDestroy(FViewId) ;
119  if (e != NULL)
120  e -> accept() ;
121  else
122  close() ;
123  }
124 }
125 //************************************************************
126 // Dessin de la scene
127 //************************************************************
129 {
130  QPainter p(this);
131 
132  makeCurrent();
133  glPushAttrib(GL_ALL_ATTRIB_BITS);
134  glMatrixMode(GL_PROJECTION);
135  glPushMatrix();
136  glMatrixMode(GL_MODELVIEW);
137  glPushMatrix();
138 
139  // Reset OpenGL parameters
140  glEnable(GL_DEPTH_TEST); // z-buffer
141  glDepthFunc(GL_LEQUAL);
142  // resizeGL(width(), height());
143 
144  glClearColor(0,0,0, 1);
145  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
146  glLoadIdentity() ;
147 
148  FOwner -> getControler() -> viewInit(FViewId);
149  FOwner -> getControler() -> viewDraw(FViewId) ;
150 
151  glMatrixMode(GL_MODELVIEW);
152  glPopMatrix();
153  glMatrixMode(GL_PROJECTION);
154  glPopMatrix();
155  glPopAttrib();
156 
157  if (FDragMode)
158  {
159  p.setPen(Qt::white) ;
160  p.drawRect(FStartX, FStartY, FCurX - FStartX, FCurY - FStartY);
161  if ( FOwner->getControler()->getModeDeselectionAtStop() )
162  p.drawText(FStartX, FStartY, "Deselect");
163  else
164  p.drawText(FStartX, FStartY, "Select");
165  }
166  p.end();
167 }
168 //************************************************************
169 // Modif de la taille de la fenetre
170 //************************************************************
171 void GLWindow :: resizeGL(int width , int height)
172 {
173  glViewport(0,0,width,height);
174 
175 // glMatrixMode(GL_PROJECTION);
176 // glLoadIdentity();
177 // glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0);
178 // glMatrixMode(GL_MODELVIEW);
179  }
180 //************************************************************
181 // Initialisation OpenGL
182 //************************************************************
184 {
185  glEnable(GL_DEPTH_TEST); // z-buffer
186  glDepthFunc(GL_LEQUAL);
187 
188  // glEnable(GL_NORMALIZE);
189 
190  glDisable(GL_BLEND);
191  // glEnable(GL_CULL_FACE);
192 
193  glEnable(GL_POLYGON_MODE);
194  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
195 
196  ::glEnable(GL_POLYGON_OFFSET_FILL);
197  ::glPolygonOffset(1.0f,1.0f);
198 
199  // Proprietes des surfaces ----------------------------------------------
200  static const GLfloat Material_Ks[] = {0.5, 0.5, 0.5, 1.0};
201  static const GLfloat Material_Ke[] = {0.0, 0.0, 0.0, 1.0};
202  static const GLfloat Material_Se = 100;
203 
204  glEnable(GL_COLOR_MATERIAL);
205  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR , Material_Ks);
206  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION , Material_Ke);
207  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, Material_Se);
208 
209  // Couleur des lumieres ----------------------------------------------------
210  static const GLfloat Light_Ka[] = {0.1, 0.1, 0.1, 1.0};
211  static const GLfloat Light_Kd[] = {1.0, 1.0, 1.0, 1.0};
212  static const GLfloat Light_Ks[] = {0.5, 0.5, 0.5, 1.0};
213 
214  glLightfv(GL_LIGHT0, GL_AMBIENT , Light_Ka);
215  glLightfv(GL_LIGHT0, GL_DIFFUSE , Light_Kd);
216  glLightfv(GL_LIGHT0, GL_SPECULAR, Light_Ks);
217  //**************************************************************************
218 
219  creation() ;
220 }
221 //************************************************************
222 // Creation de la vue dans le controleur
223 //************************************************************
225 {
226  if (FShared == NULL)
227  {
228  GMap3d :: CControlerGMap* controler = FOwner -> getControler() ;
229 
230  FViewId = controler->viewCreate(FViewType);
231 
232  controler->viewAddPrecompile(FViewId, PRECOMPILE_GRID);
233  controler->viewAddPrecompile(FViewId, PRECOMPILE_AXIS);
234  controler->viewAddPrecompile(FViewId, PRECOMPILE_AIMED_POINT);
235  controler->viewAddPrecompile(FViewId,
236  PRECOMPILE_OBJECT_TRANSFORMATION);
237  controler->viewAddPrecompile(FViewId, PRECOMPILE_PREVIEW);
238  controler->viewAddPrecompile(FViewId, PRECOMPILE_NORMAL_VECTOR);
239  controler->viewAddPrecompile(FViewId, PRECOMPILE_SEW);
240  controler->viewAddPrecompile(FViewId, PRECOMPILE_VERTEX);
241 #ifdef MODULE_SPAMOD
242  controler->viewAddPrecompile(FViewId, PRECOMPILE_SPAMOD);
243  controler->viewDisablePrecompile(FViewId, PRECOMPILE_SPAMOD);
244  controler->getParameterSpamod(FViewId)->setViewMode(SPAMOD_NONE);
245 #endif // MODULE_SPAMOD
246  controler->viewAddPrecompile(FViewId, PRECOMPILE_DART);
247  controler->viewAddPrecompile(FViewId, PRECOMPILE_FACE);
248 
249  controler->viewDisablePrecompile(FViewId, PRECOMPILE_SEW);
250  controler->viewDisablePrecompile(FViewId, PRECOMPILE_VERTEX);
251  controler->viewDisablePrecompile(FViewId, PRECOMPILE_FACE);
252  controler->viewDisablePrecompile(FViewId, PRECOMPILE_NORMAL_VECTOR);
253 
254  // On charge les paramètres de l'utilisateur
255  controler->loadAllParameters(FViewId);
256 
257  // Sauf pour le point de vue et de la position de l'oeil
258  // pour la vue mère (i.e. la première fois)
259  controler->getParameterAimedPosition(FViewId)->reinit();
260  controler->getParameterEyePosition(FViewId)->reinit();
261  }
262  else
263  {
264  FViewId = FOwner -> getControler() ->
265  viewCreateShare(FViewType , FShared->FViewId) ;
266  }
267 }
268 //*************************************************************
269 // Gestion des evenements
270 //*************************************************************
271 void GLWindow :: mousePressEvent(QMouseEvent * eb)
272 {
273  CControlerGMap * controler = FOwner -> getControler() ;
274  int y = this -> height() - eb -> y() ;
275 
276  if (eb->modifiers() == Qt::ControlModifier) // <CONTROL> key is pressed:
277  {
278  switch (eb -> button())
279  {
280  case Qt::LeftButton: // bouton gauche de la souris
281 
282  controler ->
283  operationModeIndependentStart(MODE_OPERATION_SCENE_TRANSLATION ,
284  FViewId, int (eb -> x()), y) ;
285  break;
286  case Qt::MidButton : // bouton milieu
287  controler ->
288  operationModeIndependentStart(MODE_OPERATION_SCENE_ROTATION,
289  FViewId, int(eb->x()), y);
290  break;
291  case Qt::RightButton : // bouton droit
292  controler ->
293  operationModeIndependentStart(MODE_OPERATION_SCENE_SCALE,
294  FViewId, int(eb->x()), y);
295  break;
296  default : {}
297  }
298  }
299  else
300  {
301  // Clic du bouton gauche de la souris
302  if (eb -> button() == Qt :: LeftButton)
303  {
304  controler->
305  setHalfSelectionOrbit(eb -> modifiers() == Qt :: ShiftModifier) ;
306  controler->operationModeStart(FViewId, int(eb->x()), y) ;
307 
308  CreationObjet * boite = FOwner -> getCreationActive() ;
309 
310  if (boite != NULL)
311  boite -> update() ;
312 
313  dialogOperations * op = FOwner -> getOperationActive() ;
314 
315  if (op != NULL)
316  op -> update() ;
317 
318  OptionsCarac * carac = FOwner -> getOptionsCaracActive() ;
319  if (carac != NULL)
320  carac -> update() ;
321 
322  FOwner -> repaint() ;
323 
324  if (controler->getMode() == MODE_OPERATION_SELECTION)
325  {
326  FStartX = int (eb -> x()); FStartY = int (eb -> y());
327  FCurX = FStartX; FCurY = FStartY;
328  FDragMode = true;
329 
330  if (eb -> modifiers() == Qt :: ShiftModifier)
331  controler -> setModeDeselectionAtStop();
332  }
333  }
334  else if (eb -> button() == Qt::MidButton)
335  {
336  if (controler->isInCreationMode())
337  {
338  CreationObjet * boite = FOwner -> getCreationActive() ;
339 
340  if (boite != NULL)
341  boite -> create() ;
342  }
343  else
344  {
345  FSelection -> niveauSuivant() ;
346 #ifdef MODULE_ARCHITECTURE
347  FOwner -> getFlapSelection() -> nextLevel();
348 #endif
349  }
350  }
351  else if (eb -> button() == Qt :: RightButton)
352  {
353  FOwner -> getControler() -> lookAtMouseClick(FViewId, eb -> x(), y);
354  repaint();
355  }
356  }
357 }
358 
359 void GLWindow :: mouseMoveEvent(QMouseEvent * em)
360 {
361  int y = this -> height() - em -> y() ;
362  FOwner -> getControler() -> operationModeMove(int (em -> x()), y) ;
363  CreationObjet * boite = FOwner -> getCreationActive() ;
364  if (boite != NULL)
365  boite -> update() ;
366 
367  dialogOperations * op = FOwner -> getOperationActive() ;
368 
369  if (op != NULL)
370  op -> update() ;
371 
372  if (FDragMode)
373  { FCurX = int (em -> x()); FCurY = int (em -> y()); }
374 
375  FOwner -> repaint() ;
376  this -> update() ;
377 }
378 
379 void GLWindow :: mouseReleaseEvent(QMouseEvent * eb)
380 {
381  CControlerGMap * controler = FOwner -> getControler();
382  FDragMode = false;
383  int y = this -> height() - eb -> y() ;
384 
385  controler -> operationModeStop(int(eb->x()), y);
386 
387  CreationObjet * boite = FOwner -> getCreationActive() ;
388  if (boite != NULL) boite -> update() ;
389 
390  dialogOperations * op = FOwner -> getOperationActive() ;
391  if (op != NULL) op -> update() ;
392 
393  FOwner -> repaint() ;
394  this -> update() ;
395 }
396 
398 {
399  if (e -> button() == Qt::LeftButton)
400  {
401  FOwner -> setDoubleCliquee(this) ;
402  }
403  else
404  {
405  mousePressEvent(e);
406  }
407 }