1 /*
2    File:        MenuGrid.cpp
3   Description: Menu graphics management
4   Program:     BlockOut
5   Author:      Jean-Luc PONS
6 
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2 of the License, or
10   (at your option) any later version.
11 
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16 */
17 
18 #include "MenuGrid.h"
19 
20 // ----------------------------------------------------------------
21 
MenuGrid()22 MenuGrid::MenuGrid() {
23 
24   gridList = 0;
25   redList = 0;
26   blueList = 0;
27   topList = 0;
28   nwList = 0;
29   neList = 0;
30   swList = 0;
31   seList = 0;
32   bnList = 0;
33   bwList = 0;
34   bsList = 0;
35   beList = 0;
36   memset(matrix,0,sizeof(matrix));
37 
38   // Initialiase order matrix
39   int i,j;
40   int dist[GRID_WIDTH*GRID_HEIGHT];
41   for(i=0;i<GRID_WIDTH;i++) {
42     for(j=0;j<GRID_HEIGHT;j++) {
43       orderMatrix[i + GRID_WIDTH*j].x = i;
44       orderMatrix[i + GRID_WIDTH*j].y = j;
45       dist[i + GRID_WIDTH*j] = (i-GRID_WIDTH/2) * (i-GRID_WIDTH/2) + (j-GRID_HEIGHT/2) * (j-GRID_HEIGHT/2);
46     }
47   }
48 
49   // Sort
50   BOOL end = FALSE;
51   i=0;
52   j=GRID_WIDTH*GRID_HEIGHT-1;
53 
54   while(!end) {
55     end = TRUE;
56     for(i=0;i<j;i++) {
57       if( dist[i]<dist[i+1] ) {
58 
59         // Swap dist
60         int tmp = dist[i];
61         dist[i] = dist[i+1];
62         dist[i+1] = tmp;
63         // Swap orderMatrix
64         POINT2D tmp2 = orderMatrix[i];
65         orderMatrix[i] = orderMatrix[i+1];
66         orderMatrix[i+1] = tmp2;
67 
68         end = FALSE;
69       }
70     }
71     j--;
72   }
73 
74 }
75 
76 // ----------------------------------------------------------------
77 
Clear()78 void MenuGrid::Clear() {
79   memset(matrix,0,sizeof(matrix));
80 }
81 
82 // ----------------------------------------------------------------
83 
SetValue(int x,int y,int value)84 void MenuGrid::SetValue(int x,int y,int value) {
85   matrix[x + GRID_WIDTH*y] = value;
86 }
87 
88 // ----------------------------------------------------------------
89 
Create()90 int MenuGrid::Create() {
91 
92   // Global var
93   cSide  = 0.1f;
94   startX = -(float)GRID_WIDTH  * cSide / 2.0f;
95   startY = -(float)GRID_HEIGHT * cSide / 2.0f;
96   startZ = 3.0f + cSide;
97 
98   if( !CreateGrid() ) return GL_FAIL;
99   if( !CreateCube() ) return GL_FAIL;
100 
101   return GL_OK;
102 
103 }
104 
105 // ----------------------------------------------------------------
106 
CreateGrid()107 int MenuGrid::CreateGrid() {
108 
109   // Material
110   memset (&gridMaterial, 0, sizeof (GLMATERIAL));
111   gridMaterial.Diffuse.r = 1.0f;
112   gridMaterial.Diffuse.g = 1.0f;
113   gridMaterial.Diffuse.b = 1.0f;
114   gridMaterial.Ambient.r = 0.0f;
115   gridMaterial.Ambient.g = 0.5f;
116   gridMaterial.Ambient.b = 0.0f;
117 
118   // Grid
119   gridList = glGenLists(1);
120   glNewList(gridList,GL_COMPILE);
121   glBegin(GL_LINES);
122   for(int i=0;i<=GRID_WIDTH;i++) {
123     glVertex3f(startX + (i*cSide) - cSide/2.0f, -startY , startZ);
124     glVertex3f(startX + (i*cSide) - cSide/2.0f,  startY , startZ);
125   }
126   for(int i=0;i<=GRID_HEIGHT;i++) {
127     glVertex3f( -startX - cSide/2.0f, startY + (i*cSide) , startZ );
128     glVertex3f(  startX - cSide/2.0f, startY + (i*cSide) , startZ );
129   }
130   glEnd();
131   glEndList();
132 
133   return GL_OK;
134 
135 }
136 
137 // ----------------------------------------------------------------
138 
CreateCube()139 int MenuGrid::CreateCube() {
140 
141   // Material
142   memset (&redMaterial, 0, sizeof (GLMATERIAL));
143   redMaterial.Diffuse.r = 0.5f;
144   redMaterial.Diffuse.g = 0.0f;
145   redMaterial.Diffuse.b = 0.0f;
146   redMaterial.Ambient.r = 1.0f;
147   redMaterial.Ambient.g = 0.0f;
148   redMaterial.Ambient.b = 0.0f;
149 
150   // Red face
151   redList = glGenLists(1);
152   glNewList(redList,GL_COMPILE);
153   glBegin(GL_QUADS);
154 
155   glNormal3f(0.0f,0.0f,-1.0f);
156   glVertex3f(0 * cSide + startX,
157              1 * cSide + startY,
158             -1 * cSide + startZ);
159 
160   glNormal3f(0.0f,0.0f,-1.0f);
161   glVertex3f( 1 * cSide + startX,
162               1 * cSide + startY,
163              -1 * cSide + startZ);
164 
165   glNormal3f(0.0f,0.0f,-1.0f);
166   glVertex3f( 1 * cSide + startX,
167               0 * cSide + startY,
168              -1 * cSide + startZ);
169 
170   glNormal3f(0.0f,0.0f,-1.0f);
171   glVertex3f( 0 * cSide + startX,
172               0 * cSide + startY,
173              -1 * cSide + startZ );
174   glEnd();
175   glEndList();
176 
177   // Material
178   memset (&blueMaterial, 0, sizeof (GLMATERIAL));
179   blueMaterial.Diffuse.r = 0.0f;
180   blueMaterial.Diffuse.g = 0.0f;
181   blueMaterial.Diffuse.b = 1.0f;
182   blueMaterial.Ambient.r = 0.2f;
183   blueMaterial.Ambient.g = 0.2f;
184   blueMaterial.Ambient.b = 0.7f;
185 
186   // Blue faces
187   blueList = glGenLists(1);
188   glNewList(blueList,GL_COMPILE);
189   glBegin(GL_QUADS);
190 
191   // Face 1
192   glNormal3f(1.0f,0.0f,0.0f);
193   glVertex3f( 1 * cSide + startX,
194               1 * cSide + startY,
195              -1 * cSide + startZ);
196 
197   glNormal3f(1.0f,0.0f,0.0f);
198   glVertex3f( 1 * cSide + startX,
199               1 * cSide + startY,
200               0 * cSide + startZ);
201 
202   glNormal3f(1.0f,0.0f,0.0f);
203   glVertex3f( 1 * cSide + startX,
204               0 * cSide + startY,
205               0 * cSide + startZ);
206 
207   glNormal3f(1.0f,0.0f,0.0f);
208   glVertex3f( 1 * cSide + startX,
209               0 * cSide + startY,
210              -1 * cSide + startZ);
211 
212   // Face 2
213   glNormal3f(0.0f,1.0f,0.0f);
214   glVertex3f( 0 * cSide + startX,
215               1 * cSide + startY,
216               0 * cSide + startZ);
217 
218   glNormal3f(0.0f,1.0f,0.0f);
219   glVertex3f( 1 * cSide + startX,
220               1 * cSide + startY,
221               0 * cSide + startZ);
222 
223   glNormal3f(0.0f,1.0f,0.0f);
224   glVertex3f( 1 * cSide + startX,
225               1 * cSide + startY,
226              -1 * cSide + startZ);
227 
228   glNormal3f(0.0f,1.0f,0.0f);
229   glVertex3f( 0 * cSide + startX,
230               1 * cSide + startY,
231              -1 * cSide + startZ);
232 
233   // Face 3
234   glNormal3f(-1.0f,0.0f,0.0f);
235   glVertex3f( 0 * cSide + startX,
236               1 * cSide + startY,
237               0 * cSide + startZ);
238 
239   glNormal3f(-1.0f,0.0f,0.0f);
240   glVertex3f( 0 * cSide + startX,
241               1 * cSide + startY,
242              -1 * cSide + startZ);
243 
244   glNormal3f(-1.0f,0.0f,0.0f);
245   glVertex3f( 0 * cSide + startX,
246               0 * cSide + startY,
247              -1 * cSide + startZ);
248 
249   glNormal3f(-1.0f,0.0f,0.0f);
250   glVertex3f( 0 * cSide + startX,
251               0 * cSide + startY,
252               0 * cSide + startZ);
253 
254   // Face 4
255   glNormal3f(0.0f,-1.0f,0.0f);
256   glVertex3f( 1 * cSide + startX,
257               0 * cSide + startY,
258              -1 * cSide + startZ);
259 
260   glNormal3f(0.0f,-1.0f,0.0f);
261   glVertex3f( 1 * cSide + startX,
262               0 * cSide + startY,
263               0 * cSide + startZ);
264 
265   glNormal3f(0.0f,-1.0f,0.0f);
266   glVertex3f( 0 * cSide + startX,
267               0 * cSide + startY,
268               0 * cSide + startZ);
269 
270   glNormal3f(0.0f,-1.0f,0.0f);
271   glVertex3f( 0 * cSide + startX,
272               0 * cSide + startY,
273              -1 * cSide + startZ);
274 
275   glEnd();
276   glEndList();
277 
278   // Edge
279   topList = glGenLists(1);
280   glNewList(topList,GL_COMPILE);
281   glBegin(GL_LINES);
282   glVertex3f( 0 * cSide + startX,1 * cSide + startY,-1 * cSide + startZ);  // 0
283   glVertex3f( 1 * cSide + startX,1 * cSide + startY,-1 * cSide + startZ);  // 1
284 
285   glVertex3f( 1 * cSide + startX,1 * cSide + startY,-1 * cSide + startZ);  // 1
286   glVertex3f( 1 * cSide + startX,0 * cSide + startY,-1 * cSide + startZ);  // 2
287 
288   glVertex3f( 1 * cSide + startX,0 * cSide + startY,-1 * cSide + startZ);  // 2
289   glVertex3f( 0 * cSide + startX,0 * cSide + startY,-1 * cSide + startZ);  // 3
290 
291   glVertex3f( 0 * cSide + startX,0 * cSide + startY,-1 * cSide + startZ);  // 3
292   glVertex3f( 0 * cSide + startX,1 * cSide + startY,-1 * cSide + startZ);  // 0
293   glEnd();
294   glEndList();
295 
296   nwList = glGenLists(1);
297   glNewList(nwList,GL_COMPILE);
298   glBegin(GL_LINES);
299   glVertex3f( 1 * cSide + startX,1 * cSide + startY,-1 * cSide + startZ);  // 1
300   glVertex3f( 1 * cSide + startX,1 * cSide + startY,0 * cSide + startZ);   // 5
301   glEnd();
302   glEndList();
303 
304   neList = glGenLists(1);
305   glNewList(neList,GL_COMPILE);
306   glBegin(GL_LINES);
307   glVertex3f( 0 * cSide + startX,1 * cSide + startY,-1 * cSide + startZ);  // 0
308   glVertex3f( 0 * cSide + startX,1 * cSide + startY,0 * cSide + startZ);   // 4
309   glEnd();
310   glEndList();
311 
312   swList = glGenLists(1);
313   glNewList(swList,GL_COMPILE);
314   glBegin(GL_LINES);
315   glVertex3f( 1 * cSide + startX,0 * cSide + startY,-1 * cSide + startZ);  // 2
316   glVertex3f( 1 * cSide + startX,0 * cSide + startY,0 * cSide + startZ);   // 6
317   glEnd();
318   glEndList();
319 
320   seList = glGenLists(1);
321   glNewList(seList,GL_COMPILE);
322   glBegin(GL_LINES);
323   glVertex3f( 0 * cSide + startX,0 * cSide + startY,-1 * cSide + startZ);  // 3
324   glVertex3f( 0 * cSide + startX,0 * cSide + startY,0 * cSide + startZ);   // 7
325   glEnd();
326   glEndList();
327 
328   bnList = glGenLists(1);
329   glNewList(bnList,GL_COMPILE);
330   glBegin(GL_LINES);
331   glVertex3f( 0 * cSide + startX,1 * cSide + startY,0 * cSide + startZ);   // 4
332   glVertex3f( 1 * cSide + startX,1 * cSide + startY,0 * cSide + startZ);   // 5
333   glEnd();
334   glEndList();
335 
336   bwList = glGenLists(1);
337   glNewList(bwList,GL_COMPILE);
338   glBegin(GL_LINES);
339   glVertex3f( 1 * cSide + startX,1 * cSide + startY,0 * cSide + startZ);   // 5
340   glVertex3f( 1 * cSide + startX,0 * cSide + startY,0 * cSide + startZ);   // 6
341   glEnd();
342   glEndList();
343 
344   bsList = glGenLists(1);
345   glNewList(bsList,GL_COMPILE);
346   glBegin(GL_LINES);
347   glVertex3f( 1 * cSide + startX,0 * cSide + startY,0 * cSide + startZ);   // 6
348   glVertex3f( 0 * cSide + startX,0 * cSide + startY,0 * cSide + startZ);   // 7
349   glEnd();
350   glEndList();
351 
352   beList = glGenLists(1);
353   glNewList(beList,GL_COMPILE);
354   glBegin(GL_LINES);
355   glVertex3f( 0 * cSide + startX,0 * cSide + startY,0 * cSide + startZ);   // 7
356   glVertex3f( 0 * cSide + startX,1 * cSide + startY,0 * cSide + startZ);   // 4
357   glEnd();
358   glEndList();
359 
360   return GL_OK;
361 }
362 
363 // ----------------------------------------------------------------
364 
RenderCube(int x,int y)365 void MenuGrid::RenderCube(int x,int y) {
366 
367   glEnable(GL_CULL_FACE);
368   glCullFace(GL_BACK);
369   glEnable(GL_LIGHTING);
370   glTranslatef(x*cSide - cSide/2.0f,y*cSide,0.0f);
371 
372   // Draw faces
373   GLApplication::SetMaterial(&blueMaterial);
374   glCallList(blueList);
375   GLApplication::SetMaterial(&redMaterial);
376   glCallList(redList);
377 
378   // Edges
379   glDisable(GL_CULL_FACE);
380   glDisable(GL_LIGHTING);
381 
382   // Top edge
383   GLApplication::SetMaterial( &gridMaterial );
384   glCallList(topList);
385 
386   if( x<GRID_WIDTH/2 || y<GRID_HEIGHT/2) {
387     glCallList(nwList);
388   }
389 
390   if( x>GRID_WIDTH/2 || y<GRID_HEIGHT/2) {
391     glCallList(neList);
392   }
393 
394   if( x<GRID_WIDTH/2 || y>GRID_HEIGHT/2) {
395     glCallList(swList);
396   }
397 
398   if( x>GRID_WIDTH/2 || y>GRID_HEIGHT/2) {
399     glCallList(seList);
400   }
401 
402   if( x>GRID_WIDTH/2 ) {
403     glCallList(beList);
404   } else {
405     glCallList(bwList);
406   }
407 
408   if( y>GRID_HEIGHT/2 ) {
409     glCallList(bsList);
410   } else {
411     glCallList(bnList);
412   }
413 
414 }
415 
416 // ----------------------------------------------------------------
417 
Render()418 void MenuGrid::Render() {
419 
420   // Render grid
421   glDisable(GL_BLEND);
422   glDisable(GL_DEPTH_TEST);
423   glDisable(GL_LIGHTING);
424   glDisable(GL_TEXTURE_2D);
425   glLineWidth(1.0f);
426 
427   GLApplication::SetMaterial(&gridMaterial);
428   glCallList(gridList);
429 
430   // Render cubes
431   for(int i=0;i<GRID_WIDTH*GRID_HEIGHT;i++) {
432     int x = orderMatrix[i].x;
433     int y = orderMatrix[i].y;
434     glPushMatrix();
435     if( matrix[x + GRID_WIDTH*y] ) {
436       RenderCube(x,y);
437     }
438     glPopMatrix();
439   }
440 
441 }
442 
443 // ----------------------------------------------------------------
444 
InvalidateDeviceObjects()445 void MenuGrid::InvalidateDeviceObjects() {
446 
447      DELETE_LIST(gridList);
448     DELETE_LIST(blueList);
449     DELETE_LIST(redList);
450      DELETE_LIST(topList);
451      DELETE_LIST(nwList);
452      DELETE_LIST(neList);
453      DELETE_LIST(swList);
454      DELETE_LIST(seList);
455      DELETE_LIST(bnList);
456      DELETE_LIST(bwList);
457      DELETE_LIST(bsList);
458      DELETE_LIST(beList);
459 
460 }
461 
462