3 * Daniel Nelson - 8/26/0
5 * Copyright (C) 2000 Daniel Nelson
6 * Copyright (C) 2004 Andrew Sayman
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * Daniel Nelson - aluminumangel.org
26 * Handles all the prettyness; or uglyness, as it now stands.
34 # include <GL/glext.h>
44 # include <strstrea.h>
52 #include "TextureLoader.h"
54 #include "Displayer.h"
55 #include "CelebrationManager.h"
56 #include "GarbageFlavorImage.h"
57 #include "SignManager.h"
58 #include "LightManager.h"
59 #include "MetaState.h"
60 #include "SparkleManager.h"
62 #include "ScoreRecordManager.h"
65 GLenum
Displayer::rescale_method
;
66 bool Displayer::opengl_version_1_2
;
69 int Displayer::main_window
;
70 GLfloat
Displayer::play_offset_y
;
72 #ifndef NO_MULTITEXTURING
75 PFNGLACTIVETEXTUREARBPROC
Displayer::glActiveTextureARB
;
76 PFNGLCLIENTACTIVETEXTUREARBPROC
Displayer::glClientActiveTextureARB
;
81 GLint
Displayer::screen_length
;
84 void Displayer::initialize ( int width
, int height
)
86 glutInitDisplayMode(GLUT_DOUBLE
| GLUT_RGBA
| GLUT_DEPTH
);
87 if (width
!= -1 && height
!= -1) {
88 glutInitWindowSize(width
, height
);
90 glutInitWindowSize(DC_WINDOW_PIXEL_STARTING_WIDTH
,
91 DC_WINDOW_PIXEL_STARTING_HEIGHT
);
93 main_window
= glutCreateWindow(GC_NAME
);
97 opengl_version_1_2
= false;
98 char *string
= (char *) glGetString(GL_VERSION
);
99 if (string
[0] > '1' || (string
[0] == '1' && string
[2] >= '2'))
100 opengl_version_1_2
= true;
102 // determine rescaling method for normals
103 if (opengl_version_1_2
)
104 rescale_method
= GL_RESCALE_NORMAL
;
106 rescale_method
= GL_NORMALIZE
;
108 #ifndef NO_MULTITEXTURING
109 // check for multitexturing
110 if (checkExtension("GL_ARB_multitexture")) {
112 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB
, &n
);
113 if (n
> 1) state
|= DS_MULTITEXTURING
;
118 // locate the extension function pointers
119 if (state
& DS_MULTITEXTURING
) {
121 = (PFNGLACTIVETEXTUREARBPROC
) wglGetProcAddress("glActiveTextureARB");
122 glClientActiveTextureARB
123 = (PFNGLCLIENTACTIVETEXTUREARBPROC
) wglGetProcAddress("glClientActiveTextureARB");
129 string
= (char *) glGetString(GL_EXTENSIONS
);
130 cout
<< "OpenGL version: " << glGetString(GL_VERSION
)
131 << "\nOpenGL extensions:\n " << *string
;
132 for (char *p
= string
+ 1; *p
; p
++) {
133 if (isspace(*p
)) continue;
134 if (isspace(*(p
- 1)))
141 SparkleManager::initialize();
142 SignManager::initialize();
143 LightManager::initialize();
144 GarbageFlavorImage::initialize();
145 CelebrationManager::initialize();
146 ScoreRecordManager::initialize();
148 glClearColor(0.0f
, 0.0f
, 0.0f
, 0.0f
);
150 glEnable(GL_TEXTURE_2D
);
153 glEnable(GL_CLIP_PLANE_PLAY_FLOOR
);
154 const GLdouble play_bottom
[]
155 = { 0.0, 1.0, 0.0, DC_PLAY_HEIGHT
* DC_CAMERA_HEIGHT_RATIO
};
156 glClipPlane(GL_CLIP_PLANE_PLAY_FLOOR
, play_bottom
);
159 const GLfloat headlight_position
[]
160 = { 0.0f
, DC_HEADLIGHT_Y_OFFSET
, DC_HEADLIGHT_Z_OFFSET
, 1.0f
};
161 glLightfv(GL_LIGHT0
, GL_POSITION
, headlight_position
);
163 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
165 GLfloat white
[] = { 1.0f
, 1.0f
, 1.0f
, 1.0f
};
166 glTexEnvfv(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_COLOR
, white
);
167 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
169 generateBlockDisplayList();
170 generateGarbageExtras();
171 generateGarbageThinMiddleList();
172 generateGarbageThinCapList();
173 generateGarbageThickCornerList();
174 generateGarbageThickEdgeList();
175 generateGarbageThickMiddleList();
176 generateGarbageSmallList();
177 generateSparkleList();
179 generateSwapperList();
180 generateExternalCandy();
181 generateLevelLights();
185 String::readyLetterTextures();
186 generateNameTexture();
187 generateScoreRecord();
189 glMatrixMode(GL_PROJECTION
);
191 glFrustum(-(DC_PLAY_PIXEL_OFFSET_X
/ DC_PLAY_PIXEL_WIDTH
+ 0.5f
)
192 * DC_PLAY_WIDTH
, ((1.0f
- DC_PLAY_PIXEL_OFFSET_X
- DC_PLAY_PIXEL_WIDTH
)
193 / DC_PLAY_PIXEL_WIDTH
+ 0.5f
) * DC_PLAY_WIDTH
, -DC_PLAY_HEIGHT
194 * DC_CAMERA_HEIGHT_RATIO
, DC_PLAY_HEIGHT
* (1.0 - DC_CAMERA_HEIGHT_RATIO
),
196 glMatrixMode(GL_MODELVIEW
);
199 void Displayer::gameStart ( )
201 LightManager::resetHeadLight();
202 ScoreRecordManager::gameStart();
205 void Displayer::gameFinish ( )
207 CelebrationManager::gameFinish();
208 ScoreRecordManager::gameFinish();
211 void Displayer::cleanUp ( )
213 glutDestroyWindow(main_window
);
214 for (int n
= DC_NUMBER_USE_GARBAGE_TEX
; n
--; )
215 if (garbage_texture_data
[n
] != null
) {
216 delete [] garbage_texture_data
[n
];
217 garbage_texture_data
[n
] = null
;
219 for (int n
= DC_NUMBER_MESSAGE_TEX
; n
--; )
220 if (message_texture_data
[n
] != null
) {
221 delete [] message_texture_data
[n
];
222 message_texture_data
[n
] = null
;
225 if (player_rank_texture_data
!= null
) {
226 delete [] player_rank_texture_data
;
227 player_rank_texture_data
= null
;
229 if (MetaState::mode
& CM_SOLO
)
230 for (int n
= GC_SCORE_REC_LENGTH
- 1; n
--; )
231 if (record_texture_data
[n
] != null
) {
232 delete [] record_texture_data
[n
];
233 record_texture_data
[n
] = null
;
235 if (record_texture_data
!= null
) {
236 delete [] record_texture_data
;
237 record_texture_data
= null
;
240 String::freeLetterTextures();
243 void Displayer::reshape ( int width
, int height
)
245 if (DC_WINDOW_PIXEL_WIDTH
* height
/ DC_WINDOW_PIXEL_HEIGHT
!= width
) {
246 height
= (height
+ width
) >> 1;
247 glutReshapeWindow(DC_WINDOW_PIXEL_WIDTH
* height
/ DC_WINDOW_PIXEL_HEIGHT
,
250 glViewport(0, 0, width
, height
);
252 screen_length
= width
;
257 void Displayer::displayMeta ( )
259 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
263 // disables GL_BLEND internally
266 drawScoreToBeatMessage();
268 glDisable(GL_TEXTURE_2D
);
270 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
271 glEnable(GL_LIGHTING
);
272 glEnable(GL_COLOR_MATERIAL
);
274 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
277 if (CelebrationManager::draw_game
) {
279 LightManager::timeStepInitialize();
281 int hold_time_step
= Game::time_step
;
282 Game::time_step
= MetaState::final_time_step
;
284 calculatePlayOffset();
286 glEnable(GL_DEPTH_TEST
);
287 glEnable(GL_CULL_FACE
);
289 LightManager::setupHeadLightMeta();
293 glEnable(GL_TEXTURE_2D
);
297 glDisable(GL_CULL_FACE
);
298 glDisable(GL_TEXTURE_2D
);
302 glDisable(GL_DEPTH_TEST
);
304 LightManager::resetHeadLight();
306 Game::time_step
= hold_time_step
;
309 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
310 glDisable(GL_LIGHTING
);
311 glDisable(GL_COLOR_MATERIAL
);
314 glEnable(GL_TEXTURE_2D
);
318 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_BLEND
);
320 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
)) {
322 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
332 void Displayer::displayPlay ( )
334 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
338 // calls glDisable(GL_BLEND) internally
341 glDisable(GL_TEXTURE_2D
);
343 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
344 glEnable(GL_LIGHTING
);
345 glEnable(GL_COLOR_MATERIAL
);
347 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
350 if (!((Game::state
& (GS_PAUSED
| GS_SYNC_WAIT
)) == GS_PAUSED
)) {
352 LightManager::timeStepInitialize();
354 calculatePlayOffset();
356 glEnable(GL_DEPTH_TEST
);
357 glEnable(GL_CULL_FACE
);
359 LightManager::setupHeadLightPlay();
363 glEnable(GL_TEXTURE_2D
);
367 glDisable(GL_CULL_FACE
);
368 glDisable(GL_TEXTURE_2D
);
372 glDisable(GL_DEPTH_TEST
);
374 LightManager::resetHeadLight();
377 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
378 glDisable(GL_LIGHTING
);
379 glDisable(GL_COLOR_MATERIAL
);
382 glEnable(GL_TEXTURE_2D
);
384 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_BLEND
);
386 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
)) {
388 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
393 if (!(Game::state
& GS_PAUSED
))
401 bool Displayer::checkExtension ( char *extension_name
)
403 char *extensions
= (char *) glGetString(GL_EXTENSIONS
);
405 if (!extensions
) return false;
407 int length
= strlen(extension_name
);
408 char *end
= extensions
+ strlen(extensions
);
410 while (extensions
< end
) {
411 int n
= strcspn(extensions
, " ");
413 if (n
== length
&& strncmp(extension_name
, extensions
, n
) == 0)
423 void Displayer::screenShot ( )
425 static int count
= 0;
426 GLubyte
*image
= new GLubyte
[4 * screen_length
* screen_length
];
428 glReadPixels(0, 0, screen_length
, screen_length
, GL_RGBA
, GL_UNSIGNED_BYTE
,
431 ostringstream file_name
;
432 file_name
<< DC_SCREEN_SHOT_FILE_NAME_BASE
"_" << setw(GC_GARBAGE_TEX_NUMBER_DIGITS
)
433 << setfill('0') << count
<< ".tga" << ends
;
434 TextureLoader::createTGA(file_name
.str().c_str(), image
, screen_length
, screen_length
,
435 TL_SCREEN_SHOT_TGA_ID
);
437 MESSAGE("creating " << file_name
.str());