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 for (int n
= DC_NUMBER_USE_GARBAGE_TEX
; n
--; )
195 if (garbage_texture_data
[n
] != null
) {
196 delete [] garbage_texture_data
[n
];
197 garbage_texture_data
[n
] = null
;
199 for (int n
= DC_NUMBER_MESSAGE_TEX
; n
--; )
200 if (message_texture_data
[n
] != null
) {
201 delete [] message_texture_data
[n
];
202 message_texture_data
[n
] = null
;
205 if (player_rank_texture_data
!= null
) {
206 delete [] player_rank_texture_data
;
207 player_rank_texture_data
= null
;
209 if (MetaState::mode
& CM_SOLO
)
210 for (int n
= GC_SCORE_REC_LENGTH
- 1; n
--; )
211 if (record_texture_data
[n
] != null
) {
212 delete [] record_texture_data
[n
];
213 record_texture_data
[n
] = null
;
215 if (record_texture_data
!= null
) {
216 delete [] record_texture_data
;
217 record_texture_data
= null
;
220 String::freeLetterTextures();
223 void Displayer::reshape ( int width
, int height
)
225 if (DC_WINDOW_PIXEL_WIDTH
* height
/ DC_WINDOW_PIXEL_HEIGHT
!= width
) {
226 height
= (height
+ width
) >> 1;
227 glutReshapeWindow(DC_WINDOW_PIXEL_WIDTH
* height
/ DC_WINDOW_PIXEL_HEIGHT
,
230 glViewport(0, 0, width
, height
);
232 screen_length
= width
;
237 void Displayer::displayMeta ( )
239 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
243 // disables GL_BLEND internally
246 drawScoreToBeatMessage();
248 glDisable(GL_TEXTURE_2D
);
250 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
251 glEnable(GL_LIGHTING
);
252 glEnable(GL_COLOR_MATERIAL
);
254 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
257 if (CelebrationManager::draw_game
) {
259 LightManager::timeStepInitialize();
261 int hold_time_step
= Game::time_step
;
262 Game::time_step
= MetaState::final_time_step
;
264 calculatePlayOffset();
266 glEnable(GL_DEPTH_TEST
);
267 glEnable(GL_CULL_FACE
);
269 LightManager::setupHeadLightMeta();
273 glEnable(GL_TEXTURE_2D
);
277 glDisable(GL_CULL_FACE
);
278 glDisable(GL_TEXTURE_2D
);
282 glDisable(GL_DEPTH_TEST
);
284 LightManager::resetHeadLight();
286 Game::time_step
= hold_time_step
;
289 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
290 glDisable(GL_LIGHTING
);
291 glDisable(GL_COLOR_MATERIAL
);
294 glEnable(GL_TEXTURE_2D
);
298 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_BLEND
);
300 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
)) {
302 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
312 void Displayer::displayPlay ( )
314 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
318 // calls glDisable(GL_BLEND) internally
321 glDisable(GL_TEXTURE_2D
);
323 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
324 glEnable(GL_LIGHTING
);
325 glEnable(GL_COLOR_MATERIAL
);
327 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
330 if (!((Game::state
& (GS_PAUSED
| GS_SYNC_WAIT
)) == GS_PAUSED
)) {
332 LightManager::timeStepInitialize();
334 calculatePlayOffset();
336 glEnable(GL_DEPTH_TEST
);
337 glEnable(GL_CULL_FACE
);
339 LightManager::setupHeadLightPlay();
343 glEnable(GL_TEXTURE_2D
);
347 glDisable(GL_CULL_FACE
);
348 glDisable(GL_TEXTURE_2D
);
352 glDisable(GL_DEPTH_TEST
);
354 LightManager::resetHeadLight();
357 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
358 glDisable(GL_LIGHTING
);
359 glDisable(GL_COLOR_MATERIAL
);
362 glEnable(GL_TEXTURE_2D
);
364 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_BLEND
);
366 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
)) {
368 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
373 if (!(Game::state
& GS_PAUSED
))
381 bool Displayer::checkExtension ( const char *extension_name
)
383 char *extensions
= (char *) glGetString(GL_EXTENSIONS
);
385 if (!extensions
) return false;
387 int length
= strlen(extension_name
);
388 char *end
= extensions
+ strlen(extensions
);
390 while (extensions
< end
) {
391 int n
= strcspn(extensions
, " ");
393 if (n
== length
&& strncmp(extension_name
, extensions
, n
) == 0)
403 void Displayer::screenShot ( )
405 static int count
= 0;
406 GLubyte
*image
= new GLubyte
[4 * screen_length
* screen_length
];
408 glReadPixels(0, 0, screen_length
, screen_length
, GL_RGBA
, GL_UNSIGNED_BYTE
,
411 ostringstream file_name
;
412 file_name
<< DC_SCREEN_SHOT_FILE_NAME_BASE
"_" << setw(GC_GARBAGE_TEX_NUMBER_DIGITS
)
413 << setfill('0') << count
<< ".tga" << ends
;
414 TextureLoader::createTGA(file_name
.str().c_str(), image
, screen_length
, screen_length
,
415 TL_SCREEN_SHOT_TGA_ID
);
417 MESSAGE("creating " << file_name
.str());