1 /****************************************************************************
2 
3  Copyright (C) 2002-2014 Gilles Debunne. All rights reserved.
4 
5  This file is part of the QGLViewer library version 2.7.2.
6 
7  http://www.libqglviewer.com - contact@libqglviewer.com
8 
9  This file may be used under the terms of the GNU General Public License
10  versions 2.0 or 3.0 as published by the Free Software Foundation and
11  appearing in the LICENSE file included in the packaging of this file.
12  In addition, as a special exception, Gilles Debunne gives you certain
13  additional rights, described in the file GPL_EXCEPTION in this package.
14 
15  libQGLViewer uses dual licensing. Commercial/proprietary software must
16  purchase a libQGLViewer Commercial License.
17 
18  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
19  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 
21 *****************************************************************************/
22 
23 #include "glview.h"
24 #include <iostream>
25 #include <qimage.h>
26 
27 #if QT_VERSION >= 0x040000
28 #include <QMouseEvent>
29 #endif
30 
31 using namespace qglviewer;
32 
33 //********************************************************************//
34 //                    Methode de la classe mere                       //
35 //********************************************************************//
36 
init()37 void GLView::init() {
38   setMouseBinding(Qt::NoModifiers, Qt::LeftButton, SELECT);
39   setMouseBinding(Qt::NoModifiers, Qt::RightButton, CAMERA, ROTATE);
40 
41   glEnable(GL_CULL_FACE);
42   /* lissage des couleurs sur les facettes */
43   glShadeModel(GL_SMOOTH);
44 /* activation de la normalisation des normales */
45 #ifdef GL_RESCALE_NORMAL // OpenGL 1.2 Only...
46   glEnable(GL_RESCALE_NORMAL);
47 #endif
48   glDisable(GL_COLOR_MATERIAL);
49 
50   /* activation des sources */
51   glEnable(GL_LIGHT0);
52   glEnable(GL_LIGHT1);
53   /* parametres des sources */
54   static GLfloat pos_source[2][4] = {{0.0, 0.0, 40.0, 0.8f},
55                                      {-40.0, 0.0, 0.0, 0.8f}};
56   static GLfloat colorLight[2][4] = {{1.0, 1.0, 1.0, 1.0},
57                                      {1.0, 1.0, 1.0, 1.0}};
58   /* Definition des sources: position */
59   glLightfv(GL_LIGHT0, GL_POSITION, pos_source[0]);
60   glLightfv(GL_LIGHT1, GL_POSITION, pos_source[1]);
61   /* puis intensite diffuse et speculaire */
62   glLightfv(GL_LIGHT0, GL_DIFFUSE, colorLight[0]);
63   glLightfv(GL_LIGHT0, GL_SPECULAR, colorLight[1]);
64   glLightfv(GL_LIGHT1, GL_DIFFUSE, colorLight[0]);
65   glLightfv(GL_LIGHT1, GL_SPECULAR, colorLight[1]);
66 
67   /* Definition de la texture */
68   QImage tex1, buf;
69   if (!buf.load("bois.jpg")) {
70     qWarning("Could not read image file, using single-color instead.");
71   } else {
72     /* Reglages des parametres de la texture */
73     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
74     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
75     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
76     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
77     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
78     /* Mise en memoire de la texture */
79     glGenTextures(1, &texture_bois);
80     glBindTexture(GL_TEXTURE_2D, texture_bois);
81     tex1 = QGLWidget::convertToGLFormat(buf); // flipped 32bit RGBA
82     gluBuild2DMipmaps(GL_TEXTURE_2D, 3, tex1.width(), tex1.height(), GL_RGBA,
83                       GL_UNSIGNED_BYTE, tex1.bits());
84     setofpiece->setTexture(texture_bois);
85   }
86 }
87 
select(const QMouseEvent * e)88 void GLView::select(const QMouseEvent *e) {
89   const int SENSITIVITY = 2;
90   const int NB_HITS_MAX = 64;
91 
92   GLdouble x = e->x();
93   GLdouble y = e->y();
94 
95   GLuint hits[NB_HITS_MAX];
96 
97   glSelectBuffer(NB_HITS_MAX, hits);
98   glRenderMode(GL_SELECT);
99   glInitNames();
100 
101   // Loads the matrices
102   glMatrixMode(GL_PROJECTION);
103   glLoadIdentity();
104   GLint viewport[4];
105   camera()->getViewport(viewport);
106   gluPickMatrix(x, y, SENSITIVITY, SENSITIVITY, viewport);
107 
108   camera()->loadProjectionMatrix(false);
109   camera()->loadModelViewMatrix();
110 
111   // Render scene with objects ids
112   // Init the name stack
113   glInitNames();
114   glPushName(255);
115 
116   // Draw the scene
117   drawWithId();
118 
119   // Get the results
120   GLint nb_hits = glRenderMode(GL_RENDER);
121   // Interpret results
122   unsigned int zMin = UINT_MAX;
123   int selected = -1;
124   for (int i = 0; i < nb_hits; ++i) {
125     if (hits[i * 4 + 1] < zMin) {
126       zMin = hits[i * 4 + 1];
127       selected = hits[i * 4 + 3];
128     }
129   }
130 
131   // Apply selected fonction
132   applySelection(selected);
133 }
134 
135 //********************************************************************//
136 //                    Methode de la classe fille vue des pieces       //
137 //********************************************************************//
applySelection(int select)138 void GLViewPieces::applySelection(int select) {
139   if (select != -1) {
140     setofpiece->setSelected(select);
141     updateGL();
142     Q_EMIT changeJoueur();
143   }
144 }
145 
draw()146 void GLViewPieces::draw() {
147   // on affiche les pieces
148   glTranslatef(-6.5, -6.5, -1.5);
149   setofpiece->paint(false);
150 }
151 
init()152 void GLViewPieces::init() {
153   GLView::init();
154 
155   setSceneRadius(12.0);
156   camera()->setPosition(Vec(30, 30, 30));
157   camera()->setUpVector(Vec(0, 0, 1));
158   camera()->lookAt(sceneCenter());
159   showEntireScene();
160 }
161 
162 //********************************************************************//
163 //                    Methode de la class fille vue du plateau        //
164 //********************************************************************//
applySelection(int select)165 void GLViewJeu::applySelection(int select) {
166   if (select != -1) {
167     setofpiece->placeSelectedPiece(select);
168     jeu.placePiece(select, setofpiece->getPiece());
169     updateGL();
170     Q_EMIT update();
171     Q_EMIT piecePlacee();
172     if (jeu.analyze())
173       Q_EMIT endGame();
174   }
175 }
176 
init()177 void GLViewJeu::init() {
178   GLView::init();
179 
180   /* decalage entre les facettes pleines et le maillage (pour les cases du
181    * plateau)  */
182   glEnable(GL_POLYGON_OFFSET_LINE);
183 
184   makePlateau();
185   jeu.init();
186 
187   setSceneCenter(Vec(9, 9, 0.5));
188   setSceneRadius(10.0);
189   camera()->setPosition(Vec(9, 35, 20));
190   camera()->setUpVector(Vec(0, 0, 1));
191   camera()->lookAt(sceneCenter());
192   showEntireScene();
193 }
194 
draw()195 void GLViewJeu::draw() {
196   // On affiche le plateau
197   glCallList(plateau);
198   // on affiche les pieces
199   setofpiece->paint(true);
200 }
201 
drawWithId()202 void GLViewJeu::drawWithId() {
203   float r = 1.5;
204   int dx = 20, ix;
205   double a, pasa = 2. * M_PI / (double)dx, x, y;
206 
207   for (int i = 0; i < 16; i++)
208     if (jeu.needDrawing(i)) {
209       glPushMatrix();
210       glTranslatef((i % 4) * 3.5 + 3.7, (i / 4) * 3.5 + 3.7, 0.);
211       glLoadName(i);
212       glBegin(GL_TRIANGLE_FAN);
213       glVertex3f(0., 0., 0.5);
214       for (ix = 0, a = 0.0; ix <= dx; ix++, a += pasa) {
215         x = r * cos(a);
216         y = -r * sin(a);
217         glVertex3d(x, y, 0.5);
218       }
219       glEnd();
220       glPopMatrix();
221     }
222 }
223 
makePlateau()224 void GLViewJeu::makePlateau() {
225   int i, j;
226   float taille = 18;
227   static GLfloat amb_diff[] = {0.15f, 0.15f, 0.15f};
228   static GLfloat ambiant[] = {0.85f, 0.4f, 0.35f};
229   static GLfloat specular1[] = {0.3f, 0.3f, 0.3f};
230   static GLfloat specular2[] = {0.0, 0.0, 0.0};
231   static GLfloat shininess = 120.0;
232 
233   plateau = glGenLists(1);
234   glNewList(plateau, GL_COMPILE);
235   glPushMatrix();
236   glTranslatef(9, 9, 0);
237   glRotatef(45, 0, 0, 1);
238   glScalef(1.1f, 1.1f, 1);
239   glTranslatef(-9, -9, 0);
240   // Couleur noire du plateau
241   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, amb_diff);
242   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular1);
243   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
244 
245   // dessous du plateau
246   glNormal3d(0, 0, -1);
247   for (j = 0; j < taille; j++) {
248     glBegin(GL_QUAD_STRIP);
249     for (i = 0; i <= taille; i++) {
250       glVertex3d(i, j, 0);
251       glVertex3d(i, j + 1, 0);
252     }
253     glEnd();
254   }
255 
256   // dessus du plateau
257   glNormal3d(0, 0, 1);
258   for (j = 0; j < taille; j++) {
259     glBegin(GL_QUAD_STRIP);
260     for (i = 0; i <= taille; i++) {
261       glVertex3d(i, j + 1, 0.5);
262       glVertex3d(i, j, 0.5);
263     }
264     glEnd();
265   }
266   // Couleur rose-orange des bords et des cercles
267   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, ambiant);
268   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular2);
269   // cote gauche
270   glNormal3d(0, -1, 0);
271   glBegin(GL_QUAD_STRIP);
272   for (i = 0; i <= taille; i++) {
273     glVertex3d(i, 0, 0.5);
274     glVertex3d(i, 0, 0);
275   }
276   glEnd();
277   // devant
278   glNormal3d(1, 0, 0);
279   glBegin(GL_QUAD_STRIP);
280   for (i = 0; i <= taille; i++) {
281     glVertex3d(taille, i, 0.5);
282     glVertex3d(taille, i, 0);
283   }
284   glEnd();
285 
286   // cote droit
287   glNormal3d(0, 1, 0);
288   glBegin(GL_QUAD_STRIP);
289   for (i = 0; i <= taille; i++) {
290     glVertex3f(i, taille, 0);
291     glVertex3f(i, taille, 0.5);
292   }
293   glEnd();
294   // derriere
295   glNormal3d(-1, 0, 0);
296   glBegin(GL_QUAD_STRIP);
297   for (i = 0; i <= taille; i++) {
298     glVertex3d(0, i, 0);
299     glVertex3d(0, i, 0.5);
300   }
301   glEnd();
302   glPopMatrix();
303 
304   // cases du plateau
305   glEnable(GL_LINE_SMOOTH);
306   glLineWidth(2.);
307   glNormal3d(0, 0, 1);
308 
309   float r = 1.5, R = 9.5;
310   int dx = 20, DX = 40, ix;
311   double a, pasa = 2. * M_PI / (double)dx, pasA = 2. * M_PI / (double)DX;
312   double x, y;
313   // Grand cercle
314   glPushMatrix();
315   glTranslatef(9, 9, 0);
316   glBegin(GL_LINE_LOOP);
317   for (ix = 0, a = 0.0; ix <= DX; ix++, a += pasA) {
318     x = R * cos(a);
319     y = R * sin(a);
320     glVertex3d(x, y, 0.51);
321   }
322   glEnd();
323   glPopMatrix();
324   // Petits cercles
325   for (int i = 0; i < 16; i++) {
326     glPushMatrix();
327     glTranslatef((i % 4) * 3.5 + 3.7, (i / 4) * 3.5 + 3.7, 0.);
328     glBegin(GL_LINE_LOOP);
329     for (ix = 0, a = 0.0; ix <= dx; ix++, a += pasa) {
330       x = r * cos(a);
331       y = r * sin(a);
332       glVertex3d(x, y, 0.51);
333     }
334     glEnd();
335     glPopMatrix();
336   }
337   glEndList();
338 }
339