00001
00002
00003
00004
00005
00006
00007
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <cassert>
00018 #include <cstdarg>
00019 #include <math.h>
00020 #include <vector>
00021
00022 #include "utils.h"
00023 #include "video.h"
00024 #include "context.h"
00025 #include "gui.h"
00026 #include "script.h"
00027
00028 using namespace std;
00029
00030 using namespace hoa_utils;
00031 using namespace hoa_video::private_video;
00032
00033
00034
00035
00036
00037 template<> hoa_video::GameVideo* Singleton<hoa_video::GameVideo>::_singleton_reference = NULL;
00038
00039 namespace hoa_video {
00040
00041 GameVideo* VideoManager = NULL;
00042 bool VIDEO_DEBUG = false;
00043
00044
00045
00046
00047
00048 Color Color::clear (0.0f, 0.0f, 0.0f, 0.0f);
00049 Color Color::white (1.0f, 1.0f, 1.0f, 1.0f);
00050 Color Color::gray (0.5f, 0.5f, 0.5f, 1.0f);
00051 Color Color::black (0.0f, 0.0f, 0.0f, 1.0f);
00052 Color Color::red (1.0f, 0.0f, 0.0f, 1.0f);
00053 Color Color::orange(1.0f, 0.4f, 0.0f, 1.0f);
00054 Color Color::yellow(1.0f, 1.0f, 0.0f, 1.0f);
00055 Color Color::green (0.0f, 1.0f, 0.0f, 1.0f);
00056 Color Color::aqua (0.0f, 1.0f, 1.0f, 1.0f);
00057 Color Color::blue (0.0f, 0.0f, 1.0f, 1.0f);
00058 Color Color::violet(0.0f, 0.0f, 1.0f, 1.0f);
00059 Color Color::brown (0.6f, 0.3f, 0.1f, 1.0f);
00060
00061
00062
00063
00064
00065
00066 float Lerp(float alpha, float initial, float final)
00067 {
00068 return alpha * final + (1.0f-alpha) * initial;
00069 }
00070
00071
00072
00073
00074
00075
00076 float RandomFloat(float a, float b)
00077 {
00078 if(a == b)
00079 return a;
00080
00081 if(a > b)
00082 {
00083 float c = a;
00084 a = b;
00085 b = c;
00086 }
00087
00088 float r = float(rand()%10001);
00089
00090 return a + (b - a) * r / 10000.0f;
00091 }
00092
00093
00094
00095
00096
00097
00098 void RotatePoint(float &x, float &y, float angle)
00099 {
00100 float old_x = x;
00101 float cos_angle = cosf(angle);
00102 float sin_angle = sinf(angle);
00103
00104 x = x * cos_angle - y * sin_angle;
00105 y = y * cos_angle + old_x * sin_angle;
00106 }
00107
00108
00109
00110
00111
00112 GameVideo::GameVideo()
00113 {
00114 _width = 0;
00115 _height = 0;
00116 _fullscreen = false;
00117 _temp_width = 0;
00118 _temp_height = 0;
00119 _temp_fullscreen = false;
00120 _blend = 0;
00121 _x_align = -1;
00122 _y_align = -1;
00123 _x_flip = 0;
00124 _y_flip = 0;
00125 _current_debug_TexSheet = -1;
00126 _uses_lights = false;
00127 _light_overlay = 0xFFFFFFFF;
00128 _last_tex_ID = 0xFFFFFFFF;
00129 _num_tex_switches = 0;
00130 _advanced_display = false;
00131 _fps_display = false;
00132 _x_shake = 0;
00133 _y_shake = 0;
00134 _gamma_value = 1.0f;
00135 _fog_color = Color(1.0f, 1.0f, 1.0f, 1.0f);
00136 _fog_intensity = 0.0f;
00137 _light_color = Color(1.0f, 1.0f, 1.0f, 1.0f);
00138 _current_text_color = Color(1.0f, 1.0f, 1.0f, 1.0f);
00139 _text_shadow = false;
00140 _coord_sys = CoordSys(0.0f, 1024.0f, 0.0f, 768.0f);
00141 _scissor_enabled = false;
00142 _viewport = ScreenRect(0, 0, 100, 100);
00143 _scissor_rect = ScreenRect(0, 0, 1024, 768);
00144 _animation_counter = 0;
00145 _current_frame_diff = 0;
00146 _lightning_active = false;
00147 _lightning_current_time = 0;
00148 _lightning_end_time = 0;
00149 _target = VIDEO_TARGET_SDL_WINDOW;
00150 _x = 0;
00151 _y = 0;
00152
00153 if (VIDEO_DEBUG)
00154 cout << "VIDEO: GameVideo constructor invoked\n";
00155
00156 strcpy(_next_temp_file, "00000000");
00157 }
00158
00159
00160
00161
00162
00163
00164 bool GameVideo::SingletonInitialize()
00165 {
00166 if(VIDEO_DEBUG)
00167 cout << "VIDEO: Initializing SDL subsystem\n";
00168
00169
00170 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
00171 {
00172 fprintf(stderr, "Barf! SDL Video Initialization failed!\n");
00173 exit(1);
00174 }
00175
00176
00177 if(TTF_Init() < 0)
00178 {
00179 if(VIDEO_DEBUG)
00180 cerr << "VIDEO ERROR: SDL_ttf did not initialize! (TTF_Init() failed)" << endl;
00181 return false;
00182 }
00183
00184 if(VIDEO_DEBUG)
00185 cout << "VIDEO: setting video mode\n";
00186
00187
00188 const SDL_VideoInfo* video_info (0);
00189 video_info = SDL_GetVideoInfo ();
00190
00191 hoa_script::ReadScriptDescriptor settings_lua;
00192 static const char *settings_filename = "dat/config/settings.lua";
00193
00194 if (!settings_lua.OpenFile(settings_filename))
00195 {
00196 fprintf(stderr, "Failed to load file '%s'.\n", settings_filename);
00197 exit(1);
00198 }
00199
00200 settings_lua.OpenTable("video_settings");
00201 int32 settings_width = settings_lua.ReadInt("screen_resx");
00202 int32 settings_height = settings_lua.ReadInt("screen_resy");
00203 bool settings_fullscreen = settings_lua.ReadBool("full_screen");
00204 settings_lua.CloseTable();
00205
00206 settings_lua.CloseFile();
00207
00208 if (video_info)
00209 {
00210
00211 if (video_info->current_w > settings_width && video_info->current_h > settings_height)
00212 {
00213 SetResolution (settings_width, settings_height);
00214 }
00215 else if (video_info->current_w > 1024 && video_info->current_h > 768)
00216 {
00217 SetResolution (1024, 768);
00218 }
00219 else if (video_info->current_w > 800 && video_info->current_h > 600)
00220 {
00221 SetResolution (800, 600);
00222 }
00223 else
00224 {
00225 SetResolution (640, 480);
00226 }
00227 }
00228 else
00229 {
00230
00231 SetResolution(settings_width, settings_height);
00232 }
00233
00234 SetFullscreen(settings_fullscreen);
00235
00236 if(!ApplySettings())
00237 {
00238 if(VIDEO_DEBUG)
00239 cerr << "VIDEO ERROR: ChangeMode() failed in GameVideo::SingletonInitialize()!" << endl;
00240 return false;
00241 }
00242
00243 if(VIDEO_DEBUG)
00244 cout << "VIDEO: Loading default font\n";
00245
00246 if(!LoadFont("img/fonts/tarnhalo.ttf", "debug_font", 16))
00247 {
00248 if(VIDEO_DEBUG)
00249 cerr << "VIDEO ERROR: Could not load tarnhalo.ttf file!" << endl;
00250 return false;
00251 }
00252
00253 if(VIDEO_DEBUG)
00254 cout << "VIDEO: Creating texture sheets\n";
00255
00256
00257
00258
00259 if(!_CreateTexSheet(512, 512, VIDEO_TEXSHEET_32x32, false))
00260 {
00261 if(VIDEO_DEBUG)
00262 cerr << "VIDEO ERROR: could not create default 32x32 tex sheet!" << endl;
00263 return false;
00264 }
00265
00266 if(!_CreateTexSheet(512, 512, VIDEO_TEXSHEET_32x64, false))
00267 {
00268 if(VIDEO_DEBUG)
00269 cerr << "VIDEO ERROR: could not create default 32x64 tex sheet!" << endl;
00270 return false;
00271 }
00272
00273 if(!_CreateTexSheet(512, 512, VIDEO_TEXSHEET_64x64, false))
00274 {
00275 if(VIDEO_DEBUG)
00276 cerr << "VIDEO ERROR: could not create default 64x64 tex sheet!" << endl;
00277 return false;
00278 }
00279
00280 if(!_CreateTexSheet(512, 512, VIDEO_TEXSHEET_ANY, true))
00281 {
00282 if(VIDEO_DEBUG)
00283 cerr << "VIDEO ERROR: could not create default static var-sized tex sheet!" << endl;
00284 return false;
00285 }
00286
00287 if(!_CreateTexSheet(512, 512, VIDEO_TEXSHEET_ANY, false))
00288 {
00289 if(VIDEO_DEBUG)
00290 cerr << "VIDEO ERROR: could not create default var-sized tex sheet!" << endl;
00291 return false;
00292 }
00293
00294
00295 GUIManager = GUISupervisor::SingletonCreate();
00296 GUIManager->SingletonInitialize();
00297
00298
00299
00300
00301
00302 EnableTextShadow(true);
00303
00304
00305
00306 if(VIDEO_DEBUG)
00307 cout << "VIDEO: Setting default menu cursor" << endl;
00308
00309 if(!SetDefaultCursor("img/menus/cursor.png"))
00310 {
00311 if(VIDEO_DEBUG)
00312 cerr << "VIDEO ERROR: problem loading default menu cursor" << endl;
00313 }
00314
00315
00316 if(VIDEO_DEBUG)
00317 cout << "VIDEO: Erasing the screen\n";
00318
00319
00320
00321 if(!Clear())
00322 {
00323 if(VIDEO_DEBUG)
00324 cerr << "VIDEO ERROR: first call to Clear() in GameVideo::SingletonInitialize() failed!" << endl;
00325 return false;
00326 }
00327
00328 if(!Display(0))
00329 {
00330 if(VIDEO_DEBUG)
00331 cerr << "VIDEO ERROR: Display() in GameVideo::SingletonInitialize() failed!" << endl;
00332 return false;
00333 }
00334
00335 if(!Clear())
00336 {
00337 if(VIDEO_DEBUG)
00338 cerr << "VIDEO ERROR: second call to Clear() in GameVideo::SingletonInitialize() failed!" << endl;
00339 return false;
00340 }
00341
00342 if(VIDEO_DEBUG)
00343 cout << "VIDEO: GameVideo::SingletonInitialize() returned successfully" << endl;
00344
00345 _rectangle_image.SetFilename("");
00346 if (!_rectangle_image.Load())
00347 {
00348 if(VIDEO_DEBUG)
00349 cerr << "VIDEO ERROR: quad StillImage for rendering rectangles could not be created" << endl;
00350 return false;
00351 }
00352
00353 return true;
00354 }
00355
00356
00357
00358
00359
00360
00361 bool GameVideo::MakeScreenshot()
00362 {
00363 private_video::ImageLoadInfo buffer;
00364
00365 if(VIDEO_DEBUG)
00366 cout << "VIDEO: Entering MakeScreenshot()" << endl;
00367
00368
00369 GLint viewport_dimensions[4];
00370 glGetIntegerv(GL_VIEWPORT, viewport_dimensions);
00371
00372
00373 buffer.width = viewport_dimensions[2];
00374 buffer.height = viewport_dimensions[3];
00375 buffer.pixels = malloc(buffer.width * buffer.height * 3);
00376
00377
00378 glReadPixels(0, 0, buffer.width, buffer.height, GL_RGB, GL_UNSIGNED_BYTE, buffer.pixels);
00379
00380 if(glGetError())
00381 {
00382 if(VIDEO_DEBUG)
00383 cerr << "VIDEO_DEBUG: glReadPixels() returned an error inside GameVideo::CaptureScreen!" << endl;
00384
00385 free(buffer.pixels);
00386 return false;
00387 }
00388
00389
00390 void* buffer_temp = malloc(buffer.width * buffer.height * 3);
00391 for (int32 i=0; i<buffer.height; ++i)
00392 {
00393 memcpy ((uint8*)buffer_temp+i*buffer.width*3, (uint8*)buffer.pixels+(buffer.height-i-1)*buffer.width*3, buffer.width*3);
00394 }
00395 free (buffer.pixels);
00396 buffer.pixels = buffer_temp;
00397
00398 _SaveJpeg("screenshot.jpg", buffer);
00399
00400 free(buffer.pixels);
00401
00402 return true;
00403 }
00404
00405
00406
00407
00408
00409
00410 GameVideo::~GameVideo()
00411 {
00412 if (VIDEO_DEBUG)
00413 cout << "VIDEO: GameVideo destructor invoked" << endl;
00414
00415
00416 _particle_manager.Destroy();
00417
00418
00419 GUIManager->SingletonDestroy();
00420
00421
00422
00423 map<string, FontProperties *>::iterator iFontProp = _font_map.begin();
00424 map<string, FontProperties *>::iterator iFontPropEnd = _font_map.end();
00425
00426 while(iFontProp != _font_map.end())
00427 {
00428 FontProperties *fp = iFontProp->second;
00429
00430 if(fp->ttf_font)
00431 TTF_CloseFont(fp->ttf_font);
00432
00433 if(fp->glyph_cache)
00434 {
00435 for(std::map<uint16, FontGlyph *>::iterator glyphitr = fp->glyph_cache->begin(); glyphitr != fp->glyph_cache->end(); glyphitr++)
00436 {
00437
00438 delete (*glyphitr).second;
00439 }
00440
00441 delete fp->glyph_cache;
00442 }
00443
00444 delete fp;
00445 ++iFontProp;
00446 }
00447
00448
00449
00450 TTF_Quit();
00451
00452
00453 vector<TexSheet *>::iterator iSheet = _tex_sheets.begin();
00454 vector<TexSheet *>::iterator iSheetEnd = _tex_sheets.end();
00455
00456 while(iSheet != iSheetEnd)
00457 {
00458 delete *iSheet;
00459 ++iSheet;
00460 }
00461
00462
00463 map<string, Image *>::iterator iImage = _images.begin();
00464 map<string, Image *>::iterator iImageEnd = _images.end();
00465
00466 while(iImage != iImageEnd)
00467 {
00468 delete iImage->second;
00469 ++iImage;
00470 }
00471 }
00472
00473
00474
00475
00476
00477
00478 void GameVideo::SetCoordSys(const CoordSys &coordinate_system)
00479 {
00480 _coord_sys = coordinate_system;
00481
00482 glMatrixMode(GL_PROJECTION);
00483 glLoadIdentity();
00484 glOrtho(_coord_sys.GetLeft(), _coord_sys.GetRight(), _coord_sys.GetBottom(), _coord_sys.GetTop(), -1, 1);
00485
00486
00487 glMatrixMode(GL_MODELVIEW);
00488 glLoadIdentity();
00489 }
00490
00491
00492
00493
00494
00495
00496 void GameVideo::SetCoordSys
00497 (
00498 float left,
00499 float right,
00500 float bottom,
00501 float top
00502 )
00503 {
00504 SetCoordSys(CoordSys(left, right, bottom, top));
00505 }
00506
00507
00508
00509
00510
00511
00512 void GameVideo::SetDrawFlags(int32 first_flag, ...)
00513 {
00514 int32 flag = first_flag;
00515 va_list args;
00516
00517 va_start(args, first_flag);
00518 while( flag != 0 )
00519 {
00520 switch (flag) {
00521 case VIDEO_X_LEFT: _x_align=-1; break;
00522 case VIDEO_X_CENTER: _x_align=0; break;
00523 case VIDEO_X_RIGHT: _x_align=1; break;
00524
00525 case VIDEO_Y_TOP: _y_align=1; break;
00526 case VIDEO_Y_CENTER: _y_align=0; break;
00527 case VIDEO_Y_BOTTOM: _y_align=-1; break;
00528
00529 case VIDEO_X_NOFLIP: _x_flip=0; break;
00530 case VIDEO_X_FLIP: _x_flip=1; break;
00531
00532 case VIDEO_Y_NOFLIP: _y_flip=0; break;
00533 case VIDEO_Y_FLIP: _y_flip=1; break;
00534
00535 case VIDEO_NO_BLEND: _blend=0; break;
00536 case VIDEO_BLEND: _blend=1; break;
00537 case VIDEO_BLEND_ADD: _blend=2; break;
00538
00539 default:
00540 if(VIDEO_DEBUG)
00541 cerr << "Unknown flag " << flag << " passed to SetDrawFlags()\n";
00542 break;
00543 }
00544 flag = va_arg(args, int32);
00545 }
00546 va_end(args);
00547 }
00548
00549
00550
00551
00552
00553
00554
00555 bool GameVideo::ApplySettings()
00556 {
00557
00558 if (_target == VIDEO_TARGET_SDL_WINDOW) {
00559
00560 if (!UnloadTextures())
00561 {
00562 cerr << "VIDEO: Failed to delete OpenGL textures during a context change" << endl;
00563 }
00564
00565 int32 flags = SDL_OPENGL;
00566
00567 if (_temp_fullscreen == true) {
00568 flags |= SDL_FULLSCREEN;
00569 }
00570
00571 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
00572 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
00573 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
00574 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
00575 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
00576 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
00577
00578
00579 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 2);
00580 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
00581
00582
00583 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
00584
00585 if (!SDL_SetVideoMode(_temp_width, _temp_height, 0, flags)) {
00586
00587
00588
00589 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
00590 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
00591 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
00592 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
00593 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
00594
00595
00596 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
00597 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
00598
00599
00600 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);
00601
00602 if (!SDL_SetVideoMode(_temp_width, _temp_height, 0, flags)) {
00603 if (VIDEO_DEBUG) {
00604 cerr << "VIDEO ERROR: SDL_SetVideoMode() failed with error: " << SDL_GetError() << endl;
00605 }
00606 _temp_fullscreen = _fullscreen;
00607 _temp_width = _width;
00608 _temp_height = _height;
00609
00610 if (_width > 0) {
00611 ReloadTextures();
00612 }
00613 return false;
00614 }
00615 }
00616
00617
00618 glDepthMask ( GL_FALSE );
00619
00620 _width = _temp_width;
00621 _height = _temp_height;
00622 _fullscreen = _temp_fullscreen;
00623
00624 ReloadTextures();
00625
00626 EnableFog(_fog_color, _fog_intensity);
00627
00628 return true;
00629 }
00630
00631
00632 else if (_target == VIDEO_TARGET_QT_WIDGET)
00633 {
00634 _width = _temp_width;
00635 _height = _temp_height;
00636 _fullscreen = _temp_fullscreen;
00637
00638 return true;
00639 }
00640
00641 return false;
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00651 void GameVideo::SetViewport(float left, float right, float bottom, float top)
00652 {
00653 assert(left < right);
00654 assert(bottom < top);
00655
00656 int32 l=int32(left*_width*.01f);
00657 int32 b=int32(bottom*_height*.01f);
00658 int32 r=int32(right*_width*.01f);
00659 int32 t=int32(top*_height*.01f);
00660
00661 if (l<0) l=0;
00662 if (b<0) b=0;
00663 if (r>_width) r=_width;
00664 if (t>_height) t=_height;
00665
00666 _viewport = ScreenRect(l, b, r-l+1, t-b+1);
00667 glViewport(l, b, r-l+1, t-b+1);
00668 }
00669
00670
00671
00672
00673
00674
00675
00676 bool GameVideo::Clear()
00677 {
00678 if(_uses_lights)
00679 return Clear(_light_color);
00680 else
00681 return Clear(Color::black);
00682 }
00683
00684
00685
00686
00687
00688
00689
00690
00691 bool GameVideo::Clear(const Color &c)
00692 {
00693 SetViewport(0,100,0,100);
00694 glClearColor(c[0], c[1], c[2], c[3]);
00695 glClear(GL_COLOR_BUFFER_BIT);
00696
00697 _num_tex_switches = 0;
00698
00699 if(glGetError())
00700 return false;
00701
00702 return true;
00703 }
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727 bool GameVideo::Display(int32 frame_time)
00728 {
00729
00730 _particle_manager.Update(frame_time);
00731
00732
00733 _PushContext();
00734 SetCoordSys(0, 1024, 0, 768);
00735 _UpdateShake(frame_time);
00736
00737
00738 _lightning_current_time += frame_time;
00739
00740 if(_lightning_current_time > _lightning_end_time)
00741 _lightning_active = false;
00742
00743
00744 if(_fader.ShouldUseFadeOverlay())
00745 {
00746 Color c = _fader.GetFadeOverlayColor();
00747 StillImage fade_overlay;
00748 fade_overlay.SetDimensions(1024.0f, 768.0f);
00749 fade_overlay.SetColor(c);
00750 LoadImage(fade_overlay);
00751 SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, 0);
00752 PushState();
00753 Move(0, 0);
00754 DrawImage(fade_overlay);
00755 PopState();
00756 DeleteImage(fade_overlay);
00757 }
00758
00759
00760
00761
00762
00763 if(_advanced_display)
00764 _DEBUG_ShowAdvancedStats();
00765
00766 if(_fps_display)
00767 DrawFPS(frame_time);
00768
00769 if(!_DEBUG_ShowTexSheet())
00770 {
00771 if(VIDEO_DEBUG)
00772 {
00773
00774
00775
00776 static bool has_failed = false;
00777
00778 if(!has_failed)
00779 {
00780 cerr << "VIDEO ERROR: _DEBUG_ShowTexSheet() failed\n";
00781 has_failed = true;
00782 }
00783 }
00784 }
00785
00786 _PopContext();
00787
00788 SDL_GL_SwapBuffers();
00789
00790 _fader.Update(frame_time);
00791
00792
00793
00794 int32 old_frame_index = _animation_counter / VIDEO_ANIMATION_FRAME_PERIOD;
00795 _animation_counter += frame_time;
00796 int32 current_frame_index = _animation_counter / VIDEO_ANIMATION_FRAME_PERIOD;
00797
00798 _current_frame_diff = current_frame_index - old_frame_index;
00799
00800 return true;
00801 }
00802
00803
00804
00805
00806
00807
00808 bool GameVideo::IsFullscreen()
00809 {
00810 return _fullscreen;
00811 }
00812
00813
00814
00815
00816
00817
00818
00819
00820 bool GameVideo::SetFullscreen(bool fullscreen)
00821 {
00822 _temp_fullscreen = fullscreen;
00823 return true;
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833 bool GameVideo::ToggleFullscreen()
00834 {
00835 return SetFullscreen(!_temp_fullscreen);
00836 }
00837
00838
00839
00840
00841
00842
00843
00844 bool GameVideo::SetResolution(int32 width, int32 height)
00845 {
00846 if (width <= 0 || height <= 0)
00847 {
00848 if (VIDEO_DEBUG)
00849 cerr << "VIDEO ERROR: invalid width and/or height passed to SetResolution!" << endl;
00850 return false;
00851 }
00852
00853 _temp_width = width;
00854 _temp_height = height;
00855 return true;
00856 }
00857
00858
00859
00860
00861
00862
00863
00864 bool GameVideo::_DEBUG_ShowAdvancedStats()
00865 {
00866
00867 char text[50];
00868 sprintf(text, "Switches: %d\nParticles: %d", _num_tex_switches, _particle_manager.GetNumParticles());
00869
00870 if( !SetFont("debug_font"))
00871 return false;
00872
00873 Move(896.0f, 690.0f);
00874 if( !DrawText(text))
00875 return false;
00876
00877 return true;
00878 }
00879
00880
00881
00882
00883
00884
00885
00886 void GameVideo::Move(float tx, float ty)
00887 {
00888 #ifndef NDEBUG
00889 GLint matrix_mode;
00890 glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
00891 assert(matrix_mode == GL_MODELVIEW);
00892 #endif
00893 glLoadIdentity();
00894 glTranslatef(tx, ty, 0);
00895 _x = tx;
00896 _y = ty;
00897 }
00898
00899
00900
00901
00902 void GameVideo::MoveRelative(float tx, float ty)
00903 {
00904 #ifndef NDEBUG
00905 GLint matrix_mode;
00906 glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
00907 assert(matrix_mode == GL_MODELVIEW);
00908 #endif
00909 glTranslatef(tx, ty, 0);
00910 _x += tx;
00911 _y += ty;
00912 }
00913
00914
00915
00916
00917 void GameVideo::GetDrawPosition(float &x, float &y)
00918 {
00919 x = _x;
00920 y = _y;
00921 }
00922
00923
00924
00925
00926
00927
00928 void GameVideo::Rotate(float ac_angle)
00929 {
00930 #ifndef NDEBUG
00931 GLint matrix_mode;
00932 glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
00933 assert(matrix_mode == GL_MODELVIEW);
00934 #endif
00935 glRotatef(ac_angle, 0, 0, 1);
00936 }
00937
00938
00939
00940
00941
00942
00943 void GameVideo::Scale(float x, float y)
00944 {
00945 #ifndef NDEBUG
00946 GLint matrix_mode;
00947 glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
00948 assert(matrix_mode == GL_MODELVIEW);
00949 #endif
00950
00951 glScalef(x, y, 1.0f);
00952 }
00953
00954
00955
00956
00957
00958
00959
00960
00961 void GameVideo::PushState()
00962 {
00963 _PushContext();
00964 }
00965
00966
00967
00968
00969
00970
00971 void GameVideo::PopState()
00972 {
00973 _PopContext();
00974 }
00975
00976
00977
00978
00979
00980
00981 bool GameVideo::LoadMenuSkin(std::string skin_name, std::string border_image, std::string background_image, bool make_default)
00982 {
00983 return GUIManager->LoadMenuSkin(skin_name, border_image, background_image,
00984 Color::clear, Color::clear, Color::clear, Color::clear, make_default);
00985 }
00986
00987
00988
00989 bool GameVideo::LoadMenuSkin(std::string skin_name, std::string border_image, Color background_color, bool make_default)
00990 {
00991 return GUIManager->LoadMenuSkin(skin_name, border_image, "",
00992 background_color, background_color, background_color, background_color, make_default);
00993 }
00994
00995
00996
00997 bool GameVideo::LoadMenuSkin(std::string skin_name, std::string border_image, Color top_left, Color top_right,
00998 Color bottom_left, Color bottom_right, bool make_default)
00999 {
01000 return GUIManager->LoadMenuSkin(skin_name, border_image, "",
01001 top_left, top_right, bottom_left, bottom_right, make_default);
01002 }
01003
01004
01005
01006 bool GameVideo::LoadMenuSkin(std::string skin_name, std::string border_image, std::string background_image,
01007 Color background_color, bool make_default)
01008 {
01009 return GUIManager->LoadMenuSkin(skin_name, border_image, background_image,
01010 background_color, background_color, background_color, background_color, make_default);
01011 }
01012
01013
01014
01015 bool GameVideo::LoadMenuSkin(std::string skin_name, std::string border_image, std::string background_image,
01016 Color top_left, Color top_right, Color bottom_left, Color bottom_right, bool make_default)
01017 {
01018 return GUIManager->LoadMenuSkin(skin_name, border_image, background_image,
01019 top_left, top_right, bottom_left, bottom_right, make_default);
01020 }
01021
01022
01023
01024
01025
01026
01027 bool GameVideo::_BindTexture(GLuint tex_ID)
01028 {
01029 if(tex_ID != _last_tex_ID)
01030 {
01031 _last_tex_ID = tex_ID;
01032 glBindTexture(GL_TEXTURE_2D, tex_ID);
01033 ++_num_tex_switches;
01034 }
01035
01036 if(glGetError())
01037 return false;
01038
01039 return true;
01040 }
01041
01042
01043
01044
01045
01046
01047
01048
01049 bool GameVideo::ToggleAdvancedDisplay()
01050 {
01051 _advanced_display = !_advanced_display;
01052 return true;
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062 bool GameVideo::EnableSceneLighting(const Color &color)
01063 {
01064 _light_color = color;
01065
01066 if(color[3] != 1.0f)
01067 {
01068 if(VIDEO_DEBUG)
01069 cerr << "VIDEO ERROR: color passed to EnableSceneLighting() had alpha other than 1.0f!" << endl;
01070 _light_color[3] = 1.0f;
01071 }
01072
01073 return true;
01074 }
01075
01076
01077
01078
01079 void GameVideo::DisableSceneLighting()
01080 {
01081 _light_color = Color::white;
01082 }
01083
01084
01085
01086
01087
01088 Color &GameVideo::GetSceneLightingColor()
01089 {
01090 return _light_color;
01091 }
01092
01093
01094
01095
01096
01097
01098
01099
01100 bool GameVideo::EnableFog(const Color &color, float intensity)
01101 {
01102
01103
01104
01105 if(intensity < 0.0f)
01106 {
01107 intensity = 0.0f;
01108 if(VIDEO_DEBUG)
01109 cerr << "VIDEO ERROR: negative intensity passed to SetFog()" << endl;
01110 }
01111 else if(intensity > 1.0f)
01112 {
01113 intensity = 1.0f;
01114 if(VIDEO_DEBUG)
01115 cerr << "VIDEO ERROR: intensity larger than 1.0f passed to SetFog()" << endl;
01116 }
01117
01118
01119 _fog_color = color;
01120 _fog_intensity = intensity;
01121
01122
01123 if(intensity == 0.0f)
01124 {
01125 glDisable(GL_FOG);
01126 }
01127 else
01128 {
01129 glEnable(GL_FOG);
01130 glHint(GL_FOG_HINT, GL_DONT_CARE);
01131 glFogf(GL_FOG_MODE, GL_LINEAR);
01132 glFogf(GL_FOG_START, 0.0f - intensity);
01133 glFogf(GL_FOG_END, 1.0f - intensity);
01134 glFogfv(GL_FOG_COLOR, (GLfloat *)color.GetColors());
01135 }
01136
01137 return true;
01138 }
01139
01140
01141
01142
01143 void GameVideo::DisableFog()
01144 {
01145 glDisable(GL_FOG);
01146 _fog_intensity = 0.0f;
01147 }
01148
01149
01150
01151
01152
01153
01154 void GameVideo::SetTransform(float m[16])
01155 {
01156 glMatrixMode(GL_MODELVIEW);
01157 glLoadIdentity();
01158 glLoadMatrixf(m);
01159 }
01160
01161
01162
01163
01164 bool GameVideo::EnablePointLights()
01165 {
01166 _light_overlay = _CreateBlankGLTexture(1024, 1024);
01167
01168 _uses_lights = true;
01169
01170 return true;
01171 }
01172
01173
01174
01175
01176 void GameVideo::DisablePointLights()
01177 {
01178 if(_light_overlay != 0xFFFFFFFF)
01179 {
01180 _DeleteTexture(_light_overlay);
01181 }
01182
01183 _light_overlay = 0xFFFFFFFF;
01184
01185 _uses_lights = false;
01186 }
01187
01188
01189
01190
01191
01192
01193
01194 bool GameVideo::ApplyLightingOverlay()
01195 {
01196 if(_light_overlay != 0xFFFFFFFF)
01197 {
01198
01199 _BindTexture(_light_overlay);
01200 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1024, 1024, 0);
01201
01202 CoordSys temp_CoordSys = _coord_sys;
01203
01204 SetCoordSys(0.0f, 1.0f, 0.0f, 1.0f);
01205 float xlo = 0.0f, ylo = 0.0f, xhi = 1.0f, yhi = 1.0f;
01206 glEnable(GL_TEXTURE_2D);
01207
01208 float mx = _width / 1024.0f;
01209 float my = _height / 1024.0f;
01210
01211 glEnable(GL_BLEND);
01212 glBlendFunc(GL_DST_COLOR, GL_ZERO);
01213
01214 _BindTexture(_light_overlay);
01215
01216 GLfloat vertices[8] = { xlo, ylo, xhi, ylo, xhi, yhi, xlo, yhi };
01217 GLfloat tex_coords[8] = { 0.0f, 0.0f, mx, 0.0f, mx, my, 0.0f, my };
01218
01219 glEnableClientState ( GL_VERTEX_ARRAY );
01220 glEnableClientState ( GL_TEXTURE_COORD_ARRAY );
01221
01222 glVertexPointer ( 2, GL_FLOAT, 0, vertices );
01223 glTexCoordPointer ( 2, GL_FLOAT, 0, tex_coords );
01224
01225 glDrawArrays ( GL_QUADS, 0, 4 );
01226
01227 glDisableClientState ( GL_TEXTURE_COORD_ARRAY );
01228 glDisableClientState ( GL_VERTEX_ARRAY );
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240 SetCoordSys(temp_CoordSys.GetLeft(), temp_CoordSys.GetRight(), temp_CoordSys.GetBottom(), temp_CoordSys.GetTop());
01241 }
01242
01243 return true;
01244 }
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 bool GameVideo::CaptureScreen(StillImage &id)
01261 {
01262 if(VIDEO_DEBUG)
01263 cout << "VIDEO: Entering CaptureScreen()" << endl;
01264
01265
01266 GLint viewport_dimensions[4];
01267 glGetIntegerv(GL_VIEWPORT, viewport_dimensions);
01268
01269
01270 int32 width = viewport_dimensions[2];
01271 int32 height = viewport_dimensions[3];
01272 ScreenRect screen_rect(0, height, width, height);
01273
01274
01275
01276 if (id._filename == "")
01277 id._filename = "captured_screen";
01278 Image *new_image = new Image(id._filename, "<T>", width, height, false);
01279
01280
01281 TexSheet *sheet = _CreateTexSheet(RoundUpPow2(width), RoundUpPow2(height), VIDEO_TEXSHEET_ANY, false);
01282
01283 if(!sheet)
01284 {
01285
01286
01287 if (VIDEO_DEBUG)
01288 cerr << "VIDEO_DEBUG: GameVideo::_InsertImageInTexSheet() returned NULL!" << endl;
01289
01290 return false;
01291 }
01292 if (!sheet->tex_mem_manager->Insert(new_image))
01293 {
01294 if (VIDEO_DEBUG)
01295 cerr << "VIDEO_DEBUG: TexMemMgr->Insert(image) returned NULL in " << __FUNCTION__ << endl;
01296 _RemoveSheet(sheet);
01297 return false;
01298 }
01299
01300 if (!sheet->CopyScreenRect(0, 0, screen_rect))
01301 {
01302 if (VIDEO_DEBUG)
01303 cerr << "VIDEO_DEBUG: TexSheet->CopyScreenRect() failed in " << __FUNCTION__ << endl;
01304 _RemoveSheet(sheet);
01305 return false;
01306 }
01307
01308 new_image->ref_count = 1;
01309
01310
01311 if(id._width == 0.0f)
01312 id._width = (float)width;
01313
01314 if(id._height == 0.0f)
01315 id._height = (float)height;
01316
01317
01318 ImageElement element(new_image, 0, 0, 0.0f, 1.0f, 1.0f, 0.0f, id._width, id._height, id._color);
01319 id._elements.push_back(element);
01320
01321
01322 _images[id._filename] = new_image;
01323
01324 return true;
01325 }
01326
01327
01328
01329
01330
01331 void GameVideo::SetGamma(float value)
01332 {
01333 _gamma_value = value;
01334
01335
01336 if (_gamma_value > 2.0f)
01337 {
01338 if(VIDEO_DEBUG) cout << "VIDEO: Tried to set gamma over 2.0f!" << endl;
01339 _gamma_value = 2.0f;
01340 }
01341 else if (_gamma_value < 0.0f)
01342 {
01343 if(VIDEO_DEBUG) cout << "VIDEO: Tried to set gamma below 0.0f!" << endl;
01344 _gamma_value = 0.0f;
01345 }
01346
01347 SDL_SetGamma(_gamma_value, _gamma_value, _gamma_value);
01348 }
01349
01350
01351
01352
01353
01354 float GameVideo::GetGamma()
01355 {
01356 return _gamma_value;
01357 }
01358
01359
01360
01361
01362
01363
01364 void GameVideo::ToggleFPS()
01365 {
01366 _fps_display = !_fps_display;
01367 }
01368
01369
01370
01371
01372
01373
01374 std::string GameVideo::_CreateTempFilename(const std::string &extension)
01375 {
01376
01377 string file_name = "/tmp/allacrost";
01378 file_name += _next_temp_file;
01379 file_name += extension;
01380
01381
01382
01383
01384
01385
01386 for(int32 digit = 7; digit >= 0; --digit)
01387 {
01388 ++_next_temp_file[digit];
01389
01390 if(_next_temp_file[digit] > 'z')
01391 {
01392 if(digit==0)
01393 {
01394 if(VIDEO_DEBUG)
01395 cerr << "VIDEO ERROR: _nextTempFile went past 'zzzzzzzz'" << endl;
01396 return file_name;
01397 }
01398
01399 _next_temp_file[digit] = '0';
01400 }
01401 else
01402 {
01403 if(_next_temp_file[digit] > '9' && _next_temp_file[digit] < 'a')
01404 _next_temp_file[digit] = 'a';
01405
01406
01407 break;
01408 }
01409 }
01410
01411 return file_name;
01412 }
01413
01414
01415
01416
01417
01418
01419
01420 void GameVideo::_PushContext()
01421 {
01422
01423 glMatrixMode(GL_MODELVIEW);
01424 glPushMatrix();
01425
01426
01427 private_video::Context c;
01428 c.coordinate_system = _coord_sys;
01429 c.blend = _blend;
01430 c.x_align = _x_align;
01431 c.y_align = _y_align;
01432 c.x_flip = _x_flip;
01433 c.y_flip = _y_flip;
01434
01435 c.viewport = _viewport;
01436 c.scissor_rectangle = _scissor_rect;
01437 c.scissoring_enabled = _scissor_enabled;
01438
01439 c.font = _current_font;
01440 c.text_color = _current_text_color;
01441
01442 _context_stack.push(c);
01443 }
01444
01445
01446
01447
01448
01449
01450
01451 void GameVideo::_PopContext()
01452 {
01453
01454 private_video::Context c = _context_stack.top();
01455 SetCoordSys(c.coordinate_system);
01456 _blend = c.blend;
01457 _x_align = c.x_align;
01458 _y_align = c.y_align;
01459 _x_flip = c.x_flip;
01460 _y_flip = c.y_flip;
01461
01462 _current_font = c.font;
01463 _current_text_color = c.text_color;
01464
01465 _viewport = c.viewport;
01466 _scissor_rect = c.scissor_rectangle;
01467 _scissor_enabled = c.scissoring_enabled;
01468 _context_stack.pop();
01469
01470
01471 glMatrixMode(GL_MODELVIEW);
01472 glPopMatrix();
01473
01474 glViewport(_viewport.left, _viewport.top, _viewport.width, _viewport.height);
01475
01476 if(_scissor_enabled)
01477 {
01478 glEnable(GL_SCISSOR_TEST);
01479 glScissor(_scissor_rect.left, _scissor_rect.top, _scissor_rect.width, _scissor_rect.height);
01480 }
01481 else
01482 {
01483 glDisable(GL_SCISSOR_TEST);
01484 }
01485 }
01486
01487
01488
01489
01490
01491
01492 int32 GameVideo::_ConvertYAlign(int32 y_align)
01493 {
01494 switch(y_align)
01495 {
01496 case VIDEO_Y_BOTTOM:
01497 return -1;
01498 case VIDEO_Y_CENTER:
01499 return 0;
01500 default:
01501 return 1;
01502 }
01503 }
01504
01505
01506
01507
01508
01509
01510 int32 GameVideo::_ConvertXAlign(int32 x_align)
01511 {
01512 switch(x_align)
01513 {
01514 case VIDEO_X_LEFT:
01515 return -1;
01516 case VIDEO_X_CENTER:
01517 return 0;
01518 default:
01519 return 1;
01520 }
01521 }
01522
01523
01524
01525
01526 bool GameVideo::SetDefaultCursor(const std::string &cursor_image_filename)
01527 {
01528 _default_menu_cursor.SetFilename(cursor_image_filename);
01529 return LoadImage(_default_menu_cursor);
01530 }
01531
01532
01533
01534
01535
01536 StillImage *GameVideo::GetDefaultCursor()
01537 {
01538 if(_default_menu_cursor.GetWidth() != 0.0f)
01539 return &_default_menu_cursor;
01540 else
01541 return NULL;
01542 }
01543
01544
01545
01546
01547
01548
01549 void GameVideo::PushMatrix()
01550 {
01551 glPushMatrix();
01552 }
01553
01554
01555
01556
01557
01558 void GameVideo::PopMatrix()
01559 {
01560 glPopMatrix();
01561 }
01562
01563
01564
01565
01566
01567
01568 void GameVideo::EnableScissoring(bool enable)
01569 {
01570 _scissor_enabled = enable;
01571
01572 if(enable)
01573 glEnable(GL_SCISSOR_TEST);
01574 else
01575 glDisable(GL_SCISSOR_TEST);
01576 }
01577
01578
01579
01580
01581
01582
01583 void GameVideo::SetScissorRect(float left, float right, float bottom, float top)
01584 {
01585 _scissor_rect = CalculateScreenRect(left, right, bottom, top);
01586 glScissor(_scissor_rect.left, _scissor_rect.top, _scissor_rect.width, _scissor_rect.height);
01587 }
01588
01589
01590
01591
01592
01593 void GameVideo::SetScissorRect(const ScreenRect &rect)
01594 {
01595 _scissor_rect = rect;
01596 glScissor(rect.left, rect.top, rect.width, rect.height);
01597 }
01598
01599
01600
01601
01602
01603 ScreenRect GameVideo::CalculateScreenRect(float left, float right, float bottom, float top)
01604 {
01605 ScreenRect rect;
01606
01607 int32 scr_left = _ScreenCoordX(left);
01608 int32 scr_right = _ScreenCoordX(right);
01609 int32 scr_bottom = _ScreenCoordY(bottom);
01610 int32 scr_top = _ScreenCoordY(top);
01611
01612 int32 temp;
01613 if(scr_left > scr_right)
01614 {
01615 temp = scr_left;
01616 scr_left = scr_right;
01617 scr_right = temp;
01618 }
01619
01620 if(scr_top > scr_bottom)
01621 {
01622 temp = scr_top;
01623 scr_top = scr_bottom;
01624 scr_bottom = temp;
01625 }
01626
01627 rect.top = scr_top;
01628 rect.left = scr_left;
01629 rect.width = scr_right - scr_left;
01630 rect.height = scr_bottom - scr_top;
01631
01632 return rect;
01633 }
01634
01635
01636
01637
01638
01639
01640 int32 GameVideo::_ScreenCoordX(float x)
01641 {
01642 float percent;
01643 if(_coord_sys.GetLeft() < _coord_sys.GetRight())
01644 percent = (x - _coord_sys.GetLeft()) / (_coord_sys.GetRight() - _coord_sys.GetLeft());
01645 else
01646 percent = (x - _coord_sys.GetRight()) / (_coord_sys.GetLeft() - _coord_sys.GetRight());
01647
01648 return int32(percent * float(_width));
01649 }
01650
01651
01652
01653
01654
01655
01656 int32 GameVideo::_ScreenCoordY(float y)
01657 {
01658 float percent;
01659 if(_coord_sys.GetTop() < _coord_sys.GetBottom())
01660 percent = (y - _coord_sys.GetTop()) / (_coord_sys.GetBottom() - _coord_sys.GetTop());
01661 else
01662 percent = (y - _coord_sys.GetBottom()) / (_coord_sys.GetTop() - _coord_sys.GetBottom());
01663
01664 return int32(percent * float(_height));
01665 }
01666
01667
01668
01669
01670
01671
01672 bool GameVideo::_ShouldSmooth() {
01673 return ( _width != VIDEO_STANDARD_RES_WIDTH ||
01674 _height != VIDEO_STANDARD_RES_HEIGHT);
01675 }
01676
01677
01678
01679
01680
01681
01682 bool GameVideo::MakeLightning(const std::string &lit_file)
01683 {
01684 FILE *fp = fopen(lit_file.c_str(), "rb");
01685 if(!fp)
01686 return false;
01687
01688 int32 data_size;
01689 if(!fread(&data_size, 4, 1, fp))
01690 {
01691 fclose(fp);
01692 return false;
01693 }
01694
01695
01696
01697
01698 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
01699 data_size = ((data_size & 0xFF000000) >> 24) |
01700 ((data_size & 0x00FF0000) >> 8) |
01701 ((data_size & 0x0000FF00) << 8) |
01702 ((data_size & 0x000000FF) << 24);
01703 #endif
01704
01705 uint8 *data = new uint8[data_size];
01706
01707 if(!fread(data, data_size, 1, fp))
01708 {
01709 delete [] data;
01710 fclose(fp);
01711 return false;
01712 }
01713
01714 fclose(fp);
01715
01716 _lightning_data.clear();
01717
01718 for(int32 j = 0; j < data_size; ++j)
01719 {
01720 float f = float(data[j]) / 255.0f;
01721 _lightning_data.push_back(f);
01722 }
01723
01724 delete [] data;
01725
01726 _lightning_active = true;
01727 _lightning_current_time = 0;
01728 _lightning_end_time = data_size * 1000 / 100;
01729
01730 return true;
01731 }
01732
01733
01734
01735
01736
01737
01738 bool GameVideo::DrawLightning()
01739 {
01740 if(!_lightning_active)
01741 return true;
01742
01743
01744
01745 float t = _lightning_current_time * 100.0f / 1000.0f;
01746
01747 int32 rounded_t = static_cast<int32>(t);
01748 t -= rounded_t;
01749
01750
01751
01752 float data1 = _lightning_data[rounded_t];
01753 float data2 = _lightning_data[rounded_t+1];
01754
01755 float intensity = data1 * (1-t) + data2 * t;
01756
01757 DrawFullscreenOverlay(Color(1.0f, 1.0f, 1.0f, intensity));
01758
01759 return true;
01760 }
01761
01762
01763
01764
01765
01766
01767 bool GameVideo::DrawFullscreenOverlay(const Color &color)
01768 {
01769 PushState();
01770
01771 SetCoordSys(0.0f, 1.0f, 0.0f, 1.0f);
01772 SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, VIDEO_BLEND, 0);
01773 Move(0.0f, 0.0f);
01774 StillImage img;
01775 img.SetDimensions(1.0f, 1.0f);
01776 LoadImage(img);
01777 DrawImage(img, color);
01778
01779 PopState();
01780
01781 return true;
01782 }
01783
01784
01785
01786
01787
01788
01789
01790 bool GameVideo::SetTarget(VIDEO_TARGET target)
01791 {
01792 if(target <= VIDEO_TARGET_INVALID || target >= VIDEO_TARGET_TOTAL)
01793 {
01794 if(VIDEO_DEBUG)
01795 cerr << "VIDEO ERROR: tried to set video engine to invalid target (" << target << ")" << endl;
01796 return false;
01797 }
01798
01799 _target = target;
01800 return true;
01801 }
01802
01803
01804
01805
01806
01807
01808
01809 void GameVideo::DrawGrid(float x, float y, float x_step, float y_step, const Color &c)
01810 {
01811 PushState();
01812
01813 Move(0, 0);
01814
01815 float x_Max = _coord_sys.GetRight();
01816 float y_Max = _coord_sys.GetBottom();
01817
01818 std::vector<GLfloat> vertices;
01819 int numvertices = 0;
01820 for (; x <= x_Max; x += x_step)
01821 {
01822 vertices.push_back(x);
01823 vertices.push_back(_coord_sys.GetBottom());
01824 vertices.push_back(x);
01825 vertices.push_back(_coord_sys.GetTop());
01826 numvertices += 2;
01827 }
01828 for (; y < y_Max; y += y_step)
01829 {
01830 vertices.push_back(_coord_sys.GetLeft());
01831 vertices.push_back(y);
01832 vertices.push_back(_coord_sys.GetRight());
01833 vertices.push_back(y);
01834 numvertices += 2;
01835 }
01836 glColor4fv(&c[0]);
01837 glEnableClientState ( GL_VERTEX_ARRAY );
01838 glVertexPointer ( 2, GL_FLOAT, 0, &(vertices[0]) );
01839 glDrawArrays ( GL_LINES, 0, numvertices );
01840 glDisableClientState ( GL_VERTEX_ARRAY );
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857 PopState();
01858 }
01859
01860
01861
01862
01863 void GameVideo::DrawRectangle(const float width, const float height, const Color &color)
01864 {
01865 _rectangle_image._elements[0].width = width;
01866 _rectangle_image._elements[0].height = height;
01867
01868 VideoManager->DrawImage(_rectangle_image, color);
01869 }
01870
01871 }