00001
00002
00003
00004
00005
00006
00007
00009
00010 #include "utils.h"
00011 #include <cassert>
00012 #include <cstdarg>
00013 #include "video.h"
00014 #include <math.h>
00015 #include "gui.h"
00016
00017 using namespace std;
00018 using namespace hoa_video::private_video;
00019
00020 namespace hoa_video
00021 {
00022
00023
00024
00025
00026
00027
00028 bool GameVideo::_DrawStillImage(const StillImage &id)
00029 {
00030
00031
00032
00033
00034 if(!_uses_lights && (_light_color != Color::white))
00035 return _DrawStillImage(id, _light_color);
00036 else
00037 return _DrawStillImage(id, Color::white);
00038 }
00039
00040
00041
00042
00043
00044
00045
00046 bool GameVideo::_DrawStillImage(const StillImage &id, const Color &color)
00047 {
00048
00049 if (color[3] == 0.0f) {
00050 return true;
00051 }
00052
00053 size_t num_elements = id._elements.size();
00054
00055 float modulation = _fader.GetFadeModulation();
00056 Color fade_color(modulation, modulation, modulation, 1.0f);
00057
00058 float x_shake = _x_shake * (_coord_sys.GetRight() - _coord_sys.GetLeft()) / 1024.0f;
00059 float y_shake = _y_shake * (_coord_sys.GetTop() - _coord_sys.GetBottom()) / 768.0f;
00060
00061 float x_align_offset = ((_x_align+1) * id._width) * 0.5f * -_coord_sys.GetHorizontalDirection();
00062 float y_align_offset = ((_y_align+1) * id._height) * 0.5f * -_coord_sys.GetVerticalDirection();
00063
00064 glPushMatrix();
00065 MoveRelative(x_align_offset, y_align_offset);
00066
00067 bool skip_modulation = (color == Color::white && modulation == 1.0f);
00068
00069
00070 if (!skip_modulation)
00071 fade_color = color * fade_color;
00072
00073 Color color_modulated[4];
00074
00075 for(uint32 iElement = 0; iElement < num_elements; ++iElement)
00076 {
00077 glPushMatrix();
00078
00079 float x_off = (float)id._elements[iElement].x_offset;
00080 float y_off = (float)id._elements[iElement].y_offset;
00081
00082 if(_x_flip)
00083 {
00084 x_off = id._width - x_off - id._elements[iElement].width;
00085 }
00086
00087 if(_y_flip)
00088 {
00089 y_off = id._height - y_off - id._elements[iElement].height;
00090 }
00091
00092 x_off += x_shake;
00093 y_off += y_shake;
00094
00095
00096
00097
00098
00099
00100 MoveRelative(x_off * _coord_sys.GetHorizontalDirection(), y_off * _coord_sys.GetVerticalDirection());
00101
00102 float x_scale = id._elements[iElement].width;
00103 float y_scale = id._elements[iElement].height;
00104
00105 if(_coord_sys.GetHorizontalDirection() < 0.0f)
00106 x_scale = -x_scale;
00107 if(_coord_sys.GetVerticalDirection() < 0.0f)
00108 y_scale = -y_scale;
00109
00110 glScalef(x_scale, y_scale, 1.0f);
00111
00112 bool success;
00113
00114 if(skip_modulation)
00115 success = _DrawElement(id._elements[iElement], id._elements[iElement].color);
00116 else
00117 {
00118 color_modulated[0] = id._elements[iElement].color[0] * fade_color;
00119 color_modulated[1] = id._elements[iElement].color[1] * fade_color;
00120 color_modulated[2] = id._elements[iElement].color[2] * fade_color;
00121 color_modulated[3] = id._elements[iElement].color[3] * fade_color;
00122 success = _DrawElement(id._elements[iElement], color_modulated);
00123 }
00124
00125 if(!success)
00126 {
00127 if(VIDEO_DEBUG)
00128 cerr << "VIDEO ERROR: _DrawElement() failed in DrawImage()!" << endl;
00129
00130 glPopMatrix();
00131 return false;
00132 }
00133 glPopMatrix();
00134 }
00135
00136 glPopMatrix();
00137 return true;
00138 }
00139
00140
00141
00142
00143
00144
00145 bool GameVideo::_DrawElement(const ImageElement &element, const Color *color_array) {
00146 Image *img = element.image;
00147
00148
00149 static const float xlo = 0.0f;
00150 static const float xhi = 1.0f;
00151 static const float ylo = 0.0f;
00152 static const float yhi = 1.0f;
00153
00154
00155
00156 static const float vert_coords[] =
00157 {
00158 xlo, ylo,
00159 xhi, ylo,
00160 xhi, yhi,
00161 xlo, yhi,
00162 };
00163
00164
00165 if(_blend)
00166 {
00167 glEnable(GL_BLEND);
00168 if (_blend == 1)
00169 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00170 else
00171 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00172 }
00173 else
00174 {
00175
00176
00177 if(!element.blend)
00178 glDisable(GL_BLEND);
00179 else
00180 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00181 }
00182
00183
00184 static const int num_vertexes = 4;
00185 static const int coords_per_vertex = 2;
00186
00187
00188
00189
00190 if (img)
00191 {
00192
00193 float s0,s1,t0,t1;
00194
00195 s0 = img->u1 + element.u1 * (img->u2 - img->u1);
00196 s1 = img->u1 + element.u2 * (img->u2 - img->u1);
00197 t0 = img->v1 + element.v1 * (img->v2 - img->v1);
00198 t1 = img->v1 + element.v2 * (img->v2 - img->v1);
00199
00200
00201
00202 if (_x_flip)
00203 {
00204 float temp = s0;
00205 s0 = s1;
00206 s1 = temp;
00207 }
00208
00209
00210 if (_y_flip)
00211 {
00212 float temp = t0;
00213 t0 = t1;
00214 t1 = temp;
00215 }
00216
00217
00218
00219
00220 float tex_coords[] = {
00221 s0, t1,
00222 s1, t1,
00223 s1, t0,
00224 s0, t0,
00225 };
00226
00227
00228 glEnable(GL_TEXTURE_2D);
00229 _BindTexture(img->texture_sheet->tex_ID);
00230
00231
00232 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00233
00234
00235 glTexCoordPointer(coords_per_vertex, GL_FLOAT, 0, tex_coords);
00236 if (element.one_color)
00237 {
00238 glColor4fv((GLfloat *)&color_array[0]);
00239 }
00240 else
00241 {
00242 glEnableClientState(GL_COLOR_ARRAY);
00243 glColorPointer(4, GL_FLOAT, 0, (GLfloat *)color_array);
00244 }
00245
00246 glEnableClientState(GL_VERTEX_ARRAY);
00247
00248
00249 glVertexPointer(coords_per_vertex, GL_FLOAT, 0, vert_coords);
00250
00251
00252 glDrawArrays(GL_QUADS, 0, num_vertexes);
00253 }
00254 else
00255 {
00256
00257
00258 if (element.one_color)
00259 {
00260 glColor4fv((GLfloat *)&color_array[0]);
00261 glDisableClientState(GL_COLOR_ARRAY);
00262 }
00263 else
00264 {
00265 glEnableClientState(GL_COLOR_ARRAY);
00266
00267 glColorPointer(4, GL_FLOAT, 0, (GLfloat *)color_array);
00268 }
00269
00270 glEnableClientState(GL_VERTEX_ARRAY);
00271
00272
00273 glVertexPointer(coords_per_vertex, GL_FLOAT, 0, vert_coords);
00274
00275
00276 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00277
00278
00279 glDrawArrays(GL_QUADS, 0, num_vertexes);
00280 }
00281
00282 if (_blend)
00283 glDisable(GL_BLEND);
00284
00285 if(glGetError())
00286 {
00287 if(VIDEO_DEBUG)
00288 cerr << "VIDEO ERROR: glGetError() returned true in _DrawElement()!" << endl;
00289 return false;
00290 }
00291
00292 return true;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 bool GameVideo::DrawHalo(const StillImage &id, float x, float y, const Color &color)
00305 {
00306 PushMatrix();
00307 Move(x, y);
00308
00309 char oldBlendMode = _blend;
00310 _blend = VIDEO_BLEND_ADD;
00311 DrawImage(id, color);
00312 _blend = oldBlendMode;
00313 PopMatrix();
00314
00315 return true;
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325 bool GameVideo::DrawLight(const StillImage &id, float x, float y, const Color &color)
00326 {
00327 if(!_uses_lights)
00328 {
00329 if(VIDEO_DEBUG)
00330 cerr << "VIDEO ERROR: called DrawLight() even though real lighting was not enabled!" << endl;
00331 return false;
00332 }
00333
00334 return DrawHalo(id, x, y, color);
00335 }
00336
00337
00338
00339
00340
00341
00342 void GameVideo::DrawFPS(uint32 frame_time)
00343 {
00344 _PushContext();
00345 GUIManager->DrawFPS(frame_time);
00346 _PopContext();
00347
00348 }
00349
00350
00351
00352
00353
00354
00355
00356 bool GameVideo::DrawImage(const ImageDescriptor &id) {
00357 if (id._animated) {
00358 const AnimatedImage &anim = dynamic_cast<const AnimatedImage &>(id);
00359 return _DrawStillImage(*anim.GetFrame(anim.GetCurrentFrameIndex()));
00360 }
00361 else {
00362 return _DrawStillImage(dynamic_cast<const StillImage &>(id));
00363 }
00364 }
00365
00366
00367
00368
00369
00370
00371
00372 bool GameVideo::DrawImage(const ImageDescriptor &id, const Color &color)
00373 {
00374 if(id._animated)
00375 {
00376 const AnimatedImage &anim = dynamic_cast<const AnimatedImage &>(id);
00377 return _DrawStillImage(*anim.GetFrame(anim.GetCurrentFrameIndex()), color);
00378 }
00379 else
00380 {
00381 return _DrawStillImage(dynamic_cast<const StillImage &>(id), color);
00382 }
00383 }
00384
00385
00386 }