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