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.
29 #include "Displayer.h"
35 //FIXME: This file may need GL/glext.h
45 #include "TextureLoader.h"
47 #include "CelebrationManager.h"
48 #include "GarbageFlavorImage.h"
49 #include "SignManager.h"
50 #include "LightManager.h"
51 #include "MetaState.h"
52 #include "SparkleManager.h"
54 #include "ScoreRecordManager.h"
57 GLenum
Displayer::rescale_method
;
58 bool Displayer::opengl_version_1_2
;
61 int Displayer::main_window
;
62 GLfloat
Displayer::play_offset_y
;
64 #ifndef NO_MULTITEXTURING
68 PFNGLACTIVETEXTUREARBPROC
Displayer::glActiveTextureARB
;
69 PFNGLCLIENTACTIVETEXTUREARBPROC
Displayer::glClientActiveTextureARB
;
75 GLint
Displayer::screen_length
;
78 void Displayer::initialize ( int width
, int height
)
80 glutInitDisplayMode(GLUT_DOUBLE
| GLUT_RGBA
| GLUT_DEPTH
);
81 if (width
!= -1 && height
!= -1) {
82 glutInitWindowSize(width
, height
);
84 glutInitWindowSize(DC_WINDOW_PIXEL_STARTING_WIDTH
,
85 DC_WINDOW_PIXEL_STARTING_HEIGHT
);
87 main_window
= glutCreateWindow(GC_NAME
);
91 opengl_version_1_2
= false;
92 char *string
= (char *) glGetString(GL_VERSION
);
93 if (string
[0] > '1' || (string
[0] == '1' && string
[2] >= '2'))
94 opengl_version_1_2
= true;
96 // determine rescaling method for normals
97 if (opengl_version_1_2
)
98 rescale_method
= GL_RESCALE_NORMAL
;
100 rescale_method
= GL_NORMALIZE
;
102 #ifndef NO_MULTITEXTURING
103 // check for multitexturing
104 if (checkExtension("GL_ARB_multitexture")) {
106 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB
, &n
);
107 if (n
> 1) state
|= DS_MULTITEXTURING
;
112 // locate the extension function pointers
113 if (state
& DS_MULTITEXTURING
) {
115 = (PFNGLACTIVETEXTUREARBPROC
) wglGetProcAddress("glActiveTextureARB");
116 glClientActiveTextureARB
117 = (PFNGLCLIENTACTIVETEXTUREARBPROC
) wglGetProcAddress("glClientActiveTextureARB");
121 SparkleManager::initialize();
122 SignManager::initialize();
123 LightManager::initialize();
124 GarbageFlavorImage::initialize();
125 CelebrationManager::initialize();
126 ScoreRecordManager::initialize();
128 glClearColor(0.0f
, 0.0f
, 0.0f
, 0.0f
);
130 glEnable(GL_TEXTURE_2D
);
133 glEnable(GL_CLIP_PLANE_PLAY_FLOOR
);
134 const GLdouble play_bottom
[]
135 = { 0.0, 1.0, 0.0, DC_PLAY_HEIGHT
* DC_CAMERA_HEIGHT_RATIO
};
136 glClipPlane(GL_CLIP_PLANE_PLAY_FLOOR
, play_bottom
);
139 const GLfloat headlight_position
[]
140 = { 0.0f
, DC_HEADLIGHT_Y_OFFSET
, DC_HEADLIGHT_Z_OFFSET
, 1.0f
};
141 glLightfv(GL_LIGHT0
, GL_POSITION
, headlight_position
);
143 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
145 GLfloat white
[] = { 1.0f
, 1.0f
, 1.0f
, 1.0f
};
146 glTexEnvfv(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_COLOR
, white
);
147 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
149 generateBlockDisplayList();
150 generateGarbageExtras();
151 generateGarbageThinMiddleList();
152 generateGarbageThinCapList();
153 generateGarbageThickCornerList();
154 generateGarbageThickEdgeList();
155 generateGarbageThickMiddleList();
156 generateGarbageSmallList();
157 generateSparkleList();
159 generateSwapperList();
160 generateExternalCandy();
161 generateLevelLights();
165 String::readyLetterTextures();
166 generateNameTexture();
167 generateScoreRecord();
169 glMatrixMode(GL_PROJECTION
);
171 glFrustum(-(DC_PLAY_PIXEL_OFFSET_X
/ DC_PLAY_PIXEL_WIDTH
+ 0.5f
)
172 * DC_PLAY_WIDTH
, ((1.0f
- DC_PLAY_PIXEL_OFFSET_X
- DC_PLAY_PIXEL_WIDTH
)
173 / DC_PLAY_PIXEL_WIDTH
+ 0.5f
) * DC_PLAY_WIDTH
, -DC_PLAY_HEIGHT
174 * DC_CAMERA_HEIGHT_RATIO
, DC_PLAY_HEIGHT
* (1.0 - DC_CAMERA_HEIGHT_RATIO
),
176 glMatrixMode(GL_MODELVIEW
);
179 void Displayer::gameStart ( )
181 LightManager::resetHeadLight();
182 ScoreRecordManager::gameStart();
185 void Displayer::gameFinish ( )
187 CelebrationManager::gameFinish();
188 ScoreRecordManager::gameFinish();
191 void Displayer::cleanUp ( )
193 for (int n
= DC_NUMBER_USE_GARBAGE_TEX
; n
--; )
194 if (garbage_texture_data
[n
] != null
) {
195 delete [] garbage_texture_data
[n
];
196 garbage_texture_data
[n
] = null
;
198 for (int n
= DC_NUMBER_MESSAGE_TEX
; n
--; )
199 if (message_texture_data
[n
] != null
) {
200 delete [] message_texture_data
[n
];
201 message_texture_data
[n
] = null
;
204 if (player_rank_texture_data
!= null
) {
205 delete [] player_rank_texture_data
;
206 player_rank_texture_data
= null
;
208 if (MetaState::mode
& CM_SOLO
)
209 for (int n
= GC_SCORE_REC_LENGTH
- 1; n
--; )
210 if (record_texture_data
[n
] != null
) {
211 delete [] record_texture_data
[n
];
212 record_texture_data
[n
] = null
;
214 if (record_texture_data
!= null
) {
215 delete [] record_texture_data
;
216 record_texture_data
= null
;
219 String::freeLetterTextures();
222 void Displayer::reshape ( int width
, int height
)
224 if (DC_WINDOW_PIXEL_WIDTH
* height
/ DC_WINDOW_PIXEL_HEIGHT
!= width
) {
225 height
= (height
+ width
) >> 1;
226 glutReshapeWindow(DC_WINDOW_PIXEL_WIDTH
* height
/ DC_WINDOW_PIXEL_HEIGHT
,
229 glViewport(0, 0, width
, height
);
231 screen_length
= width
;
236 void Displayer::displayMeta ( )
238 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
242 // disables GL_BLEND internally
245 drawScoreToBeatMessage();
247 glDisable(GL_TEXTURE_2D
);
249 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
250 glEnable(GL_LIGHTING
);
251 glEnable(GL_COLOR_MATERIAL
);
253 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
256 if (CelebrationManager::draw_game
) {
258 LightManager::timeStepInitialize();
260 int hold_time_step
= Game::time_step
;
261 Game::time_step
= MetaState::final_time_step
;
263 calculatePlayOffset();
265 glEnable(GL_DEPTH_TEST
);
266 glEnable(GL_CULL_FACE
);
268 LightManager::setupHeadLightMeta();
272 glEnable(GL_TEXTURE_2D
);
276 glDisable(GL_CULL_FACE
);
277 glDisable(GL_TEXTURE_2D
);
281 glDisable(GL_DEPTH_TEST
);
283 LightManager::resetHeadLight();
285 Game::time_step
= hold_time_step
;
288 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
289 glDisable(GL_LIGHTING
);
290 glDisable(GL_COLOR_MATERIAL
);
293 glEnable(GL_TEXTURE_2D
);
297 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_BLEND
);
299 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
)) {
301 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
311 void Displayer::displayPlay ( )
313 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
317 // calls glDisable(GL_BLEND) internally
320 glDisable(GL_TEXTURE_2D
);
322 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
323 glEnable(GL_LIGHTING
);
324 glEnable(GL_COLOR_MATERIAL
);
326 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
329 if (!((Game::state
& (GS_PAUSED
| GS_SYNC_WAIT
)) == GS_PAUSED
)) {
331 LightManager::timeStepInitialize();
333 calculatePlayOffset();
335 glEnable(GL_DEPTH_TEST
);
336 glEnable(GL_CULL_FACE
);
338 LightManager::setupHeadLightPlay();
342 glEnable(GL_TEXTURE_2D
);
346 glDisable(GL_CULL_FACE
);
347 glDisable(GL_TEXTURE_2D
);
351 glDisable(GL_DEPTH_TEST
);
353 LightManager::resetHeadLight();
356 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
))
357 glDisable(GL_LIGHTING
);
358 glDisable(GL_COLOR_MATERIAL
);
361 glEnable(GL_TEXTURE_2D
);
363 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_BLEND
);
365 if (!(MetaState::mode
& CM_REALLY_LOW_GRAPHICS
)) {
367 // calls glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
372 if (!(Game::state
& GS_PAUSED
))
380 bool Displayer::checkExtension ( const char *extension_name
)
382 char *extensions
= (char *) glGetString(GL_EXTENSIONS
);
384 if (!extensions
) return false;
386 int length
= strlen(extension_name
);
387 char *end
= extensions
+ strlen(extensions
);
389 while (extensions
< end
) {
390 int n
= strcspn(extensions
, " ");
392 if (n
== length
&& strncmp(extension_name
, extensions
, n
) == 0)
402 void Displayer::screenShot ( )
404 static int count
= 0;
405 GLubyte
*image
= new GLubyte
[4 * screen_length
* screen_length
];
407 glReadPixels(0, 0, screen_length
, screen_length
, GL_RGBA
, GL_UNSIGNED_BYTE
,
410 std::ostringstream file_name
;
411 file_name
<< DC_SCREEN_SHOT_FILE_NAME_BASE
"_" << std::setw(GC_GARBAGE_TEX_NUMBER_DIGITS
)
412 << std::setfill('0') << count
<< ".tga" << std::ends
;
413 TextureLoader::createTGA(file_name
.str().c_str(), image
, screen_length
, screen_length
,
414 TL_SCREEN_SHOT_TGA_ID
);
416 MESSAGE("creating " << file_name
.str());