
На HiDPI мониторах downscaled текстуры выглядят мягко говоря не очень красиво. Искал способ решить эту проблему. В итоге мои исследования привели к такому не самому легковесному решению.
- Получить device pixel ratio для настройки размров canvas.
- Получить размер canvas и разрешение css.
- На их основе вычислить отношение.
- Использовать это отношение для расчета координат мыши и тача.
После этого все будет выглядеть красиво на HiDPI мониторах. Но есть одна “особенность” – увеличенный (в зависимости от отношения размеров css и canvas) в несколько раз фреймбуфер. При отношении равном 2, получаем размер фреймбуфера в четыре раза больший, со всеми вытекающими.
Немного кода
CSS
canvas {
width: 100vw;
height: 100vh;
display: block;
}
canvas {
width: 100vw;
height: 100vh;
display: block;
}
canvas { width: 100vw; height: 100vh; display: block; }
JavaScript
window.addEventListener('resize', resizeCanvas, false);
function resizeCanvas() {
var realToCSSPixels = window.devicePixelRatio;
var displayWidth = Math.floor(canvas.clientWidth * realToCSSPixels);
var displayHeight = Math.floor(canvas.clientHeight * realToCSSPixels);
if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
canvas.width = displayWidth;
canvas.height = displayHeight;
}
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas, false);
function resizeCanvas() {
var realToCSSPixels = window.devicePixelRatio;
var displayWidth = Math.floor(canvas.clientWidth * realToCSSPixels);
var displayHeight = Math.floor(canvas.clientHeight * realToCSSPixels);
if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
canvas.width = displayWidth;
canvas.height = displayHeight;
}
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas, false); function resizeCanvas() { var realToCSSPixels = window.devicePixelRatio; var displayWidth = Math.floor(canvas.clientWidth * realToCSSPixels); var displayHeight = Math.floor(canvas.clientHeight * realToCSSPixels); if (canvas.width !== displayWidth || canvas.height !== displayHeight) { canvas.width = displayWidth; canvas.height = displayHeight; } } resizeCanvas();
C++
int width, height;
emscripten_get_canvas_element_size(nullptr, &width, &height);
double cssWidth, cssHeight;
emscripten_get_element_css_size(nullptr, &cssWidth, &cssHeight);
const auto ratiox = (float)(width / cssWidth);
const auto ration = (float)(height / cssHeight);
int width, height;
emscripten_get_canvas_element_size(nullptr, &width, &height);
double cssWidth, cssHeight;
emscripten_get_element_css_size(nullptr, &cssWidth, &cssHeight);
const auto ratiox = (float)(width / cssWidth);
const auto ration = (float)(height / cssHeight);
int width, height; emscripten_get_canvas_element_size(nullptr, &width, &height); double cssWidth, cssHeight; emscripten_get_element_css_size(nullptr, &cssWidth, &cssHeight); const auto ratiox = (float)(width / cssWidth); const auto ration = (float)(height / cssHeight);
Можно сделать настройку, доступную пользователю – пусть он сам решает, что ему лучше – производительность или качество рендеринга.