1 /*
2 File: MenuGraphics.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 "Menu.h"
19
20 // ---------------------------------------------------------------------
21
InitGraphics()22 void Menu::InitGraphics() {
23
24 startMenuTime = 0.0f;
25
26 // Intitial rotation matrix of "BLOCKOUT" letters (Startup demo)
27
28 blOrgMatrix.Init33( 1.0f , 0.0f , 0.0f ,
29 0.0f ,-1.0f , 0.0f ,
30 0.0f , 0.0f ,-1.0f );
31
32 // Origin and end position of "BLOCKOUT" letters (Startup demo)
33
34 // B
35 startPos[0] = v(0.7f,-0.5f,0.0f);
36 endPos[0] = v(0.65f,0.9f ,3.0f);
37
38 // L
39 startPos[1] = v(0.25f,-0.5f,0.0f);
40 endPos[1] = v(0.25f,1.1f,3.0f);
41
42 // O
43 startPos[2] = v(0.0f,-0.5f,0.0f);
44 endPos[2] = v(-0.15f,1.1f,3.0f);
45
46 // C
47 startPos[3] = v(-0.25f,-0.5f,0.0f);
48 endPos[3] = v(-0.55f,1.1f,3.0f);
49
50 // K
51 startPos[4] = v(-0.7f,-0.5f,0.0f);
52 endPos[4]= v(-1.25f,0.9f,3.0f);
53
54 // O
55 startPos[5] = v(0.25f,-0.5f,0.0f);
56 endPos[5] = v(0.25f,0.4f,3.0f);
57
58 // U
59 startPos[6] = v(0.0f,-0.5f,0.0f);
60 endPos[6] = v(-0.15f,0.4f,3.0f);
61
62 // T
63 startPos[7] = v( -0.25f,-0.5f,0.0f);
64 endPos[7] = v(-0.55f,0.4f,3.0f);
65
66 // II
67 startPos[8] = v( -0.5f,-0.5f,0.0f);
68 endPos[8] = v(-1.35f,0.4f,3.0f);
69
70 for(int i=0;i<BLLETTER_NB;i++) {
71 isAdded[i] = FALSE;
72 isStarted[i] = FALSE;
73 }
74 animEnded = FALSE;
75 menuEscaped = FALSE;
76
77 }
78
79 // ---------------------------------------------------------------------
80
SetViewMatrix(GLfloat * mView)81 void Menu::SetViewMatrix(GLfloat *mView) {
82 memcpy(matView , mView , 16*sizeof(GLfloat));
83 }
84
GetViewMatrix()85 GLfloat *Menu::GetViewMatrix() {
86 return matView;
87 }
88
89 // ---------------------------------------------------------------------
90
FullRepaint()91 void Menu::FullRepaint() {
92 // For the 2 back buffers
93 fullRepaint = 2;
94 }
95
96 // ---------------------------------------------------------------------
97
Create(int width,int height)98 int Menu::Create(int width,int height) {
99
100 scrWidth = width;
101 scrHeight = height;
102
103 // Menu viewport
104 menuView.x = 0;
105 menuView.y = 0;
106 menuView.width = width;
107 menuView.height = height;
108
109 // Projection matrix
110 double fAspectRatio = (double)width / (double)height;
111 glMatrixMode( GL_PROJECTION );
112 glLoadIdentity();
113 gluPerspective(60.0,fAspectRatio,0.1,10.0);
114 glGetFloatv( GL_PROJECTION_MATRIX , matProj );
115
116 // Initialiase letters
117 if( !InitBlLetters() )
118 return GL_FAIL;
119
120 // Initialiase grid
121 if( !theGrid.Create() )
122 return GL_FAIL;
123
124 // Background
125 int x1 = fround( (float)width * 0.13f );
126 int y1 = fround( (float)height * 0.41f );
127 int x2 = fround( (float)width * 0.87f );
128 int y2 = fround( (float)height * 0.985f );
129 if( !background.RestoreDeviceObjects(STR("images/menuback.png"),STR("none"),width,height) )
130 return GL_FAIL;
131 background.UpdateSprite(x1,y1,x2,y2,0.0f,0.0f,1.0f,1.0f);
132
133 if(!background2.RestoreDeviceObjects(STR("images/menucredits.png"),STR("none"),width,height) )
134 return GL_FAIL;
135 background2.UpdateSprite(x1,y1,x2,y2,0.0f,0.0f,1.0f,1.0f);
136
137 // Font
138 wFont = fround( (float)width * 0.0205f );
139 hFont = fround( (float)height * 0.0449f );
140 if( !font.RestoreDeviceObjects(STR("images/menufont.png"),STR("none"),width,height) )
141 return GL_FAIL;
142
143 if(!font2.RestoreDeviceObjects(STR("images/menufont2.png"),STR("none"),width,height))
144 return GL_FAIL;
145
146 // onLine logo
147 if( !onlineLogo.RestoreDeviceObjects(STR("images/online.png"),STR("images/onlinea.png"),width,height) )
148 return GL_FAIL;
149
150 x1 = fround( 0.148f * (float)width );
151 y1 = fround( 0.413f * (float)height );
152 x2 = fround( 0.232f * (float)width );
153 y2 = fround( 0.524f * (float)height );
154 onlineLogo.UpdateSprite(x1,y1,x2,y2,0.0f,0.0f,1.0f,1.0f);
155
156 // Controls menu page
157 if( !controlsPage.Create(width,height) )
158 return GL_FAIL;
159
160 // Credits page
161 if( !creditsPage.Create(width,height) )
162 return GL_FAIL;
163
164 FullRepaint();
165
166 return GL_OK;
167 }
168
169 // ---------------------------------------------------------------------
170
RenderChar(int x,int y,int w,int h,BOOL selected,char c)171 void Menu::RenderChar(int x,int y,int w,int h,BOOL selected,char c) {
172
173 BOOL ok = FALSE;
174 int fnt = 1;
175
176 float sX = 0.0f;
177 float sY = 0.0f;
178 float eX = 0.0f;
179 float eY = 0.0f;
180
181 if( !selected && c==' ' ) {
182 // Do not render unselected space
183 return;
184 }
185
186 // Space
187 if( c==' ' ) {
188 sX = 12.0f * 0.0638f + 0.005f;
189 sY = 0.2930f;
190 eX = 13.0f * 0.0638f + 0.003f;
191 eY = 0.3828f;
192 ok = TRUE;
193 }
194
195 // Mapping
196 if( c>='A' && c<='O' ) {
197 sX = (float)(c-'A') * 0.0638f + 0.005f;
198 sY = 0.0f;
199 eX = (float)(c-'A'+1) * 0.0638f + 0.003f;
200 eY = 0.0898f;
201 ok = TRUE;
202 }
203
204 if( c>='P' && c<='Z' ) {
205 sX = (float)(c-'P') * 0.0638f + 0.005f;
206 sY = 0.0977f;
207 eX = (float)(c-'P'+1) * 0.0638f + 0.003f;
208 eY = 0.1875f;
209 ok = TRUE;
210 }
211
212 if( c>='a' && c<='o' ) {
213 sX = (float)(c-'a') * 0.0638f + 0.005f;
214 sY = 0.1953f;
215 eX = (float)(c-'a'+1) * 0.0638f + 0.003f;
216 eY = 0.2852f;
217 ok = TRUE;
218 }
219
220 if( c>='p' && c<='z' ) {
221 sX = (float)(c-'p') * 0.0638f + 0.005f;
222 sY = 0.2930f;
223 eX = (float)(c-'p'+1) * 0.0638f + 0.003f;
224 eY = 0.3828f;
225 ok = TRUE;
226 }
227
228 if( c>='0' && c<='9' ) {
229 sX = (float)(c-'0') * 0.0638f + 0.005f;
230 sY = 0.3906f;
231 eX = (float)(c-'0'+1) * 0.0638f + 0.003f;
232 eY = 0.4805f;
233 ok = TRUE;
234 }
235
236 if( c=='[' ) {
237 sX = 10.0f * 0.0638f + 0.005f;
238 sY = 0.3906f;
239 eX = 11.0f * 0.0638f + 0.003f;
240 eY = 0.4805f;
241 ok = TRUE;
242 }
243
244 if( c==']' ) {
245 sX = 11.0f * 0.0638f + 0.005f;
246 sY = 0.3906f;
247 eX = 12.0f * 0.0638f + 0.003f;
248 eY = 0.4805f;
249 ok = TRUE;
250 }
251
252 if( c==':' ) {
253 sX = 12.0f * 0.0638f + 0.005f;
254 sY = 0.3906f;
255 eX = 13.0f * 0.0638f + 0.003f;
256 eY = 0.4805f;
257 ok = TRUE;
258 }
259
260 if( c=='.' ) {
261 sX = 13.0f * 0.0638f + 0.005f;
262 sY = 0.3906f;
263 eX = 14.0f * 0.0638f + 0.003f;
264 eY = 0.4805f;
265 ok = TRUE;
266 }
267
268 if( c==',' ) {
269 sX = 14.0f * 0.0638f + 0.005f;
270 sY = 0.3906f;
271 eX = 15.0f * 0.0638f + 0.003f;
272 eY = 0.4805f;
273 ok = TRUE;
274 }
275
276 if( c=='-' ) {
277 sX = 11.0f * 0.0638f + 0.005f;
278 sY = 0.2930f;
279 eX = 12.0f * 0.0638f + 0.003f;
280 eY = 0.3828f;
281 ok = TRUE;
282 }
283
284 if( c=='+' ) {
285 sX = 11.0f * 0.0638f + 0.005f;
286 sY = 0.0977f;
287 eX = 12.0f * 0.0638f + 0.003f;
288 eY = 0.1875f;
289 ok = TRUE;
290 }
291
292 if( c=='/' ) {
293 sX = 12.0f * 0.0638f + 0.005f;
294 sY = 0.0977f;
295 eX = 13.0f * 0.0638f + 0.003f;
296 eY = 0.1875f;
297 ok = TRUE;
298 }
299
300 if( c=='{' ) {
301 sX = 13.0f * 0.0638f + 0.005f;
302 sY = 0.0977f;
303 eX = 14.0f * 0.0638f + 0.003f;
304 eY = 0.1875f;
305 ok = TRUE;
306 }
307
308 if( c=='@' ) {
309 sX = 14.0f * 0.0638f + 0.005f;
310 sY = 0.0977f;
311 eX = 15.0f * 0.0638f + 0.003f;
312 eY = 0.1875f;
313 ok = TRUE;
314 }
315
316 if( c=='\'' ) {
317 sX = 14.0f * 0.0638f + 0.005f;
318 sY = 0.2930f;
319 eX = 15.0f * 0.0638f + 0.003f;
320 eY = 0.3828f;
321 ok = TRUE;
322 }
323
324 if( c=='#' ) {
325 sX = 12.0f * 0.0638f + 0.005f;
326 sY = 0.2930f;
327 eX = 13.7f * 0.0638f + 0.003f;
328 eY = 0.3828f;
329 ok = TRUE;
330 }
331
332 if( c=='!' ) {
333 sX = 0.0f * 0.0638f + 0.005f;
334 sY = 0.0f;
335 eX = 1.0f * 0.0638f + 0.003f;
336 eY = 0.0898f;
337 ok = TRUE;
338 fnt = 2;
339 }
340
341 if( c=='$' ) {
342 sX = 1.0f * 0.0638f + 0.005f;
343 sY = 0.0f;
344 eX = 2.0f * 0.0638f + 0.003f;
345 eY = 0.0898f;
346 ok = TRUE;
347 fnt = 2;
348 }
349
350 if( c=='%' ) {
351 sX = 2.0f * 0.0638f + 0.005f;
352 sY = 0.0f;
353 eX = 3.0f * 0.0638f + 0.003f;
354 eY = 0.0898f;
355 ok = TRUE;
356 fnt = 2;
357 }
358
359 if( c=='&' ) {
360 sX = 3.0f * 0.0638f + 0.005f;
361 sY = 0.0f;
362 eX = 4.0f * 0.0638f + 0.003f;
363 eY = 0.0898f;
364 ok = TRUE;
365 fnt = 2;
366 }
367
368 if( c=='*' ) {
369 sX = 4.0f * 0.0638f + 0.005f;
370 sY = 0.0f;
371 eX = 5.0f * 0.0638f + 0.003f;
372 eY = 0.0898f;
373 ok = TRUE;
374 fnt = 2;
375 }
376
377 if( c=='(' ) {
378 sX = 5.0f * 0.0638f + 0.005f;
379 sY = 0.0f;
380 eX = 6.0f * 0.0638f + 0.003f;
381 eY = 0.0898f;
382 ok = TRUE;
383 fnt = 2;
384 }
385
386 if( c==')' ) {
387 sX = 6.0f * 0.0638f + 0.005f;
388 sY = 0.0f;
389 eX = 7.0f * 0.0638f + 0.003f;
390 eY = 0.0898f;
391 ok = TRUE;
392 fnt = 2;
393 }
394
395 if( c=='_' ) {
396 sX = 7.0f * 0.0638f + 0.005f;
397 sY = 0.0f;
398 eX = 8.0f * 0.0638f + 0.003f;
399 eY = 0.0898f;
400 ok = TRUE;
401 fnt = 2;
402 }
403
404 if( c=='?' ) {
405 sX = 8.0f * 0.0638f + 0.005f;
406 sY = 0.0f;
407 eX = 9.0f * 0.0638f + 0.003f;
408 eY = 0.0898f;
409 ok = TRUE;
410 fnt = 2;
411 }
412
413 if( c==';' ) {
414 sX = 9.0f * 0.0638f + 0.005f;
415 sY = 0.0f;
416 eX = 10.0f * 0.0638f + 0.003f;
417 eY = 0.0898f;
418 ok = TRUE;
419 fnt = 2;
420 }
421
422 if( !ok ) return;
423
424 if(selected) {
425 sY += 0.508f;
426 eY += 0.508f;
427 }
428
429 if( fnt==1 ) {
430 font.UpdateSprite(x,y,x+w,y+h,sX,sY,eX,eY);
431 font.Render();
432 } else {
433 font2.UpdateSprite(x,y,x+w,y+h,sX,sY,eX,eY);
434 font2.Render();
435 }
436
437 }
438
439 // ---------------------------------------------------------------------
440
RenderTitle(char * title)441 void Menu::RenderTitle(char *title) {
442
443 int lgth = (int)strlen(title);
444 int nwFont = fround((float)wFont*1.1f);
445 int nhFont = fround((float)hFont*1.1f);
446 int x1 = (scrWidth - (nwFont * lgth))/2;
447 int y1 = fround( 0.43f * (float)scrHeight );
448
449 for(int i=0;i<lgth;i++,x1+=nwFont) {
450 RenderChar(x1,y1,nwFont,nhFont,FALSE,title[i]);
451 }
452
453 }
454
455 // ---------------------------------------------------------------------
456
RenderText(int x,int y,BOOL selected,char * text)457 void Menu::RenderText(int x,int y,BOOL selected,char *text) {
458
459 float startLine = 0.515f;
460 float startColumn = 0.15f;
461 float lineHeight = 0.045f;
462
463 int lgth = (int)strlen(text);
464 int x1 = fround( startColumn*(float)scrWidth ) + x*wFont;
465 int y1 = fround( (startLine+y*lineHeight)*(float)scrHeight );
466
467 for(int i=0;i<lgth;i++,x1+=wFont) {
468 RenderChar(x1,y1,wFont,hFont,selected,text[i]);
469 }
470
471 }
472
473 // ---------------------------------------------------------------------
474
Render()475 void Menu::Render() {
476
477 // Disable texture, alpha and z buff
478 glDisable(GL_TEXTURE_2D);
479 glDisable(GL_DEPTH_TEST);
480 glDisable(GL_BLEND);
481
482 // Set Projection and viewport
483 glMatrixMode(GL_PROJECTION);
484 glLoadMatrixf(matProj);
485 glMatrixMode(GL_MODELVIEW);
486 glLoadMatrixf(matView);
487 glViewport(menuView.x,menuView.y,menuView.width,menuView.height);
488
489 // Clear and render the background
490 if( fullRepaint>0 || !animEnded ) {
491
492 // Menu startup demo
493 glClear( GL_COLOR_BUFFER_BIT );
494 theGrid.Render();
495
496 for(int i=0;i<BLLETTER_NB;i++) {
497 if( !isAdded[i] ) {
498 glMatrixMode(GL_MODELVIEW);
499 glLoadMatrixf(matView);
500 glMultMatrixf(blMatrix[i].GetGL());
501 blLetters[i]->Render(FALSE);
502 }
503 }
504
505 fullRepaint--;
506
507 }
508
509 if( animEnded ) {
510 if( selPage != &creditsPage )
511 background.Render();
512 else
513 background2.Render();
514 selPage->Render();
515 // Restore full viewport
516 glViewport(menuView.x,menuView.y,menuView.width,menuView.height);
517 }
518
519 }
520
521 // ---------------------------------------------------------------------
522
InvalidateDeviceObjects()523 void Menu::InvalidateDeviceObjects() {
524 controlsPage.InvalidateDeviceObjects();
525 creditsPage.InvalidateDeviceObjects();
526 theGrid.InvalidateDeviceObjects();
527 background.InvalidateDeviceObjects();
528 background2.InvalidateDeviceObjects();
529 font.InvalidateDeviceObjects();
530 font2.InvalidateDeviceObjects();
531 onlineLogo.InvalidateDeviceObjects();
532 for(int i=0;i<BLLETTER_NB;i++)
533 blLetters[i]->InvalidateDeviceObjects();
534 }
535
536 // ---------------------------------------------------------------------
537
ResetAnim(float fTime)538 void Menu::ResetAnim(float fTime) {
539
540 startMenuTime = fTime;
541 for(int i=0;i<BLLETTER_NB;i++) {
542 isAdded[i] = FALSE;
543 isStarted[i] = FALSE;
544 }
545 theGrid.Clear();
546 animEnded = FALSE;
547
548 }
549
550 // ---------------------------------------------------------------------
551
ProcessAnim(float fTime)552 void Menu::ProcessAnim(float fTime) {
553
554 if( startMenuTime==0.0f ) {
555 // Menu startup
556 startMenuTime = fTime;
557 }
558
559 // Compute letters transformation matrix
560 float angle = 0.0f;
561 float xPos = 0.0f;
562 float yPos = 0.0f;
563 float zPos = 0.0f;
564 GLMatrix t;
565 GLMatrix r;
566 float mTime = (fTime - startMenuTime);
567
568 for(int i=0;i<BLLETTER_NB;i++) {
569
570 float delay = (float)i * 0.25f; // 250ms delay between letters
571
572 if( mTime < delay ) {
573 angle = 0.0f;
574 xPos = startPos[i].x;
575 yPos = startPos[i].y;
576 zPos = startPos[i].z;
577 } else if( mTime > ANIMTIME+delay ) {
578
579 animEnded = (i==BLLETTER_NB-1);
580 if( animEnded ) FullRepaint();
581
582 // Add the letter to the grid
583 if( !isAdded[i] ) {
584
585 BLOCKITEM c[MAX_CUBE];
586 int nbCube;
587
588 isAdded[i] = TRUE;
589 int ox = fround( endPos[i].x*10.0f + 0.5f ) + GRID_WIDTH/2;
590 int oy = fround( endPos[i].y*10.0f ) + GRID_HEIGHT/2;
591 blLetters[i]->CopyCube(c,&nbCube);
592 for(int j=0;j<nbCube;j++) {
593 theGrid.SetValue( ox + c[j].x , oy + c[j].y , 1);
594 }
595 if(!menuEscaped)
596 soundManager->PlayTchh();
597
598 }
599
600 } else {
601
602 if( (i==1 || i==5) && !isStarted[i] ) {
603 soundManager->PlayWozz();
604 isStarted[i] = TRUE;
605 }
606
607 float ratio = (mTime-delay)/ANIMTIME;
608 angle = PI * ratio;
609 xPos = startPos[i].x + (endPos[i].x-startPos[i].x) * ratio;
610 yPos = startPos[i].y + (endPos[i].y-startPos[i].y) * ratio;
611 zPos = startPos[i].z + (endPos[i].z-startPos[i].z) * ratio;
612
613 }
614
615 t.Translate(xPos,yPos,zPos);
616 r.RotateX(angle);
617 blMatrix[i].Identity();
618 blMatrix[i].Multiply(&t);
619 blMatrix[i].Multiply(&r);
620 blMatrix[i].Multiply(&blOrgMatrix);
621
622 }
623
624
625 }
626
627 // ---------------------------------------------------------------------
628
InitBlLetters()629 int Menu::InitBlLetters() {
630
631 int hr;
632
633 VERTEX org = v(0.0f,0.0f,0.0f);
634
635 // "B" letter
636 blLetters[0] = new PolyCube();
637 blLetters[0]->AddCube(0,0,0);
638 blLetters[0]->AddCube(1,0,0);
639 blLetters[0]->AddCube(2,0,0);
640 blLetters[0]->AddCube(3,0,0);
641 blLetters[0]->AddCube(4,0,0);
642 blLetters[0]->AddCube(5,0,0);
643 blLetters[0]->AddCube(0,1,0);
644 blLetters[0]->AddCube(4,1,0);
645 blLetters[0]->AddCube(0,2,0);
646 blLetters[0]->AddCube(4,2,0);
647 blLetters[0]->AddCube(0,3,0);
648 blLetters[0]->AddCube(1,3,0);
649 blLetters[0]->AddCube(2,3,0);
650 blLetters[0]->AddCube(3,3,0);
651 blLetters[0]->AddCube(4,3,0);
652 blLetters[0]->AddCube(1,4,0);
653 blLetters[0]->AddCube(4,4,0);
654 blLetters[0]->AddCube(1,5,0);
655 blLetters[0]->AddCube(4,5,0);
656 blLetters[0]->AddCube(1,6,0);
657 blLetters[0]->AddCube(2,6,0);
658 blLetters[0]->AddCube(3,6,0);
659 blLetters[0]->AddCube(4,6,0);
660 blLetters[0]->AddCube(5,6,0);
661 hr = blLetters[0]->Create(0.1f,org,FALSE);
662 if(!hr) return GL_FAIL;
663
664 // "L" letter
665 blLetters[1] = new PolyCube();
666 blLetters[1]->AddCube(0,0,0);
667 blLetters[1]->AddCube(1,0,0);
668 blLetters[1]->AddCube(2,0,0);
669 blLetters[1]->AddCube(2,1,0);
670 blLetters[1]->AddCube(2,2,0);
671 blLetters[1]->AddCube(2,3,0);
672 blLetters[1]->AddCube(2,4,0);
673 hr = blLetters[1]->Create(0.1f,org,FALSE);
674 if(!hr) return GL_FAIL;
675
676 // "O" letter
677 blLetters[2] = new PolyCube();
678 blLetters[2]->AddCube(0,0,0);
679 blLetters[2]->AddCube(1,0,0);
680 blLetters[2]->AddCube(2,0,0);
681 blLetters[2]->AddCube(0,1,0);
682 blLetters[2]->AddCube(2,1,0);
683 blLetters[2]->AddCube(0,2,0);
684 blLetters[2]->AddCube(2,2,0);
685 blLetters[2]->AddCube(0,3,0);
686 blLetters[2]->AddCube(2,3,0);
687 blLetters[2]->AddCube(0,4,0);
688 blLetters[2]->AddCube(1,4,0);
689 blLetters[2]->AddCube(2,4,0);
690 hr = blLetters[2]->Create(0.1f,org,FALSE);
691 if(!hr) return GL_FAIL;
692
693 // "C" letter
694 blLetters[3] = new PolyCube();
695 blLetters[3]->AddCube(0,0,0);
696 blLetters[3]->AddCube(1,0,0);
697 blLetters[3]->AddCube(2,0,0);
698 blLetters[3]->AddCube(0,1,0);
699 blLetters[3]->AddCube(2,1,0);
700 blLetters[3]->AddCube(2,2,0);
701 blLetters[3]->AddCube(0,3,0);
702 blLetters[3]->AddCube(2,3,0);
703 blLetters[3]->AddCube(0,4,0);
704 blLetters[3]->AddCube(1,4,0);
705 blLetters[3]->AddCube(2,4,0);
706 hr = blLetters[3]->Create(0.1f,org,FALSE);
707 if(!hr) return GL_FAIL;
708
709
710 // "K" letter
711 blLetters[4] = new PolyCube();
712 blLetters[4]->AddCube(0,0,0);
713 blLetters[4]->AddCube(1,0,0);
714 blLetters[4]->AddCube(4,0,0);
715 blLetters[4]->AddCube(5,0,0);
716 blLetters[4]->AddCube(1,1,0);
717 blLetters[4]->AddCube(4,1,0);
718 blLetters[4]->AddCube(2,2,0);
719 blLetters[4]->AddCube(4,2,0);
720 blLetters[4]->AddCube(3,3,0);
721 blLetters[4]->AddCube(4,3,0);
722 blLetters[4]->AddCube(2,4,0);
723 blLetters[4]->AddCube(4,4,0);
724 blLetters[4]->AddCube(1,5,0);
725 blLetters[4]->AddCube(4,5,0);
726 blLetters[4]->AddCube(0,6,0);
727 blLetters[4]->AddCube(1,6,0);
728 blLetters[4]->AddCube(4,6,0);
729 blLetters[4]->AddCube(5,6,0);
730 hr = blLetters[4]->Create(0.1f,org,FALSE);
731 if(!hr) return GL_FAIL;
732
733 // "O" letter
734 blLetters[5] = new PolyCube();
735 blLetters[5]->AddCube(0,0,0);
736 blLetters[5]->AddCube(1,0,0);
737 blLetters[5]->AddCube(2,0,0);
738 blLetters[5]->AddCube(0,1,0);
739 blLetters[5]->AddCube(2,1,0);
740 blLetters[5]->AddCube(0,2,0);
741 blLetters[5]->AddCube(2,2,0);
742 blLetters[5]->AddCube(0,3,0);
743 blLetters[5]->AddCube(2,3,0);
744 blLetters[5]->AddCube(0,4,0);
745 blLetters[5]->AddCube(1,4,0);
746 blLetters[5]->AddCube(2,4,0);
747 hr = blLetters[5]->Create(0.1f,org,FALSE);
748 if(!hr) return GL_FAIL;
749
750 // "U" letter
751 blLetters[6] = new PolyCube();
752 blLetters[6]->AddCube(0,0,0);
753 blLetters[6]->AddCube(1,0,0);
754 blLetters[6]->AddCube(2,0,0);
755 blLetters[6]->AddCube(0,1,0);
756 blLetters[6]->AddCube(2,1,0);
757 blLetters[6]->AddCube(0,2,0);
758 blLetters[6]->AddCube(2,2,0);
759 blLetters[6]->AddCube(0,3,0);
760 blLetters[6]->AddCube(2,3,0);
761 blLetters[6]->AddCube(0,4,0);
762 blLetters[6]->AddCube(2,4,0);
763 hr = blLetters[6]->Create(0.1f,org,FALSE);
764 if(!hr) return GL_FAIL;
765
766 // "T" letter
767 blLetters[7] = new PolyCube();
768 blLetters[7]->AddCube(1,0,0);
769 blLetters[7]->AddCube(1,1,0);
770 blLetters[7]->AddCube(1,2,0);
771 blLetters[7]->AddCube(1,3,0);
772 blLetters[7]->AddCube(0,4,0);
773 blLetters[7]->AddCube(1,4,0);
774 blLetters[7]->AddCube(2,4,0);
775 hr = blLetters[7]->Create(0.1f,org,FALSE);
776 if(!hr) return GL_FAIL;
777
778 // "II" letter
779 blLetters[8] = new PolyCube();
780 blLetters[8]->AddCube(0,0,0);
781 blLetters[8]->AddCube(1,0,0);
782 blLetters[8]->AddCube(2,0,0);
783 blLetters[8]->AddCube(3,0,0);
784 blLetters[8]->AddCube(4,0,0);
785 blLetters[8]->AddCube(1,1,0);
786 blLetters[8]->AddCube(1,2,0);
787 blLetters[8]->AddCube(3,1,0);
788 blLetters[8]->AddCube(3,2,0);
789 blLetters[8]->AddCube(0,3,0);
790 blLetters[8]->AddCube(1,3,0);
791 blLetters[8]->AddCube(2,3,0);
792 blLetters[8]->AddCube(3,3,0);
793 blLetters[8]->AddCube(4,3,0);
794 hr = blLetters[8]->Create(0.1f,org,FALSE);
795 if(!hr) return GL_FAIL;
796
797 return GL_OK;
798 }
799