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.
33 //FIXME: This file may need GL/glext.h
45 #include "TextureLoader.h"
47 #include "Displayer.h"
48 #include "CelebrationManager.h"
49 #include "GarbageFlavorImage.h"
50 #include "SignManager.h"
51 #include "LightManager.h"
52 #include "MetaState.h"
53 #include "SparkleManager.h"
55 #include "ScoreRecordManager.h"
58 GLenum
Displayer::rescale_method
;
59 bool Displayer::opengl_version_1_2
;
62 int Displayer::main_window
;
63 GLfloat
Displayer::play_offset_y
;
65 #ifndef NO_MULTITEXTURING
69 PFNGLACTIVETEXTUREARBPROC
Displayer::glActiveTextureARB
;
70 PFNGLCLIENTACTIVETEXTUREARBPROC
Displayer::glClientActiveTextureARB
;
76 GLint
Displayer::screen_length
;
79 void Displayer::initialize ( int width
, int height
)
81 glutInitDisplayMode(GLUT_DOUBLE
| GLUT_RGBA
| GLUT_DEPTH
);
82 if (width
!= -1 && height
!= -1) {
83 glutInitWindowSize(width
, height
);
85 glutInitWindowSize(DC_WINDOW_PIXEL_STARTING_WIDTH
,
86 DC_WINDOW_PIXEL_STARTING_HEIGHT
);
88 main_window
= glutCreateWindow(GC_NAME
);
92 opengl_version_1_2
= false;
93 char *string
= (char *) glGetString(GL_VERSION
);
94 if (string
[0] > '1' || (string
[0] == '1' && string
[2] >= '2'))
95 opengl_version_1_2
= true;
97 // determine rescaling method for normals
98 if (opengl_version_1_2
)
99 rescale_method
= GL_RESCALE_NORMAL
;
101 rescale_method
= GL_NORMALIZE
;
103 #ifndef NO_MULTITEXTURING
104 // check for multitexturing
105 if (checkExtension("GL_ARB_multitexture")) {
107 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB
, &n
);
108 if (n
> 1) state
|= DS_MULTITEXTURING
;
113 // locate the extension function pointers
114 if (state
& DS_MULTITEXTURING
) {
116 = (PFNGLACTIVETEXTUREARBPROC
) wglGetProcAddress("glActiveTextureARB");
117 glClientActiveTextureARB
118 = (PFNGLCLIENTACTIVETEXTUREARBPROC
) wglGetProcAddress("glClientActiveTextureARB");
122 SparkleManager::initialize();
123 SignManager::initialize();
124 LightManager::initialize();
125 GarbageFlavorImage::initialize();
126 CelebrationManager::initialize();
127 ScoreRecordManager::initialize();
129 glClearColor(0.0f
, 0.0f
, 0.0f
, 0.0f
);
131 glEnable(GL_TEXTURE_2D
);
134 glEnable(GL_CLIP_PLANE_PLAY_FLOOR
);
135 const GLdouble play_bottom
[]
136 = { 0.0, 1.0, 0.0, DC_PLAY_HEIGHT
* DC_CAMERA_HEIGHT_RATIO
};
137 glClipPlane(GL_CLIP_PLANE_PLAY_FLOOR
, play_bottom
);
140 const GLfloat headlight_position
[]
141 = { 0.0f
, DC_HEADLIGHT_Y_OFFSET
, DC_HEADLIGHT_Z_OFFSET
, 1.0f
};
142 glLightfv(GL_LIGHT0
, GL_POSITION
, headlight_position
);
144 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
146 GLfloat white
[] = { 1.0f
, 1.0f
, 1.0f
, 1.0f
};
147 glTexEnvfv(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_COLOR
, white
);
148 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
150 generateBlockDisplayList();
151 generateGarbageExtras();
152 generateGarbageThinMiddleList();
153 generateGarbageThinCapList();
154 generateGarbageThickCornerList();
155 generateGarbageThickEdgeList();
156 generateGarbageThickMiddleList();
157 generateGarbageSmallList();
158 generateSparkleList();
160 generateSwapperList();
161 generateExternalCandy();
162 generateLevelLights();
166 String::readyLetterTextures();
167 generateNameTexture();
168 generateScoreRecord();
170 glMatrixMode(GL_PROJECTION
);
172 glFrustum(-(DC_PLAY_PIXEL_OFFSET_X
/ DC_PLAY_PIXEL_WIDTH
+ 0.5f
)
173 * DC_PLAY_WIDTH
, ((1.0f
- DC_PLAY_PIXEL_OFFSET_X
- DC_PLAY_PIXEL_WIDTH
)
174 / DC_PLAY_PIXEL_WIDTH
+ 0.5f
) * DC_PLAY_WIDTH
, -DC_PLAY_HEIGHT
175 * DC_CAMERA_HEIGHT_RATIO
, DC_PLAY_HEIGHT
* (1.0 - DC_CAMERA_HEIGHT_RATIO
),
177 glMatrixMode(GL_MODELVIEW
);
180 void Displayer::gameStart ( )
182 LightManager::resetHeadLight();
183 ScoreRecordManager::gameStart();
186 void Displayer::gameFinish ( )
188 CelebrationManager::gameFinish();
189 ScoreRecordManager::gameFinish();
192 void Displayer::cleanUp ( )
194 glutDestroyWindow(main_window
);
195 for (int n
= DC_NUMBER_USE_GARBAGE_TEX
; n
--; )
196 if (garbage_texture_data
[n
] != null
) {
197 delete [] garbage_texture_data
[n
];
198 garbage_texture_data
[n
] = null
;
200 for (int n
= DC_NUMBER_MESSAGE_TEX
; n
--; )
201 if (message_texture_data
[n
] != null
) {
202 delete [] message_texture_data
[n
];
203 message_texture_data
[n
] = null
;
206 if (player_rank_texture_data
!= null
) {
207 delete [] player_rank_texture_data
;
208 player_rank_texture_data
= null
;
210 if (MetaState::mode
& CM_SOLO
)
211 for (int n
= GC_SCORE_REC_LENGTH
- 1; n
--; )
212 if (record_texture_data
[n
] != null
) {
213 delete [] record_texture_data
[n
];
214 record_texture_data
[n
] = null
;
216 if (record_texture_data
!= null
) {
217 delete [] record_texture_data
;
218 record_texture_data
= null
;
221 String::freeLetterTextures();
224 void Displayer::reshape ( int width
, int height
)
226 if (DC_WINDOW_PIXEL_WIDTH
* height
/ DC_WINDOW_PIXEL_HEIGHT
!= width
) {
227 height
= (height
+ width
) >> 1;
228 glutReshapeWindow(DC_WINDOW_PIXEL_WIDTH
* height
/ DC_WINDOW_PIXEL_HEIGHT
,
231 glViewport(0, 0, width
, height
);
233 screen_length
= width
;
238 void Displayer::displayMeta ( )
240 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
244 // disables GL_BLEND internally
247 drawScoreToBeatMessage();
249 glDisable(GL_TEXTURE_2D
);
251 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
252 glEnable(GL_LIGHTING
);
253 glEnable(GL_COLOR_MATERIAL
);
255 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
258 if (CelebrationManager::draw_game
) {
260 LightManager::timeStepInitialize();
262 int hold_time_step
= Game::time_step
;
263 Game::time_step
= MetaState::final_time_step
;
265 calculatePlayOffset();
267 glEnable(GL_DEPTH_TEST
);
268 glEnable(GL_CULL_FACE
);
270 LightManager::setupHeadLightMeta();
274 glEnable(GL_TEXTURE_2D
);
278 glDisable(GL_CULL_FACE
);
279 glDisable(GL_TEXTURE_2D
);
283 glDisable(GL_DEPTH_TEST
);
285 LightManager::resetHeadLight();
287 Game::time_step
= hold_time_step
;
290 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
291 glDisable(GL_LIGHTING
);
292 glDisable(GL_COLOR_MATERIAL
);
295 glEnable(GL_TEXTURE_2D
);
299 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_BLEND
);
301 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
)) {
303 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
313 void Displayer::displayPlay ( )
315 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
319 // calls glDisable(GL_BLEND) internally
322 glDisable(GL_TEXTURE_2D
);
324 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
325 glEnable(GL_LIGHTING
);
326 glEnable(GL_COLOR_MATERIAL
);
328 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
331 if (!((Game::state
& (GS_PAUSED
| GS_SYNC_WAIT
)) == GS_PAUSED
)) {
333 LightManager::timeStepInitialize();
335 calculatePlayOffset();
337 glEnable(GL_DEPTH_TEST
);
338 glEnable(GL_CULL_FACE
);
340 LightManager::setupHeadLightPlay();
344 glEnable(GL_TEXTURE_2D
);
348 glDisable(GL_CULL_FACE
);
349 glDisable(GL_TEXTURE_2D
);
353 glDisable(GL_DEPTH_TEST
);
355 LightManager::resetHeadLight();
358 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
359 glDisable(GL_LIGHTING
);
360 glDisable(GL_COLOR_MATERIAL
);
363 glEnable(GL_TEXTURE_2D
);
365 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_BLEND
);
367 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
)) {
369 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
374 if (!(Game::state
& GS_PAUSED
))
382 bool Displayer::checkExtension ( char *extension_name
)
384 char *extensions
= (char *) glGetString(GL_EXTENSIONS
);
386 if (!extensions
) return false;
388 int length
= strlen(extension_name
);
389 char *end
= extensions
+ strlen(extensions
);
391 while (extensions
< end
) {
392 int n
= strcspn(extensions
, " ");
394 if (n
== length
&& strncmp(extension_name
, extensions
, n
) == 0)
404 void Displayer::screenShot ( )
406 static int count
= 0;
407 GLubyte
*image
= new GLubyte
[4 * screen_length
* screen_length
];
409 glReadPixels(0, 0, screen_length
, screen_length
, GL_RGBA
, GL_UNSIGNED_BYTE
,
412 ostringstream file_name
;
413 file_name
<< DC_SCREEN_SHOT_FILE_NAME_BASE
"_" << setw(GC_GARBAGE_TEX_NUMBER_DIGITS
)
414 << setfill('0') << count
<< ".tga" << ends
;
415 TextureLoader::createTGA(file_name
.str().c_str(), image
, screen_length
, screen_length
,
416 TL_SCREEN_SHOT_TGA_ID
);
418 MESSAGE("creating " << file_name
.str());