// Init the projection matrix, viewport and stuff
apply_config();
-
+
if(texture_manager == 0)
texture_manager = new TextureManager();
else
texture_manager->reload_textures();
-
+
#ifndef GL_VERSION_ES_CM_1_0
GLenum err = glewInit();
if (GLEW_OK != err)
void
GLRenderer::draw_gradient(const DrawingRequest& request)
{
- const GradientRequest* gradientrequest
+ const GradientRequest* gradientrequest
= (GradientRequest*) request.request_data;
const Color& top = gradientrequest->top;
const Color& bottom = gradientrequest->bottom;
glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
fillrectrequest->color.blue, fillrectrequest->color.alpha);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
+
if (fillrectrequest->radius != 0.0f)
{
// draw round rect
glDisable(GL_TEXTURE_2D);
glColor4f(ellipse->color.red, ellipse->color.green,
ellipse->color.blue, ellipse->color.alpha);
-
+
float x = request.pos.x;
float y = request.pos.y;
float w = ellipse->size.x/2.0f;
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
+ glColor4f(1, 1, 1, 1);
}
-void
+void
GLRenderer::do_take_screenshot()
{
// [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
{
g_config->window_size = Size(w, h);
- PHYSICAL_SCREEN_WIDTH = w;
- PHYSICAL_SCREEN_HEIGHT = h;
-
apply_config();
}
void
GLRenderer::apply_config()
-{
+{
if (false)
{
- log_info << "Applying Config:"
+ log_info << "Applying Config:"
<< "\n Desktop: " << desktop_size.width << "x" << desktop_size.height
<< "\n Window: " << g_config->window_size
<< "\n FullRes: " << g_config->fullscreen_size
float scale = (scale1 < scale2) ? scale1 : scale2;
SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * scale);
SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * scale);
- }
+ }
else if (SCREEN_WIDTH < min_size.width || SCREEN_HEIGHT < min_size.height)
{
float scale1 = float(min_size.width)/SCREEN_WIDTH;
SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * scale);
SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * scale);
}
-
- glViewport(0, 0, screen_size.width, screen_size.height);
+ viewport.x = 0;
+ viewport.y = 0;
+ viewport.w = screen_size.width;
+ viewport.h = screen_size.height;
+
+ glViewport(viewport.x, viewport.y, viewport.w, viewport.h);
}
else
{
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(window);
- glViewport(std::max(0, (screen_size.width - new_size.width) / 2),
- std::max(0, (screen_size.height - new_size.height) / 2),
- std::min(new_size.width, screen_size.width),
- std::min(new_size.height, screen_size.height));
+ viewport.x = std::max(0, (screen_size.width - new_size.width) / 2);
+ viewport.y = std::max(0, (screen_size.height - new_size.height) / 2);
+ viewport.w = std::min(new_size.width, screen_size.width);
+ viewport.h = std::min(new_size.height, screen_size.height);
+
+ glViewport(viewport.x, viewport.y, viewport.w, viewport.h);
}
glMatrixMode(GL_PROJECTION);
{
glcontext = SDL_GL_CreateContext(window);
screen_size = size;
-
- PHYSICAL_SCREEN_WIDTH = size.width;
- PHYSICAL_SCREEN_HEIGHT = size.height;
SCREEN_WIDTH = size.width;
SCREEN_HEIGHT = size.height;
-
+
fullscreen_active = fullscreen;
}
}
Vector
GLRenderer::to_logical(int physical_x, int physical_y)
{
- return Vector(physical_x * float(SCREEN_WIDTH) / PHYSICAL_SCREEN_WIDTH,
- physical_y * float(SCREEN_HEIGHT) / PHYSICAL_SCREEN_HEIGHT);
+ return Vector(static_cast<float>(physical_x - viewport.x) * SCREEN_WIDTH / viewport.w,
+ static_cast<float>(physical_y - viewport.y) * SCREEN_HEIGHT / viewport.h);
}
void
SDLRenderer::SDLRenderer() :
window(),
renderer(),
+ viewport(),
desktop_size()
{
Renderer::instance_ = this;
SCREEN_WIDTH = width;
SCREEN_HEIGHT = height;
- PHYSICAL_SCREEN_WIDTH = width;
- PHYSICAL_SCREEN_HEIGHT = height;
+ viewport.x = 0;
+ viewport.y = 0;
+ viewport.w = SCREEN_WIDTH;
+ viewport.h = SCREEN_HEIGHT;
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
SDLPainter::draw_inverse_ellipse(renderer, request);
}
-void
+void
SDLRenderer::do_take_screenshot()
{
// [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
{
g_config->window_size = Size(w, h);
- PHYSICAL_SCREEN_WIDTH = w;
- PHYSICAL_SCREEN_HEIGHT = h;
-
apply_config();
}
{
if (false)
{
- log_info << "Applying Config:"
+ log_info << "Applying Config:"
<< "\n Desktop: " << desktop_size.width << "x" << desktop_size.height
<< "\n Window: " << g_config->window_size
<< "\n FullRes: " << g_config->fullscreen_size
if (g_config->magnification == 0.0f) // Magic value that means 'minfill'
{
+ float magnification = 1.0f;
+
// This scales SCREEN_WIDTH/SCREEN_HEIGHT so that they never excede
// max_size.width/max_size.height resp. min_size.width/min_size.height
if (SCREEN_WIDTH > max_size.width || SCREEN_HEIGHT > max_size.height)
{
float scale1 = float(max_size.width)/SCREEN_WIDTH;
float scale2 = float(max_size.height)/SCREEN_HEIGHT;
- float scale = (scale1 < scale2) ? scale1 : scale2;
- SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * scale);
- SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * scale);
- }
+ magnification = (scale1 < scale2) ? scale1 : scale2;
+ SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * magnification);
+ SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * magnification);
+ }
else if (SCREEN_WIDTH < min_size.width || SCREEN_HEIGHT < min_size.height)
{
float scale1 = float(min_size.width)/SCREEN_WIDTH;
float scale2 = float(min_size.height)/SCREEN_HEIGHT;
- float scale = (scale1 < scale2) ? scale1 : scale2;
- SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * scale);
- SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * scale);
+ magnification = (scale1 < scale2) ? scale1 : scale2;
+ SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * magnification);
+ SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * magnification);
}
+
+ viewport.x = 0;
+ viewport.y = 0;
+ viewport.w = screen_size.width;
+ viewport.h = screen_size.height;
+
+ SDL_RenderSetScale(renderer, 1.0f, 1.0f);
+ SDL_RenderSetViewport(renderer, &viewport);
+ SDL_RenderSetScale(renderer, magnification, magnification);
}
else
{
new_size.height = static_cast<int>((float) new_size.height * float(max_size.height)/SCREEN_HEIGHT);
SCREEN_HEIGHT = static_cast<int>(max_size.height);
}
- }
- // Clear the screen to avoid garbage in unreachable areas after we
- // reset the coordinate system
- SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
- SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
- SDL_RenderClear(renderer);
- SDL_RenderPresent(renderer);
- SDL_RenderClear(renderer);
-
- // This doesn't really do what we want, as it sales the area to fill
- // the screen, but seems to be the only way to reset the coordinate
- // system and it's "close enough" to what we want, see:
- // https://bugzilla.libsdl.org/show_bug.cgi?id=2179
- SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);
+ // Clear the screen to avoid garbage in unreachable areas after we
+ // reset the coordinate system
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
+ SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
+ SDL_RenderClear(renderer);
+ SDL_RenderPresent(renderer);
+ SDL_RenderClear(renderer);
+
+ viewport.x = std::max(0, (screen_size.width - new_size.width) / 2);
+ viewport.y = std::max(0, (screen_size.height - new_size.height) / 2);
+ viewport.w = std::min(new_size.width, screen_size.width);
+ viewport.h = std::min(new_size.height, screen_size.height);
+
+ SDL_RenderSetScale(renderer, 1.0f, 1.0f);
+ SDL_RenderSetViewport(renderer, &viewport);
+ SDL_RenderSetScale(renderer, g_config->magnification, g_config->magnification);
+ }
}
Vector
SDLRenderer::to_logical(int physical_x, int physical_y)
{
- // SDL is doing the translation internally, so we have nothing to do
- return Vector(physical_x, physical_y);
+ return Vector(static_cast<float>(physical_x - viewport.x) * SCREEN_WIDTH / viewport.w,
+ static_cast<float>(physical_y - viewport.y) * SCREEN_HEIGHT / viewport.h);
}
void