У меня есть строгое требование иметь текстуру с разрешением (скажем) 512x512 всегда (даже если окно больше, а SDL в основном масштабирует текстуру для меня при рендеринге).Это потому, что это эмулятор классического старого компьютера, предполагающего фиксированную текстуру, я не могу переписать код для динамического принятия нескольких размеров текстур и / или соотношений текстур.
Я использую SDL_RenderSetLogicalSize()
для цели IВыше описано.
Конечно, когда это отображается в окне, я могу получить координаты мыши (относительное окно), и я могу «масштабировать» обратно до положения текстуры с получением реального размера окна (размер окна может быть изменен).
Однако здесь есть большая проблема .Как только соотношение ширины окна к высоте не совпадает с соотношением текстур (например, в полноэкранном режиме, поскольку соотношение современных дисплеев не будет совпадать с соотношением, которое я хочу использовать), на панели появляются «черные полосы»стороны или верх / низ.Это хорошо, так как я хочу всегда иметь одинаковое соотношение текстур, фиксированное, и SDL делает это для меня и т. Д. Однако я не могу найти способ спросить SDL, где моя текстура отображается именно внутри окна на основе фиксированного соотношения, которое я принудительно установил.Поскольку мне нужна только позиция внутри текстуры, а точный источник текстуры размещается самим SDL, а не мной.
Конечно, я могу написать некоторый код, чтобы выяснить, как эти "черные полосы" изменили быПроисхождение текстуры, но я могу надеяться, что есть более простой и элегантный способ «спросить» SDL об этом, поскольку, безусловно, он имеет код для размещения моей текстуры где-то, поэтому я могу повторно использовать эту информацию.
Мое очень уродливое (можно оптимизировать и избежать математики с плавающей точкой, я думаю, но в качестве первой попытки ...) решение:
static void get_mouse_texture_coords ( int x, int y )
{
int win_x_size, win_y_size;
SDL_GetWindowSize(sdl_win, &win_x_size, &win_y_size);
// I don't know if there is more sane way for this ...
// But we must figure out where is the texture within the window,
// which can be changed since the fixed ratio versus the window ratio (especially in full screen mode)
double aspect_tex = (double)SCREEN_W / (double)SCREEN_H;
double aspect_win = (double)win_x_size / (double)win_y_size;
if (aspect_win >= aspect_tex) {
// side ratio correction bars must be taken account
double zoom_factor = (double)win_y_size / (double)SCREEN_H;
int bar_size = win_x_size - (int)((double)SCREEN_W * zoom_factor);
mouse_x = (x - bar_size / 2) / zoom_factor;
mouse_y = y / zoom_factor;
} else {
// top-bottom ratio correction bars must be taken account
double zoom_factor = (double)win_x_size / (double)SCREEN_W;
int bar_size = win_y_size - (int)((double)SCREEN_H * zoom_factor);
mouse_x = x / zoom_factor;
mouse_y = (y - bar_size / 2) / zoom_factor;
}
}
Где SCREEN_W
и SCREEN_H
- этоРазмеры моей текстуры, довольно вводящие в заблуждение по именам, но все равно.Входные параметры x
и y
- это положение мыши относительно окна (сообщается SDL).mouse_x
и mouse_y
- результат, основанный на текстуре координаты.Кажется, это работает хорошо.Однако есть ли вменяемое решение или лучшее?
Код, который вызывает вышеуказанную функцию, находится в моем цикле обработчика событий (который я регулярно вызываю, конечно), что-то вроде этого:
void handle_sdl_events ( void ) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_MOUSEMOTION:
get_mouse_texture_coords(event.motion.x, event.motion.y);
break;
[...]