#include <gl_renderer.hpp>
Inherits Renderer.
Public Member Functions | |
GLRenderer () | |
~GLRenderer () | |
void | draw_surface (const DrawingRequest &request) |
void | draw_surface_part (const DrawingRequest &request) |
void | draw_text (const DrawingRequest &request) |
void | draw_gradient (const DrawingRequest &request) |
void | draw_filled_rect (const DrawingRequest &request) |
void | draw_inverse_ellipse (const DrawingRequest &request) |
void | do_take_screenshot () |
void | flip () |
void | resize (int w, int h) |
void | apply_config () |
void | apply_video_mode (const Size &size, bool fullscreen) |
Private Attributes | |
Size | desktop_size |
Size | screen_size |
bool | fullscreen_active |
Definition at line 106 of file gl_renderer.hpp.
GLRenderer::GLRenderer | ( | ) |
Definition at line 34 of file gl_renderer.cpp.
References apply_config(), apply_video_mode(), desktop_size, Config::fullscreen_size, g_config, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GLenum, Renderer::instance_, log_info, texture_manager, Config::use_fullscreen, and Config::window_size.
00034 : 00035 desktop_size(-1, -1), 00036 screen_size(-1, -1), 00037 fullscreen_active(false) 00038 { 00039 Renderer::instance_ = this; 00040 00041 #if SDL_MAJOR_VERSION > 1 || SDL_MINOR_VERSION > 2 || (SDL_MINOR_VERSION == 2 && SDL_PATCHLEVEL >= 10) 00042 // unfortunately only newer SDLs have these infos. 00043 // This must be called before SDL_SetVideoMode() or it will return 00044 // the window size instead of the desktop size. 00045 const SDL_VideoInfo *info = SDL_GetVideoInfo(); 00046 if (info) 00047 { 00048 desktop_size = Size(info->current_w, info->current_h); 00049 } 00050 #endif 00051 00052 if(texture_manager != 0) 00053 texture_manager->save_textures(); 00054 00055 #ifdef SDL_GL_SWAP_CONTROL 00056 if(config->try_vsync) { 00057 /* we want vsync for smooth scrolling */ 00058 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); 00059 } 00060 #endif 00061 00062 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 00063 00064 // FIXME: Hu? 16bit rendering? 00065 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); 00066 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); 00067 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); 00068 00069 if(g_config->use_fullscreen) 00070 { 00071 apply_video_mode(g_config->fullscreen_size, true); 00072 } 00073 else 00074 { 00075 apply_video_mode(g_config->window_size, false); 00076 } 00077 00078 // setup opengl state and transform 00079 glDisable(GL_DEPTH_TEST); 00080 glDisable(GL_CULL_FACE); 00081 glEnable(GL_TEXTURE_2D); 00082 glEnable(GL_BLEND); 00083 glEnableClientState(GL_VERTEX_ARRAY); 00084 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 00085 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00086 00087 // Init the projection matrix, viewport and stuff 00088 apply_config(); 00089 00090 if(texture_manager == 0) 00091 texture_manager = new TextureManager(); 00092 else 00093 texture_manager->reload_textures(); 00094 00095 #ifndef GL_VERSION_ES_CM_1_0 00096 GLenum err = glewInit(); 00097 if (GLEW_OK != err) 00098 { 00099 std::ostringstream out; 00100 out << "GLRenderer: " << glewGetErrorString(err); 00101 throw std::runtime_error(out.str()); 00102 } 00103 log_info << "Using GLEW " << glewGetString(GLEW_VERSION) << std::endl; 00104 log_info << "GLEW_ARB_texture_non_power_of_two: " << static_cast<int>(GLEW_ARB_texture_non_power_of_two) << std::endl; 00105 #endif 00106 }
GLRenderer::~GLRenderer | ( | ) |
void GLRenderer::draw_surface | ( | const DrawingRequest & | request | ) | [virtual] |
Implements Renderer.
Definition at line 113 of file gl_renderer.cpp.
References DrawingRequest::alpha, DrawingRequest::angle, DrawingRequest::blend, DrawingRequest::color, DrawingRequest::drawing_effect, Surface::get_height(), Surface::get_surface_data(), Surface::get_texture(), GLSurfaceData::get_uv_bottom(), GLSurfaceData::get_uv_left(), GLSurfaceData::get_uv_right(), GLSurfaceData::get_uv_top(), Surface::get_width(), intern_draw(), DrawingRequest::pos, DrawingRequest::request_data, Vector::x, and Vector::y.
00114 { 00115 const Surface* surface = (const Surface*) request.request_data; 00116 GLTexture* gltexture = static_cast<GLTexture*>(surface->get_texture().get()); 00117 GLSurfaceData *surface_data = static_cast<GLSurfaceData*>(surface->get_surface_data()); 00118 00119 glBindTexture(GL_TEXTURE_2D, gltexture->get_handle()); 00120 intern_draw(request.pos.x, request.pos.y, 00121 request.pos.x + surface->get_width(), 00122 request.pos.y + surface->get_height(), 00123 surface_data->get_uv_left(), 00124 surface_data->get_uv_top(), 00125 surface_data->get_uv_right(), 00126 surface_data->get_uv_bottom(), 00127 request.angle, 00128 request.alpha, 00129 request.color, 00130 request.blend, 00131 request.drawing_effect); 00132 }
void GLRenderer::draw_surface_part | ( | const DrawingRequest & | request | ) | [virtual] |
Implements Renderer.
Definition at line 135 of file gl_renderer.cpp.
References DrawingRequest::alpha, DrawingRequest::color, DrawingRequest::drawing_effect, GLSurfaceData::get_uv_bottom(), GLSurfaceData::get_uv_left(), GLSurfaceData::get_uv_right(), GLSurfaceData::get_uv_top(), intern_draw(), DrawingRequest::pos, DrawingRequest::request_data, SurfacePartRequest::size, SurfacePartRequest::source, SurfacePartRequest::surface, Vector::x, and Vector::y.
00136 { 00137 const SurfacePartRequest* surfacepartrequest 00138 = (SurfacePartRequest*) request.request_data; 00139 const Surface* surface = surfacepartrequest->surface; 00140 boost::shared_ptr<GLTexture> gltexture = boost::dynamic_pointer_cast<GLTexture>(surface->get_texture()); 00141 GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data()); 00142 00143 float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left(); 00144 float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top(); 00145 00146 float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width(); 00147 float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height(); 00148 float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width(); 00149 float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height(); 00150 00151 glBindTexture(GL_TEXTURE_2D, gltexture->get_handle()); 00152 intern_draw(request.pos.x, request.pos.y, 00153 request.pos.x + surfacepartrequest->size.x, 00154 request.pos.y + surfacepartrequest->size.y, 00155 uv_left, 00156 uv_top, 00157 uv_right, 00158 uv_bottom, 00159 0.0, 00160 request.alpha, 00161 request.color, 00162 Blend(), 00163 request.drawing_effect); 00164 }
void GLRenderer::draw_text | ( | const DrawingRequest & | request | ) |
void GLRenderer::draw_gradient | ( | const DrawingRequest & | request | ) | [virtual] |
Implements Renderer.
Definition at line 167 of file gl_renderer.cpp.
References GradientRequest::bottom, DrawingRequest::request_data, SCREEN_HEIGHT, SCREEN_WIDTH, and GradientRequest::top.
00168 { 00169 const GradientRequest* gradientrequest 00170 = (GradientRequest*) request.request_data; 00171 const Color& top = gradientrequest->top; 00172 const Color& bottom = gradientrequest->bottom; 00173 00174 glDisable(GL_TEXTURE_2D); 00175 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 00176 glEnableClientState(GL_COLOR_ARRAY); 00177 00178 float vertices[] = { 00179 0, 0, 00180 SCREEN_WIDTH, 0, 00181 SCREEN_WIDTH, SCREEN_HEIGHT, 00182 0, SCREEN_HEIGHT 00183 }; 00184 glVertexPointer(2, GL_FLOAT, 0, vertices); 00185 00186 float colors[] = { 00187 top.red, top.green, top.blue, top.alpha, 00188 top.red, top.green, top.blue, top.alpha, 00189 bottom.red, bottom.green, bottom.blue, bottom.alpha, 00190 bottom.red, bottom.green, bottom.blue, bottom.alpha, 00191 }; 00192 glColorPointer(4, GL_FLOAT, 0, colors); 00193 00194 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 00195 00196 glDisableClientState(GL_COLOR_ARRAY); 00197 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 00198 00199 glEnable(GL_TEXTURE_2D); 00200 glColor4f(1, 1, 1, 1); 00201 }
void GLRenderer::draw_filled_rect | ( | const DrawingRequest & | request | ) | [virtual] |
Implements Renderer.
Definition at line 204 of file gl_renderer.cpp.
References Color::alpha, Color::blue, FillRectRequest::color, Rectf::get_bottom(), Rectf::get_left(), Rectf::get_right(), Rectf::get_top(), Color::green, DrawingRequest::pos, FillRectRequest::radius, Color::red, DrawingRequest::request_data, FillRectRequest::size, Vector::x, and Vector::y.
00205 { 00206 const FillRectRequest* fillrectrequest 00207 = (FillRectRequest*) request.request_data; 00208 00209 glDisable(GL_TEXTURE_2D); 00210 glColor4f(fillrectrequest->color.red, fillrectrequest->color.green, 00211 fillrectrequest->color.blue, fillrectrequest->color.alpha); 00212 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 00213 00214 if (fillrectrequest->radius != 0.0f) 00215 { 00216 // draw round rect 00217 // Keep radius in the limits, so that we get a circle instead of 00218 // just graphic junk 00219 float radius = std::min(fillrectrequest->radius, 00220 std::min(fillrectrequest->size.x/2, 00221 fillrectrequest->size.y/2)); 00222 00223 // inner rectangle 00224 Rectf irect(request.pos.x + radius, 00225 request.pos.y + radius, 00226 request.pos.x + fillrectrequest->size.x - radius, 00227 request.pos.y + fillrectrequest->size.y - radius); 00228 00229 int n = 8; 00230 int p = 0; 00231 std::vector<float> vertices((n+1) * 4 * 2); 00232 00233 for(int i = 0; i <= n; ++i) 00234 { 00235 float x = sinf(i * (M_PI/2) / n) * radius; 00236 float y = cosf(i * (M_PI/2) / n) * radius; 00237 00238 vertices[p++] = irect.get_left() - x; 00239 vertices[p++] = irect.get_top() - y; 00240 00241 vertices[p++] = irect.get_right() + x; 00242 vertices[p++] = irect.get_top() - y; 00243 } 00244 00245 for(int i = 0; i <= n; ++i) 00246 { 00247 float x = cosf(i * (M_PI/2) / n) * radius; 00248 float y = sinf(i * (M_PI/2) / n) * radius; 00249 00250 vertices[p++] = irect.get_left() - x; 00251 vertices[p++] = irect.get_bottom() + y; 00252 00253 vertices[p++] = irect.get_right() + x; 00254 vertices[p++] = irect.get_bottom() + y; 00255 } 00256 00257 glVertexPointer(2, GL_FLOAT, 0, &*vertices.begin()); 00258 glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size()/2); 00259 } 00260 else 00261 { 00262 float x = request.pos.x; 00263 float y = request.pos.y; 00264 float w = fillrectrequest->size.x; 00265 float h = fillrectrequest->size.y; 00266 00267 float vertices[] = { 00268 x, y, 00269 x+w, y, 00270 x+w, y+h, 00271 x, y+h 00272 }; 00273 glVertexPointer(2, GL_FLOAT, 0, vertices); 00274 00275 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 00276 } 00277 00278 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 00279 glEnable(GL_TEXTURE_2D); 00280 glColor4f(1, 1, 1, 1); 00281 }
void GLRenderer::draw_inverse_ellipse | ( | const DrawingRequest & | request | ) | [virtual] |
Implements Renderer.
Definition at line 284 of file gl_renderer.cpp.
References Color::alpha, Color::blue, InverseEllipseRequest::color, Color::green, DrawingRequest::pos, Color::red, DrawingRequest::request_data, SCREEN_HEIGHT, SCREEN_WIDTH, InverseEllipseRequest::size, Vector::x, and Vector::y.
00285 { 00286 const InverseEllipseRequest* ellipse = (InverseEllipseRequest*)request.request_data; 00287 00288 glDisable(GL_TEXTURE_2D); 00289 glColor4f(ellipse->color.red, ellipse->color.green, 00290 ellipse->color.blue, ellipse->color.alpha); 00291 00292 float x = request.pos.x; 00293 float y = request.pos.y; 00294 float w = ellipse->size.x/2.0f; 00295 float h = ellipse->size.y/2.0f; 00296 00297 static const int slices = 16; 00298 static const int points = (slices+1) * 12; 00299 00300 float vertices[points * 2]; 00301 int p = 0; 00302 00303 // Bottom 00304 vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT; 00305 vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT; 00306 vertices[p++] = x; vertices[p++] = y+h; 00307 00308 // Top 00309 vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0; 00310 vertices[p++] = 0; vertices[p++] = 0; 00311 vertices[p++] = x; vertices[p++] = y-h; 00312 00313 // Left 00314 vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0; 00315 vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT; 00316 vertices[p++] = x+w; vertices[p++] = y; 00317 00318 // Right 00319 vertices[p++] = 0; vertices[p++] = 0; 00320 vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT; 00321 vertices[p++] = x-w; vertices[p++] = y; 00322 00323 for(int i = 0; i < slices; ++i) 00324 { 00325 float ex1 = sinf(M_PI/2 / slices * i) * w; 00326 float ey1 = cosf(M_PI/2 / slices * i) * h; 00327 00328 float ex2 = sinf(M_PI/2 / slices * (i+1)) * w; 00329 float ey2 = cosf(M_PI/2 / slices * (i+1)) * h; 00330 00331 // Bottom/Right 00332 vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT; 00333 vertices[p++] = x + ex1; vertices[p++] = y + ey1; 00334 vertices[p++] = x + ex2; vertices[p++] = y + ey2; 00335 00336 // Top/Left 00337 vertices[p++] = 0; vertices[p++] = 0; 00338 vertices[p++] = x - ex1; vertices[p++] = y - ey1; 00339 vertices[p++] = x - ex2; vertices[p++] = y - ey2; 00340 00341 // Top/Right 00342 vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0; 00343 vertices[p++] = x + ex1; vertices[p++] = y - ey1; 00344 vertices[p++] = x + ex2; vertices[p++] = y - ey2; 00345 00346 // Bottom/Left 00347 vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT; 00348 vertices[p++] = x - ex1; vertices[p++] = y + ey1; 00349 vertices[p++] = x - ex2; vertices[p++] = y + ey2; 00350 } 00351 00352 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 00353 glVertexPointer(2, GL_FLOAT, 0, vertices); 00354 00355 glDrawArrays(GL_TRIANGLES, 0, points); 00356 00357 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 00358 00359 glEnable(GL_TEXTURE_2D); 00360 glColor4f(1, 1, 1, 1); 00361 }
void GLRenderer::do_take_screenshot | ( | ) | [virtual] |
Implements Renderer.
Definition at line 364 of file gl_renderer.cpp.
References log_debug, log_warning, SCREEN_HEIGHT, and SCREEN_WIDTH.
00365 { 00366 // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it? 00367 00368 SDL_Surface *shot_surf; 00369 // create surface to hold screenshot 00370 #if SDL_BYTEORDER == SDL_BIG_ENDIAN 00371 shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0); 00372 #else 00373 shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0); 00374 #endif 00375 if (!shot_surf) { 00376 log_warning << "Could not create RGB Surface to contain screenshot" << std::endl; 00377 return; 00378 } 00379 00380 // read pixels into array 00381 char* pixels = new char[3 * SCREEN_WIDTH * SCREEN_HEIGHT]; 00382 if (!pixels) { 00383 log_warning << "Could not allocate memory to store screenshot" << std::endl; 00384 SDL_FreeSurface(shot_surf); 00385 return; 00386 } 00387 glPixelStorei(GL_PACK_ALIGNMENT, 1); 00388 glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels); 00389 00390 // copy array line-by-line 00391 for (int i = 0; i < SCREEN_HEIGHT; i++) { 00392 char* src = pixels + (3 * SCREEN_WIDTH * (SCREEN_HEIGHT - i - 1)); 00393 if(SDL_MUSTLOCK(shot_surf)) 00394 { 00395 SDL_LockSurface(shot_surf); 00396 } 00397 char* dst = ((char*)shot_surf->pixels) + i * shot_surf->pitch; 00398 memcpy(dst, src, 3 * SCREEN_WIDTH); 00399 if(SDL_MUSTLOCK(shot_surf)) 00400 { 00401 SDL_UnlockSurface(shot_surf); 00402 } 00403 } 00404 00405 // free array 00406 delete[](pixels); 00407 00408 // save screenshot 00409 static const std::string writeDir = PHYSFS_getWriteDir(); 00410 static const std::string dirSep = PHYSFS_getDirSeparator(); 00411 static const std::string baseName = "screenshot"; 00412 static const std::string fileExt = ".bmp"; 00413 std::string fullFilename; 00414 for (int num = 0; num < 1000; num++) { 00415 std::ostringstream oss; 00416 oss << baseName; 00417 oss << std::setw(3) << std::setfill('0') << num; 00418 oss << fileExt; 00419 std::string fileName = oss.str(); 00420 fullFilename = writeDir + dirSep + fileName; 00421 if (!PHYSFS_exists(fileName.c_str())) { 00422 SDL_SaveBMP(shot_surf, fullFilename.c_str()); 00423 log_debug << "Wrote screenshot to \"" << fullFilename << "\"" << std::endl; 00424 SDL_FreeSurface(shot_surf); 00425 return; 00426 } 00427 } 00428 log_warning << "Did not save screenshot, because all files up to \"" << fullFilename << "\" already existed" << std::endl; 00429 SDL_FreeSurface(shot_surf); 00430 }
void GLRenderer::flip | ( | ) | [virtual] |
void GLRenderer::resize | ( | int | w, | |
int | h | |||
) | [virtual] |
Implements Renderer.
Definition at line 440 of file gl_renderer.cpp.
References apply_config(), g_config, and Config::window_size.
00441 { 00442 // This causes the screen to go black, which is annoying, but seems 00443 // unavoidable with SDL at the moment 00444 SDL_SetVideoMode(w, h, 0, SDL_OPENGL | SDL_RESIZABLE); 00445 00446 g_config->window_size = Size(w, h); 00447 00448 apply_config(); 00449 }
void GLRenderer::apply_config | ( | ) | [virtual] |
Implements Renderer.
Definition at line 452 of file gl_renderer.cpp.
References apply_video_mode(), Config::aspect_size, desktop_size, Config::fullscreen_size, g_config, Size::height, log_info, Config::magnification, scale(), SCREEN_HEIGHT, screen_size, SCREEN_WIDTH, Config::use_fullscreen, Size::width, and Config::window_size.
Referenced by GLRenderer(), and resize().
00453 { 00454 if (false) 00455 { 00456 log_info << "Applying Config:" 00457 << "\n Desktop: " << desktop_size.width << "x" << desktop_size.height 00458 << "\n Window: " << g_config->window_size 00459 << "\n FullRes: " << g_config->fullscreen_size 00460 << "\n Aspect: " << g_config->aspect_size 00461 << "\n Magnif: " << g_config->magnification 00462 << std::endl; 00463 } 00464 00465 float target_aspect = static_cast<float>(desktop_size.width) / static_cast<float>(desktop_size.height); 00466 if (g_config->aspect_size != Size(0, 0)) 00467 { 00468 target_aspect = float(g_config->aspect_size.width) / float(g_config->aspect_size.height); 00469 } 00470 00471 float desktop_aspect = 4.0f / 3.0f; // random default fallback guess 00472 if (desktop_size.width != -1 && desktop_size.height != -1) 00473 { 00474 desktop_aspect = float(desktop_size.width) / float(desktop_size.height); 00475 } 00476 00477 Size screen_size; 00478 00479 // Get the screen width 00480 if (g_config->use_fullscreen) 00481 { 00482 screen_size = g_config->fullscreen_size; 00483 desktop_aspect = float(screen_size.width) / float(screen_size.height); 00484 } 00485 else 00486 { 00487 screen_size = g_config->window_size; 00488 } 00489 00490 apply_video_mode(screen_size, g_config->use_fullscreen); 00491 00492 if (target_aspect > 1.0f) 00493 { 00494 SCREEN_WIDTH = static_cast<int>(screen_size.width * (target_aspect / desktop_aspect)); 00495 SCREEN_HEIGHT = static_cast<int>(screen_size.height); 00496 } 00497 else 00498 { 00499 SCREEN_WIDTH = static_cast<int>(screen_size.width); 00500 SCREEN_HEIGHT = static_cast<int>(screen_size.height * (target_aspect / desktop_aspect)); 00501 } 00502 00503 Size max_size(1280, 800); 00504 Size min_size(640, 480); 00505 00506 if (g_config->magnification == 0.0f) // Magic value that means 'minfill' 00507 { 00508 // This scales SCREEN_WIDTH/SCREEN_HEIGHT so that they never excede 00509 // max_size.width/max_size.height resp. min_size.width/min_size.height 00510 if (SCREEN_WIDTH > max_size.width || SCREEN_HEIGHT > max_size.height) 00511 { 00512 float scale1 = float(max_size.width)/SCREEN_WIDTH; 00513 float scale2 = float(max_size.height)/SCREEN_HEIGHT; 00514 float scale = (scale1 < scale2) ? scale1 : scale2; 00515 SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * scale); 00516 SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * scale); 00517 } 00518 else if (SCREEN_WIDTH < min_size.width || SCREEN_HEIGHT < min_size.height) 00519 { 00520 float scale1 = float(min_size.width)/SCREEN_WIDTH; 00521 float scale2 = float(min_size.height)/SCREEN_HEIGHT; 00522 float scale = (scale1 < scale2) ? scale1 : scale2; 00523 SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * scale); 00524 SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * scale); 00525 } 00526 00527 00528 glViewport(0, 0, screen_size.width, screen_size.height); 00529 } 00530 else 00531 { 00532 SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH / g_config->magnification); 00533 SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT / g_config->magnification); 00534 00535 // This works by adding black borders around the screen to limit 00536 // SCREEN_WIDTH/SCREEN_HEIGHT to max_size.width/max_size.height 00537 Size new_size = screen_size; 00538 00539 if (SCREEN_WIDTH > max_size.width) 00540 { 00541 new_size.width = static_cast<int>((float) new_size.width * float(max_size.width)/SCREEN_WIDTH); 00542 SCREEN_WIDTH = static_cast<int>(max_size.width); 00543 } 00544 00545 if (SCREEN_HEIGHT > max_size.height) 00546 { 00547 new_size.height = static_cast<int>((float) new_size.height * float(max_size.height)/SCREEN_HEIGHT); 00548 SCREEN_HEIGHT = static_cast<int>(max_size.height); 00549 } 00550 00551 // Clear both buffers so that we get a clean black border without junk 00552 glClear(GL_COLOR_BUFFER_BIT); 00553 SDL_GL_SwapBuffers(); 00554 glClear(GL_COLOR_BUFFER_BIT); 00555 SDL_GL_SwapBuffers(); 00556 00557 glViewport(std::max(0, (screen_size.width - new_size.width) / 2), 00558 std::max(0, (screen_size.height - new_size.height) / 2), 00559 std::min(new_size.width, screen_size.width), 00560 std::min(new_size.height, screen_size.height)); 00561 } 00562 00563 glMatrixMode(GL_PROJECTION); 00564 glLoadIdentity(); 00565 00566 glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1, 1); 00567 00568 glMatrixMode(GL_MODELVIEW); 00569 glLoadIdentity(); 00570 glTranslatef(0, 0, 0); 00571 check_gl_error("Setting up view matrices"); 00572 }
void GLRenderer::apply_video_mode | ( | const Size & | size, | |
bool | fullscreen | |||
) |
Definition at line 575 of file gl_renderer.cpp.
References fullscreen_active, Size::height, screen_size, and Size::width.
Referenced by apply_config(), and GLRenderer().
00576 { 00577 // Only change video mode when its different from the current one 00578 if (screen_size != size || fullscreen_active != fullscreen) 00579 { 00580 int flags = SDL_OPENGL; 00581 00582 if (fullscreen) 00583 { 00584 flags |= SDL_FULLSCREEN; 00585 } 00586 else 00587 { 00588 flags |= SDL_RESIZABLE; 00589 } 00590 00591 if (SDL_Surface *screen = SDL_SetVideoMode(size.width, size.height, 0, flags)) 00592 { 00593 screen_size = Size(screen->w, screen->h); 00594 fullscreen_active = fullscreen; 00595 } 00596 else 00597 { 00598 std::ostringstream msg; 00599 msg << "Couldn't set video mode " << size.width << "x" << size.height << ": " << SDL_GetError(); 00600 throw std::runtime_error(msg.str()); 00601 } 00602 } 00603 }
Size GLRenderer::desktop_size [private] |
Size GLRenderer::screen_size [private] |
Definition at line 110 of file gl_renderer.hpp.
Referenced by apply_config(), and apply_video_mode().
bool GLRenderer::fullscreen_active [private] |